diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7e6b92fc..c69132fd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: rm $ZIPNAME echo "OUTNAME=${ZIPNAME%.zip}" >> $GITHUB_ENV - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: ${{ env.OUTNAME }} path: release/* diff --git a/.gitignore b/.gitignore index 2f203cf95..0b2f6cff2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.obj *.elf *.map +*.dis # Precompiled Headers *.gch @@ -35,10 +36,14 @@ # OS leftovers desktop.ini +.DS_Store # Sublime files *.sublime-* +# Visual Studio Code files +.vscode + # Build directories /build /output @@ -49,3 +54,5 @@ desktop.ini # User additions /zzz_backup +/arm9/source/language.inl +*.trf diff --git a/Makefile b/Makefile index cfbec5c0f..81b6695b4 100644 --- a/Makefile +++ b/Makefile @@ -16,18 +16,28 @@ export RELDIR := release export COMMON_DIR := ../common # Definitions for initial RAM disk -VRAM_OUT := $(OUTDIR)/vram0.tar -VRAM_DATA := data -VRAM_FLAGS := --make-new --path-limit 99 --size-limit 262144 +VRAM_TAR := $(OUTDIR)/vram0.tar +VRAM_DATA := data/* +VRAM_FLAGS := --make-new --path-limit 99 ifeq ($(NTRBOOT),1) - VRAM_SCRIPTS := resources/gm9/scripts + VRAM_SCRIPTS := resources/gm9/scripts/* endif +# Definitions for translation files +JSON_FOLDER := resources/languages +TRF_FOLDER := resources/gm9/languages + +SOURCE_JSON := $(JSON_FOLDER)/source.json +LANGUAGE_INL := arm9/source/language.inl + +JSON_FILES := $(filter-out $(SOURCE_JSON),$(wildcard $(JSON_FOLDER)/*.json)) +TRF_FILES := $(subst $(JSON_FOLDER),$(TRF_FOLDER),$(JSON_FILES:.json=.trf)) + ifeq ($(OS),Windows_NT) ifeq ($(TERM),cygwin) PY3 := py -3 # Windows / CMD/PowerShell else - PY3 := python3 # Windows / MSYS2 + PY3 := py # Windows / MSYS2 endif else PY3 := python3 # Unix-like @@ -40,18 +50,18 @@ export ASFLAGS := -g -x assembler-with-cpp $(INCLUDE) export CFLAGS := -DDBUILTS="\"$(DBUILTS)\"" -DDBUILTL="\"$(DBUILTL)\"" -DVERSION="\"$(VERSION)\"" -DFLAVOR="\"$(FLAVOR)\"" \ -g -Os -Wall -Wextra -Wcast-align -Wformat=2 -Wno-main \ -fomit-frame-pointer -ffast-math -std=gnu11 -MMD -MP \ - -Wno-unused-function -Wno-format-truncation $(INCLUDE) -ffunction-sections -fdata-sections + -Wno-unused-function -Wno-format-truncation -Wno-format-nonliteral $(INCLUDE) -ffunction-sections -fdata-sections export LDFLAGS := -Tlink.ld -nostartfiles -Wl,--gc-sections,-z,max-page-size=4096 -ELF := arm9/arm9.elf arm11/arm11.elf +ELF := arm9/arm9_code.elf arm9/arm9_data.elf arm11/arm11.elf -.PHONY: all firm vram0 elf release clean +.PHONY: all firm $(VRAM_TAR) elf release clean all: firm clean: @set -e; for elf in $(ELF); do \ $(MAKE) --no-print-directory -C $$(dirname $$elf) clean; \ done - @rm -rf $(OUTDIR) $(RELDIR) $(FIRM) $(FIRMD) $(VRAM_OUT) + @rm -rf $(OUTDIR) $(RELDIR) $(FIRM) $(FIRMD) $(VRAM_TAR) $(LANGUAGE_INL) $(TRF_FILES) unmarked_readme: .FORCE @$(PY3) utils/unmark.py -f README.md data/README_internal.md @@ -75,29 +85,44 @@ release: clean unmarked_readme @cp $(OUTDIR)/$(FLAVOR)_dev.firm.sha $(RELDIR)/ @cp $(ELF) $(RELDIR)/elf @cp $(CURDIR)/README.md $(RELDIR) + @cp $(CURDIR)/resources/lua-doc.md $(RELDIR)/lua-doc.md @cp -R $(CURDIR)/resources/gm9 $(RELDIR)/gm9 @cp -R $(CURDIR)/resources/sample $(RELDIR)/sample @-7za a $(RELDIR)/$(FLAVOR)-$(VERSION)-$(DBUILTS).zip ./$(RELDIR)/* -vram0: - @mkdir -p "$(OUTDIR)" - @echo "Creating $(VRAM_OUT)" - @$(PY3) utils/add2tar.py $(VRAM_FLAGS) $(VRAM_OUT) $(shell ls -d $(SPLASH) $(OVERRIDE_FONT) $(VRAM_DATA)/* $(VRAM_SCRIPTS)) +$(VRAM_TAR): $(SPLASH) $(OVERRIDE_FONT) $(VRAM_DATA) $(VRAM_SCRIPTS) + @mkdir -p "$(@D)" + @echo "Creating $@" + @$(PY3) utils/add2tar.py $(VRAM_FLAGS) $(VRAM_TAR) $(shell ls -d -1 $^) + +$(LANGUAGE_INL): $(SOURCE_JSON) + @echo "Creating $@" + @$(PY3) utils/transcp.py $< $@ + +$(TRF_FOLDER)/%.trf: $(JSON_FOLDER)/%.json + @$(PY3) utils/transriff.py $< $@ %.elf: .FORCE @echo "Building $@" - @$(MAKE) --no-print-directory -C $(@D) + @$(MAKE) --no-print-directory -C $(@D) $(@F) + +# Indicate a few explicit dependencies: +# The ARM9 data section depends on the VRAM drive +arm9/arm9_data.elf: $(VRAM_TAR) $(LANGUAGE_INL) +# And the code section depends on the data section being built already +arm9/arm9_code.elf: arm9/arm9_data.elf -firm: $(ELF) vram0 - @test `wc -c <$(VRAM_OUT)` -le 262144 +firm: $(ELF) $(TRF_FILES) @mkdir -p $(call dirname,"$(FIRM)") $(call dirname,"$(FIRMD)") @echo "[FLAVOR] $(FLAVOR)" @echo "[VERSION] $(VERSION)" @echo "[BUILD] $(DBUILTL)" @echo "[FIRM] $(FIRM)" - @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -A 0x80C0000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy + @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -D $(ELF) -C NDMA NDMA XDMA @echo "[FIRM] $(FIRMD)" - @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -A 0x80C0000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy + @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -D $(ELF) -C NDMA NDMA XDMA + +vram0: $(VRAM_TAR) .FORCE # legacy target name .FORCE: diff --git a/Makefile.build b/Makefile.build index 0a36f6fed..0a4bd47c7 100755 --- a/Makefile.build +++ b/Makefile.build @@ -1,4 +1,6 @@ +LIBS ?= + OBJECTS := $(patsubst $(SOURCE)/%.s, $(BUILD)/%.o, \ $(patsubst $(SOURCE)/%.c, $(BUILD)/%.o, \ $(call rwildcard, $(SOURCE), *.s *.c))) @@ -11,11 +13,12 @@ all: $(TARGET).elf .PHONY: clean clean: - @rm -rf $(BUILD) $(TARGET).elf $(TARGET).map + @rm -rf $(BUILD) $(TARGET).elf $(TARGET).dis $(TARGET).map $(TARGET).elf: $(OBJECTS) $(OBJECTS_COMMON) @mkdir -p "$(@D)" - @$(CC) $(LDFLAGS) $^ -o $@ + @$(CC) $(LDFLAGS) $^ -o $@ $(LIBS) + @$(OBJDUMP) -S -h $@ > $@.dis $(BUILD)/%.cmn.o: $(COMMON_DIR)/%.c @mkdir -p "$(@D)" diff --git a/Makefile.common b/Makefile.common index d8c82582a..71e40f9b2 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1,3 +1,4 @@ +export OBJDUMP := arm-none-eabi-objdump dirname = $(shell dirname $(1)) @@ -67,6 +68,10 @@ ifdef SD_TIMEOUT CFLAGS += -DSD_TIMEOUT=$(SD_TIMEOUT) endif +ifeq ($(NO_LUA),1) + CFLAGS += -DNO_LUA +endif + ifdef N_PANES CFLAGS += -DN_PANES=$(N_PANES) endif diff --git a/README.md b/README.md index a54835dcb..d024c0eb6 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Build `GodMode9.firm` via `make firm`. This requires [firmtool](https://github.c You may run `make release` to get a nice, release-ready package of all required files. To build __SafeMode9__ (a bricksafe variant of GodMode9, with limited write permissions) instead of GodMode9, compile with `make FLAVOR=SafeMode9`. To switch screens, compile with `make SWITCH_SCREENS=1`. For additional customization, you may choose the internal font by replacing `font_default.frf` inside the `data` directory. You may also hardcode the brightness via `make FIXED_BRIGHTNESS=x`, whereas `x` is a value between 0...15. -Further customization is possible by hardcoding `aeskeydb.bin` (just put the file into the `data` folder when compiling). All files put into the `data` folder will turn up in the `V:` drive, but keep in mind there's a hard 3MB limit for all files inside, including overhead. A standalone script runner is compiled by providing `autorun.gm9` (again, in the `data` folder) and building with `make SCRIPT_RUNNER=1`. There's more possibility for customization, read the Makefiles to learn more. +Further customization is possible by hardcoding `aeskeydb.bin` (just put the file into the `data` folder when compiling). All files put into the `data` folder will turn up in the `V:` drive, but keep in mind there's a hard 223.5KiB limit for all files inside, including overhead. A standalone script runner is compiled by providing `autorun.lua` or `autorun.gm9` (again, in the `data` folder) and building with `make SCRIPT_RUNNER=1`. There's more possibility for customization, read the Makefiles to learn more. To build a .firm signed with SPI boot keys (for ntrboot and the like), run `make NTRBOOT=1`. You may need to rename the output files if the ntrboot installer you use uses hardcoded filenames. Some features such as boot9 / boot11 access are not currently available from the ntrboot environment. @@ -65,6 +65,10 @@ For certain functionality, GodMode9 may need 'support files'. Support files shou * __`seeddb.bin`__: This file is optional and required to decrypt and mount seed-encrypted NCCHs and CIAs (if the seed in question is not installed to your NAND). Note that your seeddb.bin must also contain the seed for the specific game you need to decrypt. * __`encTitleKeys.bin`__ / __`decTitleKeys.bin`__: These files are optional and provide titlekeys, which are required to decrypt and install contents downloaded from CDN (for DSi and 3DS content). +### Fonts and translations +GodMode9 also supports custom fonts and translations as support files. These both use custom formats, fonts use FRF (Font RIFF) files which can be created using the `fontriff.py` Python script in the 'utils' folder. Translations use TRF (Translation RIFF) files from the `transriff.py` script. Examples of the inputs to these scripts can be found in the 'fonts' and 'languages' folders of the 'resources' folder respectively. + +TRF files can be placed in `0:/gm9/languages` to show in the language menu accessible from the HOME menu and shown on first load. Official translations are provided from the community via the [GodMode9 Crowdin](https://crowdin.com/project/GodMode9). Languages can use a special font by having an FRF with the same name, for example `en.trf` and `en.frf`. ## Drives in GodMode9 GodMode9 provides access to system data via drives, a listing of what each drive contains and additional info follows below. Some of these drives are removable (such as drive `7:`), some will only turn up if they are available (drive `8:` and everything associated with EmuNAND, f.e.). Information on the 3DS console file system is also found on [3Dbrew.org](https://3dbrew.org/wiki/Flash_Filesystem). @@ -88,7 +92,7 @@ GodMode9 provides access to system data via drives, a listing of what each drive * __`K: AESKEYDB IMAGE`__: An `aeskeydb.bin` image can be mounted and accessed via this drive. The drive shows all keys inside the aeskeydb.bin. This is read-only. * __`T: TICKET.DB IMAGE / BDRI IMAGE`__: Ticket database files can be mounted and accessed via this drive. This provides easy and quick access to all tickets inside the `ticket.db`. This drive also provides access to other BDRI images, such as the Title database (`title.db`). * __`M: MEMORY VIRTUAL`__: This provides access to various memory regions. This is protected by a special write permission, and caution is advised when doing modifications inside this drive. This drive also gives access to `boot9.bin`, `boot11.bin` (boot9strap only) and `otp.mem` (sighaxed systems only). -* __`V: VRAM VIRTUAL`__: This drive resides in the first VRAM bank and contains files essential to GodMode9. The font (in FRF format), the splash logo (in PNG format) and the readme file are found there, as well as any file that is provided inside the `data` folder at build time. This is read-only. +* __`V: VRAM VIRTUAL`__: This drive resides in part of ARM9 internal memory and contains files essential to GodMode9. The font (in FRF format), the splash logo (in PNG format) and the readme file are found there, as well as any file that is provided inside the `data` folder at build time. This is read-only. * __`Y: TITLE MANAGER`__: The title manager is accessed via the HOME menu and provides easy access to all installed titles. * __`Z: LAST SEARCH`__: After a search operation, search results are found inside this drive. The drive can be accessed at a later point to return to the former search results. @@ -118,8 +122,9 @@ With the possibilites GodMode9 provides, not everything may be obvious at first * __Inject a file to another file__: Put exactly one file (the file to be injected from) into the clipboard (via the Y button). Press A on the file to be injected to. There will be an option to inject the first file into it. ### Scripting functionality -* __Run .gm9 scripts from anywhere on your SD card__: You can run scripts in .gm9 format via the A button menu. .gm9 scripts use a shell-like language and can be edited in any text editor. For an overview of usable commands have a look into the sample scripts included in the release archive. *Don't run scripts from untrusted sources.* -* __Run .gm9 scripts via a neat menu__: Press the HOME button, select `More...` -> `Scripts...`. Any script you put into `0:/gm9/scripts` (subdirs included) will be found here. Scripts ran via this method won't have the confirmation at the beginning either. +* __Run .lua scripts from anywhere on your SD card__: You can run Lua scripts via the A button menu. For an overview of usable commands have a look into the documentation and sample scripts included in the release archive. *Don't run scripts from untrusted sources.* +* __Run Lua scripts via a neat menu__: Press the HOME button, select `More...` -> `Lua scripts...`. Any script you put into `0:/gm9/luascripts` (subdirs included) will be found here. Scripts ran via this method won't have the confirmation at the beginning either. +* __Run legacy .gm9 scripts__: The old format of .gm9 scripts is still available, but is deprecated and will see no further development. ### SD card handling * __Format your SD card / setup an EmuNAND__: Press the HOME button, select `More...` -> `SD format menu`. This also allows to setup a RedNAND (single/multi) or GW type EmuNAND on your SD card. You will get a warning prompt and an unlock sequence before any operation starts. @@ -179,9 +184,13 @@ This tool would not have been possible without the help of numerous people. Than * **Wolfvak** for ARM11 code, FIRM binary launcher, exception handlers, PCX code, Makefile and for help on countless other occasions * **SciresM** for helping me figure out RomFS and for boot9strap * **SciresM**, **Myria**, **Normmatt**, **TuxSH** and **hedgeberg** for figuring out sighax and giving us access to bootrom -* **ihaveamac** for first developing the simple CIA generation method and for being of great help in porting it +* **ihaveamac** for implementing Lua support, and first developing the simple CIA generation method and for being of great help in porting it +* **DarkRTA** for linker support during the implementation of Lua +* **luigoalma** for fixing Lua to compile without issues +* **Gruetzig** for re-implementing the Lua os module * **wwylele** and **aspargas2** for documenting and implementing the DISA, DIFF, and BDRI formats * **dratini0** for savefile management, based on [TWLSaveTool](https://github.com/TuxSH/TWLSaveTool/) +* **Pk11** for unicode support and her ongoing work on GodMode9 translations and translation support * **b1l1s** for helping me figure out A9LH compatibility * **Gelex** and **AuroraWright** for helping me figure out various things * **stuckpixel** for the new 6x10 font and help on various things @@ -198,6 +207,7 @@ This tool would not have been possible without the help of numerous people. Than * **Lilith Valentine** for testing and helpful advice * **Project Nayuki** for [qrcodegen](https://github.com/nayuki/QR-Code-generator) * **Amazingmax fonts** for the Amazdoom font +* **TakWolf** for [fusion-pixel-font](https://github.com/TakWolf/fusion-pixel-font) used for Chinese and Korean * The fine folks on **the official GodMode9 IRC channel and Discord server** * The fine folks on **freenode #Cakey** * All **[3dbrew.org](https://www.3dbrew.org/wiki/Main_Page) editors** diff --git a/arm11/Makefile b/arm11/Makefile index 3528587f3..b52d531e9 100644 --- a/arm11/Makefile +++ b/arm11/Makefile @@ -1,6 +1,6 @@ PROCESSOR := ARM11 -TARGET := $(shell basename $(CURDIR)) +TARGET := $(shell basename "$(CURDIR)") SOURCE := source BUILD := build @@ -11,7 +11,7 @@ INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") ASFLAGS += $(SUBARCH) $(INCLUDE) CFLAGS += $(SUBARCH) $(INCLUDE) -flto -LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map -flto +LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map -flto include ../Makefile.common include ../Makefile.build diff --git a/arm11/link.ld b/arm11/link.ld index 36642423a..51122881f 100644 --- a/arm11/link.ld +++ b/arm11/link.ld @@ -16,7 +16,7 @@ SECTIONS __text_va = ABSOLUTE(.); *(.text*) . = ALIGN(4K); - __text_len = . - __text_va; + __text_va_end = .; } >AXIWRAM .data : ALIGN(4K) @@ -25,7 +25,7 @@ SECTIONS __data_va = ABSOLUTE(.); *(.data*) . = ALIGN(4K); - __data_len = . - __data_va; + __data_va_end = .; } >AXIWRAM .rodata : ALIGN(4K) @@ -34,7 +34,7 @@ SECTIONS __rodata_va = ABSOLUTE(.); *(.rodata*) . = ALIGN(4K); - __rodata_len = . - __rodata_va; + __rodata_va_end = .; } >AXIWRAM .shared (NOLOAD) : ALIGN(4K) @@ -43,7 +43,7 @@ SECTIONS __shared_va = ABSOLUTE(.); *(.shared*) . = ALIGN(4K); - __shared_len = . - __shared_va; + __shared_va_end = .; } >AXIWRAM .bss (NOLOAD) : ALIGN(4K) @@ -52,6 +52,6 @@ SECTIONS __bss_va = ABSOLUTE(.); *(.bss*) . = ALIGN(4K); - __bss_len = . - __bss_va; + __bss_va_end = .; } >AXIWRAM } diff --git a/arm11/source/boot.s b/arm11/source/boot.s index 9e7deef36..5b2167b65 100644 --- a/arm11/source/boot.s +++ b/arm11/source/boot.s @@ -76,10 +76,12 @@ __boot: b 1b corezero_start: - @ assume __bss_len is 128 byte aligned + @ assumes the .bss section size is 128 byte aligned (or zero) ldr r0, =__bss_pa - ldr r1, =__bss_len - add r1, r0, r1 + ldr r1, =__bss_va_end @ calculate the length of .bss using the VA start and end + ldr r2, =__bss_va + sub r1, r1, r2 + add r1, r0, r1 @ fixup to be PA start and end mov r2, #0 mov r3, #0 mov r4, #0 diff --git a/arm11/source/hw/mcu.c b/arm11/source/hw/mcu.c index 33d144662..69ab77733 100755 --- a/arm11/source/hw/mcu.c +++ b/arm11/source/hw/mcu.c @@ -22,6 +22,8 @@ #include +#include "common.h" + #include "arm/timer.h" #include "hw/gpio.h" @@ -116,16 +118,13 @@ u32 mcuGetSpecialHID(void) void mcuSetStatusLED(u32 period_ms, u32 color) { - u32 r, g, b; + u32 r, g, b, delay; mcuStatusLED ledState; - // handle proper non-zero periods - // so small the hardware can't handle it - if (period_ms != 0 && period_ms < 63) - period_ms = 63; + delay = clamp((period_ms * 0x200) / 1000, 1, 0xFF); - ledState.delay = (period_ms * 0x10) / 1000; - ledState.smoothing = 0x40; + ledState.delay = delay; + ledState.smoothing = delay; ledState.loop_delay = 0x10; ledState.unk = 0; diff --git a/arm11/source/system/sections.h b/arm11/source/system/sections.h index 008f93a6a..21e5f1294 100755 --- a/arm11/source/system/sections.h +++ b/arm11/source/system/sections.h @@ -20,7 +20,7 @@ #include -#define DEF_SECT_(n) extern u32 __##n##_pa, __##n##_va, __##n##_len; +#define DEF_SECT_(n) extern u32 __##n##_pa, __##n##_va, __##n##_va_end; DEF_SECT_(text) DEF_SECT_(data) DEF_SECT_(rodata) @@ -30,6 +30,6 @@ DEF_SECT_(shared) #define SECTION_VA(n) ((u32)&__##n##_va) #define SECTION_PA(n) ((u32)&__##n##_pa) -#define SECTION_LEN(n) ((u32)&__##n##_len) +#define SECTION_LEN(n) (((u32)(&__##n##_va_end) - (u32)(&__##n##_va))) #define SECTION_TRI(n) SECTION_VA(n), SECTION_PA(n), SECTION_LEN(n) diff --git a/arm9/Makefile b/arm9/Makefile index 0a5e2c5b5..ae0d9ee7f 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -1,17 +1,24 @@ PROCESSOR := ARM9 -TARGET := $(shell basename $(CURDIR)) +TARGET := $(shell basename "$(CURDIR)") SOURCE := source BUILD := build SUBARCH := -D$(PROCESSOR) -march=armv5te -mtune=arm946e-s -mthumb -mfloat-abi=soft -INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/lodepng source/qrcodegen source/system source/utils +INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/lodepng source/lua source/qrcodegen source/system source/utils INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") ASFLAGS += $(SUBARCH) $(INCLUDE) CFLAGS += $(SUBARCH) $(INCLUDE) -fno-builtin-memcpy -flto -LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map -flto +LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map -flto +LIBS += -lm include ../Makefile.common include ../Makefile.build + +arm9_data.elf: arm9.elf + $(OBJCOPY) -O elf32-littlearm -j .rodata* -j .data* -j .bss* $< $@ + +arm9_code.elf: arm9.elf + $(OBJCOPY) -O elf32-littlearm -j .text* -j .vectors* $< $@ diff --git a/arm9/link.ld b/arm9/link.ld index e9f0a08dd..b8beedf0c 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -4,8 +4,10 @@ ENTRY(_start) MEMORY { - AHBWRAM (RWX) : ORIGIN = 0x08006000, LENGTH = 512K VECTORS (RX) : ORIGIN = 0x08000000, LENGTH = 64 + CODEMEM (RX) : ORIGIN = 0x08000040, LENGTH = 512K - 64 + BOOTROM (R) : ORIGIN = 0x08080000, LENGTH = 128K /* BootROM mirrors, don't touch! */ + DATAMEM (RW) : ORIGIN = 0x080A0000, LENGTH = 384K } SECTIONS @@ -16,7 +18,7 @@ SECTIONS KEEP(*(.vectors)); . = ALIGN(4); __vectors_len = ABSOLUTE(.) - __vectors_vma; - } >VECTORS AT>AHBWRAM + } >VECTORS AT>CODEMEM .text : ALIGN(4) { __text_s = ABSOLUTE(.); @@ -24,24 +26,28 @@ SECTIONS *(.text*); . = ALIGN(4); __text_e = ABSOLUTE(.); - } >AHBWRAM + } >CODEMEM .rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); - } >AHBWRAM + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + . = ALIGN(4); + } >DATAMEM .data : ALIGN(4) { *(.data*); . = ALIGN(4); - } >AHBWRAM + } >DATAMEM - .bss : ALIGN(4) { + .bss (NOLOAD) : ALIGN(4) { __bss_start = .; *(.bss*); . = ALIGN(4); __bss_end = .; - } >AHBWRAM + } >DATAMEM __end__ = ABSOLUTE(.); } diff --git a/arm9/source/common/screenshot.c b/arm9/source/common/screenshot.c index 285a63382..2deb65926 100644 --- a/arm9/source/common/screenshot.c +++ b/arm9/source/common/screenshot.c @@ -27,7 +27,7 @@ void CreateScreenshot(void) { fvx_rmkdir(OUTPUT_PATH); get_dstime(&dstime); - snprintf(filename, 64, OUTPUT_PATH "/snap_%02X%02X%02X%02X%02X%02X.png", + snprintf(filename, sizeof(filename), OUTPUT_PATH "/snap_%02X%02X%02X%02X%02X%02X.png", dstime.bcd_Y, dstime.bcd_M, dstime.bcd_D, dstime.bcd_h, dstime.bcd_m, dstime.bcd_s); filename[63] = '\0'; diff --git a/arm9/source/common/swkbd.c b/arm9/source/common/swkbd.c index 978e896b6..f410812d5 100644 --- a/arm9/source/common/swkbd.c +++ b/arm9/source/common/swkbd.c @@ -1,5 +1,6 @@ #include +#include "language.h" #include "swkbd.h" #include "timer.h" #include "hid.h" @@ -80,7 +81,7 @@ static void DrawKey(const TouchBox* key, const bool pressed, const u32 uppercase if (key->id == KEY_TXTBOX) return; char keystr[16]; - if (key->id >= 0x80) snprintf(keystr, 16, "%s", keystrs[key->id - 0x80]); + if (key->id >= 0x80) snprintf(keystr, sizeof(keystr), "%s", keystrs[key->id - 0x80]); else { keystr[0] = (uppercase) ? to_uppercase(key->id) : key->id; keystr[1] = 0; @@ -146,8 +147,8 @@ static void DrawTextBox(const TouchBox* txtbox, const char* inputstr, const u32 // draw input string DrawStringF(BOT_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%c", (*scroll) ? '<' : '|', - input_shown_size, - input_shown_size, + (int) input_shown_size, + (int) input_shown_size, (*scroll > inputstr_size) ? "" : inputstr + *scroll, (inputstr_size - (s32) *scroll > input_shown_size) ? '>' : '|' ); @@ -159,11 +160,11 @@ static void DrawTextBox(const TouchBox* txtbox, const char* inputstr, const u32 } DrawStringF(BOT_SCREEN, x-(FONT_WIDTH_EXT/2), y+10, COLOR_STD_FONT, COLOR_STD_BG, "%-*.*s^%-*.*s", - 1 + cpos, - 1 + cpos, + (int) (1 + cpos), + (int) (1 + cpos), "", - input_shown_length - cpos, - input_shown_length - cpos, + (int) (input_shown_length - cpos), + (int) (input_shown_length - cpos), "" ); } @@ -253,9 +254,9 @@ bool ShowKeyboard(char* inputstr, const u32 max_size, const char *format, ...) { TouchBox* textbox = swkbd_alphabet; // always use this textbox static bool show_instr = true; - static const char* instr = "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt"; + const char* instr = STR_KEYBOARD_CONTROLS_DETAILS; if (show_instr) { - ShowPrompt(false, instr); + ShowPrompt(false, "%s", instr); show_instr = false; } @@ -268,7 +269,7 @@ bool ShowKeyboard(char* inputstr, const u32 max_size, const char *format, ...) { char str[512]; // arbitrary limit, should be more than enough va_list va; va_start(va, format); - vsnprintf(str, 512, format, va); + vsnprintf(str, sizeof(str), format, va); va_end(va); u32 str_width = GetDrawStringWidth(str); if (str_width < (24 * FONT_WIDTH_EXT)) str_width = 24 * FONT_WIDTH_EXT; @@ -332,7 +333,7 @@ bool ShowKeyboard(char* inputstr, const u32 max_size, const char *format, ...) { swkbd = swkbd_numpad; } else if (key == KEY_SWITCH) { ClearScreen(BOT_SCREEN, COLOR_STD_BG); - return ShowStringPrompt(inputstr, max_size, str); + return ShowStringPrompt(inputstr, max_size, "%s", str); } else if (key == KEY_UNICODE) { if (cursor > 3 && cursor <= inputstr_size) { u16 codepoint = 0; diff --git a/arm9/source/common/swkbd.h b/arm9/source/common/swkbd.h index b81ec0dee..86f93d440 100644 --- a/arm9/source/common/swkbd.h +++ b/arm9/source/common/swkbd.h @@ -86,4 +86,4 @@ enum { #define ShowKeyboardOrPrompt (TouchIsCalibrated() ? ShowKeyboard : ShowStringPrompt) -bool ShowKeyboard(char* inputstr, u32 max_size, const char *format, ...); +bool PRINTF_ARGS(3) ShowKeyboard(char* inputstr, u32 max_size, const char *format, ...); diff --git a/arm9/source/common/touchcal.c b/arm9/source/common/touchcal.c index f1e16c54c..76412dc75 100644 --- a/arm9/source/common/touchcal.c +++ b/arm9/source/common/touchcal.c @@ -2,6 +2,7 @@ #include "ui.h" #include "hid.h" #include "crc16.h" +#include "language.h" #include "spiflash.h" #include "support.h" @@ -46,8 +47,8 @@ bool ShowTouchCalibrationDialog(void) // clear screen, draw instructions ClearScreen(BOT_SCREEN, COLOR_STD_BG); - DrawStringCenter(BOT_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, - "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!"); + DrawStringCenter(BOT_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", + STR_TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS); // set calibration defaults SetCalibrationDefaults(); diff --git a/arm9/source/common/ui.c b/arm9/source/common/ui.c index d8fb7cb54..c8207aee1 100644 --- a/arm9/source/common/ui.c +++ b/arm9/source/common/ui.c @@ -15,12 +15,24 @@ #include "power.h" #include "hid.h" #include "fixp.h" +#include "language.h" #define STRBUF_SIZE 512 // maximum size of the string buffer #define FONT_MAX_WIDTH 8 #define FONT_MAX_HEIGHT 10 #define PROGRESS_REFRESH_RATE 30 // the progress bar is only allowed to draw to screen every X milliseconds +typedef struct { + char chunk_id[4]; // NOT null terminated + u32 size; +} RiffChunkHeader; + +typedef struct { + u8 width; + u8 height; + u16 count; +} FontMeta; + static u32 font_width = 0; static u32 font_height = 0; static u32 font_count = 0; @@ -129,8 +141,8 @@ u32 GetCharacter(const char** str) return c; } -u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) { - char* hdr = (char*) pbm; +const u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) { + const char* hdr = (const char*) pbm; u32 hdr_max_size = min(512, pbm_size); u32 pbm_w = 0; u32 pbm_h = 0; @@ -191,40 +203,43 @@ u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) { return (u8*) pbm + p; } -u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count) { - u8 *ptr = (u8*) riff; - u8 riff_w = 0; - u8 riff_h = 0; - u16 riff_count = 0; +const u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count) { + const void* ptr = riff; + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; - // check header magic, then skip over - if (memcmp(ptr, "RIFF", 4) != 0) return NULL; + // check header magic and load size + if (!ptr) return NULL; + riff_header = ptr; + if (memcmp(riff_header->chunk_id, "RIFF", 4) != 0) return NULL; // ensure enough space is allocated - u32 data_size; - memcpy(&data_size, ptr + 4, sizeof(u32)); - if (data_size > riff_size) return NULL; + if (riff_header->size > riff_size) return NULL; - ptr += 8; + ptr += sizeof(RiffChunkHeader); - // check for and load META section - if (memcmp(ptr, "META", 4) == 0) { - riff_w = ptr[8]; - riff_h = ptr[9]; - memcpy(&riff_count, ptr + 10, sizeof(u16)); + while ((u32)(ptr - riff) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = ptr; - u32 section_size; - memcpy(§ion_size, ptr + 4, sizeof(u32)); - ptr += 8 + section_size; + // check for and load META section + if (memcmp(chunk_header->chunk_id, "META", 4) == 0) { - if (riff_w > FONT_MAX_WIDTH || riff_h > FONT_MAX_HEIGHT) return NULL; - } else return NULL; + if (chunk_header->size != 4) return NULL; - // all good - if (w) *w = riff_w; - if (h) *h = riff_h; - if (count) *count = riff_count; - return ptr; + const FontMeta *meta = ptr + sizeof(RiffChunkHeader); + if (meta->width > FONT_MAX_WIDTH || meta->height > FONT_MAX_HEIGHT) return NULL; + + // all good + if (w) *w = meta->width; + if (h) *h = meta->height; + if (count) *count = meta->count; + return ptr; + } + + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } + + return NULL; } // sets the font from a given RIFF or PBM @@ -232,7 +247,7 @@ u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* bool SetFont(const void* font, u32 font_size) { u32 w, h; u16 count; - u8* ptr = NULL; + const u8* ptr = NULL; if (!font) { u64 font_size64 = 0; @@ -248,33 +263,31 @@ bool SetFont(const void* font, u32 font_size) { font_height = h; font_count = count; - // character data - if (memcmp(ptr, "CDAT", 4) == 0) { - u32 section_size; - memcpy(§ion_size, ptr + 4, sizeof(u32)); - - if (font_bin) free(font_bin); - font_bin = malloc(font_height * font_count); - if (!font_bin) return NULL; + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; - memcpy(font_bin, ptr + 8, font_height * font_count); + // load total size + riff_header = font; - ptr += 8 + section_size; - } else return NULL; + while (((u32)ptr - (u32)font) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = (const void *)ptr; - // character map - if (memcmp(ptr, "CMAP", 4) == 0) { - u32 section_size; - memcpy(§ion_size, ptr + 4, sizeof(u32)); + if (memcmp(chunk_header->chunk_id, "CDAT", 4) == 0) { // character data + if (font_bin) free(font_bin); + font_bin = malloc(font_height * font_count); + if (!font_bin) return NULL; - if (font_map) free(font_map); - font_map = malloc(sizeof(u16) * font_count); - if (!font_map) return NULL; + memcpy(font_bin, ptr + sizeof(RiffChunkHeader), font_height * font_count); + } else if (memcmp(chunk_header->chunk_id, "CMAP", 4) == 0) { // character map + if (font_map) free(font_map); + font_map = malloc(sizeof(u16) * font_count); + if (!font_map) return NULL; - memcpy(font_map, ptr + 8, sizeof(u16) * font_count); + memcpy(font_map, ptr + sizeof(RiffChunkHeader), sizeof(u16) * font_count); + } - ptr += 8 + section_size; - } else return NULL; + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } } else if ((ptr = GetFontFromPbm(font, font_size, &w, &h))) { font_count = 0x100; @@ -576,18 +589,13 @@ void ResizeString(char* dest, const char* orig, int nlength, int tpos, bool alig if (nlength < olength) { TruncateString(dest, orig, nlength, tpos); - } else if (!align_right) { - int nsize = 0; - for (int i = 0; i < nlength || (orig[nsize] & 0xC0) == 0x80; nsize++) { - if ((orig[nsize] & 0xC0) != 0x80) i++; - } - snprintf(dest, UTF_BUFFER_BYTESIZE(nlength), "%-*.*s", nsize, nsize, orig); } else { int nsize = 0; - for (int i = 0; i < nlength || (orig[nsize] & 0xC0) == 0x80; nsize++) { - if ((orig[nsize] & 0xC0) != 0x80) i++; + int osize = strnlen(orig, 256); + for (int i = 0; i < nlength || (nsize <= osize && (orig[nsize] & 0xC0) == 0x80); nsize++) { + if (nsize > osize || (orig[nsize] & 0xC0) != 0x80) i++; } - snprintf(dest, UTF_BUFFER_BYTESIZE(nlength), "%*.*s", nsize, nsize, orig); + snprintf(dest, UTF_BUFFER_BYTESIZE(nlength), align_right ? "%*.*s" : "%-*.*s", nsize, nsize, orig); } } @@ -625,20 +633,20 @@ void FormatNumber(char* str, u64 number) { // str should be 32 byte in size for (; number / (mag1000 * 1000) > 0; mag1000 *= 1000); for (; mag1000 > 0; mag1000 /= 1000) { u32 pos = strnlen(str, 31); - snprintf(str + pos, 31 - pos, "%0*llu%c", (pos) ? 3 : 1, (number / mag1000) % 1000, (mag1000 > 1) ? ',' : '\0'); + snprintf(str + pos, 31 - pos, "%0*llu%s", (pos) ? 3 : 1, (number / mag1000) % 1000, (mag1000 > 1) ? STR_THOUSAND_SEPARATOR : ""); } } void FormatBytes(char* str, u64 bytes) { // str should be 32 byte in size, just to be safe - const char* units[] = {" Byte", " kB", " MB", " GB"}; + const char* units[] = {STR_BYTE, STR_KB, STR_MB, STR_GB}; - if (bytes == (u64) -1) snprintf(str, 32, "INVALID"); + if (bytes == (u64) -1) snprintf(str, 32, "%s", STR_INVALID); else if (bytes < 1024) snprintf(str, 32, "%llu%s", bytes, units[0]); else { u32 scale = 1; u64 bytes100 = (bytes * 100) >> 10; for(; (bytes100 >= 1024*100) && (scale < 3); scale++, bytes100 >>= 10); - snprintf(str, 32, "%llu.%llu%s", bytes100 / 100, (bytes100 % 100) / 10, units[scale]); + snprintf(str, 32, "%llu%s%llu%s", bytes100 / 100, STR_DECIMAL_SEPARATOR, (bytes100 % 100) / 10, units[scale]); } } @@ -705,7 +713,7 @@ void ShowIconString(u16* icon, int w, int h, const char *format, ...) vsnprintf(str, STRBUF_SIZE, format, va); va_end(va); - ShowIconStringF(MAIN_SCREEN, icon, w, h, str); + ShowIconStringF(MAIN_SCREEN, icon, w, h, "%s", str); } bool ShowPrompt(bool ask, const char *format, ...) @@ -720,7 +728,7 @@ bool ShowPrompt(bool ask, const char *format, ...) ClearScreenF(true, false, COLOR_STD_BG); DrawStringCenter(MAIN_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s\n \n%s", str, - (ask) ? "( yes, no)" : "( to continue)"); + (ask) ? STR_A_YES_B_NO : STR_A_TO_CONTINUE); while (true) { u32 pad_state = InputWait(0); @@ -775,7 +783,7 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) { ClearScreenF(true, false, color_bg); DrawStringF(MAIN_SCREEN, x, y, color_font, color_bg, "%s", str); #ifndef TIMER_UNLOCK - DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, "To proceed, enter this:"); + DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, "%s", STR_TO_PROCEED_ENTER_THIS); // generate sequence const char *dpad_symbols[] = { "→", "←", "↑", "↓" }; // R L U D @@ -812,7 +820,7 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) { lvl = 0; } #else - DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, "To proceed, hold :"); + DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, STR_TO_PROCEED_HOLD_X); while (!CheckButton(BUTTON_B)) { for (u32 n = 0; n < seqlen; n++) { @@ -839,10 +847,11 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) { } #endif -u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { +u32 ShowSelectPrompt(int n, const char** options, const char *format, ...) { u32 str_width, str_height; u32 x, y, yopt; - u32 sel = 0; + int sel = 0, scroll = 0; + int n_show = min(n, 10); char str[STRBUF_SIZE]; va_list va; @@ -854,30 +863,64 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { // else if (n == 1) return ShowPrompt(true, "%s\n%s?", str, options[0]) ? 1 : 0; str_width = GetDrawStringWidth(str); - str_height = GetDrawStringHeight(str) + (n * (line_height + 2)) + (3 * line_height); + str_height = GetDrawStringHeight(str) + (n_show * (line_height + 2)) + (3 * line_height); if (str_width < 24 * font_width) str_width = 24 * font_width; - for (u32 i = 0; i < n; i++) if (str_width < GetDrawStringWidth(options[i])) - str_width = GetDrawStringWidth(options[i]); + for (int i = 0; i < n; i++) if (str_width < GetDrawStringWidth(options[i]) + (3 * font_width)) + str_width = GetDrawStringWidth(options[i]) + (3 * font_width); x = (str_width >= SCREEN_WIDTH_MAIN) ? 0 : (SCREEN_WIDTH_MAIN - str_width) / 2; y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2; yopt = y + GetDrawStringHeight(str) + 8; ClearScreenF(true, false, COLOR_STD_BG); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); - DrawStringF(MAIN_SCREEN, x, yopt + (n*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "( select, cancel)"); + DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "%s", STR_A_SELECT_B_CANCEL); while (true) { - for (u32 i = 0; i < n; i++) { - DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*i), (sel == i) ? COLOR_STD_FONT : COLOR_LIGHTGREY, COLOR_STD_BG, "%2.2s %s", + for (int i = scroll; i < scroll+n_show; i++) { + DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*(i-scroll)), (sel == i) ? COLOR_STD_FONT : COLOR_LIGHTGREY, COLOR_STD_BG, "%2.2s %s", (sel == i) ? "->" : "", options[i]); } + + // show [n more] + if (n - n_show - scroll > 0) { + char more_str[UTF_BUFFER_BYTESIZE(str_width / font_width)], temp_str[UTF_BUFFER_BYTESIZE(64)]; + snprintf(temp_str, sizeof(temp_str), STR_N_MORE, (n - (n_show-1) - scroll)); + ResizeString(more_str, temp_str, str_width / font_width, 8, false); + DrawString(MAIN_SCREEN, more_str, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG); + } + // show scroll bar + u32 bar_x = x + str_width + 2; + const u32 flist_height = (n_show * (line_height + 2)); + const u32 bar_width = 2; + if (n > n_show) { // draw position bar at the right + const u32 bar_height_min = 32; + u32 bar_height = (n_show * flist_height) / n; + if (bar_height < bar_height_min) bar_height = bar_height_min; + const u32 bar_y = ((u64) scroll * (flist_height - bar_height)) / (n - n_show) + yopt; + + DrawRectangle(MAIN_SCREEN, bar_x, bar_y, bar_width, bar_height, COLOR_SIDE_BAR); + } + u32 pad_state = InputWait(0); if (pad_state & BUTTON_DOWN) sel = (sel+1) % n; else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n; + else if (pad_state & BUTTON_RIGHT) sel += n_show; + else if (pad_state & BUTTON_LEFT) sel -= n_show; else if (pad_state & BUTTON_A) break; else if (pad_state & BUTTON_B) { sel = n; break; } + if (sel < 0) sel = 0; + else if (sel >= n) sel = n-1; + + int prev_scroll = scroll; + if (sel < scroll) scroll = sel; + else if (sel == n-1 && sel >= (scroll + n_show - 1)) scroll = sel - n_show + 1; + else if (sel >= (scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1; + + if (scroll != prev_scroll) { + DrawRectangle(MAIN_SCREEN, x + font_width * 3, yopt, str_width + 4, (n_show * (line_height + 2)), COLOR_STD_BG); + } } ClearScreenF(true, false, COLOR_STD_BG); @@ -885,12 +928,12 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { return (sel >= n) ? 0 : sel + 1; } -u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const char *format, ...) { +u32 ShowFileScrollPrompt(int n, const DirEntry** options, bool hide_ext, const char *format, ...) { u32 str_height, fname_len; u32 x, y, yopt; const u32 item_width = SCREEN_WIDTH(MAIN_SCREEN) - 40; int sel = 0, scroll = 0; - u32 n_show = min(n, 10); + int n_show = min(n, 10); char str[STRBUF_SIZE]; va_list va; @@ -909,9 +952,9 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c ClearScreenF(true, false, COLOR_STD_BG); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); - DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "( select, cancel)"); + DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "%s", STR_A_SELECT_B_CANCEL); while (true) { - for (u32 i = scroll; i < scroll+n_show; i++) { + for (int i = scroll; i < scroll+n_show; i++) { char bytestr[16]; FormatBytes(bytestr, options[i]->size); @@ -925,18 +968,19 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c ResizeString(content_str, temp_str, fname_len, 8, false); DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*(i-scroll)), - (sel == (int)i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%2.2s %s", - (sel == (int)i) ? "->" : "", content_str); + (sel == i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%2.2s %s", + (sel == i) ? "->" : "", content_str); DrawStringF(MAIN_SCREEN, x + item_width - font_width * 11, yopt + ((line_height+2)*(i-scroll)), - (sel == (int)i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%10.10s", - (options[i]->type == T_DIR) ? "(dir)" : (options[i]->type == T_DOTDOT) ? "(..)" : bytestr); + (sel == i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%10.10s", + (options[i]->type == T_DIR) ? STR_DIR : (options[i]->type == T_DOTDOT) ? "(..)" : bytestr); } // show [n more] - if (n - n_show - scroll) { - char more_str[64 + 1]; - snprintf(more_str, 64, " [%d more]", (int)(n - (n_show-1) - scroll)); - DrawStringF(MAIN_SCREEN, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG, "%-*s", item_width / font_width, more_str); + if (n - n_show - scroll > 0) { + char more_str[UTF_BUFFER_BYTESIZE(item_width / font_width)], temp_str[UTF_BUFFER_BYTESIZE(64)]; + snprintf(temp_str, sizeof(temp_str), STR_N_MORE, (n - (n_show-1) - scroll)); + ResizeString(more_str, temp_str, item_width / font_width, 8, false); + DrawString(MAIN_SCREEN, more_str, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG); } // show scroll bar u32 bar_x = x + item_width + 2; @@ -954,8 +998,8 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c } else DrawRectangle(MAIN_SCREEN, bar_x, yopt, bar_width, flist_height, COLOR_STD_BG); u32 pad_state = InputWait(0); - if (pad_state & BUTTON_DOWN) sel++; - else if (pad_state & BUTTON_UP) sel--; + if (pad_state & BUTTON_DOWN) sel = (sel+1) % n; + else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n; else if (pad_state & BUTTON_RIGHT) sel += n_show; else if (pad_state & BUTTON_LEFT) sel -= n_show; else if (pad_state & BUTTON_A) break; @@ -964,15 +1008,15 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c break; } if (sel < 0) sel = 0; - else if (sel >= (int)n) sel = n-1; + else if (sel >= n) sel = n-1; if (sel < scroll) scroll = sel; - else if (sel == (int) n-1 && sel >= (int)(scroll + n_show - 1)) scroll = sel - n_show + 1; - else if (sel >= (int)(scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1; + else if (sel == n-1 && sel >= (scroll + n_show - 1)) scroll = sel - n_show + 1; + else if (sel >= (scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1; } ClearScreenF(true, false, COLOR_STD_BG); - return (sel >= (int)n) ? 0 : sel + 1; + return (sel >= n) ? 0 : sel + 1; } u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...) { @@ -989,7 +1033,7 @@ u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *f ButtonToString(keys[i], buttonstr); ptr += snprintf(ptr, STRBUF_SIZE - (ptr-str), "\n<%s> %s", buttonstr, options[i]); } - ptr += snprintf(ptr, STRBUF_SIZE - (ptr-str), "\n \n<%s> %s", "B", "cancel"); + ptr += snprintf(ptr, STRBUF_SIZE - (ptr-str), "\n \n<%s> %s", "B", STR_CANCEL); ClearScreenF(true, false, COLOR_STD_BG); DrawStringCenter(MAIN_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); @@ -1038,7 +1082,7 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alpha ClearScreenF(true, false, COLOR_STD_BG); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); DrawStringF(MAIN_SCREEN, x + 8, y + str_height - 40, COLOR_STD_FONT, COLOR_STD_BG, - "R - (↑↓) fast scroll\nL - clear data%s", resize ? "\nX - remove char\nY - insert char" : ""); + "%s\n%s", STR_R_FAST_SCROLL_L_CLEAR_DATA, resize ? STR_X_REMOVE_CHAR_Y_INSERT_CHAR : ""); // wait for all keys released while (HID_ReadState() & BUTTON_ANY); @@ -1076,15 +1120,15 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alpha DrawStringF(MAIN_SCREEN, x, y + str_height - 76, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%c\n%-*.*s^%-*.*s", (scroll) ? '<' : '|', - input_shown_size, - input_shown_size, + (int) input_shown_size, + (int) input_shown_size, (scroll > inputstr_size) ? "" : inputstr + scroll, (inputstr_size - (s32) scroll > input_shown_size) ? '>' : '|', - 1 + cpos, - 1 + cpos, + (int) 1 + cpos, + (int) 1 + cpos, "", - input_shown_length - cpos, - input_shown_length - cpos, + (int) input_shown_length - cpos, + (int) input_shown_length - cpos, "" ); @@ -1221,7 +1265,7 @@ u64 ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...) { va_list va; if (n_digits > 16) n_digits = 16; - snprintf(inputstr, 16 + 1, "%0*llX", (int) n_digits, start_val); + snprintf(inputstr, sizeof(inputstr), "%0*llX", (int) n_digits, start_val); va_start(va, format); if (ShowInputPrompt(inputstr, n_digits + 1, 0, alphabet, format, va)) { @@ -1238,7 +1282,7 @@ u64 ShowNumberPrompt(u64 start_val, const char *format, ...) { u64 ret = 0; va_list va; - snprintf(inputstr, 20 + 1, "%llu", start_val); + snprintf(inputstr, sizeof(inputstr), "%llu", start_val); va_start(va, format); if (ShowInputPrompt(inputstr, 20 + 1, 1, alphabet, format, va)) { @@ -1358,7 +1402,7 @@ bool ShowProgress(u64 current, u64 total, const char* opstr) const u32 text_pos_y = bar_pos_y + bar_height + 2; u32 prog_width = ((total > 0) && (current <= total)) ? (current * (bar_width-4)) / total : 0; u32 prog_percent = ((total > 0) && (current <= total)) ? (current * 100) / total : 0; - char tempstr[64]; + char tempstr[UTF_BUFFER_BYTESIZE(64)]; char progstr[UTF_BUFFER_BYTESIZE(64)]; static u64 last_msec_elapsed = 0; @@ -1383,16 +1427,20 @@ bool ShowProgress(u64 current, u64 total, const char* opstr) DrawRectangle(MAIN_SCREEN, bar_pos_x + 2 + prog_width, bar_pos_y + 2, (bar_width-4) - prog_width, bar_height - 4, COLOR_STD_BG); TruncateString(progstr, opstr, min(63, (bar_width / FONT_WIDTH_EXT) - 7), 8); - snprintf(tempstr, 64, "%s (%lu%%)", progstr, prog_percent); + snprintf(tempstr, sizeof(tempstr), "%s (%lu%%)", progstr, prog_percent); ResizeString(progstr, tempstr, bar_width / FONT_WIDTH_EXT, 8, false); DrawString(MAIN_SCREEN, progstr, bar_pos_x, text_pos_y, COLOR_STD_FONT, COLOR_STD_BG); if (sec_elapsed >= 1) { - snprintf(tempstr, 16, "ETA %02llum%02llus", sec_remain / 60, sec_remain % 60); + if (sec_remain >= 3600) { + snprintf(tempstr, sizeof(tempstr), STR_ETA_N_HOUR_N_MIN_N_SEC, (sec_remain / 3600), (sec_remain / 60) % 60, sec_remain % 60); + } else { + snprintf(tempstr, sizeof(tempstr), STR_ETA_N_MIN_N_SEC, sec_remain / 60, sec_remain % 60); + } ResizeString(progstr, tempstr, 16, 8, true); DrawString(MAIN_SCREEN, progstr, bar_pos_x + bar_width - 1 - (FONT_WIDTH_EXT * 16), bar_pos_y - line_height - 1, COLOR_STD_FONT, COLOR_STD_BG); } - DrawString(MAIN_SCREEN, "(hold B to cancel)", bar_pos_x + 2, text_pos_y + 14, COLOR_STD_FONT, COLOR_STD_BG); + DrawString(MAIN_SCREEN, STR_HOLD_B_TO_CANCEL, bar_pos_x + 2, text_pos_y + 14, COLOR_STD_FONT, COLOR_STD_BG); last_prog_width = prog_width; @@ -1405,13 +1453,7 @@ int ShowBrightnessConfig(int set_brightness) u32 btn_input, bar_count; int bar_x_pos, bar_y_pos, bar_width, bar_height; - const char *brightness_str = - "[←] Decrease brightness\n" - "[→] Increase brightness\n" - " \n" - "[X] Use volume slider control\n" - "[A] Set current brightness\n" - "[B] Cancel"; + const char *brightness_str = STR_BRIGHTNESS_CONTROLS; static const u16 brightness_slider_colmasks[] = { COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_WHITE }; @@ -1432,7 +1474,7 @@ int ShowBrightnessConfig(int set_brightness) // draw initial UI stuff DrawStringF(MAIN_SCREEN, (SCREEN_WIDTH_MAIN - GetDrawStringWidth(brightness_str)) / 2, - (SCREEN_HEIGHT / 4) * 2, COLOR_STD_FONT, COLOR_STD_BG, brightness_str); + (SCREEN_HEIGHT / 4) * 2, COLOR_STD_FONT, COLOR_STD_BG, "%s", brightness_str); // draw all color gradient bars for (int x = 0; x < bar_width; x++) { diff --git a/arm9/source/common/ui.h b/arm9/source/common/ui.h index 071ff9980..4f51c0bb4 100644 --- a/arm9/source/common/ui.h +++ b/arm9/source/common/ui.h @@ -24,6 +24,8 @@ #define UTF_MAX_BYTES_PER_RUNE 4 #define UTF_BUFFER_BYTESIZE(rune_count) (((rune_count) + 1) * UTF_MAX_BYTES_PER_RUNE) +#define PRINTF_ARGS(n) __attribute__ ((format (printf, (n), (n) + 1))) + #define TOP_SCREEN ((u16*)VRAM_TOP_LA) #define BOT_SCREEN ((u16*)VRAM_BOT_A) @@ -43,13 +45,13 @@ #ifndef AUTO_UNLOCK -bool ShowUnlockSequence(u32 seqlvl, const char *format, ...); +bool PRINTF_ARGS(2) ShowUnlockSequence(u32 seqlvl, const char *format, ...); #else #define ShowUnlockSequence ShowPrompt #endif -u8* GetFontFromPbm(const void* pbm, const u32 riff_size, u32* w, u32* h); -u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count); +const u8* GetFontFromPbm(const void* pbm, const u32 riff_size, u32* w, u32* h); +const u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count); bool SetFont(const void* font, const u32 font_size); u16 GetColor(const u16 *screen, int x, int y); @@ -63,8 +65,8 @@ void DrawQrCode(u16 *screen, const u8* qrcode); void DrawCharacter(u16 *screen, u32 character, int x, int y, u32 color, u32 bgcolor); void DrawString(u16 *screen, const char *str, int x, int y, u32 color, u32 bgcolor); -void DrawStringF(u16 *screen, int x, int y, u32 color, u32 bgcolor, const char *format, ...); -void DrawStringCenter(u16 *screen, u32 color, u32 bgcolor, const char *format, ...); +void PRINTF_ARGS(6) DrawStringF(u16 *screen, int x, int y, u32 color, u32 bgcolor, const char *format, ...); +void PRINTF_ARGS(4) DrawStringCenter(u16 *screen, u32 color, u32 bgcolor, const char *format, ...); u32 GetCharSize(const char* str); u32 GetPrevCharSize(const char* str); @@ -81,19 +83,19 @@ void TruncateString(char* dest, const char* orig, int nlength, int tpos); void FormatNumber(char* str, u64 number); void FormatBytes(char* str, u64 bytes); -void ShowString(const char *format, ...); -void ShowStringF(u16* screen, const char *format, ...); -void ShowIconString(u16* icon, int w, int h, const char *format, ...); -void ShowIconStringF(u16* screen, u16* icon, int w, int h, const char *format, ...); -bool ShowPrompt(bool ask, const char *format, ...); -u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...); -u32 ShowFileScrollPrompt(u32 n, const DirEntry** entries, bool hide_ext, const char *format, ...); -u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...); -bool ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...); -u64 ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...); -u64 ShowNumberPrompt(u64 start_val, const char *format, ...); -bool ShowDataPrompt(u8* data, u32* size, const char *format, ...); -bool ShowRtcSetterPrompt(void* time, const char *format, ...); +void PRINTF_ARGS(1) ShowString(const char *format, ...); +void PRINTF_ARGS(2) ShowStringF(u16* screen, const char *format, ...); +void PRINTF_ARGS(4) ShowIconString(u16* icon, int w, int h, const char *format, ...); +void PRINTF_ARGS(5) ShowIconStringF(u16* screen, u16* icon, int w, int h, const char *format, ...); +bool PRINTF_ARGS(2) ShowPrompt(bool ask, const char *format, ...); +u32 PRINTF_ARGS(3) ShowSelectPrompt(int n, const char** options, const char *format, ...); +u32 PRINTF_ARGS(4) ShowFileScrollPrompt(int n, const DirEntry** entries, bool hide_ext, const char *format, ...); +u32 PRINTF_ARGS(4) ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...); +bool PRINTF_ARGS(3) ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...); +u64 PRINTF_ARGS(3) ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...); +u64 PRINTF_ARGS(2) ShowNumberPrompt(u64 start_val, const char *format, ...); +bool PRINTF_ARGS(3) ShowDataPrompt(u8* data, u32* size, const char *format, ...); +bool PRINTF_ARGS(2) ShowRtcSetterPrompt(void* time, const char *format, ...); bool ShowProgress(u64 current, u64 total, const char* opstr); int ShowBrightnessConfig(int set_brightness); diff --git a/arm9/source/crypto/keydb.c b/arm9/source/crypto/keydb.c index 3b41d6866..88487d647 100644 --- a/arm9/source/crypto/keydb.c +++ b/arm9/source/crypto/keydb.c @@ -40,10 +40,13 @@ u32 GetUnitKeysType(void) } void CryptAesKeyInfo(AesKeyInfo* info) { - static u8 zeroes[16] = { 0 }; + static const u8 zeros[16] = { 0 }; + static const u8 keyY_dev[16] = { + 0xA2, 0x32, 0x4A, 0x7E, 0x7C, 0xE6, 0x1A, 0x9A, 0x45, 0x4A, 0x52, 0x19, 0xB3, 0x5B, 0xE9, 0x3B }; + const u8* aeskeyY = GetUnitKeysType() == KEYS_DEVKIT ? &keyY_dev[0] : &zeros[0]; u8 ctr[16] = { 0 }; memcpy(ctr, (void*) info, 12); // CTR -> slot + type + id + zeroes - setup_aeskeyY(0x2C, zeroes); + setup_aeskeyY(0x2C, aeskeyY); use_aeskey(0x2C); set_ctr(ctr); aes_decrypt(info->key, info->key, 1, AES_CNT_CTRNAND_MODE); @@ -152,7 +155,7 @@ u32 LoadKeyFromFile(void* key, u32 keyslot, char type, char* id) // load legacy slot0x??Key?.bin file instead if (!found && (type != 'I')) { char fname[64]; - snprintf(fname, 64, "slot0x%02lXKey%s%s.bin", keyslot, + snprintf(fname, sizeof(fname), "slot0x%02lXKey%s%s.bin", keyslot, (type == 'X') ? "X" : (type == 'Y') ? "Y" : (type == 'I') ? "IV" : "", (id) ? id : ""); found = (LoadSupportFile(fname, key, 16) == 16); } diff --git a/arm9/source/filesys/filetype.c b/arm9/source/filesys/filetype.c index baa090e9b..e744925f4 100644 --- a/arm9/source/filesys/filetype.c +++ b/arm9/source/filesys/filetype.c @@ -8,6 +8,7 @@ #include "keydb.h" #include "ctrtransfer.h" #include "scripting.h" +#include "gm9lua.h" #include "png.h" #include "ui.h" // only for font file detection @@ -129,6 +130,8 @@ u64 IdentifyFileType(const char* path) { return FONT_PBM; } else if (GetFontFromRiff(data, fsize, NULL, NULL, NULL)) { return FONT_RIFF; + } else if (GetLanguage(data, fsize, NULL, NULL, NULL)) { + return TRANSLATION; } else if ((fsize > sizeof(AgbHeader)) && (ValidateAgbHeader((AgbHeader*) data) == 0)) { return GAME_GBA; @@ -161,8 +164,11 @@ u64 IdentifyFileType(const char* path) { return BIN_CIFNSH; } else if (ValidateText((char*) data, (fsize > 0x200) ? 0x200 : fsize)) { u64 type = 0; - if ((fsize < SCRIPT_MAX_SIZE) && (strncasecmp(ext, SCRIPT_EXT, strnlen(SCRIPT_EXT, 16) + 1) == 0)) + if ((fsize < SCRIPT_MAX_SIZE) && (strcasecmp(ext, SCRIPT_EXT) == 0)) type |= TXT_SCRIPT; // should be a script (which is also generic text) + // this should check if it's compiled lua bytecode (done with luac), which is NOT text + else if ((fsize < LUASCRIPT_MAX_SIZE) && (strcasecmp(ext, LUASCRIPT_EXT) == 0)) + type |= TXT_LUA; if (fsize < STD_BUFFER_SIZE) type |= TXT_GENERIC; return type; } else if ((strncmp(path + 2, "/Nintendo DSiWare/", 18) == 0) && diff --git a/arm9/source/filesys/filetype.h b/arm9/source/filesys/filetype.h index de963af8a..bef05b5db 100644 --- a/arm9/source/filesys/filetype.h +++ b/arm9/source/filesys/filetype.h @@ -39,6 +39,8 @@ #define FONT_RIFF (1ULL<<34) #define NOIMG_NAND (1ULL<<35) #define HDR_NAND (1ULL<<36) +#define TRANSLATION (1ULL<<37) +#define TXT_LUA (1ULL<<38) #define TYPE_BASE 0xFFFFFFFFFFULL // 40 bit reserved for base types // #define FLAG_FIRM (1ULL<<58) // <--- for CXIs containing FIRMs @@ -76,9 +78,11 @@ #define FTYPE_KEYINIT(tp) (tp&(BIN_KEYDB)) #define FTYPE_KEYINSTALL(tp) (tp&(BIN_KEYDB)) #define FTYPE_SCRIPT(tp) (tp&(TXT_SCRIPT)) +#define FTYPE_LUA(tp) (tp&(TXT_LUA)) #define FTYPE_FONT(tp) (tp&(FONT_PBM|FONT_RIFF)) +#define FTYPE_TRANSLATION(tp) (tp&(TRANSLATION)) #define FTYPE_GFX(tp) (tp&(GFX_PNG)) -#define FTYPE_SETABLE(tp) (tp&(FONT_PBM|FONT_RIFF)) +#define FTYPE_SETABLE(tp) (tp&(FONT_PBM|FONT_RIFF|TRANSLATION)) #define FTYPE_BOOTABLE(tp) (tp&(SYS_FIRM)) #define FTYPE_INSTALLABLE(tp) (tp&(SYS_FIRM)) #define FTYPE_AGBSAVE(tp) (tp&(SYS_AGBSAVE)) diff --git a/arm9/source/filesys/fsdrive.c b/arm9/source/filesys/fsdrive.c index e680942ec..ce3e21b1a 100644 --- a/arm9/source/filesys/fsdrive.c +++ b/arm9/source/filesys/fsdrive.c @@ -1,6 +1,7 @@ #include "fsdrive.h" #include "fsgame.h" #include "fsinit.h" +#include "language.h" #include "virtual.h" #include "vcart.h" #include "sddata.h" @@ -84,13 +85,13 @@ bool GetFATVolumeLabel(const char* drv, char* label) { } bool GetRootDirContentsWorker(DirStruct* contents) { - static const char* drvname[] = { FS_DRVNAME }; + const char* drvname[] = { FS_DRVNAME }; static const char* drvnum[] = { FS_DRVNUM }; u32 n_entries = 0; char sdlabel[DRV_LABEL_LEN]; if (!GetFATVolumeLabel("0:", sdlabel) || !(*sdlabel)) - strcpy(sdlabel, "NOLABEL"); + strcpy(sdlabel, STR_LAB_NOLABEL); char carttype[16]; GetVCartTypeString(carttype); @@ -101,15 +102,15 @@ bool GetRootDirContentsWorker(DirStruct* contents) { if (!DriveType(drvnum[i])) continue; // drive not available entry->p_name = 4; entry->name = entry->path + entry->p_name; - memset(entry->path, 0x00, 64); + memset(entry->path, 0x00, 256); snprintf(entry->path, 4, "%s", drvnum[i]); if ((*(drvnum[i]) >= '7') && (*(drvnum[i]) <= '9') && !(GetMountState() & IMG_NAND)) // Drive 7...9 handling - snprintf(entry->name, 32, "[%s] %s", drvnum[i], - (*(drvnum[i]) == '7') ? "FAT IMAGE" : - (*(drvnum[i]) == '8') ? "BONUS DRIVE" : - (*(drvnum[i]) == '9') ? "RAMDRIVE" : "UNK"); + snprintf(entry->name, 252, "[%s] %s", drvnum[i], + (*(drvnum[i]) == '7') ? STR_LAB_FAT_IMAGE : + (*(drvnum[i]) == '8') ? STR_LAB_BONUS_DRIVE : + (*(drvnum[i]) == '9') ? STR_LAB_RAMDRIVE : "UNK"); else if (*(drvnum[i]) == 'G') // Game drive special handling - snprintf(entry->name, 32, "[%s] %s %s", drvnum[i], + snprintf(entry->name, 252, "[%s] %s %s", drvnum[i], (GetMountState() & GAME_CIA ) ? "CIA" : (GetMountState() & GAME_NCSD ) ? "NCSD" : (GetMountState() & GAME_NCCH ) ? "NCCH" : @@ -119,10 +120,10 @@ bool GetRootDirContentsWorker(DirStruct* contents) { (GetMountState() & SYS_FIRM ) ? "FIRM" : (GetMountState() & GAME_TAD ) ? "DSIWARE" : "UNK", drvname[i]); else if (*(drvnum[i]) == 'C') // Game cart handling - snprintf(entry->name, 32, "[%s] %s (%s)", drvnum[i], drvname[i], carttype); + snprintf(entry->name, 252, "[%s] %s (%s)", drvnum[i], drvname[i], carttype); else if (*(drvnum[i]) == '0') // SD card handling - snprintf(entry->name, 32, "[%s] %s (%s)", drvnum[i], drvname[i], sdlabel); - else snprintf(entry->name, 32, "[%s] %s", drvnum[i], drvname[i]); + snprintf(entry->name, 252, "[%s] %s (%s)", drvnum[i], drvname[i], sdlabel); + else snprintf(entry->name, 252, "[%s] %s", drvnum[i], drvname[i]); entry->size = GetTotalSpace(entry->path); entry->type = T_ROOT; entry->marked = 0; @@ -211,7 +212,7 @@ void SearchDirContents(DirStruct* contents, const char* path, const char* patter void GetDirContents(DirStruct* contents, const char* path) { if (*search_path && (DriveType(path) & DRV_SEARCH)) { - ShowString("Searching, please wait..."); + ShowString("%s", STR_SEARCHING_PLEASE_WAIT); SearchDirContents(contents, search_path, search_pattern, true); ClearScreenF(true, false, COLOR_STD_BG); } else if (title_manager_mode && (DriveType(path) & DRV_TITLEMAN)) { @@ -231,7 +232,7 @@ uint64_t GetFreeSpace(const char* path) FATFS* fsobj = GetMountedFSObject(path); if ((pdrv < 0) || !fsobj) return 0; - snprintf(fsname, 3, "%i:", pdrv); + snprintf(fsname, sizeof(fsname), "%i:", pdrv); if (f_getfree(fsname, &free_clusters, &fsptr) != FR_OK) return 0; diff --git a/arm9/source/filesys/fsdrive.h b/arm9/source/filesys/fsdrive.h index e9f4b4013..e41c461a2 100644 --- a/arm9/source/filesys/fsdrive.h +++ b/arm9/source/filesys/fsdrive.h @@ -32,16 +32,16 @@ #define DRV_LABEL_LEN (36) #define FS_DRVNAME \ - "SDCARD", \ - "SYSNAND CTRNAND", "SYSNAND TWLN", "SYSNAND TWLP", "SYSNAND SD", "SYSNAND VIRTUAL", \ - "EMUNAND CTRNAND", "EMUNAND TWLN", "EMUNAND TWLP", "EMUNAND SD", "EMUNAND VIRTUAL", \ - "IMGNAND CTRNAND", "IMGNAND TWLN", "IMGNAND TWLP", "IMGNAND VIRTUAL", \ - "GAMECART", \ - "GAME IMAGE", "AESKEYDB IMAGE", "BDRI IMAGE", "DISA/DIFF IMAGE", \ - "MEMORY VIRTUAL", \ - "VRAM VIRTUAL", \ - "TITLE MANAGER", \ - "LAST SEARCH" \ + STR_LAB_SDCARD, \ + STR_LAB_SYSNAND_CTRNAND, STR_LAB_SYSNAND_TWLN, STR_LAB_SYSNAND_TWLP, STR_LAB_SYSNAND_SD, STR_LAB_SYSNAND_VIRTUAL, \ + STR_LAB_EMUNAND_CTRNAND, STR_LAB_EMUNAND_TWLN, STR_LAB_EMUNAND_TWLP, STR_LAB_EMUNAND_SD, STR_LAB_EMUNAND_VIRTUAL, \ + STR_LAB_IMGNAND_CTRNAND, STR_LAB_IMGNAND_TWLN, STR_LAB_IMGNAND_TWLP, STR_LAB_IMGNAND_VIRTUAL, \ + STR_LAB_GAMECART, \ + STR_LAB_GAME_IMAGE, STR_LAB_AESKEYDB_IMAGE, STR_LAB_BDRI_IMAGE, STR_LAB_DISA_DIFF_IMAGE, \ + STR_LAB_MEMORY_VIRTUAL, \ + STR_LAB_VRAM_VIRTUAL, \ + STR_LAB_TITLE_MANAGER, \ + STR_LAB_LAST_SEARCH #define FS_DRVNUM \ "0:", "1:", "2:", "3:", "A:", "S:", "4:", "5:", "6:", "B:", "E:", "7:", "8:", "9:", \ diff --git a/arm9/source/filesys/fsgame.c b/arm9/source/filesys/fsgame.c index 8a0f49ff3..600eddd1f 100644 --- a/arm9/source/filesys/fsgame.c +++ b/arm9/source/filesys/fsgame.c @@ -1,6 +1,7 @@ #include "fsgame.h" #include "fsperm.h" #include "gameutil.h" +#include "language.h" #include "tie.h" #include "ui.h" #include "vff.h" @@ -39,7 +40,7 @@ bool GoodRenamer(DirEntry* entry, bool ask) { TruncateString(oldname_tr, entry->name, 32, 8); strncpy(newname_ww, goodname, 256); WordWrapString(newname_ww, 32); - if (!ShowPrompt(true, "%s\nRename to good name?\n \n%s", oldname_tr, newname_ww)) + if (!ShowPrompt(true, "%s\n%s\n \n%s", oldname_tr, STR_RENAME_TO_GOOD_NAME, newname_ww)) return true; // call it a success because user choice } diff --git a/arm9/source/filesys/fsinit.c b/arm9/source/filesys/fsinit.c index c80d34e26..f0183dcaf 100644 --- a/arm9/source/filesys/fsinit.c +++ b/arm9/source/filesys/fsinit.c @@ -21,7 +21,7 @@ bool InitExtFS() { for (u32 i = 1; i < NORM_FS; i++) { char fsname[8]; - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); if (fs_mounted[i]) continue; fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); if ((!fs_mounted[i] || !ramdrv_ready) && (i == NORM_FS - 1) && !(GetMountState() & IMG_NAND)) { @@ -44,7 +44,7 @@ bool InitImgFS(const char* path) { u32 drv_i = NORM_FS - IMGN_FS; char fsname[8]; for (; drv_i < NORM_FS; drv_i++) { - snprintf(fsname, 7, "%lu:", drv_i); + snprintf(fsname, sizeof(fsname), "%lu:", drv_i); if (!(DriveType(fsname)&DRV_IMAGE)) break; } // deinit virtual filesystem @@ -58,7 +58,7 @@ bool InitImgFS(const char* path) { else if ((type&IMG_FAT) && (drv_i < NORM_FS - IMGN_FS + 1)) drv_i = NORM_FS - IMGN_FS + 1; // reinit image filesystem for (u32 i = NORM_FS - IMGN_FS; i < drv_i; i++) { - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); } return GetMountState(); @@ -71,7 +71,7 @@ void DeinitExtFS() { for (u32 i = NORM_FS - 1; i > 0; i--) { if (fs_mounted[i]) { char fsname[8]; - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); f_mount(NULL, fsname, 1); fs_mounted[i] = false; } @@ -91,7 +91,7 @@ void DismountDriveType(u32 type) { // careful with this - no safety checks } for (u32 i = 0; i < NORM_FS; i++) { char fsname[8]; - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); if (!fs_mounted[i] || !(type & DriveType(fsname))) continue; f_mount(NULL, fsname, 1); diff --git a/arm9/source/filesys/fsperm.c b/arm9/source/filesys/fsperm.c index fb545b7df..ae4eb6060 100644 --- a/arm9/source/filesys/fsperm.c +++ b/arm9/source/filesys/fsperm.c @@ -4,6 +4,7 @@ #include "image.h" #include "unittype.h" #include "essentials.h" +#include "language.h" #include "ui.h" #include "sdmmc.h" @@ -20,7 +21,7 @@ static u32 write_permissions = PERM_BASE; bool CheckWritePermissions(const char* path) { - char area_name[16]; + char area_name[UTF_BUFFER_BYTESIZE(16)]; int drvtype = DriveType(path); u32 perm; @@ -40,7 +41,7 @@ bool CheckWritePermissions(const char* path) { // SD card write protection check if ((drvtype & (DRV_SDCARD | DRV_EMUNAND | DRV_ALIAS)) && SD_WRITE_PROTECTED) { - ShowPrompt(false, "SD card is write protected!\nCan't continue."); + ShowPrompt(false, "%s", STR_SD_WRITE_PROTECTED_CANT_CONTINUE); return false; } @@ -63,7 +64,7 @@ bool CheckWritePermissions(const char* path) { if ((drvtype & DRV_CTRNAND) || (lvl == 2)) lvl = 3; } perm = perms[lvl]; - snprintf(area_name, 16, "SysNAND (lvl%lu)", lvl); + snprintf(area_name, sizeof(area_name), STR_SYSNAND_LVL_N, lvl); } else if (drvtype & DRV_EMUNAND) { static const u32 perms[] = { PERM_EMU_LVL0, PERM_EMU_LVL1 }; u32 lvl = (drvtype & (DRV_ALIAS|DRV_CTRNAND)) ? 1 : 0; @@ -73,34 +74,34 @@ bool CheckWritePermissions(const char* path) { if (strncasecmp(path_f, path_lvl1[i], 256) == 0) lvl = 1; } perm = perms[lvl]; - snprintf(area_name, 16, "EmuNAND (lvl%lu)", lvl); + snprintf(area_name, sizeof(area_name), STR_EMUNAND_LVL_N, lvl); } else if (drvtype & DRV_GAME) { perm = PERM_GAME; - snprintf(area_name, 16, "game images"); + snprintf(area_name, sizeof(area_name), "%s", STR_GAME_IMAGES); } else if (drvtype & DRV_CART) { perm = PERM_CART; - snprintf(area_name, 16, "gamecart saves"); + snprintf(area_name, sizeof(area_name), "%s", STR_GAMECART_SAVES); } else if (drvtype & DRV_VRAM) { perm = PERM_VRAM; - snprintf(area_name, 16, "vram0"); + snprintf(area_name, sizeof(area_name), "vram0"); } else if (drvtype & DRV_XORPAD) { perm = PERM_XORPAD; - snprintf(area_name, 16, "XORpads"); + snprintf(area_name, sizeof(area_name), "XORpads"); } else if (drvtype & DRV_IMAGE) { perm = PERM_IMAGE; - snprintf(area_name, 16, "images"); + snprintf(area_name, sizeof(area_name), "%s", STR_IMAGES); } else if (drvtype & DRV_MEMORY) { perm = PERM_MEMORY; - snprintf(area_name, 16, "memory areas"); + snprintf(area_name, sizeof(area_name), "%s", STR_MEMORY_AREAS); } else if (strncasecmp(path_f, "0:/Nintendo 3DS", 15) == 0) { // this check could be better perm = PERM_SDDATA; - snprintf(area_name, 16, "SD system data"); + snprintf(area_name, sizeof(area_name), "%s", STR_SD_SYSTEM_DATA); } else if (drvtype & DRV_SDCARD) { perm = PERM_SDCARD; - snprintf(area_name, 16, "SD card"); + snprintf(area_name, sizeof(area_name), "%s", STR_SD_CARD); } else if (drvtype & DRV_RAMDRIVE) { perm = PERM_RAMDRIVE; - snprintf(area_name, 16, "RAM drive"); + snprintf(area_name, sizeof(area_name), "%s", STR_RAM_DRIVE); } else { return false; } @@ -112,14 +113,14 @@ bool CheckWritePermissions(const char* path) { // offer unlock if possible if (!(perm & (PERM_VRAM|PERM_GAME|PERM_XORPAD))) { // ask the user - if (!ShowPrompt(true, "Writing to %s is locked!\nUnlock it now?", area_name)) + if (!ShowPrompt(true, STR_WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW, area_name)) return false; return SetWritePermissions(perm, true); } // unlock not possible - ShowPrompt(false, "Unlock write permission for\n%s is not allowed.", area_name); + ShowPrompt(false, STR_UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED, area_name); return false; } @@ -144,65 +145,65 @@ bool SetWritePermissions(u32 perm, bool add_perm) { switch (perm) { case PERM_BASE: - if (!ShowUnlockSequence(1, "You want to enable base\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_BASE_WRITE)) return false; break; case PERM_SDCARD: - if (!ShowUnlockSequence(1, "You want to enable SD card\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_SD_WRITE)) return false; break; case PERM_IMAGE: - if (!ShowUnlockSequence(1, "You want to enable image\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_IMAGE_WRITE)) return false; break; case PERM_RAMDRIVE: - if (!ShowUnlockSequence(1, "You want to enable RAM drive\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_RAM_DRIVE_WRITE)) return false; break; case PERM_EMU_LVL0: - if (!ShowUnlockSequence(1, "You want to enable EmuNAND\nlvl0 writing permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_EMUNAND_0_WRITE)) return false; break; case PERM_SYS_LVL0: - if (!ShowUnlockSequence(1, "You want to enable SysNAND\nlvl0 writing permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_SYSNAND_0_WRITE)) return false; break; case PERM_EMU_LVL1: - if (!ShowUnlockSequence(2, "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.")) + if (!ShowUnlockSequence(2, "%s", STR_ENABLE_EMUNAND_1_WRITE)) return false; break; case PERM_SYS_LVL1: - if (!ShowUnlockSequence(2, "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.")) + if (!ShowUnlockSequence(2, "%s", STR_ENABLE_SYSNAND_1_WRITE)) return false; break; case PERM_CART: - if (!ShowUnlockSequence(2, "You want to enable gamecart\nsave writing permissions.")) + if (!ShowUnlockSequence(2, "%s", STR_ENABLE_GAMECART_SAVE_WRITE)) return false; break; #ifndef SAFEMODE case PERM_SYS_LVL2: - if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!")) + if (!ShowUnlockSequence(3, "%s", STR_ENABLE_SYSNAND_2_WRITE)) return false; break; case PERM_MEMORY: - if (!ShowUnlockSequence(4, "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.")) + if (!ShowUnlockSequence(4, "%s", STR_ENABLE_MEMORY_WRITE)) return false; break; case PERM_SDDATA: - if (!ShowUnlockSequence(5, "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.")) + if (!ShowUnlockSequence(5, "%s", STR_ENABLE_SD_DATA_WRITE)) return false; break; case PERM_SYS_LVL3: - if (!ShowUnlockSequence(6, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!")) + if (!ShowUnlockSequence(6, "%s", STR_ENABLE_SYSNAND_3_WRITE)) return false; break; default: - ShowPrompt(false, "Unlock write permission is not allowed."); + ShowPrompt(false, "%s", STR_UNLOCK_WRITE_NOT_ALLOWED); return false; break; #else default: - ShowPrompt(false, "Can't unlock write permission.\nTry GodMode9 instead!"); + ShowPrompt(false, "%s", STR_CANT_UNLOCK_WRITE_TRY_GODMODE9); return false; break; #endif diff --git a/arm9/source/filesys/fsutil.c b/arm9/source/filesys/fsutil.c index f785bfe73..6b9cfd0cc 100644 --- a/arm9/source/filesys/fsutil.c +++ b/arm9/source/filesys/fsutil.c @@ -11,9 +11,10 @@ #include "ff.h" #include "ui.h" #include "swkbd.h" +#include "language.h" -#define SKIP_CUR (1UL<<10) -#define OVERWRITE_CUR (1UL<<11) +#define SKIP_CUR (1UL<<11) +#define OVERWRITE_CUR (1UL<<12) #define _MAX_FS_OPT 8 // max file selector options @@ -46,13 +47,13 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { // FAT size check if (fat_size < 0x80000) { // minimum free space: 256MB - ShowPrompt(false, "Error: SD card is too small"); + ShowPrompt(false, "%s", STR_ERROR_SD_TOO_SMALL); return false; } // Write protection check if (SD_WRITE_PROTECTED) { - ShowPrompt(false, "SD card is write protected!\nCan't continue."); + ShowPrompt(false, "%s", STR_SD_WRITE_PROTECTED_CANT_CONTINUE); return false; } @@ -67,15 +68,15 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { // one last warning.... // 0:/Nintendo 3DS/ write permission is ignored here, this warning is enough - if (!ShowUnlockSequence(5, "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.")) + if (!ShowUnlockSequence(5, "%s", STR_WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA)) return false; - ShowString("Formatting SD, please wait..."); + ShowString("%s", STR_FORMATTING_SD_PLEASE_WAIT); // write the MBR to disk // !this assumes a fully deinitialized file system! if ((sdmmc_sdcard_init() != 0) || (sdmmc_sdcard_writesectors(0, 1, mbr) != 0) || (emu_size && ((sdmmc_nand_readsectors(0, 1, ncsd) != 0) || (sdmmc_sdcard_writesectors(1, 1, ncsd) != 0)))) { - ShowPrompt(false, "Error: SD card i/o failure"); + ShowPrompt(false, "%s", STR_ERROR_SD_CARD_IO_FAILURE); return false; } @@ -104,9 +105,9 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { } bool SetupBonusDrive(void) { - if (!ShowUnlockSequence(3, "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.")) + if (!ShowUnlockSequence(3, "%s", STR_FORMAT_BONUS_DRIVE_DELETE_ALL_DATA)) return false; - ShowString("Formatting drive, please wait..."); + ShowString("%s", STR_FORMATTING_DRIVE_PLEASE_WAIT); if (GetMountState() & IMG_NAND) InitImgFS(NULL); u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); @@ -130,7 +131,7 @@ bool FileUnlock(const char* path) { char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, path, 32, 8); if (GetMountState() && (res == FR_LOCKED) && - (ShowPrompt(true, "%s\nFile is currently mounted.\nUnmount to unlock?", pathstr))) { + (ShowPrompt(true, "%s\n%s", pathstr, STR_FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK))) { InitImgFS(NULL); if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) return false; @@ -250,7 +251,7 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or if (!CheckWritePermissions(dest)) return false; if (strncasecmp(dest, orig, 256) == 0) { - ShowPrompt(false, "Error: Can't inject file into itself"); + ShowPrompt(false, "%s", STR_ERROR_CANT_INJECT_FILE_INTO_ITSELF); return false; } @@ -269,12 +270,12 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or // check file limits if (!allow_expand && (off_dest + size > fvx_size(&dfile))) { - ShowPrompt(false, "Operation would write beyond end of file"); + ShowPrompt(false, "%s", STR_OPERATION_WOULD_WRITE_BEYOND_EOF); fvx_close(&dfile); fvx_close(&ofile); return false; } else if (off_orig + size > fvx_size(&ofile)) { - ShowPrompt(false, "Not enough data in file"); + ShowPrompt(false, "%s", STR_NOT_ENOUGH_DATA_IN_FILE); fvx_close(&dfile); fvx_close(&ofile); return false; @@ -295,8 +296,8 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or ret = false; if (ret && !ShowProgress(pos + bytes_read, size, orig)) { if (flags && (*flags & NO_CANCEL)) { - ShowPrompt(false, "Cancel is not allowed here"); - } else ret = !ShowPrompt(true, "B button detected. Cancel?"); + ShowPrompt(false, "%s", STR_CANCEL_IS_NOT_ALLOWED_HERE); + } else ret = !ShowPrompt(true, "%s", STR_B_DETECTED_CANCEL); ShowProgress(0, 0, orig); ShowProgress(pos + bytes_read, size, orig); } @@ -325,7 +326,7 @@ bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags // check file limits if (!allow_expand && (offset + size > fvx_size(&dfile))) { - ShowPrompt(false, "Operation would write beyond end of file"); + ShowPrompt(false, "%s", STR_OPERATION_WOULD_WRITE_BEYOND_EOF); fvx_close(&dfile); return false; } @@ -345,8 +346,8 @@ bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags ret = false; if (ret && !ShowProgress(pos + bytes_written, size, dest)) { if (flags && (*flags & NO_CANCEL)) { - ShowPrompt(false, "Cancel is not allowed here"); - } else ret = !ShowPrompt(true, "B button detected. Cancel?"); + ShowPrompt(false, "%s", STR_CANCEL_IS_NOT_ALLOWED_HERE); + } else ret = !ShowPrompt(true, "%s", STR_B_DETECTED_CANCEL); ShowProgress(0, 0, dest); ShowProgress(pos + bytes_written, size, dest); } @@ -362,8 +363,8 @@ bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags bool FileCreateDummy(const char* cpath, const char* filename, u64 size) { char npath[256]; // 256 is the maximum length of a full path if (!CheckWritePermissions(cpath)) return false; - if (filename) snprintf(npath, 255, "%s/%s", cpath, filename); - else snprintf(npath, 255, "%s", cpath); + if (filename) snprintf(npath, sizeof(npath), "%s/%s", cpath, filename); + else snprintf(npath, sizeof(npath), "%s", cpath); // create dummy file (fail if already existing) // then, expand the file size via cluster preallocation @@ -380,7 +381,7 @@ bool FileCreateDummy(const char* cpath, const char* filename, u64 size) { bool DirCreate(const char* cpath, const char* dirname) { char npath[256]; // 256 is the maximum length of a full path if (!CheckWritePermissions(cpath)) return false; - snprintf(npath, 255, "%s/%s", cpath, dirname); + snprintf(npath, sizeof(npath), "%s/%s", cpath, dirname); if (fa_mkdir(npath) != FR_OK) return false; return (fa_stat(npath, NULL) == FR_OK); } @@ -466,7 +467,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, // the copy process takes place here if (!ShowProgress(0, 0, orig) && !(flags && (*flags & NO_CANCEL))) { - if (ShowPrompt(true, "%s\nB button detected. Cancel?", deststr)) return false; + if (ShowPrompt(true, "%s\n%s", deststr, STR_B_DETECTED_CANCEL)) return false; ShowProgress(0, 0, orig); } if (move && fvx_stat(dest, NULL) != FR_OK) { // moving if dest not existing @@ -476,14 +477,14 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, char* fname = orig + strnlen(orig, 256); if (append) { - if (!silent) ShowPrompt(false, "%s\nError: Cannot append a folder", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_CANNOT_APPEND_FOLDER); return false; } // create the destination folder if it does not already exist if (fvx_opendir(&pdir, dest) != FR_OK) { if (fvx_mkdir(dest) != FR_OK) { - if (!silent) ShowPrompt(false, "%s\nError: Overwriting file with dir", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_OVERWRITING_FILE_WITH_DIR); return false; } } else fvx_closedir(&pdir); @@ -516,7 +517,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, } else if (move) { // moving if destination exists if (fvx_stat(dest, &fno) != FR_OK) return false; if (fno.fattrib & AM_DIR) { - if (!silent) ShowPrompt(false, "%s\nError: Overwriting dir with file", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_OVERWRITING_DIR_WITH_FILE); return false; } if (fvx_unlink(dest) != FR_OK) return false; @@ -535,7 +536,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, if ((!append || (fvx_open(&dfile, dest, FA_WRITE | FA_OPEN_EXISTING) != FR_OK)) && (fvx_open(&dfile, dest, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)) { - if (!silent) ShowPrompt(false, "%s\nError: Cannot open destination file", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_CANNOT_OPEN_DESTINATION_FILE); fvx_close(&ofile); return false; } @@ -544,7 +545,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, osize = fvx_size(&ofile); dsize = append ? fvx_size(&dfile) : 0; // always 0 if not appending to file if ((fvx_lseek(&dfile, (osize + dsize)) != FR_OK) || (fvx_sync(&dfile) != FR_OK) || (fvx_tell(&dfile) != (osize + dsize))) { // check space via cluster preallocation - if (!silent) ShowPrompt(false, "%s\nError: Not enough space available", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_NOT_ENOUGH_SPACE_AVAILABLE); ret = false; } @@ -566,8 +567,8 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, u64 total = osize; if (ret && !ShowProgress(current, total, orig)) { if (flags && (*flags & NO_CANCEL)) { - ShowPrompt(false, "%s\nCancel is not allowed here", deststr); - } else ret = !ShowPrompt(true, "%s\nB button detected. Cancel?", deststr); + ShowPrompt(false, "%s\n%s", deststr, STR_CANCEL_IS_NOT_ALLOWED_HERE); + } else ret = !ShowPrompt(true, "%s\n%s", deststr, STR_B_DETECTED_CANCEL); ShowProgress(0, 0, orig); ShowProgress(current, total, orig); } @@ -614,14 +615,14 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // moving only for regular FAT drives (= not alias drives) if (move && !(ddrvtype & odrvtype & DRV_STDFAT)) { - ShowPrompt(false, "Error: Only FAT files can be moved"); + ShowPrompt(false, "%s", STR_ERROR_ONLY_FAT_FILES_CAN_BE_MOVED); return false; } // is destination part of origin? u32 olen = strnlen(lorig, 255); if ((strncasecmp(ldest, lorig, olen) == 0) && (ldest[olen] == '/')) { - ShowPrompt(false, "%s\nError: Destination is part of origin", deststr); + ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_DESTINATION_IS_PART_OF_ORIGIN); return false; } @@ -633,7 +634,7 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // check & fix destination == origin while (strncasecmp(ldest, lorig, 255) == 0) { - if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "%s\nDestination equals origin\nChoose another name?", deststr)) + if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "%s\n%s", deststr, STR_ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME)) return false; } @@ -644,12 +645,11 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { return true; } const char* optionstr[5] = - {"Choose new name", "Overwrite file(s)", "Skip file(s)", "Overwrite all", "Skip all"}; - u32 user_select = ShowSelectPrompt((*flags & ASK_ALL) ? 5 : 3, optionstr, - "Destination already exists:\n%s", deststr); + {STR_CHOOSE_NEW_NAME, STR_OVERWRITE_FILES, STR_SKIP_FILES, STR_OVERWRITE_ALL, STR_SKIP_ALL}; + u32 user_select = ShowSelectPrompt((*flags & ASK_ALL) ? 5 : 3, optionstr, STR_DESTINATION_ALREADY_EXISTS, deststr); if (user_select == 1) { do { - if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "Choose new destination name")) + if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "%s", STR_CHOOSE_NEW_DESTINATION_NAME)) return false; } while (fa_stat(ldest, NULL) == FR_OK); } else if (user_select == 2) { @@ -673,7 +673,7 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // setup buffer u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return false; } @@ -699,20 +699,20 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // prevent illegal operations if (force_unmount && (odrvtype & ddrvtype & (DRV_SYSNAND|DRV_EMUNAND|DRV_IMAGE))) { - ShowPrompt(false, "Copy operation is not allowed"); + ShowPrompt(false, "%s", STR_COPY_OPERATION_IS_NOT_ALLOWED); return false; } // check destination == origin if (strncasecmp(ldest, lorig, 255) == 0) { - ShowPrompt(false, "%s\nDestination equals origin", deststr); + ShowPrompt(false, "%s\n%s", deststr, STR_DESTINATION_EQUALS_ORIGIN); return false; } // setup buffer u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return false; } @@ -731,7 +731,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { char dest[256]; // maximum path name length in FAT char* oname = strrchr(orig, '/'); if (oname == NULL) return false; // not a proper origin path - snprintf(dest, 255, "%s/%s", destdir, (++oname)); + snprintf(dest, sizeof(dest), "%s/%s", destdir, (++oname)); // virtual destination special handling if (GetVirtualSource(destdir) & ~VRT_BDRI) { @@ -745,9 +745,9 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { if (!ReadVirtualDir(&dvfile, &vdir)) return false; if (dvfile.size == osize) break; // file found } - if (!ShowPrompt(true, "Entry not found: %s\nInject into %s instead?", dest, dvfile.name)) + if (!ShowPrompt(true, STR_ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD, dest, dvfile.name)) return false; - snprintf(dest, 255, "%s/%s", destdir, dvfile.name); + snprintf(dest, sizeof(dest), "%s/%s", destdir, dvfile.name); } else if (osize < dvfile.size) { // if origin is smaller than destination... char deststr[UTF_BUFFER_BYTESIZE(36)]; char origstr[UTF_BUFFER_BYTESIZE(36)]; @@ -758,7 +758,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { FormatBytes(osizestr, osize); FormatBytes(dsizestr, dvfile.size); if (dvfile.size > osize) { - if (!ShowPrompt(true, "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", origstr, osizestr, deststr, dsizestr)) + if (!ShowPrompt(true, STR_FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE, origstr, osizestr, deststr, dsizestr)) return false; } } @@ -772,7 +772,7 @@ bool PathMove(const char* destdir, const char* orig, u32* flags) { char dest[256]; // maximum path name length in FAT char* oname = strrchr(orig, '/'); if (oname == NULL) return false; // not a proper origin path - snprintf(dest, 255, "%s/%s", destdir, (++oname)); + snprintf(dest, sizeof(dest), "%s/%s", destdir, (++oname)); return PathMoveCopy(dest, orig, flags, true); } @@ -832,13 +832,13 @@ bool FileSelectorWorker(char* result, const char* text, const char* path, const (entry->type == T_DOTDOT) || (strncmp(entry->name, "._", 2) == 0)) continue; if (!new_style && n_opt == _MAX_FS_OPT) { - snprintf(opt_names[n_opt++], 32, "[more...]"); + snprintf(opt_names[n_opt++], 32, "%s", STR_BRACKET_MORE); break; } if (!new_style) { char temp_str[256]; - snprintf(temp_str, 256, "%s", entry->name); + snprintf(temp_str, sizeof(temp_str), "%s", entry->name); if (hide_ext && (entry->type == T_FILE)) { char* dot = strrchr(temp_str, '.'); if (dot) *dot = '\0'; @@ -849,7 +849,7 @@ bool FileSelectorWorker(char* result, const char* text, const char* path, const n_found++; } if ((pos >= contents->n_entries) && (n_opt < n_found) && !new_style) - snprintf(opt_names[n_opt++], 32, "[more...]"); + snprintf(opt_names[n_opt++], 32, "%s", STR_BRACKET_MORE); if (!n_opt) break; const char* optionstr[_MAX_FS_OPT+1] = { NULL }; @@ -874,7 +874,7 @@ bool FileSelectorWorker(char* result, const char* text, const char* path, const if (!n_found) { // not a single matching entry found char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, path_local, 32, 8); - ShowPrompt(false, "%s\nNo usable entries found.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NO_USABLE_ENTRIES_FOUND); return false; } } diff --git a/arm9/source/filesys/sddata.c b/arm9/source/filesys/sddata.c index 1148cf234..cec19cf43 100644 --- a/arm9/source/filesys/sddata.c +++ b/arm9/source/filesys/sddata.c @@ -276,7 +276,7 @@ bool SetupNandSdDrive(const char* path, const char* sd_path, const char* movable // build the alias path (id0) u32 sha256sum[8]; sha_quick(sha256sum, sd_keyy[num], 0x10, SHA256_MODE); - snprintf(alias, 127, "%s/Nintendo 3DS/%08lX%08lX%08lX%08lX", + snprintf(alias, sizeof(alias), "%s/Nintendo 3DS/%08lX%08lX%08lX%08lX", sd_path, sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); // find the alias path (id1) diff --git a/arm9/source/filesys/support.c b/arm9/source/filesys/support.c index 0f261d471..474237bbd 100644 --- a/arm9/source/filesys/support.c +++ b/arm9/source/filesys/support.c @@ -17,7 +17,7 @@ bool CheckSupportFile(const char* fname) const char* base_paths[] = { SUPPORT_FILE_PATHS }; for (u32 i = 0; i < countof(base_paths); i++) { char path[256]; - snprintf(path, 256, "%s/%s", base_paths[i], fname); + snprintf(path, sizeof(path), "%s/%s", base_paths[i], fname); if (fvx_stat(path, NULL) == FR_OK) return true; } @@ -40,7 +40,7 @@ size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len) for (u32 i = 0; i < countof(base_paths); i++) { UINT len32; char path[256]; - snprintf(path, 256, "%s/%s", base_paths[i], fname); + snprintf(path, sizeof(path), "%s/%s", base_paths[i], fname); if (fvx_qread(path, buffer, 0, max_len, &len32) == FR_OK) return len32; } @@ -68,7 +68,7 @@ bool SaveSupportFile(const char* fname, void* buffer, size_t len) // write support file if (idx >= 0) { char path[256]; - snprintf(path, 256, "%s/%s", base_paths[idx], fname); + snprintf(path, sizeof(path), "%s/%s", base_paths[idx], fname); fvx_unlink(path); if (fvx_qwrite(path, buffer, 0, len, NULL) == FR_OK) return true; diff --git a/arm9/source/filesys/support.h b/arm9/source/filesys/support.h index 1146157b6..26c1ba170 100644 --- a/arm9/source/filesys/support.h +++ b/arm9/source/filesys/support.h @@ -3,7 +3,9 @@ #include "common.h" // scripts / payloads dir names +#define LANGUAGES_DIR "languages" #define SCRIPTS_DIR "scripts" +#define LUASCRIPTS_DIR "luascripts" #define PAYLOADS_DIR "payloads" bool CheckSupportFile(const char* fname); @@ -11,5 +13,6 @@ size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len); bool SaveSupportFile(const char* fname, void* buffer, size_t len); bool SetAsSupportFile(const char* fname, const char* source); +bool GetSupportDir(char* path, const char* dname); bool CheckSupportDir(const char* fpath); bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern); diff --git a/arm9/source/filesys/vff.h b/arm9/source/filesys/vff.h index 23a6d0bab..864ba0681 100644 --- a/arm9/source/filesys/vff.h +++ b/arm9/source/filesys/vff.h @@ -8,6 +8,7 @@ #define fvx_tell(fp) ((fp)->fptr) #define fvx_size(fp) ((fp)->obj.objsize) +#define fvx_eof(fp) (fvx_tell(fp) == fvx_size(fp)) #define FN_ANY 0x00 #define FN_HIGHEST 0x01 diff --git a/arm9/source/game/bps.c b/arm9/source/game/bps.c index 4adf8eddf..3ad98530d 100644 --- a/arm9/source/game/bps.c +++ b/arm9/source/game/bps.c @@ -18,6 +18,7 @@ #include +#include "language.h" #include "common.h" #include "timer.h" #include "crc32.h" @@ -143,18 +144,18 @@ static bool BEAT_UpdateProgress(const BEAT_Context *ctx) static const char *BEAT_ErrString(int error) { // Get an error description string switch(error) { - case BEAT_OK: return "No error"; - case BEAT_EOAL: return "End of action list"; - case BEAT_ABORTED: return "Aborted by user"; - case BEAT_IO_ERROR: return "Failed to read/write file"; - case BEAT_OVERFLOW: return "Attempted to write beyond end of file"; - case BEAT_BADPATCH: return "Invalid patch file"; - case BEAT_BADINPUT: return "Invalid input file"; - case BEAT_BADOUTPUT: return "Output file checksum mismatch"; - case BEAT_BADCHKSUM: return "File checksum failed"; - case BEAT_PATCH_EXPECT: return "Expected more patch data"; - case BEAT_OUT_OF_MEMORY: return "Out of memory"; - default: return "Unknown error"; + case BEAT_OK: return STR_BEAT_NO_ERROR; + case BEAT_EOAL: return STR_BEAT_END_OF_ACTION_LIST; + case BEAT_ABORTED: return STR_BEAT_ABORTED_BY_USER; + case BEAT_IO_ERROR: return STR_BEAT_FAILED_TO_READ_WRITE_FILE; + case BEAT_OVERFLOW: return STR_BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF; + case BEAT_BADPATCH: return STR_BEAT_INVALID_PATCH_FILE; + case BEAT_BADINPUT: return STR_BEAT_INVALID_INPUT_FILE; + case BEAT_BADOUTPUT: return STR_BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH; + case BEAT_BADCHKSUM: return STR_BEAT_FILE_CHECKSUM_FAILED; + case BEAT_PATCH_EXPECT: return STR_BEAT_EXPECTED_MORE_PATCH_DATA; + case BEAT_OUT_OF_MEMORY: return STR_BEAT_OUT_OF_MEMORY; + default: return STR_BEAT_UNKNOWN_ERROR; } } @@ -221,7 +222,7 @@ static s32 BEAT_DecodeSigned(u32 val) // Extract the signed number static int BEAT_RunActions(BEAT_Context *ctx, const BEAT_Action *acts) { // Parses an action list and runs commands specified in `acts` u32 vli, len; - int cmd, res; + int cmd, res = BEAT_OK; while((res == BEAT_OK) && (ctx->foff[BEAT_PF] < (BEAT_RANGE(ctx, BEAT_PF) - ctx->eoal_offset))) { @@ -660,19 +661,18 @@ static int BEAT_Run(const char *p, const char *s, const char *d, bool bpm) progress_timer = timer_start(); res = (bpm ? BPM_InitCTX : BPS_InitCTX)(&ctx, p, s, d); if (res != BEAT_OK) { - ShowPrompt(false, "Failed to initialize %s file:\n%s", - bpm ? "BPM" : "BPS", BEAT_ErrString(res)); + ShowPrompt(false, bpm ? STR_FAILED_TO_INITIALIZE_BPM_FILE : STR_FAILED_TO_INITIALIZE_BPS_FILE, BEAT_ErrString(res)); } else { res = (bpm ? BPM_RunActions : BPS_RunActions)(&ctx); switch(res) { case BEAT_OK: - ShowPrompt(false, "Patch successfully applied"); + ShowPrompt(false, "%s", STR_PATCH_SUCCESSFULLY_APPLIED); break; case BEAT_ABORTED: - ShowPrompt(false, "Patching aborted by user"); + ShowPrompt(false, "%s", STR_PATCHING_ABORTED_BY_USER); break; default: - ShowPrompt(false, "Failed to run patch:\n%s", BEAT_ErrString(res)); + ShowPrompt(false, STR_FAILED_TO_RUN_PATCH, BEAT_ErrString(res)); break; } } diff --git a/arm9/source/game/codelzss.c b/arm9/source/game/codelzss.c index d740547fa..a75ca9571 100644 --- a/arm9/source/game/codelzss.c +++ b/arm9/source/game/codelzss.c @@ -1,4 +1,5 @@ #include "codelzss.h" +#include "language.h" #include "ui.h" #define CODE_COMP_SIZE(f) ((f)->off_size_comp & 0xFFFFFF) @@ -45,10 +46,10 @@ u32 DecompressCodeLzss(u8* code, u32* code_size, u32 max_size) { // main decompression loop while ((ptr_in > comp_start) && (ptr_out > comp_start)) { - if (!ShowProgress(data_end - ptr_out, data_end - data_start, "Decompressing .code...")) { - if (ShowPrompt(true, "Decompressing .code...\nB button detected. Cancel?")) return 1; - ShowProgress(0, data_end - data_start, "Decompressing .code..."); - ShowProgress(data_end - ptr_out, data_end - data_start, "Decompressing .code..."); + if (!ShowProgress(data_end - ptr_out, data_end - data_start, STR_DECOMPRESSING_DOT_CODE)) { + if (ShowPrompt(true, "%s", STR_DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL)) return 1; + ShowProgress(0, data_end - data_start, STR_DECOMPRESSING_DOT_CODE); + ShowProgress(data_end - ptr_out, data_end - data_start, STR_DECOMPRESSING_DOT_CODE); } // sanity check @@ -242,13 +243,13 @@ bool CompressCodeLzss(const u8* a_pUncompressed, u32 a_uUncompressedSize, u8* a_ u8* pDest = a_pCompressed + a_uUncompressedSize; while (pSrc - a_pUncompressed > 0 && pDest - a_pCompressed > 0) { - if (!ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, "Compressing .code...")) { - if (ShowPrompt(true, "Compressing .code...\nB button detected. Cancel?")) { + if (!ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, STR_COMPRESSING_DOT_CODE)) { + if (ShowPrompt(true, "%s", STR_COMPRESSING_DOT_CODE_B_DETECTED_CANCEL)) { bResult = false; break; } - ShowProgress(0, a_uUncompressedSize, "Compressing .code..."); - ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, "Compressing .code..."); + ShowProgress(0, a_uUncompressedSize, STR_COMPRESSING_DOT_CODE); + ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, STR_COMPRESSING_DOT_CODE); } u8* pFlag = --pDest; diff --git a/arm9/source/game/firm.c b/arm9/source/game/firm.c index f9f750992..c30468124 100644 --- a/arm9/source/game/firm.c +++ b/arm9/source/game/firm.c @@ -12,18 +12,19 @@ // valid addresses for FIRM section loading // pairs of start / end address, provided by Wolfvak #define FIRM_VALID_ADDRESS \ - 0x08000040, 0x08100000, \ 0x18000000, 0x18600000, \ 0x1FF00000, 0x1FFFFC00 // valid addresses (installable) for FIRM section loading #define FIRM_VALID_ADDRESS_INSTALL \ FIRM_VALID_ADDRESS, \ + 0x08000040, 0x080F7FFF, \ 0x10000000, 0x10200000 // valid addresses (bootable) for FIRM section loading #define FIRM_VALID_ADDRESS_BOOT \ FIRM_VALID_ADDRESS, \ + 0x08000040, 0x08100000, \ 0x20000000, 0x27FFFA00 static const u32 whitelist_boot[] = { FIRM_VALID_ADDRESS_BOOT }; diff --git a/arm9/source/game/gba.c b/arm9/source/game/gba.c index 65a8fb0c0..26eb98c2c 100644 --- a/arm9/source/game/gba.c +++ b/arm9/source/game/gba.c @@ -87,3 +87,17 @@ u32 ValidateAgbHeader(AgbHeader* agb) { return 0; } */ + +// see: http://problemkaputt.de/gbatek.htm#gbacartridgeheader +const char* AgbDestStr(const char* code) { + switch(code[3]) { + case 'J': return STR_REGION_JAPAN; + case 'E': return STR_REGION_AMERICAS; + case 'P': return STR_REGION_EUROPE; + case 'D': return STR_REGION_GERMANY; + case 'F': return STR_REGION_FRANCE; + case 'I': return STR_REGION_ITALY; + case 'S': return STR_REGION_SPAIN; + default: return STR_REGION_UNKNOWN; + } +} diff --git a/arm9/source/game/gba.h b/arm9/source/game/gba.h index 967b24720..7b3613389 100644 --- a/arm9/source/game/gba.h +++ b/arm9/source/game/gba.h @@ -1,6 +1,7 @@ #pragma once #include "common.h" +#include "language.h" #define GBAVC_MAGIC '.', 'C', 'A', 'A' #define AGBSAVE_MAGIC '.', 'S', 'A', 'V' @@ -28,16 +29,6 @@ ((size) == GBASAVE_FLASH_64K) || \ ((size) == GBASAVE_FLASH_128K)) -// see: http://problemkaputt.de/gbatek.htm#gbacartridgeheader -#define AGB_DESTSTR(code) \ - (((code)[3] == 'J') ? "Japan" : \ - ((code)[3] == 'E') ? "USA/English" : \ - ((code)[3] == 'P') ? "Europe/Elsewhere" : \ - ((code)[3] == 'D') ? "German" : \ - ((code)[3] == 'F') ? "French" : \ - ((code)[3] == 'I') ? "Italian" : \ - ((code)[3] == 'S') ? "Spanish" : "Unknown") - // see: http://3dbrew.org/wiki/3DS_Virtual_Console#Footer // still a lot of unknowns in here, also redundant stuff left out @@ -89,5 +80,8 @@ typedef struct { } __attribute__((packed, aligned(16))) AgbHeader; + u32 ValidateAgbSaveHeader(AgbSaveHeader* header); u32 ValidateAgbHeader(AgbHeader* agb); + +const char* AgbDestStr(const char* code); diff --git a/arm9/source/game/ips.c b/arm9/source/game/ips.c index 76cef60b7..a8f66f6c1 100644 --- a/arm9/source/game/ips.c +++ b/arm9/source/game/ips.c @@ -5,6 +5,7 @@ #include "ips.h" #include "common.h" #include "fsperm.h" +#include "language.h" #include "ui.h" #include "vff.h" @@ -30,21 +31,21 @@ char errName[256]; int displayError(int errcode) { switch(errcode) { case IPS_NOTTHIS: - ShowPrompt(false, "%s\nThe patch is most likely not intended for this file.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE); break; case IPS_THISOUT: - ShowPrompt(false, "%s\nYou most likely applied the patch on the output file.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT); break; case IPS_SCRAMBLED: - ShowPrompt(false, "%s\nThe patch is technically valid,\nbut seems scrambled or malformed.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED); break; case IPS_INVALID: - ShowPrompt(false, "%s\nThe patch is invalid.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCH_IS_INVALID); break; case IPS_16MB: - ShowPrompt(false, "%s\nOne or both files is bigger than 16MB.\nThe IPS format doesn't support that.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT); break; case IPS_INVALID_FILE_PATH: - ShowPrompt(false, "%s\nThe requested file path was invalid.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_REQUESTED_FILE_PATH_WAS_INVALID); break; case IPS_CANCELED: - ShowPrompt(false, "%s\nPatching canceled.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCHING_CANCELED); break; case IPS_MEMORY: - ShowPrompt(false, "%s\nNot enough memory.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_NOT_ENOUGH_MEMORY); break; } fvx_close(&patchFile); fvx_close(&inFile); @@ -112,7 +113,7 @@ UINT read24() { int ApplyIPSPatch(const char* patchName, const char* inName, const char* outName) { int error = IPS_INVALID; UINT outlen_min, outlen_max, outlen_min_mem; - snprintf(errName, 256, "%s", patchName); + snprintf(errName, sizeof(errName), "%s", patchName); if (fvx_open(&patchFile, patchName, FA_READ) != FR_OK) return displayError(IPS_INVALID_FILE_PATH); patchSize = fvx_size(&patchFile); @@ -140,7 +141,7 @@ int ApplyIPSPatch(const char* patchName, const char* inName, const char* outName while (offset != 0x454F46) // 454F46=EOF { if (!ShowProgress(patchOffset, patchSize, patchName)) { - if (ShowPrompt(true, "%s\nB button detected. Cancel?", patchName)) return displayError(IPS_CANCELED); + if (ShowPrompt(true, "%s\n%s", patchName, STR_B_DETECTED_CANCEL)) return displayError(IPS_CANCELED); ShowProgress(0, patchSize, patchName); ShowProgress(patchOffset, patchSize, patchName); } @@ -211,7 +212,7 @@ int ApplyIPSPatch(const char* patchName, const char* inName, const char* outName while (offset != 0x454F46) { if (!ShowProgress(offset, outSize, outName)) { - if (ShowPrompt(true, "%s\nB button detected. Cancel?", outName)) return displayError(IPS_CANCELED); + if (ShowPrompt(true, "%s\n%s", outName, STR_B_DETECTED_CANCEL)) return displayError(IPS_CANCELED); ShowProgress(0, outSize, outName); ShowProgress(offset, outSize, outName); } diff --git a/arm9/source/game/nds.c b/arm9/source/game/nds.c index 964842c45..75f181e3c 100644 --- a/arm9/source/game/nds.c +++ b/arm9/source/game/nds.c @@ -55,21 +55,25 @@ u32 BuildTwlSaveHeader(void* sav, u32 size) { u16 n_sct = 1; u16 sct_track = 1; u16 sct_heads = 1; - while (true) { - if (sct_heads < sct_track) { - u16 n_sct_next = sct_track * (sct_heads+1) * (sct_heads+1); - if (n_sct_next < n_sct_max) { - sct_heads++; + u16 n_sct_next = 0; + while (n_sct_next <= n_sct_max) { + n_sct_next = sct_track * (sct_heads + 1) * (sct_heads + 1); + if (n_sct_next <= n_sct_max) { + sct_heads++; + n_sct = n_sct_next; + + sct_track++; + n_sct_next = sct_track * sct_heads * sct_heads; + if (n_sct_next <= n_sct_max) { n_sct = n_sct_next; - } else break; - } else { - u16 n_sct_next = (sct_track+1) * sct_heads * sct_heads; - if (n_sct_next < n_sct_max) { - sct_track++; - n_sct = n_sct_next; - } else break; + } } } + n_sct_next = (sct_track + 1) * sct_heads * sct_heads; + if (n_sct_next <= n_sct_max) { + sct_track++; + n_sct = n_sct_next; + } // sectors per cluster (should be identical to Nintendo) u8 clr_size = (n_sct > 8 * 1024) ? 8 : (n_sct > 1024) ? 4 : 1; diff --git a/arm9/source/game/region.c b/arm9/source/game/region.c index a224d53a4..eb1a18441 100644 --- a/arm9/source/game/region.c +++ b/arm9/source/game/region.c @@ -1,4 +1,5 @@ #include "common.h" +#include "language.h" #include "region.h" // Names of system regions, short form. @@ -12,13 +13,16 @@ const char* const g_regionNamesShort[SMDH_NUM_REGIONS] = { "TWN", }; -// Names of system regions, long form. -const char* const g_regionNamesLong[SMDH_NUM_REGIONS] = { - "Japan", - "Americas", - "Europe", - "Australia", - "China", - "Korea", - "Taiwan", +// Names of system regions, long form and translatable. +const char* regionNameLong(int region) { + switch(region) { + case REGION_JPN: return STR_REGION_JAPAN; + case REGION_USA: return STR_REGION_AMERICAS; + case REGION_EUR: return STR_REGION_EUROPE; + case REGION_AUS: return STR_REGION_AUSTRALIA; + case REGION_CHN: return STR_REGION_CHINA; + case REGION_KOR: return STR_REGION_KOREA; + case REGION_TWN: return STR_REGION_TAIWAN; + default: return STR_REGION_UNKNOWN; + } }; diff --git a/arm9/source/game/region.h b/arm9/source/game/region.h index 20c2cb8d1..b3f8830a7 100644 --- a/arm9/source/game/region.h +++ b/arm9/source/game/region.h @@ -27,5 +27,5 @@ // Names of system regions, short form. extern const char* const g_regionNamesShort[SMDH_NUM_REGIONS]; -// Names of system regions, long form. -extern const char* const g_regionNamesLong[SMDH_NUM_REGIONS]; +// Names of system regions, long form and translatable. +const char* regionNameLong(int region); diff --git a/arm9/source/game/ticket.c b/arm9/source/game/ticket.c index 24005cd48..d5cdb13ad 100644 --- a/arm9/source/game/ticket.c +++ b/arm9/source/game/ticket.c @@ -120,7 +120,7 @@ u32 BuildVariableFakeTicket(Ticket** ticket, u32* ticket_size, const u8* title_i } u32 BuildFakeTicket(Ticket* ticket, const u8* title_id) { - Ticket* tik; + Ticket* tik = NULL; u32 ticket_size = sizeof(TicketCommon); u32 res = BuildVariableFakeTicket(&tik, &ticket_size, title_id, TICKET_MAX_CONTENTS); if (res != 0) return res; diff --git a/arm9/source/gamecart/command_ctr.c b/arm9/source/gamecart/command_ctr.c index 49c882984..3e2f8e2d7 100644 --- a/arm9/source/gamecart/command_ctr.c +++ b/arm9/source/gamecart/command_ctr.c @@ -27,7 +27,7 @@ void CTR_CmdReadData(u32 sector, u32 length, u32 blocks, void* buffer) (u32)((sector << 9) & 0xFFFFFFFF), 0x00000000, 0x00000000 }; - CTR_SendCommand(read_cmd, length, blocks, 0x704822C, buffer); + CTR_SendCommand(read_cmd, length, blocks, 0x104822C, buffer); // Clock divider 5 (13.4 MHz). Same as Process9. } void CTR_CmdReadHeader(void* buffer) diff --git a/arm9/source/gamecart/gamecart.c b/arm9/source/gamecart/gamecart.c index 7bd2d5006..0ca8077ac 100644 --- a/arm9/source/gamecart/gamecart.c +++ b/arm9/source/gamecart/gamecart.c @@ -64,6 +64,11 @@ u32 GetCartName(char* name, CartData* cdata) { u32 GetCartInfoString(char* info, size_t info_size, CartData* cdata) { size_t info_index = 0; + u8 padding; + + // read the last byte of the cart storage, but ignore the result + ReadCartBytes(&padding, cdata->cart_size - 1, 1, cdata, false); + if (cdata->cart_type & CART_CTR) { CartDataCtr* cdata_i = (CartDataCtr*)cdata; NcsdHeader* ncsd = &(cdata_i->ncsd); @@ -107,8 +112,10 @@ u32 GetCartInfoString(char* info, size_t info_size, CartData* cdata) { "Save chip ID : \n"); info_index += snprintf(info + info_index, info_size - info_index, + "Padding Byte : %02X\n" "Timestamp : 20%02X-%02X-%02X %02X:%02X:%02X\n" "GM9 Version : %s\n", + padding, init_time.bcd_Y, init_time.bcd_M, init_time.bcd_D, init_time.bcd_h, init_time.bcd_m, init_time.bcd_s, VERSION); @@ -247,7 +254,7 @@ u32 InitCartRead(CartData* cdata) { if (nds_header->device_capacity >= 15) return 1; // too big, not valid if (cdata->cart_size == 0) cdata->cart_size = (128 * 1024) << nds_header->device_capacity; - cdata->data_size = nds_header->ntr_rom_size + 0x88; + cdata->data_size = nds_header->ntr_rom_size; cdata->arm9i_rom_offset = 0; // TWL header @@ -266,6 +273,15 @@ u32 InitCartRead(CartData* cdata) { NTR_CmdReadHeader(cdata->storage); if (!NTR_Secure_Init(cdata->storage, NULL, Cart_GetID(), 1)) return 1; } + } else { + // Check if immediately after the reported cart size + // is the magic number string 'ac' (auth code). + // If found, add 0x88 bytes for the download play RSA key. + u16 rsaMagic; + ReadCartBytes(&rsaMagic, cdata->data_size, 2, cdata, false); + if(rsaMagic == 0x6361) { + cdata->data_size += 0x88; + } } // store encrypted secure area diff --git a/arm9/source/godmode.c b/arm9/source/godmode.c index 256d4d10c..c07a6bccb 100644 --- a/arm9/source/godmode.c +++ b/arm9/source/godmode.c @@ -25,6 +25,8 @@ #include "vram0.h" #include "i2c.h" #include "pxi.h" +#include "language.h" +#include "gm9lua.h" #ifndef N_PANES #define N_PANES 3 @@ -58,19 +60,18 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { size_t firm_size = FileGetSize(bootpath); if (!firm_size) return 1; if (firm_size > FIRM_MAX_SIZE) { - if (verbose) ShowPrompt(false, "%s\nFIRM too big, can't boot", pathstr); // unlikely + if (verbose) ShowPrompt(false, "%s\n%s", pathstr, STR_FIRM_TOO_BIG); // unlikely return 1; } - if (verbose && !ShowPrompt(true, "%s (%dkB)\nWarning: Do not boot FIRMs\nfrom untrusted sources.\n \nBoot FIRM?", - pathstr, firm_size / 1024)) + if (verbose && !ShowPrompt(true, STR_PATH_DO_NOT_BOOT_UNTRUSTED, pathstr, firm_size / 1024)) return 1; void* firm = (void*) malloc(FIRM_MAX_SIZE); if (!firm) return 1; if ((FileGetData(bootpath, firm, firm_size, 0) != firm_size) || !IsBootableFirm(firm, firm_size)) { - if (verbose) ShowPrompt(false, "%s\nNot a bootable FIRM.", pathstr); + if (verbose) ShowPrompt(false, "%s\n%s", pathstr, STR_NOT_BOOTABLE_FIRM); free(firm); return 1; } @@ -81,7 +82,7 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { FirmA9LHeader* a9l = (FirmA9LHeader*)(void*) ((u8*) firm + arm9s->offset); if (verbose && (ValidateFirmA9LHeader(a9l) == 0) && - ShowPrompt(true, "%s\nFIRM is encrypted.\n \nDecrypt before boot?", pathstr) && + ShowPrompt(true, "%s\n%s", pathstr, STR_FIRM_ENCRYPTED) && (DecryptFirmFull(firm, firm_size) != 0)) { free(firm); return 1; @@ -90,8 +91,10 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { // unsupported location handling char fixpath[256] = { 0 }; if (verbose && (*bootpath != '0') && (*bootpath != '1')) { - const char* optionstr[2] = { "Make a copy at " OUTPUT_PATH "/temp.firm", "Try to boot anyways" }; - u32 user_select = ShowSelectPrompt(2, optionstr, "%s\nWarning: Trying to boot from an\nunsupported location.", pathstr); + char str[UTF_BUFFER_BYTESIZE(256)]; + snprintf(str, sizeof(str), STR_MAKE_COPY_AT_OUT_TEMP_FIRM, OUTPUT_PATH); + const char* optionstr[2] = { str, STR_TRY_BOOT_ANYWAYS }; + u32 user_select = ShowSelectPrompt(2, optionstr, "%s\n%s", pathstr, STR_WARNING_BOOT_UNSUPPORTED_LOCATION); if (user_select == 1) { FileSetData(OUTPUT_PATH "/temp.firm", firm, firm_size, 0, true); bootpath = OUTPUT_PATH "/temp.firm"; @@ -100,7 +103,7 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { // fix the boot path ("sdmc"/"nand" for Luma et al, hacky af) if ((*bootpath == '0') || (*bootpath == '1')) - snprintf(fixpath, 256, "%s%s", (*bootpath == '0') ? "sdmc" : "nand", bootpath + 1); + snprintf(fixpath, sizeof(fixpath), "%s%s", (*bootpath == '0') ? "sdmc" : "nand", bootpath + 1); else strncpy(fixpath, bootpath, 256); fixpath[255] = '\0'; @@ -144,14 +147,14 @@ u32 SplashInit(const char* modestr) { } if (modestr) DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(modestr), - SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, modestr); + SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, "%s", modestr); DrawStringF(BOT_SCREEN, pos_xb, pos_yb, COLOR_STD_FONT, COLOR_STD_BG, "%s\n%*.*s\n%s\n \n \n%s\n%s\n \n%s\n%s", - namestr, strnlen(namestr, 64), strnlen(namestr, 64), + namestr, strlen(namestr), strlen(namestr), "--------------------------------", "https://github.com/d0k3/GodMode9", "Releases:", "https://github.com/d0k3/GodMode9/releases/", // this won't fit with a 8px width font "Hourlies:", "https://d0k3.secretalgorithm.com/"); - DrawStringF(BOT_SCREEN, pos_xu, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, loadstr); + DrawStringF(BOT_SCREEN, pos_xu, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, "%s", loadstr); DrawStringF(BOT_SCREEN, pos_xb, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, "built: " DBUILTL); return 0; @@ -162,14 +165,14 @@ static DirStruct* current_dir = NULL; static DirStruct* clipboard = NULL; static PaneData* panedata = NULL; -void GetTimeString(char* timestr, bool forced_update, bool full_year) { +void GetTimeString(char* timestr, bool forced_update, bool full_year) { // timestr should be 32 bytes static DsTime dstime; static u64 timer = (u64) -1; // this ensures we don't check the time too often if (forced_update || (timer == (u64) -1) || (timer_sec(timer) > 30)) { get_dstime(&dstime); timer = timer_start(); } - if (timestr) snprintf(timestr, 31, "%s%02lX-%02lX-%02lX %02lX:%02lX", full_year ? "20" : "", + if (timestr) snprintf(timestr, UTF_BUFFER_BYTESIZE(32), STR_DATE_TIME_FORMAT, full_year ? "20" : "", (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D, (u32) dstime.bcd_h, (u32) dstime.bcd_m); } @@ -237,7 +240,7 @@ void DrawTopBar(const char* curr_path) { // top bar - current path DrawRectangle(TOP_SCREEN, 0, 0, SCREEN_WIDTH_TOP, 12, COLOR_TOP_BAR); if (*curr_path) TruncateString(tempstr, curr_path, min(63, len_path / FONT_WIDTH_EXT), 8); - else snprintf(tempstr, 16, "[root]"); + else snprintf(tempstr, sizeof(tempstr), "%s", STR_ROOT); DrawStringF(TOP_SCREEN, bartxt_x, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%s", tempstr); bool show_time = true; @@ -246,10 +249,12 @@ void DrawTopBar(const char* curr_path) { const u32 bartxt_rx = SCREEN_WIDTH_TOP - (19*FONT_WIDTH_EXT) - bartxt_x; char bytestr0[32]; char bytestr1[32]; - DrawStringF(TOP_SCREEN, bartxt_rx, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%19.19s", "LOADING..."); + char tempstr[UTF_BUFFER_BYTESIZE(19)]; + ResizeString(tempstr, STR_LOADING, 19, 19, true); + DrawString(TOP_SCREEN, tempstr, bartxt_rx, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR); FormatBytes(bytestr0, GetFreeSpace(curr_path)); FormatBytes(bytestr1, GetTotalSpace(curr_path)); - snprintf(tempstr, 64, "%s/%s", bytestr0, bytestr1); + snprintf(tempstr, sizeof(tempstr), "%s/%s", bytestr0, bytestr1); DrawStringF(TOP_SCREEN, bartxt_rx, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%19.19s", tempstr); show_time = false; } @@ -264,15 +269,16 @@ void DrawTopBar(const char* curr_path) { #endif if (show_time) { // clock & battery + char timestr[UTF_BUFFER_BYTESIZE(32)]; + GetTimeString(timestr, false, false); + const u32 battery_width = 16; const u32 battery_height = 9; const u32 battery_x = SCREEN_WIDTH_TOP - battery_width - bartxt_x; const u32 battery_y = (12 - battery_height) / 2; - const u32 clock_x = battery_x - (15*FONT_WIDTH_EXT); + const u32 clock_x = battery_x - (GetDrawStringWidth(timestr) + FONT_WIDTH_EXT); - char timestr[32]; - GetTimeString(timestr, false, false); - DrawStringF(TOP_SCREEN, clock_x, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%14.14s", timestr); + DrawStringF(TOP_SCREEN, clock_x, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%s", timestr); DrawBatteryBitmap(TOP_SCREEN, battery_x, battery_y, battery_width, battery_height); } } @@ -300,8 +306,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, u32 curr_pan } // left top - current file info - if (curr_pane) snprintf(tempstr, 63, "PANE #%lu", curr_pane); - else snprintf(tempstr, 63, "CURRENT"); + if (curr_pane) snprintf(tempstr, sizeof(tempstr), STR_PANE_N, curr_pane); + else snprintf(tempstr, sizeof(tempstr), "%s", STR_CURRENT); DrawStringF(MAIN_SCREEN, 2, info_start, COLOR_STD_FONT, COLOR_STD_BG, "[%s]", tempstr); // file / entry name ResizeString(tempstr, curr_entry->name, str_len_info, 8, false); @@ -309,28 +315,27 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, u32 curr_pan DrawStringF(MAIN_SCREEN, 4, info_start + 12, color_current, COLOR_STD_BG, "%s", tempstr); // size (in Byte) or type desc if (curr_entry->type == T_DIR) { - ResizeString(tempstr, "(dir)", str_len_info, 8, false); + ResizeString(tempstr, STR_DIR, str_len_info, 8, false); } else if (curr_entry->type == T_DOTDOT) { - snprintf(tempstr, 21, "%20s", ""); + snprintf(tempstr, sizeof(tempstr), "%20s", ""); } else if (curr_entry->type == T_ROOT) { int drvtype = DriveType(curr_entry->path); - char drvstr[32]; - snprintf(drvstr, 31, "(%s%s)", - ((drvtype & DRV_SDCARD) ? "SD" : (drvtype & DRV_RAMDRIVE) ? "RAMdrive" : (drvtype & DRV_GAME) ? "Game" : - (drvtype & DRV_SYSNAND) ? "SysNAND" : (drvtype & DRV_EMUNAND) ? "EmuNAND" : (drvtype & DRV_IMAGE) ? "Image" : - (drvtype & DRV_XORPAD) ? "XORpad" : (drvtype & DRV_MEMORY) ? "Memory" : (drvtype & DRV_ALIAS) ? "Alias" : - (drvtype & DRV_CART) ? "Gamecart" : (drvtype & DRV_VRAM) ? "VRAM" : (drvtype & DRV_SEARCH) ? "Search" : - (drvtype & DRV_TITLEMAN) ? "TitleManager" : ""), - ((drvtype & DRV_FAT) ? " FAT" : (drvtype & DRV_VIRTUAL) ? " Virtual" : "")); + const char* drvstr = + (drvtype & DRV_SDCARD) ? STR_SD_FAT : (drvtype & DRV_RAMDRIVE) ? STR_RAMDRIVE_FAT : (drvtype & DRV_GAME) ? STR_GAME_VIRTUAL : + (drvtype & (DRV_SYSNAND | DRV_FAT)) ? STR_SYSNAND_FAT : (drvtype & (DRV_SYSNAND | DRV_VIRTUAL)) ? STR_SYSNAND_VIRTUAL : + (drvtype & (DRV_EMUNAND | DRV_FAT)) ? STR_EMUNAND_FAT : (drvtype & (DRV_EMUNAND | DRV_VIRTUAL)) ? STR_EMUNAND_VIRTUAL : + (drvtype & DRV_IMAGE) ? STR_IMAGE_FAT : (drvtype & DRV_XORPAD) ? STR_XORPAD_VIRTUAL : (drvtype & DRV_MEMORY) ? STR_MEMORY_VIRTUAL : + (drvtype & DRV_ALIAS) ? STR_ALIAS_FAT : (drvtype & DRV_CART) ? STR_GAMECART_VIRTUAL : (drvtype & DRV_VRAM) ? STR_VRAM_VIRTUAL : + (drvtype & DRV_SEARCH) ? STR_SEARCH : (drvtype & DRV_TITLEMAN) ? STR_TITLEMANAGER_VIRTUAL : ""; ResizeString(tempstr, drvstr, str_len_info, 8, false); } else { - char numstr[32]; - char bytestr[32]; + char numstr[UTF_BUFFER_BYTESIZE(32)]; + char bytestr[UTF_BUFFER_BYTESIZE(32)]; FormatNumber(numstr, curr_entry->size); - snprintf(bytestr, 31, "%s Byte", numstr); + snprintf(bytestr, sizeof(bytestr), STR_N_BYTE, numstr); ResizeString(tempstr, bytestr, str_len_info, 8, false); } - DrawStringF(MAIN_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, tempstr); + DrawStringF(MAIN_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, "%s", tempstr); // path of file (if in search results) if ((DriveType(curr_path) & DRV_SEARCH) && strrchr(curr_entry->path, '/')) { char dirstr[256]; @@ -345,32 +350,31 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, u32 curr_pan // right top - clipboard DrawStringF(MAIN_SCREEN, SCREEN_WIDTH_MAIN - len_info, info_start, COLOR_STD_FONT, COLOR_STD_BG, "%*s", - len_info / FONT_WIDTH_EXT, (clipboard->n_entries) ? "[CLIPBOARD]" : ""); + (int) (len_info / FONT_WIDTH_EXT), (clipboard->n_entries) ? STR_CLIPBOARD : ""); for (u32 c = 0; c < n_cb_show; c++) { u32 color_cb = COLOR_ENTRY(&(clipboard->entry[c])); ResizeString(tempstr, (clipboard->n_entries > c) ? clipboard->entry[c].name : "", str_len_info, 8, true); DrawStringF(MAIN_SCREEN, SCREEN_WIDTH_MAIN - len_info - 4, info_start + 12 + (c*10), color_cb, COLOR_STD_BG, "%s", tempstr); } *tempstr = '\0'; - if (clipboard->n_entries > n_cb_show) snprintf(tempstr, 60, "+ %lu more", clipboard->n_entries - n_cb_show); + if (clipboard->n_entries > n_cb_show) snprintf(tempstr, sizeof(tempstr), STR_PLUS_N_MORE, clipboard->n_entries - n_cb_show); DrawStringF(MAIN_SCREEN, SCREEN_WIDTH_MAIN - len_info - 4, info_start + 12 + (n_cb_show*10), COLOR_DARKGREY, COLOR_STD_BG, - "%*s", len_info / FONT_WIDTH_EXT, tempstr); + "%*s", (int) (len_info / FONT_WIDTH_EXT), tempstr); // bottom: instruction block - char instr[512]; - snprintf(instr, 512, "%s\n%s%s%s%s%s%s%s%s", + char instr[UTF_BUFFER_BYTESIZE(512)]; + snprintf(instr, sizeof(instr), "%s\n%s%s%s%s%s%s%s%s", FLAVOR " " VERSION, // generic start part - (*curr_path) ? ((clipboard->n_entries == 0) ? "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n" : - "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n") : - ((GetWritePermissions() > PERM_BASE) ? "R+Y - Relock write permissions\n" : ""), - (*curr_path) ? "" : (GetMountState()) ? "R+X - Unmount image\n" : "", - (*curr_path) ? "" : (CheckSDMountState()) ? "R+B - Unmount SD card\n" : "R+B - Remount SD card\n", - (*curr_path) ? "R+A - Directory options\n" : "R+A - Drive options\n", - "R+L - Make a Screenshot\n", - "R+←→ - Switch to prev/next pane\n", - (clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "SELECT - Restore Clipboard\n", // only if clipboard is full - "START - Reboot / [+R] Poweroff\nHOME button for HOME menu"); // generic end part - DrawStringF(MAIN_SCREEN, instr_x, SCREEN_HEIGHT - 4 - GetDrawStringHeight(instr), COLOR_STD_FONT, COLOR_STD_BG, instr); + (*curr_path) ? ((clipboard->n_entries == 0) ? STR_MARK_DELETE_COPY : STR_MARK_DELETE_PASTE) : + ((GetWritePermissions() > PERM_BASE) ? STR_RELOCK_WRITE_PERMISSION : ""), + (*curr_path) ? "" : (GetMountState()) ? STR_UNMOUNT_IMAGE : "", + (*curr_path) ? "" : (CheckSDMountState()) ? STR_UNMOUNT_SD : STR_REMOUNT_SD, + (*curr_path) ? STR_DIRECTORY_OPTIONS : STR_DRIVE_OPTIONS, + STR_MAKE_SCREENSHOT, + STR_PREV_NEXT_PANE, + (clipboard->n_entries) ? STR_CLEAR_CLIPBOARD : STR_RESTORE_CLIPBOARD, // only if clipboard is full + STR_REBOOT_POWEROFF_HOME); // generic end part + DrawStringF(MAIN_SCREEN, instr_x, SCREEN_HEIGHT - 4 - GetDrawStringHeight(instr), COLOR_STD_FONT, COLOR_STD_BG, "%s", instr); } void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) { @@ -393,14 +397,14 @@ void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) { if (offset_i < contents->n_entries) { DirEntry* curr_entry = &(contents->entry[offset_i]); char namestr[UTF_BUFFER_BYTESIZE(str_width - 10)]; - char bytestr[10 + 1]; + char rawbytestr[32], bytestr[UTF_BUFFER_BYTESIZE(10)]; color_font = (cursor != offset_i) ? COLOR_ENTRY(curr_entry) : COLOR_STD_FONT; - FormatBytes(bytestr, curr_entry->size); + FormatBytes(rawbytestr, curr_entry->size); + ResizeString(bytestr, (curr_entry->type == T_DIR) ? STR_DIR : (curr_entry->type == T_DOTDOT) ? "(..)" : rawbytestr, 10, 10, true); ResizeString(namestr, curr_entry->name, str_width - 10, str_width - 20, false); - snprintf(tempstr, str_width * 4 + 1, "%s%10.10s", namestr, - (curr_entry->type == T_DIR) ? "(dir)" : (curr_entry->type == T_DOTDOT) ? "(..)" : bytestr); - } else snprintf(tempstr, str_width + 1, "%-*.*s", str_width, str_width, ""); - DrawStringF(ALT_SCREEN, pos_x, pos_y, color_font, COLOR_STD_BG, "%s", tempstr); + snprintf(tempstr, sizeof(tempstr), "%s%s", namestr, bytestr); + } else snprintf(tempstr, sizeof(tempstr), "%-*.*s", str_width, str_width, ""); + DrawString(ALT_SCREEN, tempstr, pos_x, pos_y, color_font, COLOR_STD_BG); pos_y += stp_y; } @@ -420,9 +424,9 @@ void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) { u32 SdFormatMenu(const char* slabel) { static const u32 cluster_size_table[5] = { 0x0, 0x0, 0x4000, 0x8000, 0x10000 }; - static const char* option_emunand_size[7] = { "No EmuNAND", "RedNAND size (min)", "GW EmuNAND size (full)", - "MultiNAND size (2x)", "MultiNAND size (3x)", "MultiNAND size (4x)", "User input..." }; - static const char* option_cluster_size[4] = { "Auto", "16KB Clusters", "32KB Clusters", "64KB Clusters" }; + const char* option_emunand_size[7] = { STR_NO_EMUNAND, STR_REDNAND_SIZE_MIN, STR_GW_EMUNAND_SIZE_FULL, + STR_MULTINAND_SIZE_2X, STR_MULTINAND_SIZE_3X, STR_MULTINAND_SIZE_4X, STR_USER_INPUT }; + const char* option_cluster_size[4] = { STR_AUTO, STR_16KB_CLUSTERS, STR_32KB_CLUSTERS, STR_64KB_CLUSTERS }; u32 sysnand_min_size_sectors = GetNandMinSizeSectors(NAND_SYSNAND); u64 sysnand_min_size_mb = ((sysnand_min_size_sectors * 0x200) + 0xFFFFF) / 0x100000; u64 sysnand_multi_size_mb = (align(sysnand_min_size_sectors + 1, 0x2000) * 0x200) / 0x100000; @@ -431,55 +435,61 @@ u32 SdFormatMenu(const char* slabel) { u32 cluster_size = 0; u64 sdcard_size_mb = 0; u64 emunand_size_mb = (u64) -1; - u32 user_select; + u32 user_select = 0; // check actual SD card size sdcard_size_mb = GetSDCardSize() / 0x100000; if (!sdcard_size_mb) { - ShowPrompt(false, "Error: SD card not detected."); + ShowPrompt(false, "%s", STR_SD_NOT_DETECTED); return 1; } - user_select = ShowSelectPrompt(7, option_emunand_size, "Format SD card (%lluMB)?\nChoose EmuNAND size:", sdcard_size_mb); + user_select = ShowSelectPrompt(7, option_emunand_size, STR_FORMAT_SD_CHOOSE_EMUNAND, sdcard_size_mb); if (user_select && (user_select < 4)) { emunand_size_mb = (user_select == 2) ? sysnand_min_size_mb : (user_select == 3) ? sysnand_size_mb : 0; } else if ((user_select >= 4) && (user_select <= 6)) { u32 n = (user_select - 2); emunand_size_mb = n * sysnand_multi_size_mb; } else if (user_select == 7) do { - emunand_size_mb = ShowNumberPrompt(sysnand_min_size_mb, "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", sdcard_size_mb); + emunand_size_mb = ShowNumberPrompt(sysnand_min_size_mb, STR_SD_SIZE_IS_ENTER_EMUNAND_SIZE, sdcard_size_mb); if (emunand_size_mb == (u64) -1) break; } while (emunand_size_mb > sdcard_size_mb); if (emunand_size_mb == (u64) -1) return 1; - user_select = ShowSelectPrompt(4, option_cluster_size, "Format SD card (%lluMB)?\nChoose cluster size:", sdcard_size_mb); + user_select = ShowSelectPrompt(4, option_cluster_size, STR_FORMAT_SD_CHOOSE_CLUSTER, sdcard_size_mb); if (!user_select) return 1; else cluster_size = cluster_size_table[user_select]; - snprintf(label, DRV_LABEL_LEN + 4, "0:%s", (slabel && *slabel) ? slabel : "GM9SD"); - if (!ShowKeyboardOrPrompt(label + 2, 11 + 1, "Format SD card (%lluMB)?\nEnter label:", sdcard_size_mb)) + snprintf(label, sizeof(label), "0:%s", (slabel && *slabel) ? slabel : "GM9SD"); + if (!ShowKeyboardOrPrompt(label + 2, 11 + 1, STR_FORMAT_SD_ENTER_LABEL, sdcard_size_mb)) return 1; if (!FormatSDCard(emunand_size_mb, cluster_size, label)) { - ShowPrompt(false, "Format SD: failed!"); + ShowPrompt(false, "%s", STR_FORMAT_SD_FAILED); return 1; } if (emunand_size_mb >= sysnand_min_size_mb) { u32 emunand_offset = 1; u32 n_emunands = 1; - if (emunand_size_mb >= 2 * sysnand_size_mb) { - static const char* option_emunand_type[4] = { "RedNAND type (multi)", "RedNAND type (single)", "GW EmuNAND type", "Don't set up" }; - user_select = ShowSelectPrompt(4, option_emunand_type, "Choose EmuNAND type to set up:"); - if (user_select > 3) return 0; - emunand_offset = (user_select == 3) ? 0 : 1; + if (emunand_size_mb >= 2 * sysnand_multi_size_mb) { /* space can fit single/multi RedNAND or GW type */ + const char* option_emunand_type[4] = { STR_REDNAND_TYPE_MULTI, STR_REDNAND_TYPE_SINGLE, STR_DONT_SET_UP, 0 }; + u32 n_opt = 3; + if (emunand_size_mb >= sysnand_size_mb) { + option_emunand_type[2] = STR_GW_EMUNAND_TYPE; + option_emunand_type[3] = STR_DONT_SET_UP; + n_opt++; + } + user_select = ShowSelectPrompt(n_opt, option_emunand_type, "%s", STR_CHOOSE_EMUNAND_TYPE); + if (user_select == n_opt) return 0; + emunand_offset = (n_opt == 4 && user_select == 3) ? 0 : 1; if (user_select == 1) n_emunands = 4; - } else if (emunand_size_mb >= sysnand_size_mb) { - static const char* option_emunand_type[3] = { "RedNAND type", "GW EmuNAND type", "Don't set up" }; - user_select = ShowSelectPrompt(3, option_emunand_type, "Choose EmuNAND type to set up:"); + } else if (emunand_size_mb >= sysnand_size_mb) { /* space can fit single RedNAND or GW type, but not multi RedNAND */ + const char* option_emunand_type[3] = { STR_REDNAND_TYPE, STR_GW_EMUNAND_TYPE, STR_DONT_SET_UP }; + user_select = ShowSelectPrompt(3, option_emunand_type, "%s", STR_CHOOSE_EMUNAND_TYPE); if (user_select > 2) return 0; emunand_offset = (user_select == 2) ? 0 : 1; // 0 -> GW EmuNAND - } else user_select = ShowPrompt(true, "Clone SysNAND to RedNAND?") ? 1 : 0; + } else user_select = ShowPrompt(true, "%s", STR_CLONE_SYSNAND_TO_REDNAND) ? 1 : 0; /* space can only fit a single RedNAND */ if (!user_select) return 0; u8 ncsd[0x200]; @@ -491,7 +501,7 @@ u32 SdFormatMenu(const char* slabel) { if ((ReadNandSectors(ncsd, 0, 1, 0xFF, NAND_SYSNAND) != 0) || (WriteNandSectors(ncsd, 0, 1, 0xFF, NAND_EMUNAND) != 0) || (!PathCopy("E:", "S:/nand_minsize.bin", &flags))) { - ShowPrompt(false, "Cloning SysNAND to EmuNAND: failed!"); + ShowPrompt(false, "%s", STR_CLONING_SYSNAND_TO_EMUNAND_FAILED); break; } } @@ -524,7 +534,7 @@ u32 FileGraphicsViewer(const char* path) { if ((ret == 0) && w && h && (w <= SCREEN_WIDTH(ALT_SCREEN)) && (h <= SCREEN_HEIGHT)) { ClearScreenF(true, true, COLOR_STD_BG); DrawBitmap(ALT_SCREEN, -1, -1, w, h, bitmap); - ShowString("Press to continue"); + ShowString("%s", STR_PRESS_A_TO_CONTINUE); while(!(InputWait(0) & (BUTTON_A | BUTTON_B))); ClearScreenF(true, true, COLOR_STD_BG); } else ret = 1; @@ -571,13 +581,13 @@ u32 FileHexViewer(const char* path) { } static bool show_instr = true; - static const char* instr = "Hexeditor Controls:\n ↑↓→←(+R) - Scroll\nR+Y - Switch view\nX - Search / goto...\nA - Enter edit mode\nA+↑↓→← - Edit value\nB - Exit\n"; + const char* instr = STR_HEXEDITOR_CONTROLS; if (show_instr) { // show one time instructions - ShowPrompt(false, instr); + ShowPrompt(false, "%s", instr); show_instr = false; } - if (MAIN_SCREEN != TOP_SCREEN) ShowString(instr); + if (MAIN_SCREEN != TOP_SCREEN) ShowString("%s", instr); memcpy(bottom_cpy, BOT_SCREEN, SCREEN_SIZE_BOT); data = buffer; @@ -708,7 +718,7 @@ u32 FileHexViewer(const char* path) { // draw offset / ASCII representation if (x_off >= 0) DrawStringF(screen, x_off - x0, y, cutoff ? COLOR_HVOFFS : COLOR_HVOFFSI, - COLOR_STD_BG, "%08X", (unsigned int) offset + curr_pos); + COLOR_STD_BG, "%08X", (unsigned int) (offset + curr_pos)); if (x_ascii >= 0) { for (u32 i = 0; i < cols; i++) DrawCharacter(screen, ascii[i], x_ascii - x0 + (FONT_WIDTH_EXT * i), y, COLOR_HVASCII, COLOR_STD_BG); @@ -744,37 +754,35 @@ u32 FileHexViewer(const char* path) { else if (found_size && (pad_state & BUTTON_R1) && (pad_state & BUTTON_X)) { found_offset = FileFindData(path, found_data, found_size, found_offset + 1); if (found_offset == (u32) -1) { - ShowPrompt(false, "Not found!"); + ShowPrompt(false, "%s", STR_NOT_FOUND); found_size = 0; } else offset = found_offset; if (MAIN_SCREEN == TOP_SCREEN) ClearScreen(TOP_SCREEN, COLOR_STD_BG); else if (dual_screen) ClearScreen(BOT_SCREEN, COLOR_STD_BG); else memcpy(BOT_SCREEN, bottom_cpy, SCREEN_SIZE_BOT); } else if (pad_state & BUTTON_X) { - static const char* optionstr[3] = { "Go to offset", "Search for string", "Search for data" }; - u32 user_select = ShowSelectPrompt(3, optionstr, "Current offset: %08X\nSelect action:", - (unsigned int) offset); + const char* optionstr[3] = { STR_GO_TO_OFFSET, STR_SEARCH_FOR_STRING, STR_SEARCH_FOR_DATA }; + u32 user_select = ShowSelectPrompt(3, optionstr, STR_CURRENT_OFFSET_SELECT_ACTION, offset); if (user_select == 1) { // -> goto offset - u64 new_offset = ShowHexPrompt(offset, 8, "Current offset: %08X\nEnter new offset below.", - (unsigned int) offset); + u64 new_offset = ShowHexPrompt(offset, 8, STR_CURRENT_OFFSET_ENTER_NEW, offset); if (new_offset != (u64) -1) offset = new_offset; } else if (user_select == 2) { if (!found_size) *found_data = 0; - if (ShowKeyboardOrPrompt((char*) found_data, 64 + 1, "Enter search string below.\n(R+X to repeat search)")) { + if (ShowKeyboardOrPrompt((char*) found_data, 64 + 1, "%s", STR_ENTER_SEARCH_REPEAT_SEARCH)) { found_size = strnlen((char*) found_data, 64); found_offset = FileFindData(path, found_data, found_size, offset); if (found_offset == (u32) -1) { - ShowPrompt(false, "Not found!"); + ShowPrompt(false, "%s", STR_NOT_FOUND); found_size = 0; } else offset = found_offset; } } else if (user_select == 3) { u32 size = found_size; - if (ShowDataPrompt(found_data, &size, "Enter search data below.\n(R+X to repeat search)")) { + if (ShowDataPrompt(found_data, &size, "%s", STR_ENTER_SEARCH_REPEAT_SEARCH)) { found_size = size; found_offset = FileFindData(path, found_data, size, offset); if (found_offset == (u32) -1) { - ShowPrompt(false, "Not found!"); + ShowPrompt(false, "%s", STR_NOT_FOUND); found_size = 0; } else offset = found_offset; } @@ -799,9 +807,9 @@ u32 FileHexViewer(const char* path) { // check for user edits u32 diffs = 0; for (u32 i = 0; i < edit_bsize; i++) if (buffer[i] != buffer_cpy[i]) diffs++; - if (diffs && ShowPrompt(true, "You made edits in %i place(s).\nWrite changes to file?", diffs)) + if (diffs && ShowPrompt(true, STR_MADE_EDITS_SAVE_CHANGES, diffs)) if (!FileSetData(path, buffer, min(edit_bsize, (fsize - edit_start)), edit_start, false)) - ShowPrompt(false, "Failed writing to file!"); + ShowPrompt(false, "%s", STR_FAILED_WRITING_TO_FILE); data = buffer; last_offset = (u32) -1; // force reload from file } else if (pad_state & BUTTON_A) { @@ -851,38 +859,36 @@ u32 ShaCalculator(const char* path, bool sha1) { u8 hash[32]; TruncateString(pathstr, path, 32, 8); if (!FileGetSha(path, hash, 0, 0, sha1)) { - ShowPrompt(false, "Calculating SHA-%s: failed!", sha1 ? "1" : "256"); + ShowPrompt(false, STR_CALCULATING_SHA_FAILED, sha1 ? "1" : "256"); return 1; } else { - static char pathstr_prev[32 + 1] = { 0 }; + static char pathstr_prev[UTF_BUFFER_BYTESIZE(32)] = { 0 }; static u8 hash_prev[32] = { 0 }; char sha_path[256]; u8 sha_file[32]; - snprintf(sha_path, 256, "%s.sha%c", path, sha1 ? '1' : '\0'); + snprintf(sha_path, sizeof(sha_path), "%s.sha%c", path, sha1 ? '1' : '\0'); bool have_sha = (FileGetData(sha_path, sha_file, hashlen, 0) == hashlen); bool match_sha = have_sha && (memcmp(hash, sha_file, hashlen) == 0); bool match_prev = (memcmp(hash, hash_prev, hashlen) == 0); bool write_sha = (!have_sha || !match_sha) && (drvtype & DRV_SDCARD); // writing only on SD char hash_str[32+1+32+1]; if (sha1) - snprintf(hash_str, 20+1+20+1, "%016llX%04X\n%016llX%04X", getbe64(hash + 0), getbe16(hash + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%04X\n%016llX%04X", getbe64(hash + 0), getbe16(hash + 8), getbe64(hash + 10), getbe16(hash + 18)); else - snprintf(hash_str, 32+1+32+1, "%016llX%016llX\n%016llX%016llX", getbe64(hash + 0), getbe64(hash + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%016llX\n%016llX%016llX", getbe64(hash + 0), getbe64(hash + 8), getbe64(hash + 16), getbe64(hash + 24)); - if (ShowPrompt(write_sha, "%s\n%s%s%s%s%s%c \nWrite .SHA%s file?", + if (ShowPrompt(write_sha, "%s\n%s%s%s%s%s", pathstr, hash_str, - (have_sha) ? "\nSHA verification: " : "", - (have_sha) ? ((match_sha) ? "passed!" : "failed!") : "", - (match_prev) ? "\n \nIdentical with previous file:\n" : "", + (have_sha) ? ((match_sha) ? STR_SHA_VERIFICATION_PASSED : STR_SHA_VERIFICATION_FAILED) : "", + (match_prev) ? STR_IDENTICAL_WITH_PREVIOUS : "", (match_prev) ? pathstr_prev : "", - (write_sha) ? '\n' : '\0', - (sha1) ? "1" : "") && write_sha) { + (sha1) ? STR_WRITE_SHA1_FILE : STR_WRITE_SHA_FILE) && write_sha) { FileSetData(sha_path, hash, hashlen, 0, true); } - strncpy(pathstr_prev, pathstr, 32 + 1); + strncpy(pathstr_prev, pathstr, UTF_BUFFER_BYTESIZE(32)); memcpy(hash_prev, hash, hashlen); } @@ -895,26 +901,26 @@ u32 CmacCalculator(const char* path) { if (IdentifyFileType(path) != GAME_CMD) { u8 cmac[16] __attribute__((aligned(4))); if (CalculateFileCmac(path, cmac) != 0) { - ShowPrompt(false, "Calculating CMAC: failed!"); + ShowPrompt(false, "%s", STR_CALCULATING_CMAC_FAILED); return 1; } else { u8 cmac_file[16]; bool identical = ((ReadFileCmac(path, cmac_file) == 0) && (memcmp(cmac, cmac_file, 16) == 0)); - if (ShowPrompt(!identical, "%s\n%016llX%016llX\n%s%s%s", + if (ShowPrompt(!identical, "%s\n%016llX%016llX\n%s%s", pathstr, getbe64(cmac + 0), getbe64(cmac + 8), - "CMAC verification: ", (identical) ? "passed!" : "failed!", - (!identical) ? "\n \nFix CMAC in file?" : "") && + (identical) ? STR_CMAC_VERIFICATION_PASSED : STR_CMAC_VERIFICATION_FAILED, + (!identical) ? STR_FIX_CMAC_IN_FILE : "") && !identical && (WriteFileCmac(path, cmac, true) != 0)) { - ShowPrompt(false, "Fixing CMAC: failed!"); + ShowPrompt(false, "%s", STR_FIXING_CMAC_FAILED); } } } else { // special handling for CMD files bool correct = (CheckCmdCmac(path) == 0); - if (ShowPrompt(!correct, "%s\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n%s%s%s", - pathstr, "CMAC verification: ", (correct) ? "passed!" : "failed!", - (!correct) ? "\n \nFix CMAC in file?" : "") && + if (ShowPrompt(!correct, "%s\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n%s%s", + pathstr, (correct) ? STR_CMAC_VERIFICATION_PASSED : STR_CMAC_VERIFICATION_FAILED, + (!correct) ? STR_FIX_CMAC_IN_FILE : "") && !correct && (FixCmdCmac(path, true) != 0)) { - ShowPrompt(false, "Fixing CMAC: failed!"); + ShowPrompt(false, "%s", STR_FIXING_CMAC_FAILED); } } @@ -931,7 +937,7 @@ u32 StandardCopy(u32* cursor, u32* scroll) { } u32 flags = BUILD_PATH; - if ((n_marked > 1) && ShowPrompt(true, "Copy all %lu selected items?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_COPY_ALL_SELECTED_ITEMS, n_marked)) { u32 n_success = 0; for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; @@ -943,18 +949,18 @@ u32 StandardCopy(u32* cursor, u32* scroll) { else { // on failure: show error, break char currstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(currstr, path, 32, 12); - ShowPrompt(false, "%s\nFailed copying item", currstr); + ShowPrompt(false, "%s\n%s", currstr, STR_FAILED_COPYING_ITEM); break; } current_dir->entry[i].marked = false; } - if (n_success) ShowPrompt(false, "%lu items copied to %s", n_success, OUTPUT_PATH); + if (n_success) ShowPrompt(false, STR_ITEMS_COPIED_TO_OUT, n_success, OUTPUT_PATH); } else { char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, curr_entry->path, 32, 8); if (!PathCopy(OUTPUT_PATH, curr_entry->path, &flags)) - ShowPrompt(false, "%s\nFailed copying item", pathstr); - else ShowPrompt(false, "%s\nCopied to %s", pathstr, OUTPUT_PATH); + ShowPrompt(false, "%s\n%s", pathstr, STR_FAILED_COPYING_ITEM); + else ShowPrompt(false, STR_PATH_COPIED_TO_OUT, pathstr, OUTPUT_PATH); } return 0; @@ -968,7 +974,7 @@ u32 CartRawDump(void) { u64 dsize = 0; if (!cdata ||(InitCartRead(cdata) != 0) || (GetCartName(cname, cdata) != 0)) { - ShowPrompt(false, "Cart init failed!"); + ShowPrompt(false, "%s", STR_CART_INIT_FAILED); free(cdata); return 1; } @@ -976,7 +982,7 @@ u32 CartRawDump(void) { // input dump size dsize = cdata->cart_size; FormatBytes(bytestr, dsize); - dsize = ShowHexPrompt(dsize, 8, "Cart: %s\nDetected size: %s\n \nInput dump size below.", cname, bytestr); + dsize = ShowHexPrompt(dsize, 8, STR_CART_DETECTED_SIZE_INPUT_BELOW, cname, bytestr); if (!dsize || (dsize == (u64) -1)) { free(cdata); return 1; @@ -985,10 +991,10 @@ u32 CartRawDump(void) { // for NDS carts: ask for secure area encryption if (cdata->cart_type & CART_NTR) SetSecureAreaEncryption( - !ShowPrompt(true, "Cart: %s\nNDS cart detected\nDecrypt the secure area?", cname)); + !ShowPrompt(true, STR_NDS_CART_DECRYPT_SECURE_AREA, cname)); // destination path - snprintf(dest, 256, "%s/%s_%08llX.%s", + snprintf(dest, sizeof(dest), "%s/%s_%08llX.%s", OUTPUT_PATH, cname, dsize, (cdata->cart_type & CART_CTR) ? "3ds" : "nds"); // buffer allocation @@ -1013,8 +1019,8 @@ u32 CartRawDump(void) { } } - if (ret) ShowPrompt(false, "%s\nFailed dumping cart", cname); - else ShowPrompt(false, "%s\nDumped to %s", cname, OUTPUT_PATH); + if (ret) ShowPrompt(false, STR_FAILED_DUMPING_CART, cname); + else ShowPrompt(false, STR_PATH_DUMPED_TO_OUT, cname, OUTPUT_PATH); free(buf); free(cdata); @@ -1024,7 +1030,7 @@ u32 CartRawDump(void) { u32 DirFileAttrMenu(const char* path, const char *name) { bool drv = (path[2] == '\0'); bool vrt = (!drv); // will be checked below - char namestr[128], datestr[32], attrstr[128], sizestr[192]; + char namestr[UTF_BUFFER_BYTESIZE(128)], datestr[UTF_BUFFER_BYTESIZE(32)], attrstr[UTF_BUFFER_BYTESIZE(128)], sizestr[UTF_BUFFER_BYTESIZE(192)]; FILINFO fno; u8 new_attrib; @@ -1036,8 +1042,8 @@ u32 DirFileAttrMenu(const char* path, const char *name) { if (fvx_stat(path, &fno) != FR_OK) return 1; vrt = (fno.fattrib & AM_VRT); new_attrib = fno.fattrib; - snprintf(datestr, 32, "%s: %04d-%02d-%02d %02d:%02d:%02d\n", - (fno.fattrib & AM_DIR) ? "created" : "modified", + snprintf(datestr, sizeof(datestr), "%s: %04d-%02d-%02d %02d:%02d:%02d\n", + (fno.fattrib & AM_DIR) ? STR_CREATED : STR_MODIFIED, 1980 + ((fno.fdate >> 9) & 0x7F), (fno.fdate >> 5) & 0xF, fno.fdate & 0x1F, (fno.ftime >> 11) & 0x1F, (fno.ftime >> 5) & 0x3F, (fno.ftime & 0x1F) << 1); } else { @@ -1054,7 +1060,7 @@ u32 DirFileAttrMenu(const char* path, const char *name) { u32 tfiles = 0; // this may take a while... - ShowString("Analyzing %s, please wait...", drv ? "drive" : "dir"); + ShowString("%s", drv ? STR_ANALYZING_DRIVE : STR_ANALYZING_DIR); if (!DirInfo(path, &tsize, &tdirs, &tfiles)) return 1; FormatBytes(bytestr, tsize); @@ -1064,32 +1070,27 @@ u32 DirFileAttrMenu(const char* path, const char *name) { FormatBytes(freestr, GetFreeSpace(path)); FormatBytes(drvsstr, GetTotalSpace(path)); FormatBytes(usedstr, GetTotalSpace(path) - GetFreeSpace(path)); - snprintf(sizestr, 192, "%lu files & %lu subdirs\n%s total size\n \nspace free: %s\nspace used: %s\nspace total: %s", + snprintf(sizestr, sizeof(sizestr), STR_N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL, tfiles, tdirs, bytestr, freestr, usedstr, drvsstr); } else { // dir specific - snprintf(sizestr, 192, "%lu files & %lu subdirs\n%s total size", - tfiles, tdirs, bytestr); + snprintf(sizestr, sizeof(sizestr), STR_N_FILES_N_SUBDIRS_TOTAL_SIZE, tfiles, tdirs, bytestr); } } else { // for files char bytestr[32]; FormatBytes(bytestr, fno.fsize); - snprintf(sizestr, 64, "filesize: %s", bytestr); + snprintf(sizestr, sizeof(sizestr), STR_FILESIZE_X, bytestr); } while(true) { if (!drv) { - snprintf(attrstr, 128, - " \n" - "[%c] %sread-only [%c] %shidden\n" - "[%c] %ssystem [%c] %sarchive\n" - "[%c] %svirtual\n" - "%s", + snprintf(attrstr, sizeof(attrstr), + STR_READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL, (new_attrib & AM_RDO) ? 'X' : ' ', vrt ? "" : "↑", (new_attrib & AM_HID) ? 'X' : ' ', vrt ? "" : "↓", (new_attrib & AM_SYS) ? 'X' : ' ', vrt ? "" : "→", (new_attrib & AM_ARC) ? 'X' : ' ', vrt ? "" : "←", vrt ? 'X' : ' ', vrt ? "" : " ", - vrt ? "" : " \n(↑↓→← to change attributes)\n" + vrt ? "" : STR_UDRL_CHANGE_ATTRIBUTES ); } @@ -1100,7 +1101,7 @@ u32 DirFileAttrMenu(const char* path, const char *name) { "%s \n" // attr (not for drives) "%s\n", // options namestr, datestr, sizestr, attrstr, - (drv || vrt || (new_attrib == fno.fattrib)) ? "( to continue)" : "( to apply, to cancel)" + (drv || vrt || (new_attrib == fno.fattrib)) ? STR_A_TO_CONTINUE : STR_A_APPLY_B_CANCEL ); while(true) { @@ -1111,7 +1112,7 @@ u32 DirFileAttrMenu(const char* path, const char *name) { const u8 mask = (AM_RDO | AM_HID | AM_SYS | AM_ARC); bool apply = (new_attrib != fno.fattrib) && (pad_state & BUTTON_A); if (apply && !PathAttr(path, new_attrib & mask, mask)) { - ShowPrompt(false, "%s\nFailed to set attributes!", namestr); + ShowPrompt(false, "%s\n%s", namestr, STR_FAILED_TO_SET_ATTRIBUTES); } } ClearScreenF(true, false, COLOR_STD_BG); @@ -1191,12 +1192,14 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan bool keyinstallable = (FTYPE_KEYINSTALL(filetype)) && !((drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND)); bool scriptable = (FTYPE_SCRIPT(filetype)); bool fontable = (FTYPE_FONT(filetype)); + bool translationable = (FTYPE_TRANSLATION(filetype)); bool viewable = (FTYPE_GFX(filetype)); bool setable = (FTYPE_SETABLE(filetype)); bool bootable = (FTYPE_BOOTABLE(filetype)); bool installable = (FTYPE_INSTALLABLE(filetype)); bool agbexportable = (FTYPE_AGBSAVE(filetype) && (drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND)); bool agbimportable = (FTYPE_AGBSAVE(filetype) && (drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND)); + bool luascriptable = (FTYPE_LUA(filetype)); char cxi_path[256] = { 0 }; // special options for TMD if ((filetype & GAME_TMD) && @@ -1211,14 +1214,15 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit || cxi_dumpable || tik_buildable || key_buildable || titleinfo || renamable || trimable || transferable || hsinjectable || restorable || xorpadable || ebackupable || ncsdfixable || extrcodeable || keyinitable || - keyinstallable || bootable || scriptable || fontable || viewable || installable || agbexportable || - agbimportable || cia_installable || tik_installable || tik_dumpable || cif_installable; + keyinstallable || bootable || scriptable || fontable || translationable || viewable || installable || + agbexportable || agbimportable || cia_installable || tik_installable || tik_dumpable || cif_installable || + luascriptable; char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, file_path, 32, 8); char tidstr[32] = { 0 }; - if (tid) snprintf(tidstr, 32, "\ntid: <%016llX>", tid); + if (tid) snprintf(tidstr, sizeof(tidstr), "\ntid: <%016llX>", tid); u32 n_marked = 0; if ((&(current_dir->entry[*cursor]))->marked) { @@ -1249,54 +1253,72 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan titleman = 2; n_opt = 2; } + + // format strings that need it + char buildkeydb_str[256], buildtikdbenc_str[256], buildtikdbdec_str[256], + copyto_str[256], decryptto_str[256], encryptto_str[256], extractexefs_str[256], + initkeydb_str[256], installkeydb_str[256]; + snprintf(buildkeydb_str, sizeof(buildkeydb_str), STR_BUILD_X, KEYDB_NAME); + snprintf(buildtikdbenc_str, sizeof(buildtikdbenc_str), STR_BUILD_X, TIKDB_NAME_ENC); + snprintf(buildtikdbdec_str, sizeof(buildtikdbdec_str), STR_BUILD_X, TIKDB_NAME_DEC); + snprintf(copyto_str, sizeof(copyto_str), STR_COPY_TO_OUT, OUTPUT_PATH); + snprintf(decryptto_str, sizeof(decryptto_str), STR_DECRYPT_FILE_OUT, OUTPUT_PATH); + snprintf(encryptto_str, sizeof(encryptto_str), STR_ENCRYPT_FILE_OUT, OUTPUT_PATH); + snprintf(extractexefs_str, sizeof(extractexefs_str), STR_EXTRACT_X, EXEFS_CODE_NAME); + snprintf(initkeydb_str, sizeof(initkeydb_str), STR_INIT_X, KEYDB_NAME); + snprintf(installkeydb_str, sizeof(installkeydb_str), STR_INSTALL_X, KEYDB_NAME); + if (special > 0) optionstr[special-1] = - (filetype & IMG_NAND ) ? "NAND image options..." : - (filetype & IMG_FAT ) ? (transferable) ? "CTRNAND options..." : "Mount as FAT image" : - (filetype & GAME_CIA ) ? "CIA image options..." : - (filetype & GAME_NCSD ) ? "NCSD image options..." : - (filetype & GAME_NCCH ) ? "NCCH image options..." : - (filetype & GAME_EXEFS) ? "Mount as EXEFS image" : - (filetype & GAME_ROMFS) ? "Mount as ROMFS image" : - (filetype & GAME_TMD ) ? "TMD file options..." : - (filetype & GAME_CDNTMD)? "TMD/CDN options..." : - (filetype & GAME_TWLTMD)? "TMD/TWL options..." : - (filetype & GAME_TIE ) ? "Manage Title..." : - (filetype & GAME_BOSS ) ? "BOSS file options..." : - (filetype & GAME_NUSCDN)? "Decrypt NUS/CDN file" : - (filetype & GAME_SMDH) ? "Show SMDH title info" : - (filetype & GAME_NDS) ? "NDS image options..." : - (filetype & GAME_GBA) ? "GBA image options..." : - (filetype & GAME_TICKET)? "Ticket options..." : - (filetype & GAME_TAD) ? "TAD image options..." : - (filetype & GAME_3DSX) ? "Show 3DSX title info" : - (filetype & SYS_FIRM ) ? "FIRM image options..." : - (filetype & SYS_AGBSAVE)? (agbimportable) ? "AGBSAVE options..." : "Dump GBA VC save" : - (filetype & SYS_TICKDB) ? "Ticket.db options..." : - (filetype & SYS_DIFF) ? "Mount as DIFF image" : - (filetype & SYS_DISA) ? "Mount as DISA image" : - (filetype & BIN_CIFNSH) ? "Install cifinish.bin" : - (filetype & BIN_TIKDB) ? "Titlekey options..." : - (filetype & BIN_KEYDB) ? "AESkeydb options..." : - (filetype & BIN_LEGKEY) ? "Build " KEYDB_NAME : - (filetype & BIN_NCCHNFO)? "NCCHinfo options..." : - (filetype & TXT_SCRIPT) ? "Execute GM9 script" : - (FTYPE_FONT(filetype)) ? "Font options..." : - (filetype & GFX_PNG) ? "View PNG file" : - (filetype & HDR_NAND) ? "Rebuild NCSD header" : - (filetype & NOIMG_NAND) ? "Rebuild NCSD header" : "???"; - optionstr[hexviewer-1] = "Show in Hexeditor"; - optionstr[calcsha256-1] = "Calculate SHA-256"; - optionstr[calcsha1-1] = "Calculate SHA-1"; - optionstr[fileinfo-1] = "Show file info"; - if (textviewer > 0) optionstr[textviewer-1] = "Show in Textviewer"; - if (calccmac > 0) optionstr[calccmac-1] = "Calculate CMAC"; - if (copystd > 0) optionstr[copystd-1] = "Copy to " OUTPUT_PATH; - if (inject > 0) optionstr[inject-1] = "Inject data @offset"; - if (searchdrv > 0) optionstr[searchdrv-1] = "Open containing folder"; - if (titleman > 0) optionstr[titleman-1] = "Open title folder"; - - int user_select = ShowSelectPrompt(n_opt, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + (filetype & IMG_NAND) ? STR_NAND_IMAGE_OPTIONS : + (filetype & IMG_FAT) ? (transferable) ? STR_CTRNAND_OPTIONS : STR_MOUNT_FAT_IMAGE : + (filetype & GAME_CIA) ? STR_CIA_IMAGE_OPTIONS : + (filetype & GAME_NCSD) ? STR_NCSD_IMAGE_OPTIONS : + (filetype & GAME_NCCH) ? STR_NCCH_IMAGE_OPTIONS : + (filetype & GAME_EXEFS) ? STR_MOUNT_AS_EXEFS_IMAGE : + (filetype & GAME_ROMFS) ? STR_MOUNT_AS_ROMFS_IMAGE : + (filetype & GAME_TMD) ? STR_TMD_FILE_OPTIONS : + (filetype & GAME_CDNTMD)? STR_TMD_CDN_OPTIONS : + (filetype & GAME_TWLTMD)? STR_TMD_TWL_OPTIONS : + (filetype & GAME_TIE) ? STR_MANAGE_TITLE : + (filetype & GAME_BOSS) ? STR_BOSS_FILE_OPTIONS : + (filetype & GAME_NUSCDN)? STR_DECRYPT_NUS_CDN_FILE : + (filetype & GAME_SMDH) ? STR_SHOW_SMDH_TITLE_INFO : + (filetype & GAME_NDS) ? STR_NDS_IMAGE_OPTIONS : + (filetype & GAME_GBA) ? STR_GBA_IMAGE_OPTIONS : + (filetype & GAME_TICKET)? STR_TICKET_OPTIONS : + (filetype & GAME_TAD) ? STR_TAD_IMAGE_OPTIONS : + (filetype & GAME_3DSX) ? STR_SHOW_3DSX_TITLE_INFO : + (filetype & SYS_FIRM) ? STR_FIRM_IMAGE_OPTIONS : + (filetype & SYS_AGBSAVE)? (agbimportable) ? STR_AGBSAVE_OPTIONS : STR_DUMP_GBA_VC_SAVE : + (filetype & SYS_TICKDB) ? STR_TICKET_DB_OPTIONS : + (filetype & SYS_DIFF) ? STR_MOUNT_AS_DIFF_IMAGE : + (filetype & SYS_DISA) ? STR_MOUNT_AS_DISA_IAMGE : + (filetype & BIN_CIFNSH) ? STR_INSTALL_CIFINISH_BIN : + (filetype & BIN_TIKDB) ? STR_TITLEKEY_OPTIONS : + (filetype & BIN_KEYDB) ? STR_AESKEYDB_OPTIONS : + (filetype & BIN_LEGKEY) ? buildkeydb_str : + (filetype & BIN_NCCHNFO)? STR_NCCHINFO_OPTIONS : + (filetype & TXT_SCRIPT) ? STR_EXECUTE_GM9_SCRIPT : + (filetype & TXT_LUA) ? STR_EXECUTE_LUA_SCRIPT : + (FTYPE_FONT(filetype)) ? STR_FONT_OPTIONS : + (filetype & TRANSLATION)? STR_LANGUAGE_OPTIONS : + (filetype & GFX_PNG) ? STR_VIEW_PNG_FILE : + (filetype & HDR_NAND) ? STR_REBUILD_NCSD_HEADER : + (filetype & NOIMG_NAND) ? STR_REBUILD_NCSD_HEADER : "???"; + optionstr[hexviewer-1] = STR_SHOW_IN_HEXEDITOR; + optionstr[calcsha256-1] = STR_CALCULATE_SHA256; + optionstr[calcsha1-1] = STR_CALCULATE_SHA1; + optionstr[fileinfo-1] = STR_SHOW_FILE_INFO; + if (textviewer > 0) optionstr[textviewer-1] = STR_SHOW_IN_TEXTVIEWER; + if (calccmac > 0) optionstr[calccmac-1] = STR_CALCULATE_CMAC; + if (copystd > 0) optionstr[copystd-1] = copyto_str; + if (inject > 0) optionstr[inject-1] = STR_INJECT_DATA_AT_OFFSET; + if (searchdrv > 0) optionstr[searchdrv-1] = STR_OPEN_CONTAINING_FOLDER; + if (titleman > 0) optionstr[titleman-1] = STR_OPEN_TITLE_FOLDER; + + int user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(n_opt, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(n_opt, optionstr, "%s%s", pathstr, tidstr)); if (user_select == hexviewer) { // -> show in hex viewer FileHexViewer(file_path); GetDirContents(current_dir, current_path); @@ -1317,10 +1339,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == calccmac) { // -> calculate CMAC - optionstr[0] = "Check current CMAC only"; - optionstr[1] = "Verify CMAC for all"; - optionstr[2] = "Fix CMAC for all"; - user_select = (n_marked > 1) ? ShowSelectPrompt(3, optionstr, "%s\n(%lu files selected)", pathstr, n_marked) : 1; + optionstr[0] = STR_CHECK_CURRENT_CMAC_ONLY; + optionstr[1] = STR_VERIFY_CMAC_FOR_ALL; + optionstr[2] = STR_FIX_CMAC_FOR_ALL; + user_select = (n_marked > 1) ? ShowSelectPrompt(3, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : 1; if (user_select == 1) { CmacCalculator(file_path); return 0; @@ -1347,14 +1369,14 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan current_dir->entry[i].marked = false; } if (n_fixed) { - if (n_nocmac) ShowPrompt(false, "%lu/%lu/%lu files ok/fixed/total\n%lu/%lu have no CMAC", + if (n_nocmac) ShowPrompt(false, STR_N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC, n_success, n_fixed, n_marked, n_nocmac, n_marked); - else ShowPrompt(false, "%lu/%lu files verified ok\n%lu/%lu files fixed", + else ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED, n_success, n_marked, n_fixed, n_marked); } else { - if (n_nocmac) ShowPrompt(false, "%lu/%lu files verified ok\n%lu/%lu have no CMAC", + if (n_nocmac) ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC, n_success, n_marked, n_nocmac, n_marked); - else ShowPrompt(false, "%lu/%lu files verified ok", n_success, n_marked); + else ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED, n_success, n_marked); } return 0; } @@ -1371,10 +1393,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else if (user_select == inject) { // -> inject data from clipboard char origstr[UTF_BUFFER_BYTESIZE(18)]; TruncateString(origstr, clipboard->entry[0].name, 18, 10); - u64 offset = ShowHexPrompt(0, 8, "Inject data from %s?\nSpecify offset below.", origstr); + u64 offset = ShowHexPrompt(0, 8, STR_INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW, origstr); if (offset != (u64) -1) { if (!FileInjectFile(file_path, clipboard->entry[0].path, (u32) offset, 0, 0, NULL)) - ShowPrompt(false, "Failed injecting %s", origstr); + ShowPrompt(false, STR_FAILED_INJECTING_PATH, origstr); clipboard->n_entries = 0; } return 0; @@ -1441,51 +1463,56 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan int install = (installable) ? ++n_opt : -1; int boot = (bootable) ? ++n_opt : -1; int script = (scriptable) ? ++n_opt : -1; + int luascript = (luascriptable) ? ++n_opt : -1; int font = (fontable) ? ++n_opt : -1; + int translation = (translationable) ? ++n_opt : -1; int view = (viewable) ? ++n_opt : -1; int agbexport = (agbexportable) ? ++n_opt : -1; int agbimport = (agbimportable) ? ++n_opt : -1; int setup = (setable) ? ++n_opt : -1; - if (mount > 0) optionstr[mount-1] = (filetype & GAME_TMD) ? "Mount CXI/NDS to drive" : "Mount image to drive"; - if (restore > 0) optionstr[restore-1] = "Restore SysNAND (safe)"; - if (ebackup > 0) optionstr[ebackup-1] = "Update embedded backup"; - if (ncsdfix > 0) optionstr[ncsdfix-1] = "Rebuild NCSD header"; - if (show_info > 0) optionstr[show_info-1] = "Show title info"; - if (decrypt > 0) optionstr[decrypt-1] = (cryptable_inplace) ? "Decrypt file (...)" : "Decrypt file (" OUTPUT_PATH ")"; - if (encrypt > 0) optionstr[encrypt-1] = (cryptable_inplace) ? "Encrypt file (...)" : "Encrypt file (" OUTPUT_PATH ")"; - if (cia_build > 0) optionstr[cia_build-1] = (cia_build_legit < 0) ? "Build CIA from file" : "Build CIA (standard)"; - if (cia_build_legit > 0) optionstr[cia_build_legit-1] = "Build CIA (legit)"; - if (cxi_dump > 0) optionstr[cxi_dump-1] = "Dump CXI/NDS file"; - if (cia_install > 0) optionstr[cia_install-1] = "Install game image"; - if (tik_install > 0) optionstr[tik_install-1] = "Install ticket"; - if (tik_dump > 0) optionstr[tik_dump-1] = "Dump ticket file"; - if (cif_install > 0) optionstr[cif_install-1] = "Install cifinish.bin"; - if (uninstall > 0) optionstr[uninstall-1] = "Uninstall title"; - if (tik_build_enc > 0) optionstr[tik_build_enc-1] = "Build " TIKDB_NAME_ENC; - if (tik_build_dec > 0) optionstr[tik_build_dec-1] = "Build " TIKDB_NAME_DEC; - if (key_build > 0) optionstr[key_build-1] = "Build " KEYDB_NAME; - if (verify > 0) optionstr[verify-1] = "Verify file"; - if (ctrtransfer > 0) optionstr[ctrtransfer-1] = "Transfer image to CTRNAND"; - if (hsinject > 0) optionstr[hsinject-1] = "Inject to H&S"; - if (trim > 0) optionstr[trim-1] = "Trim file"; - if (rename > 0) optionstr[rename-1] = "Rename file"; - if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)"; - if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)"; - if (extrcode > 0) optionstr[extrcode-1] = "Extract " EXEFS_CODE_NAME; - if (keyinit > 0) optionstr[keyinit-1] = "Init " KEYDB_NAME; - if (keyinstall > 0) optionstr[keyinstall-1] = "Install " KEYDB_NAME; - if (install > 0) optionstr[install-1] = "Install FIRM"; - if (boot > 0) optionstr[boot-1] = "Boot FIRM"; - if (script > 0) optionstr[script-1] = "Execute GM9 script"; - if (view > 0) optionstr[view-1] = "View PNG file"; - if (font > 0) optionstr[font-1] = "Set as active font"; - if (agbexport > 0) optionstr[agbexport-1] = "Dump GBA VC save"; - if (agbimport > 0) optionstr[agbimport-1] = "Inject GBA VC save"; - if (setup > 0) optionstr[setup-1] = "Set as default"; + if (mount > 0) optionstr[mount-1] = (filetype & GAME_TMD) ? STR_MOUNT_CXI_NDS_TO_DRIVE : STR_MOUNT_IMAGE_TO_DRIVE; + if (restore > 0) optionstr[restore-1] = STR_RESTORE_SYSNAND_SAFE; + if (ebackup > 0) optionstr[ebackup-1] = STR_UPDATE_EMBEDDED_BACKUP; + if (ncsdfix > 0) optionstr[ncsdfix-1] = STR_REBUILD_NCSD_HEADER; + if (show_info > 0) optionstr[show_info-1] = STR_SHOW_TITLE_INFO; + if (decrypt > 0) optionstr[decrypt-1] = (cryptable_inplace) ? STR_DECRYPT_FILE : decryptto_str; + if (encrypt > 0) optionstr[encrypt-1] = (cryptable_inplace) ? STR_ENCRYPT_FILE : encryptto_str; + if (cia_build > 0) optionstr[cia_build-1] = (cia_build_legit < 0) ? STR_BUILD_CIA_FROM_FILE : STR_BUILD_CIA_STANDARD; + if (cia_build_legit > 0) optionstr[cia_build_legit-1] = STR_BUILD_CIA_LEGIT; + if (cxi_dump > 0) optionstr[cxi_dump-1] = STR_DUMP_CXI_NDS_FILE; + if (cia_install > 0) optionstr[cia_install-1] = STR_INSTALL_GAME_IMAGE; + if (tik_install > 0) optionstr[tik_install-1] = STR_INSTALL_TICKET; + if (tik_dump > 0) optionstr[tik_dump-1] = STR_DUMP_TICKET_FILE; + if (cif_install > 0) optionstr[cif_install-1] = STR_INSTALL_CIFINISH_BIN; + if (uninstall > 0) optionstr[uninstall-1] = STR_UNINSTALL_TITLE; + if (tik_build_enc > 0) optionstr[tik_build_enc-1] = buildtikdbenc_str; + if (tik_build_dec > 0) optionstr[tik_build_dec-1] = buildtikdbdec_str; + if (key_build > 0) optionstr[key_build-1] = buildkeydb_str; + if (verify > 0) optionstr[verify-1] = STR_VERIFY_FILE; + if (ctrtransfer > 0) optionstr[ctrtransfer-1] = STR_TRANSFER_IMAGE_TO_CTRNAND; + if (hsinject > 0) optionstr[hsinject-1] = STR_INJECT_TO_H_AND_S; + if (trim > 0) optionstr[trim-1] = STR_TRIM_FILE; + if (rename > 0) optionstr[rename-1] = STR_RENAME_FILE; + if (xorpad > 0) optionstr[xorpad-1] = STR_BUILD_XORPADS_SD; + if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = STR_BUILD_XORPADS_INPLACE; + if (extrcode > 0) optionstr[extrcode-1] = extractexefs_str; + if (keyinit > 0) optionstr[keyinit-1] = initkeydb_str; + if (keyinstall > 0) optionstr[keyinstall-1] = installkeydb_str; + if (install > 0) optionstr[install-1] = STR_INSTALL_FIRM; + if (boot > 0) optionstr[boot-1] = STR_BOOT_FIRM; + if (script > 0) optionstr[script-1] = STR_EXECUTE_GM9_SCRIPT; + if (luascript > 0) optionstr[luascript-1] = STR_EXECUTE_LUA_SCRIPT; + if (view > 0) optionstr[view-1] = STR_VIEW_PNG_FILE; + if (font > 0) optionstr[font-1] = STR_SET_AS_ACTIVE_FONT; + if (translation > 0) optionstr[translation-1] = STR_SET_AS_ACTIVE_LANGUAGE; + if (agbexport > 0) optionstr[agbexport-1] = STR_DUMP_BA_VC_SAVE; + if (agbimport > 0) optionstr[agbimport-1] = STR_INJECT_GBA_VC_SAVE; + if (setup > 0) optionstr[setup-1] = STR_SET_AS_DEFAULT; // auto select when there is only one option - user_select = (n_opt <= 1) ? n_opt : (int) ShowSelectPrompt(n_opt, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + user_select = (n_opt <= 1) ? n_opt : (int) ((n_marked > 1) ? + ShowSelectPrompt(n_opt, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(n_opt, optionstr, "%s%s", pathstr, tidstr)); if (user_select == mount) { // -> mount file as image const char* mnt_drv_paths[] = { "7:", "G:", "K:", "T:", "I:", "D:" }; // maybe move that to fsdrive.h if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) @@ -1500,10 +1527,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } if (!drv_path) { - ShowPrompt(false, "Mounting image: failed"); + ShowPrompt(false, "%s", STR_MOUNTING_IMAGE_FAILED); InitImgFS(NULL); } else { // open in next pane? - if (ShowPrompt(true, "%s\nMounted as drive %s\nEnter path now?", pathstr, drv_path)) { + if (ShowPrompt(true, STR_PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW, pathstr, drv_path)) { if (N_PANES) { memcpy((*pane)->path, current_path, 256); // store current pane state (*pane)->cursor = *cursor; @@ -1521,18 +1548,21 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } else if (user_select == decrypt) { // -> decrypt game file if (cryptable_inplace) { - optionstr[0] = "Decrypt to " OUTPUT_PATH; - optionstr[1] = "Decrypt inplace"; - user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + char decryptToOut[UTF_BUFFER_BYTESIZE(64)]; + snprintf(decryptToOut, sizeof(decryptToOut), STR_DECRYPT_TO_OUT, OUTPUT_PATH); + optionstr[0] = decryptToOut; + optionstr[1] = STR_DECRYPT_INPLACE; + user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(2, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(2, optionstr, "%s%s", pathstr, tidstr)); } else user_select = 1; bool inplace = (user_select == 2); if (!user_select) { // do nothing when no choice is made - } else if ((n_marked > 1) && ShowPrompt(true, "Try to decrypt all %lu selected files?", n_marked)) { + } else if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_DECRYPT_ALL_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_unencrypted = 0; u32 n_other = 0; - ShowString("Trying to decrypt %lu files...", n_marked); + ShowString(STR_TRYING_TO_DECRYPT_N_FILES, n_marked); for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; if (!current_dir->entry[i].marked) @@ -1551,41 +1581,44 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nDecryption failed\n \nContinue?", lpathstr)) continue; + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_DECRYPTION_FAILED_CONTINUE)) continue; else break; } current_dir->entry[i].marked = false; } if (n_other || n_unencrypted) { - ShowPrompt(false, "%lu/%lu files decrypted ok\n%lu/%lu not encrypted\n%lu/%lu not of same type", + ShowPrompt(false, STR_N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_unencrypted, n_marked, n_other, n_marked); - } else ShowPrompt(false, "%lu/%lu files decrypted ok", n_success, n_marked); - if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH); + } else ShowPrompt(false, STR_N_OF_N_FILES_DECRYPTED, n_success, n_marked); + if (!inplace && n_success) ShowPrompt(false, STR_N_FILES_WRITTEN_TO_OUT, n_success, OUTPUT_PATH); } else { if (!(filetype & BIN_KEYDB) && (CheckEncryptedGameFile(file_path) != 0)) { - ShowPrompt(false, "%s\nFile is not encrypted", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FILE_NOT_ENCRYPTED); } else { u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(file_path, inplace, false) : CryptGameFile(file_path, inplace, false); - if (inplace || (ret != 0)) ShowPrompt(false, "%s\nDecryption %s", pathstr, (ret == 0) ? "success" : "failed"); - else ShowPrompt(false, "%s\nDecrypted to %s", pathstr, OUTPUT_PATH); + if (inplace || (ret != 0)) ShowPrompt(false, "%s\n%s", pathstr, (ret == 0) ? STR_DECRYPTION_SUCCESS : STR_DECRYPTION_FAILED); + else ShowPrompt(false, STR_PATH_DECRYPTED_TO_OUT, pathstr, OUTPUT_PATH); } } return 0; } else if (user_select == encrypt) { // -> encrypt game file if (cryptable_inplace) { - optionstr[0] = "Encrypt to " OUTPUT_PATH; - optionstr[1] = "Encrypt inplace"; - user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + char encryptToOut[UTF_BUFFER_BYTESIZE(64)]; + snprintf(encryptToOut, sizeof(encryptToOut), STR_ENCRYPT_TO_OUT, OUTPUT_PATH); + optionstr[0] = encryptToOut; + optionstr[1] = STR_ENCRYPT_INPLACE; + user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(2, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(2, optionstr, "%s%s", pathstr, tidstr)); } else user_select = 1; bool inplace = (user_select == 2); if (!user_select) { // do nothing when no choice is made - } else if ((n_marked > 1) && ShowPrompt(true, "Try to encrypt all %lu selected files?", n_marked)) { + } else if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_ENCRYPT_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; - ShowString("Trying to encrypt %lu files...", n_marked); + ShowString(STR_TRYING_TO_ENCRYPT_N_FILES, n_marked); for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; if (!current_dir->entry[i].marked) @@ -1600,28 +1633,28 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nEncryption failed\n \nContinue?", lpathstr)) continue; + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_ENCRYPTION_FAILED_CONTINUE)) continue; else break; } current_dir->entry[i].marked = false; } if (n_other) { - ShowPrompt(false, "%lu/%lu files encrypted ok\n%lu/%lu not of same type", + ShowPrompt(false, STR_N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - } else ShowPrompt(false, "%lu/%lu files encrypted ok", n_success, n_marked); - if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH); + } else ShowPrompt(false, STR_N_OF_N_FILES_ENCRYPTED, n_success, n_marked); + if (!inplace && n_success) ShowPrompt(false, STR_N_FILES_WRITTEN_TO_OUT, n_success, OUTPUT_PATH); } else { u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(file_path, inplace, true) : CryptGameFile(file_path, inplace, true); - if (inplace || (ret != 0)) ShowPrompt(false, "%s\nEncryption %s", pathstr, (ret == 0) ? "success" : "failed"); - else ShowPrompt(false, "%s\nEncrypted to %s", pathstr, OUTPUT_PATH); + if (inplace || (ret != 0)) ShowPrompt(false, "%s\n%s", pathstr, (ret == 0) ? STR_ENCRYPTION_SUCCESS : STR_ENCRYPTION_FAILED); + else ShowPrompt(false, STR_PATH_ENCRYPTED_TO_OUT, pathstr, OUTPUT_PATH); } return 0; } else if ((user_select == cia_build) || (user_select == cia_build_legit) || (user_select == cxi_dump)) { // -> build CIA / dump CXI char* type = (user_select == cxi_dump) ? "CXI" : "CIA"; bool force_legit = (user_select == cia_build_legit); - if ((n_marked > 1) && ShowPrompt(true, "Try to process all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_PROCESS_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; for (u32 i = 0; i < current_dir->n_entries; i++) { @@ -1638,31 +1671,30 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nBuild %s failed\n \nContinue?", lpathstr, type)) continue; + if (ShowPrompt(true, STR_PATH_BUILD_TYPE_FAILED_CONTINUE, lpathstr, type)) continue; else break; } current_dir->entry[i].marked = false; } - if (n_other) ShowPrompt(false, "%lu/%lu %ss built ok\n%lu/%lu not of same type", + if (n_other) ShowPrompt(false, STR_N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, type, n_other, n_marked); - else ShowPrompt(false, "%lu/%lu %ss built ok", n_success, n_marked, type); - if (n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH); + else ShowPrompt(false, STR_N_OF_N_TYPES_BUILT, n_success, n_marked, type); + if (n_success) ShowPrompt(false, STR_N_FILES_WRITTEN_TO_OUT, n_success, OUTPUT_PATH); if (n_success && in_output_path) GetDirContents(current_dir, current_path); if (n_success != (n_marked - n_other)) { - ShowPrompt(false, "%lu file(s) failed conversion.\nVerification is recommended.", + ShowPrompt(false, STR_N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED, n_marked - (n_success + n_other)); } } else { if (((user_select != cxi_dump) && (BuildCiaFromGameFile(file_path, force_legit) == 0)) || ((user_select == cxi_dump) && (DumpCxiSrlFromGameFile(file_path) == 0))) { - ShowPrompt(false, "%s\n%s built to %s", pathstr, type, OUTPUT_PATH); + ShowPrompt(false, STR_PATH_TYPE_BUILT_TO_OUT, pathstr, type, OUTPUT_PATH); if (in_output_path) GetDirContents(current_dir, current_path); } else { - ShowPrompt(false, "%s\n%s build failed", pathstr, type); + ShowPrompt(false, STR_PATH_TYPE_BUILD_FAILED, pathstr, type); if ((filetype & (GAME_NCCH|GAME_NCSD)) && - ShowPrompt(true, "%s\nfile failed conversion.\n \nVerify now?", pathstr)) { - ShowPrompt(false, "%s\nVerification %s", pathstr, - (VerifyGameFile(file_path) == 0) ? "success" : "failed"); + ShowPrompt(true, "%s\n%s", pathstr, STR_FILE_FAILED_CONVERSION_VERIFY_NOW)) { + ShowPrompt(false, "%s\n%s", pathstr, (VerifyGameFile(file_path) == 0) ? STR_VERIFICATION_SUCCESS : STR_VERIFICATION_FAILED); } } } @@ -1675,17 +1707,18 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan (user_select == tik_install) ? &InstallTicketFile : &InstallCifinishFile; bool to_emunand = false; if (CheckVirtualDrive("E:")) { - optionstr[0] = "Install to SysNAND"; - optionstr[1] = "Install to EmuNAND"; - user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + optionstr[0] = STR_INSTALL_TO_SYSNAND; + optionstr[1] = STR_INSTALL_TO_EMUNAND; + user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(2, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(2, optionstr, "%s%s", pathstr, tidstr)); if (!user_select) return 0; else to_emunand = (user_select == 2); } - if ((n_marked > 1) && ShowPrompt(true, "Try to install all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_INSTALL_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; - ShowString("Trying to install %lu files...", n_marked); + ShowString(STR_TRYING_TO_INSTALL_N_FILES, n_marked); for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; if (!current_dir->entry[i].marked) @@ -1700,22 +1733,21 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nInstall failed\n \nContinue?", lpathstr)) continue; + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_INSTALL_FAILED_CONTINUE)) continue; else break; } current_dir->entry[i].marked = false; } if (n_other) { - ShowPrompt(false, "%lu/%lu files installed ok\n%lu/%lu not of same type", + ShowPrompt(false, STR_N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - } else ShowPrompt(false, "%lu/%lu files installed ok", n_success, n_marked); + } else ShowPrompt(false, STR_N_OF_N_FILES_INSTALLED, n_success, n_marked); } else { u32 ret = (*InstallFunction)(file_path, to_emunand); - ShowPrompt(false, "%s\nInstall %s", pathstr, (ret == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (ret == 0) ? STR_INSTALL_SUCCESS : STR_INSTALL_FAILED); if ((ret != 0) && (filetype & (GAME_NCCH|GAME_NCSD)) && - ShowPrompt(true, "%s\nfile failed install.\n \nVerify now?", pathstr)) { - ShowPrompt(false, "%s\nVerification %s", pathstr, - (VerifyGameFile(file_path) == 0) ? "success" : "failed"); + ShowPrompt(true, "%s\n%s", pathstr, STR_FILE_FAILED_INSTALL_VERIFY_NOW)) { + ShowPrompt(false, "%s\n%s", pathstr, (VerifyGameFile(file_path) == 0) ? STR_VERIFICATION_SUCCESS : STR_VERIFICATION_FAILED); } } return 0; @@ -1724,12 +1756,12 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan bool full_uninstall = false; // safety confirmation - optionstr[0] = "Keep ticket & savegame"; - optionstr[1] = "Uninstall everything"; - optionstr[2] = "Abort uninstall"; + optionstr[0] = STR_KEEP_TICKET_AND_SAVEGAME; + optionstr[1] = STR_UNINSTALL_EVERYTHING; + optionstr[2] = STR_ABORT_UNINSTALL; user_select = (int) (n_marked > 1) ? - ShowSelectPrompt(3, optionstr, "Uninstall %lu selected titles?", n_marked) : - ShowSelectPrompt(3, optionstr, "%s\nUninstall selected title?", pathstr); + ShowSelectPrompt(3, optionstr, STR_UNINSTALL_N_SELECTED_TITLES, n_marked) : + ShowSelectPrompt(3, optionstr, "%s\n%s", pathstr, STR_UNINSTALL_SELECTED_TITLE); full_uninstall = (user_select == 2); if (!user_select || (user_select == 3)) return 0; @@ -1747,11 +1779,11 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan if (UninstallGameDataTie(path, true, full_uninstall, full_uninstall) == 0) n_success++; } - ShowPrompt(false, "%lu/%lu titles uninstalled", n_success, n_marked); + ShowPrompt(false, STR_N_OF_N_TITLES_UNINSTALLED, n_success, n_marked); } else if (CheckWritePermissions(file_path)) { - ShowString("%s\nUninstalling, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_UNINSTALLING_PLEASE_WAIT); if (UninstallGameDataTie(file_path, true, full_uninstall, full_uninstall) != 0) - ShowPrompt(false, "%s\nUninstall failed!", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_UNINSTALL_FAILED); ClearScreenF(true, false, COLOR_STD_BG); } @@ -1759,7 +1791,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == verify) { // -> verify game / nand file - if ((n_marked > 1) && ShowPrompt(true, "Try to verify all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_VERIFY_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; u32 n_processed = 0; @@ -1779,7 +1811,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nVerification failed\n \nContinue?", lpathstr)) { + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_VERIFICATION_FAILED_CONTINUE)) { if (!(filetype & (GAME_CIA|GAME_TMD|GAME_NCSD|GAME_NCCH))) ShowProgress(0, n_marked, path); // restart progress bar continue; @@ -1787,21 +1819,19 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } current_dir->entry[i].marked = false; } - if (n_other) ShowPrompt(false, "%lu/%lu files verified ok\n%lu/%lu not of same type", + if (n_other) ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%lu/%lu files verified ok", n_success, n_marked); + else ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED, n_success, n_marked); } else { - ShowString("%s\nVerifying file, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_VERIFYING_FILE_PLEASE_WAIT); if (filetype & IMG_NAND) { - ShowPrompt(false, "%s\nNAND validation %s", pathstr, - (ValidateNandDump(file_path) == 0) ? "success" : "failed"); - } else ShowPrompt(false, "%s\nVerification %s", pathstr, - (VerifyGameFile(file_path) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (ValidateNandDump(file_path) == 0) ? STR_NAND_VALIDATION_SUCCESS : STR_NAND_VALIDATION_FAILED); + } else ShowPrompt(false, "%s\n%s", pathstr, (VerifyGameFile(file_path) == 0) ? STR_VERIFICATION_SUCCESS : STR_VERIFICATION_FAILED); } return 0; } else if (user_select == tik_dump) { // dump ticket file - if ((n_marked > 1) && ShowPrompt(true, "Dump for all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_DUMP_FOR_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_legit = 0; bool force_legit = true; @@ -1817,20 +1847,18 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan current_dir->entry[i].marked = false; } if (force_legit && (n_success != n_marked)) - if (!ShowPrompt(true, "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", - n_legit, n_marked)) break; + if (!ShowPrompt(true, STR_N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL, n_legit, n_marked)) break; if (!force_legit) break; force_legit = false; } - ShowPrompt(false, "%lu/%lu tickets dumped to %s", - n_success, n_marked, OUTPUT_PATH); + ShowPrompt(false, STR_N_OF_N_TICKETS_DUMPED_TO_OUT, n_success, n_marked, OUTPUT_PATH); } else { if (DumpTicketForGameFile(file_path, true) == 0) { - ShowPrompt(false, "%s\nTicket dumped to %s", pathstr, OUTPUT_PATH); - } else if (ShowPrompt(false, "%s\nLegit ticket not found.\n \nDump anyways?", pathstr)) { + ShowPrompt(false, STR_PATH_TICKET_DUMPED_TO_OUT, pathstr, OUTPUT_PATH); + } else if (ShowPrompt(false, STR_LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS, pathstr)) { if (DumpTicketForGameFile(file_path, false) == 0) - ShowPrompt(false, "%s\nTicket dumped to %s", pathstr, OUTPUT_PATH); - else ShowPrompt(false, "%s\nDump ticket failed!"); + ShowPrompt(false, STR_PATH_TICKET_DUMPED_TO_OUT, pathstr, OUTPUT_PATH); + else ShowPrompt(false, "%s\n%s", pathstr, STR_DUMP_TICKET_FAILED); } } return 0; @@ -1839,7 +1867,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan bool dec = (user_select == tik_build_dec); const char* path_out = (dec) ? OUTPUT_PATH "/" TIKDB_NAME_DEC : OUTPUT_PATH "/" TIKDB_NAME_ENC; if (BuildTitleKeyInfo(NULL, dec, false) != 0) return 1; // init database - ShowString("Building %s...", (dec) ? TIKDB_NAME_DEC : TIKDB_NAME_ENC); + ShowString(STR_BUILDING_X, (dec) ? TIKDB_NAME_DEC : TIKDB_NAME_ENC); if (n_marked > 1) { u32 n_success = 0; u32 n_other = 0; @@ -1855,18 +1883,17 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan if (BuildTitleKeyInfo(path, dec, false) == 0) n_success++; // ignore failures for now } if (BuildTitleKeyInfo(NULL, dec, true) == 0) { - if (n_other) ShowPrompt(false, "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + if (n_other) ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED, path_out, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%s\n%lu/%lu files processed", path_out, n_success, n_marked); - } else ShowPrompt(false, "%s\nBuild database failed.", path_out); - } else ShowPrompt(false, "%s\nBuild database %s.", path_out, - (BuildTitleKeyInfo(file_path, dec, true) == 0) ? "success" : "failed"); + else ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED, path_out, n_success, n_marked); + } else ShowPrompt(false, "%s\n%s", path_out, STR_BUILD_DATABASE_FAILED); + } else ShowPrompt(false, "%s\n%s", path_out, (BuildTitleKeyInfo(file_path, dec, true) == 0) ? STR_BUILD_DATABASE_SUCCESS : STR_BUILD_DATABASE_FAILED); return 0; } else if (user_select == key_build) { // -> (Re)Build AES key database const char* path_out = OUTPUT_PATH "/" KEYDB_NAME; if (BuildKeyDb(NULL, false) != 0) return 1; // init database - ShowString("Building %s...", KEYDB_NAME); + ShowString(STR_BUILDING_X, KEYDB_NAME); if (n_marked > 1) { u32 n_success = 0; u32 n_other = 0; @@ -1882,16 +1909,15 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan if (BuildKeyDb(path, false) == 0) n_success++; // ignore failures for now } if (BuildKeyDb(NULL, true) == 0) { - if (n_other) ShowPrompt(false, "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + if (n_other) ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED, path_out, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%s\n%lu/%lu files processed", path_out, n_success, n_marked); - } else ShowPrompt(false, "%s\nBuild database failed.", path_out); - } else ShowPrompt(false, "%s\nBuild database %s.", path_out, - (BuildKeyDb(file_path, true) == 0) ? "success" : "failed"); + else ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED, path_out, n_success, n_marked); + } else ShowPrompt(false, "%s\n%s", path_out, STR_BUILD_DATABASE_FAILED); + } else ShowPrompt(false, "%s\n%s", path_out, (BuildKeyDb(file_path, true) == 0) ? STR_BUILD_DATABASE_SUCCESS : STR_BUILD_DATABASE_FAILED); return 0; } else if (user_select == trim) { // -> Game file trimmer - if ((n_marked > 1) && ShowPrompt(true, "Try to trim all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_TRIM_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; u32 n_processed = 0; @@ -1914,7 +1940,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } else { // on failure: show error, continue (should not happen) char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nTrimming failed\n \nContinue?", lpathstr)) { + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_TRIMMING_FAILED_CONTINUE)) { ShowProgress(0, n_marked, path); // restart progress bar continue; } else break; @@ -1922,9 +1948,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan current_dir->entry[i].marked = false; } FormatBytes(savingsstr, savings); - if (n_other) ShowPrompt(false, "%lu/%lu files trimmed ok\n%lu/%lu not of same type\n%s saved", + if (n_other) ShowPrompt(false, STR_N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED, n_success, n_marked, n_other, n_marked, savingsstr); - else ShowPrompt(false, "%lu/%lu files trimmed ok\n%s saved", n_success, n_marked, savingsstr); + else ShowPrompt(false, STR_N_OF_N_FILES_TRIMMED_X_SAVED, n_success, n_marked, savingsstr); if (n_success) GetDirContents(current_dir, current_path); } else { u64 trimsize = GetGameFileTrimmedSize(file_path); @@ -1937,14 +1963,14 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan FormatBytes(dsizestr, currentsize - trimsize); if (!trimsize || trimsize > currentsize) { - ShowPrompt(false, "%s\nFile can't be trimmed.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FILE_CANT_BE_TRIMMED); } else if (trimsize == currentsize) { - ShowPrompt(false, "%s\nFile is already trimmed.", pathstr); - } else if (ShowPrompt(true, "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?", + ShowPrompt(false, "%s\n%s", pathstr, STR_FILE_ALREADY_TRIMMED); + } else if (ShowPrompt(true, STR_PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE, pathstr, csizestr, tsizestr, dsizestr)) { - if (TrimGameFile(file_path) != 0) ShowPrompt(false, "%s\nTrimming failed.", pathstr); + if (TrimGameFile(file_path) != 0) ShowPrompt(false, "%s\n%s", pathstr, STR_TRIMMING_FAILED); else { - ShowPrompt(false, "%s\nTrimmed by %s.", pathstr, dsizestr); + ShowPrompt(false, STR_PATH_TRIMMED_BY_X, pathstr, dsizestr); GetDirContents(current_dir, current_path); } } @@ -1952,7 +1978,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == rename) { // -> Game file renamer - if ((n_marked > 1) && ShowPrompt(true, "Try to rename all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_RENAME_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; ShowProgress(0, 0, ""); for (u32 i = 0; i < current_dir->n_entries; i++) { @@ -1963,9 +1989,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan n_success++; current_dir->entry[i].marked = false; } - ShowPrompt(false, "%lu/%lu renamed ok", n_success, n_marked); + ShowPrompt(false, STR_N_OF_N_RENAMED, n_success, n_marked); } else if (!GoodRenamer(&(current_dir->entry[*cursor]), true)) { - ShowPrompt(false, "%s\nCould not rename to good name", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_COULD_NOT_RENAME_TO_GOOD_NAME); } return 0; } @@ -1977,22 +2003,22 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan char* destdrv[2] = { NULL }; n_opt = 0; if (DriveType("1:")) { - optionstr[n_opt] = "SysNAND H&S inject"; + optionstr[n_opt] = STR_SYSNAND_H_AND_S_INJECT; destdrv[n_opt++] = "1:"; } if (DriveType("4:")) { - optionstr[n_opt] = "EmuNAND H&S inject"; + optionstr[n_opt] = STR_EMUNAND_H_AND_S_INJECT; destdrv[n_opt++] = "4:"; } user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, "%s", pathstr) : n_opt; if (user_select) { - ShowPrompt(false, "%s\nH&S inject %s", pathstr, - (InjectHealthAndSafety(file_path, destdrv[user_select-1]) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (InjectHealthAndSafety(file_path, destdrv[user_select-1]) == 0) ? + STR_H_AND_S_INJECT_SUCCESS : STR_H_AND_S_INJECT_FAILURE); } return 0; } else if (user_select == extrcode) { // -> Extract .code - if ((n_marked > 1) && ShowPrompt(true, "Try to extract all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_EXTRACT_ALL_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; u32 n_processed = 0; @@ -2018,15 +2044,15 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } current_dir->entry[i].marked = false; } - if (n_other) ShowPrompt(false, "%lu/%lu files extracted ok\n%lu/%lu not of same type", + if (n_other) ShowPrompt(false, STR_N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%lu/%lu files extracted ok", n_success, n_marked); + else ShowPrompt(false, STR_N_OF_N_FILES_EXTRACTED, n_success, n_marked); } else { char extstr[8] = { 0 }; - ShowString("%s\nExtracting .code, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_EXTRACTING_DOT_CODE); if (ExtractCodeFromCxiFile((filetype & GAME_TMD) ? cxi_path : file_path, NULL, extstr) == 0) { - ShowPrompt(false, "%s\n%s extracted to " OUTPUT_PATH, pathstr, extstr); - } else ShowPrompt(false, "%s\n.code extract failed", pathstr); + ShowPrompt(false, STR_PATH_EXT_EXTRACTED_TO_OUT, pathstr, extstr, OUTPUT_PATH); + } else ShowPrompt(false, "%s\n%s", pathstr, STR_DOT_CODE_EXTRACT_FAILED); } return 0; } @@ -2034,30 +2060,30 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan char* destdrv[2] = { NULL }; n_opt = 0; if (DriveType("1:")) { - optionstr[n_opt] = "Transfer to SysNAND"; + optionstr[n_opt] = STR_TRANSFER_TO_SYSNAND; destdrv[n_opt++] = "1:"; } if (DriveType("4:")) { - optionstr[n_opt] = "Transfer to EmuNAND"; + optionstr[n_opt] = STR_TRANSFER_TO_EMUNAND; destdrv[n_opt++] = "4:"; } if (n_opt) { user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, "%s", pathstr) : 1; if (user_select) { - ShowPrompt(false, "%s\nCTRNAND transfer %s", pathstr, - (TransferCtrNandImage(file_path, destdrv[user_select-1]) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (TransferCtrNandImage(file_path, destdrv[user_select-1]) == 0) ? + STR_CTRNAND_TRANSFER_SUCCESS: STR_CTRNAND_TRANSFER_FAILED); } - } else ShowPrompt(false, "%s\nNo valid destination found"); + } else ShowPrompt(false, "%s\n%s", pathstr, STR_NO_VALID_DESTINATION_FOUND); return 0; } else if (user_select == restore) { // -> restore SysNAND (A9LH preserving) - ShowPrompt(false, "%s\nNAND restore %s", pathstr, - (SafeRestoreNandDump(file_path) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (SafeRestoreNandDump(file_path) == 0) ? + STR_NAND_RESTORE_SUCCESS : STR_NAND_RESTORE_FAILED); return 0; } else if (user_select == ncsdfix) { // -> inject sighaxed NCSD - ShowPrompt(false, "%s\nRebuild NCSD %s", pathstr, - (FixNandHeader(file_path, !(filetype == HDR_NAND)) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (FixNandHeader(file_path, !(filetype == HDR_NAND)) == 0) ? + STR_REBUILD_NCSD_SUCCESS : STR_REBUILD_NCSD_FAILED); GetDirContents(current_dir, current_path); InitExtFS(); // this might have fixed something, so try this return 0; @@ -2065,9 +2091,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else if ((user_select == xorpad) || (user_select == xorpad_inplace)) { // -> build xorpads bool inplace = (user_select == xorpad_inplace); bool success = (BuildNcchInfoXorpads((inplace) ? current_path : OUTPUT_PATH, file_path) == 0); - ShowPrompt(false, "%s\nNCCHinfo padgen %s%s", pathstr, - (success) ? "success" : "failed", - (!success || inplace) ? "" : "\nOutput dir: " OUTPUT_PATH); + ShowPrompt(false, (success) ? STR_PATH_NCCHINFO_PADGEN_SUCCESS : STR_PATH_NCCHINFO_PADGEN_FAILED, + pathstr, (!success || inplace) ? '\0' : '\n', OUTPUT_PATH); GetDirContents(current_dir, current_path); for (; *cursor < current_dir->n_entries; (*cursor)++) { DirEntry* entry = &(current_dir->entry[*cursor]); @@ -2080,35 +2105,37 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == ebackup) { // -> update embedded backup - ShowString("%s\nUpdating embedded backup...", pathstr); + ShowString("%s\n%s", pathstr, STR_UPDATING_EMBEDDED_BACKUP); bool required = (CheckEmbeddedBackup(file_path) != 0); bool success = (required && (EmbedEssentialBackup(file_path) == 0)); - ShowPrompt(false, "%s\nBackup update: %s", pathstr, (!required) ? "not required" : - (success) ? "completed" : "failed!"); + ShowPrompt(false, "%s\n%s", pathstr, (!required) ? STR_BACKUP_UPDATE_NOT_REQUIRED : + (success) ? STR_BACKUP_UPDATE_COMPLETED : STR_BACKUP_UPDATE_FAILED); GetDirContents(current_dir, current_path); return 0; } else if (user_select == keyinit) { // -> initialise keys from aeskeydb.bin - if (ShowPrompt(true, "Warning: Keys are not verified.\nContinue on your own risk?")) - ShowPrompt(false, "%s\nAESkeydb init %s", pathstr, (InitKeyDb(file_path) == 0) ? "success" : "failed"); + if (ShowPrompt(true, "%s", STR_WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK)) + ShowPrompt(false, "%s\n%s", pathstr, (InitKeyDb(file_path) == 0) ? + STR_AESKEYDB_INIT_SUCCESS : STR_AESKEYDB_INIT_FAILED); return 0; } else if (user_select == keyinstall) { // -> install keys from aeskeydb.bin - ShowPrompt(false, "%s\nAESkeydb install %s", pathstr, (SafeInstallKeyDb(file_path) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (SafeInstallKeyDb(file_path) == 0) ? + STR_AESKEYDB_INSTALL_SUCCESS : STR_AESKEYDB_INSTALL_FAILED); return 0; } else if (user_select == install) { // -> install FIRM size_t firm_size = FileGetSize(file_path); u32 slots = 1; if (GetNandPartitionInfo(NULL, NP_TYPE_FIRM, NP_SUBTYPE_CTR, 1, NAND_SYSNAND) == 0) { - optionstr[0] = "Install to FIRM0"; - optionstr[1] = "Install to FIRM1"; - optionstr[2] = "Install to both"; + optionstr[0] = STR_INSTALL_TO_FIRM0; + optionstr[1] = STR_INSTALL_TO_FIRM1; + optionstr[2] = STR_INSTALL_TO_BOTH; // this only works up to FIRM1 - slots = ShowSelectPrompt(3, optionstr, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024); - } else slots = ShowPrompt(true, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024) ? 1 : 0; - if (slots) ShowPrompt(false, "%s (%dkB)\nInstall %s", pathstr, firm_size / 1024, - (SafeInstallFirm(file_path, slots) == 0) ? "success" : "failed!"); + slots = ShowSelectPrompt(3, optionstr, STR_PATH_N_KB_INSTALL_TO_SYSNAND, pathstr, firm_size / 1024); + } else slots = ShowPrompt(true, STR_PATH_N_KB_INSTALL_TO_SYSNAND, pathstr, firm_size / 1024) ? 1 : 0; + if (slots) ShowPrompt(false, (SafeInstallFirm(file_path, slots) == 0) ? + STR_PATH_N_KB_INSTALL_SUCCESS : STR_PATH_N_KB_INSTALL_FAILED, pathstr, firm_size / 1024); return 0; } else if (user_select == boot) { // -> boot FIRM @@ -2116,8 +2143,22 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == script) { // execute script - if (ShowPrompt(true, "%s\nWarning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", pathstr)) - ShowPrompt(false, "%s\nScript execute %s", pathstr, ExecuteGM9Script(file_path) ? "success" : "failure"); + if (ShowPrompt(true, "%s\n%s", pathstr, STR_WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS)) + ShowPrompt(false, "%s\n%s", pathstr, ExecuteGM9Script(file_path) ? STR_SCRIPT_EXECUTE_SUCCESS : STR_SCRIPT_EXECUTE_FAILURE); + GetDirContents(current_dir, current_path); + ClearScreenF(true, true, COLOR_STD_BG); + return 0; + } + else if (user_select == luascript) { // execute lua script +#ifndef NO_LUA + if (ShowPrompt(true, "%s\n%s", pathstr, STR_WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS)) + ShowPrompt(false, "%s\n%s", pathstr, ExecuteLuaScript(file_path) ? STR_SCRIPT_EXECUTE_SUCCESS : STR_SCRIPT_EXECUTE_FAILURE); +#else + // instead of outright removing the option, i think + // having it display an error would be useful + // so the user knows their issue exactly + ShowPrompt(false, "%s", STR_LUA_NOT_INCLUDED); +#endif GetDirContents(current_dir, current_path); ClearScreenF(true, true, COLOR_STD_BG); return 0; @@ -2131,23 +2172,32 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan free(font); return 0; } + else if (user_select == translation) { // set translation + u8* translation = (u8*) malloc(0x20000); // arbitrary, should be enough by far + if (!translation) return 1; + u32 translation_size = FileGetData(file_path, translation, 0x20000, 0); + if (translation_size) SetLanguage(translation, translation_size); + ClearScreenF(true, true, COLOR_STD_BG); + free(translation); + return 0; + } else if (user_select == view) { // view gfx if (FileGraphicsViewer(file_path) != 0) - ShowPrompt(false, "%s\nError: Cannot view file\n(Hint: maybe it's too big)", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_CANNOT_VIEW_FILE); return 0; } else if (user_select == agbexport) { // export GBA VC save if (DumpGbaVcSavegame(file_path) == 0) - ShowPrompt(false, "Savegame dumped to " OUTPUT_PATH "."); - else ShowPrompt(false, "Savegame dump failed!"); + ShowPrompt(false, STR_SAVEGAME_DUMPED_TO_OUT, OUTPUT_PATH); + else ShowPrompt(false, "%s", STR_SAVEGAME_DUMP_FAILED); return 0; } else if (user_select == agbimport) { // import GBA VC save if (clipboard->n_entries != 1) { - ShowPrompt(false, "GBA VC savegame has to\nbe in the clipboard."); + ShowPrompt(false, "%s", STR_GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD); } else { - ShowPrompt(false, "Savegame inject %s.", - (InjectGbaVcSavegame(file_path, clipboard->entry[0].path) == 0) ? "success" : "failed!"); + ShowPrompt(false, "%s", + (InjectGbaVcSavegame(file_path, clipboard->entry[0].path) == 0) ? STR_SAVEGAME_INJECT_SUCCESS : STR_SAVEGAME_INJECT_FAILED); clipboard->n_entries = 0; } return 0; @@ -2155,10 +2205,13 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else if (user_select == setup) { // set as default (font) if (filetype & FONT_RIFF) { if (SetAsSupportFile("font.frf", file_path)) - ShowPrompt(false, "%s\nFont will be active on next boot", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT); } else if (filetype & FONT_PBM) { if (SetAsSupportFile("font.pbm", file_path)) - ShowPrompt(false, "%s\nFont will be active on next boot", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT); + } else if (filetype & TRANSLATION) { + if (SetAsSupportFile("language.trf", file_path)) + ShowPrompt(false, "%s\n%s", pathstr, STR_LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT); } return 0; } @@ -2171,7 +2224,7 @@ u32 HomeMoreMenu(char* current_path) { if (GetNandPartitionInfo(&np_info, NP_TYPE_BONUS, NP_SUBTYPE_CTR, 0, NAND_SYSNAND) != 0) np_info.count = 0; const char* optionstr[8]; - const char* promptstr = "HOME more... menu.\nSelect action:"; + const char* promptstr = STR_HOME_MORE_MENU_SELECT_ACTION; u32 n_opt = 0; int sdformat = ++n_opt; int bonus = (np_info.count > 0x2000) ? (int) ++n_opt : -1; // 4MB minsize @@ -2184,18 +2237,18 @@ u32 HomeMoreMenu(char* current_path) { int sysinfo = ++n_opt; int readme = (FindVTarFileInfo(VRAM0_README_MD, NULL)) ? (int) ++n_opt : -1; - if (sdformat > 0) optionstr[sdformat - 1] = "SD format menu"; - if (bonus > 0) optionstr[bonus - 1] = "Bonus drive setup"; - if (multi > 0) optionstr[multi - 1] = "Switch EmuNAND"; - if (bsupport > 0) optionstr[bsupport - 1] = "Build support files"; - if (hsrestore > 0) optionstr[hsrestore - 1] = "Restore H&S"; - if (clock > 0) optionstr[clock - 1] = "Set RTC date&time"; - if (bright > 0) optionstr[bright - 1] = "Configure brightness"; - if (calib > 0) optionstr[calib - 1] = "Calibrate touchscreen"; - if (sysinfo > 0) optionstr[sysinfo - 1] = "System info"; - if (readme > 0) optionstr[readme - 1] = "Show ReadMe"; - - int user_select = ShowSelectPrompt(n_opt, optionstr, promptstr); + if (sdformat > 0) optionstr[sdformat - 1] = STR_SD_FORMAT_MENU; + if (bonus > 0) optionstr[bonus - 1] = STR_BONUS_DRIVE_MENU; + if (multi > 0) optionstr[multi - 1] = STR_SWITCH_EMUNAND; + if (bsupport > 0) optionstr[bsupport - 1] = STR_BUILD_SUPPORT_FILES; + if (hsrestore > 0) optionstr[hsrestore - 1] = STR_RESTORE_H_AND_S; + if (clock > 0) optionstr[clock - 1] = STR_SET_RTC_DATE_TIME; + if (bright > 0) optionstr[bright - 1] = STR_CONFGURE_BRIGHTNESS; + if (calib > 0) optionstr[calib - 1] = STR_CALIBRATE_TOUCHSCREEN; + if (sysinfo > 0) optionstr[sysinfo - 1] = STR_SYSTEM_INFO; + if (readme > 0) optionstr[readme - 1] = STR_SHOW_README; + + int user_select = ShowSelectPrompt(n_opt, optionstr, "%s", promptstr); if (user_select == sdformat) { // format SD card bool sd_state = CheckSDMountState(); char slabel[DRV_LABEL_LEN] = { '\0' }; @@ -2206,7 +2259,7 @@ u32 HomeMoreMenu(char* current_path) { DeinitSDCardFS(); if ((SdFormatMenu(slabel) == 0) || sd_state) {; while (!InitSDCardFS() && - ShowPrompt(true, "Initializing SD card failed! Retry?")); + ShowPrompt(true, "%s", STR_INITIALIZING_SD_FAILED_RETRY)); } ClearScreenF(true, true, COLOR_STD_BG); AutoEmuNandBase(true); @@ -2217,13 +2270,13 @@ u32 HomeMoreMenu(char* current_path) { else if (user_select == bonus) { // setup bonus drive if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & (DRV_BONUS|DRV_IMAGE))) clipboard->n_entries = 0; // remove bonus drive clipboard entries - if (!SetupBonusDrive()) ShowPrompt(false, "Setup failed!"); + if (!SetupBonusDrive()) ShowPrompt(false, "%s", STR_SETUP_FAILED); ClearScreenF(true, true, COLOR_STD_BG); GetDirContents(current_dir, current_path); return 0; } else if (user_select == multi) { // switch EmuNAND offset - while (ShowPrompt(true, "Current EmuNAND offset is %06X.\nSwitch to next offset?", GetEmuNandBase())) { + while (ShowPrompt(true, STR_CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT, GetEmuNandBase())) { if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_EMUNAND)) clipboard->n_entries = 0; // remove EmuNAND clipboard entries DismountDriveType(DRV_EMUNAND); @@ -2237,9 +2290,9 @@ u32 HomeMoreMenu(char* current_path) { bool tik_enc_sys = false; bool tik_enc_emu = false; if (BuildTitleKeyInfo(NULL, false, false) == 0) { - ShowString("Building " TIKDB_NAME_ENC " (SysNAND)..."); + ShowString(STR_BUILDING_X_SYSNAND, TIKDB_NAME_ENC); tik_enc_sys = (BuildTitleKeyInfo("1:/dbs/ticket.db", false, false) == 0); - ShowString("Building " TIKDB_NAME_ENC " (EmuNAND)..."); + ShowString(STR_BUILDING_X_EMUNAND, TIKDB_NAME_ENC); tik_enc_emu = (BuildTitleKeyInfo("4:/dbs/ticket.db", false, false) == 0); if (!tik_enc_sys || BuildTitleKeyInfo(NULL, false, true) != 0) tik_enc_sys = tik_enc_emu = false; @@ -2247,9 +2300,9 @@ u32 HomeMoreMenu(char* current_path) { bool tik_dec_sys = false; bool tik_dec_emu = false; if (BuildTitleKeyInfo(NULL, true, false) == 0) { - ShowString("Building " TIKDB_NAME_DEC " (SysNAND)..."); + ShowString(STR_BUILDING_X_SYSNAND, TIKDB_NAME_DEC); tik_dec_sys = (BuildTitleKeyInfo("1:/dbs/ticket.db", true, false) == 0); - ShowString("Building " TIKDB_NAME_DEC " (EmuNAND)..."); + ShowString(STR_BUILDING_X_EMUNAND, TIKDB_NAME_DEC); tik_dec_emu = (BuildTitleKeyInfo("4:/dbs/ticket.db", true, false) == 0); if (!tik_dec_sys || BuildTitleKeyInfo(NULL, true, true) != 0) tik_dec_sys = tik_dec_emu = false; @@ -2257,17 +2310,17 @@ u32 HomeMoreMenu(char* current_path) { bool seed_sys = false; bool seed_emu = false; if (BuildSeedInfo(NULL, false) == 0) { - ShowString("Building " SEEDINFO_NAME " (SysNAND)..."); + ShowString(STR_BUILDING_X_SYSNAND, SEEDINFO_NAME); seed_sys = (BuildSeedInfo("1:", false) == 0); - ShowString("Building " SEEDINFO_NAME " (EmuNAND)..."); + ShowString(STR_BUILDING_X_EMUNAND, SEEDINFO_NAME); seed_emu = (BuildSeedInfo("4:", false) == 0); if (!seed_sys || BuildSeedInfo(NULL, true) != 0) seed_sys = seed_emu = false; } - ShowPrompt(false, "Built in " OUTPUT_PATH ":\n \n%18.18-s %s\n%18.18-s %s\n%18.18-s %s", - TIKDB_NAME_ENC, tik_enc_sys ? tik_enc_emu ? "OK (Sys&Emu)" : "OK (Sys)" : "Failed", - TIKDB_NAME_DEC, tik_dec_sys ? tik_dec_emu ? "OK (Sys&Emu)" : "OK (Sys)" : "Failed", - SEEDINFO_NAME, seed_sys ? seed_emu ? "OK (Sys&Emu)" : "OK (Sys)" : "Failed"); + ShowPrompt(false, STR_BUILT_IN_OUT_STATUSES, OUTPUT_PATH, + TIKDB_NAME_ENC, tik_enc_sys ? tik_enc_emu ? STR_OK_SYS_EMU : STR_OK_SYS : STR_FAILED, + TIKDB_NAME_DEC, tik_dec_sys ? tik_dec_emu ? STR_OK_SYS_EMU : STR_OK_SYS : STR_FAILED, + SEEDINFO_NAME, seed_sys ? seed_emu ? STR_OK_SYS_EMU : STR_OK_SYS : STR_FAILED); GetDirContents(current_dir, current_path); return 0; } @@ -2275,9 +2328,9 @@ u32 HomeMoreMenu(char* current_path) { n_opt = 0; int sys = (CheckHealthAndSafetyInject("1:") == 0) ? (int) ++n_opt : -1; int emu = (CheckHealthAndSafetyInject("4:") == 0) ? (int) ++n_opt : -1; - if (sys > 0) optionstr[sys - 1] = "Restore H&S (SysNAND)"; - if (emu > 0) optionstr[emu - 1] = "Restore H&S (EmuNAND)"; - user_select = (n_opt > 1) ? ShowSelectPrompt(n_opt, optionstr, promptstr) : n_opt; + if (sys > 0) optionstr[sys - 1] = STR_RESTORE_H_AND_S_EMUNAND; + if (emu > 0) optionstr[emu - 1] = STR_RESTORE_H_AND_S_SYSNAND; + user_select = (n_opt > 1) ? ShowSelectPrompt(n_opt, optionstr, "%s", promptstr) : n_opt; if (user_select > 0) { InjectHealthAndSafety(NULL, (user_select == sys) ? "1:" : "4:"); GetDirContents(current_dir, current_path); @@ -2287,12 +2340,11 @@ u32 HomeMoreMenu(char* current_path) { else if (user_select == clock) { // RTC clock setter DsTime dstime; get_dstime(&dstime); - if (ShowRtcSetterPrompt(&dstime, "Set RTC date&time:")) { - char timestr[32]; + if (ShowRtcSetterPrompt(&dstime, "%s", STR_TITLE_SET_RTC_DATE_TIME)) { + char timestr[UTF_BUFFER_BYTESIZE(32)]; set_dstime(&dstime); GetTimeString(timestr, true, true); - ShowPrompt(false, "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", - timestr); + ShowPrompt(false, STR_NEW_RTC_DATE_TIME_IS_TIME, timestr); } return 0; } @@ -2306,8 +2358,8 @@ u32 HomeMoreMenu(char* current_path) { return 0; } else if (user_select == calib) { // touchscreen calibration - ShowPrompt(false, "Touchscreen calibration %s!", - (ShowTouchCalibrationDialog()) ? "success" : "failed"); + ShowPrompt(false, "%s", + (ShowTouchCalibrationDialog()) ? STR_TOUCHSCREEN_CALIBRATION_SUCCESS : STR_TOUCHSCREEN_CALIBRATION_FAILED); return 0; } else if (user_select == sysinfo) { // Myria's system info @@ -2321,7 +2373,7 @@ u32 HomeMoreMenu(char* current_path) { else if (user_select == readme) { // Display GodMode9 readme u64 README_md_size; char* README_md = FindVTarFileInfo(VRAM0_README_MD, &README_md_size); - MemToCViewer(README_md, README_md_size, "GodMode9 ReadMe Table of Contents"); + MemToCViewer(README_md, README_md_size, STR_GODMODE9_README_TOC); return 0; } else return 1; @@ -2406,28 +2458,72 @@ u32 GodMode(int entrypoint) { } } + // language handling + bool language_loaded = false; + if (CheckSupportFile("language.trf")) { + char* translation = (char*) malloc(0x20000); // arbitrary, should be enough by far + if (translation) { + u32 translation_size = LoadSupportFile("language.trf", translation, 0x20000); + if (translation_size) language_loaded = SetLanguage(translation, translation_size); + free(translation); + } + } + + if (!language_loaded) { + SetLanguage(NULL, 0); + + char loadpath[256]; + if (LanguageMenu(loadpath, "Select Language for GodMode9:")) { + size_t fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("language.trf", data, fsize); + SetLanguage(data, fsize); + free(data); + } + } + + // Try load font with the same name + char *ext = strstr(loadpath, ".trf"); + strcpy(ext, ".frf"); + fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("font.frf", data, fsize); + SetFont(data, fsize); + free(data); + } + } + } + } + // check for embedded essential backup if (((entrypoint == ENTRY_NANDBOOT) || (entrypoint == ENTRY_B9S)) && !PathExist("S:/essential.exefs") && CheckGenuineNandNcsd() && - ShowPrompt(true, "Essential files backup not found.\nCreate one now?")) { + ShowPrompt(true, "%s", STR_ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW)) { if (EmbedEssentialBackup("S:/nand.bin") == 0) { u32 flags = BUILD_PATH | SKIP_ALL; PathCopy(OUTPUT_PATH, "S:/essential.exefs", &flags); - ShowPrompt(false, "Backup embedded in SysNAND\nand written to " OUTPUT_PATH "."); + ShowPrompt(false, STR_BACKUP_EMBEDDED_WRITTEN_TO_OUT, OUTPUT_PATH); } } + // note: this is kinda duplicated in arm9/source/lua/gm9internalsys.c as well // check internal clock if (IS_UNLOCKED) { // we could actually do this on any entrypoint DsTime dstime; get_dstime(&dstime); if ((DSTIMEGET(&dstime, bcd_Y) < 18) && - ShowPrompt(true, "RTC date&time seems to be\nwrong. Set it now?") && - ShowRtcSetterPrompt(&dstime, "Set RTC date&time:")) { - char timestr[32]; + ShowPrompt(true, "%s", STR_RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW) && + ShowRtcSetterPrompt(&dstime, "%s", STR_TITLE_SET_RTC_DATE_TIME)) { + char timestr[UTF_BUFFER_BYTESIZE(32)]; set_dstime(&dstime); GetTimeString(timestr, true, true); - ShowPrompt(false, "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", timestr); + ShowPrompt(false, STR_NEW_RTC_DATE_TIME_IS_TIME, timestr); } } @@ -2445,17 +2541,17 @@ u32 GodMode(int entrypoint) { bootloader = false; while (HID_ReadState() & BUTTON_ANY); // wait until no buttons are pressed while (!bootloader && !godmode9) { - const char* optionstr[6] = { "Resume GodMode9", "Resume bootloader", "Select payload...", "Select script...", - "Poweroff system", "Reboot system" }; - int user_select = ShowSelectPrompt(6, optionstr, FLAVOR " bootloader menu.\nSelect action:"); + const char* optionstr[6] = { STR_RESUME_GODMODE9, STR_RESUME_BOOTLOADER, STR_SELECT_PAYLOAD, STR_SELECT_SCRIPT, + STR_POWEROFF_SYSTEM, STR_REBOOT_SYSTEM }; + int user_select = ShowSelectPrompt(6, optionstr, STR_FLAVOR_BOOTLOADER_SELECT_OPTION, FLAVOR); char loadpath[256]; if (user_select == 1) { godmode9 = true; } else if (user_select == 2) { bootloader = true; - } else if ((user_select == 3) && (FileSelectorSupport(loadpath, "Bootloader payloads menu.\nSelect payload:", PAYLOADS_DIR, "*.firm"))) { + } else if ((user_select == 3) && (FileSelectorSupport(loadpath, STR_BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD, PAYLOADS_DIR, "*.firm"))) { BootFirmHandler(loadpath, false, false); - } else if ((user_select == 4) && (FileSelectorSupport(loadpath, "Bootloader scripts menu.\nSelect script:", SCRIPTS_DIR, "*.gm9"))) { + } else if ((user_select == 4) && (FileSelectorSupport(loadpath, STR_BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT, SCRIPTS_DIR, "*.gm9"))) { ExecuteGM9Script(loadpath); } else if (user_select == 5) { exit_mode = GODMODE_EXIT_POWEROFF; @@ -2470,13 +2566,16 @@ u32 GodMode(int entrypoint) { if (bootloader) { const char* bootfirm_paths[] = { BOOTFIRM_PATHS }; if (IsBootableFirm(firm_in_mem, FIRM_MAX_SIZE)) { + DeinitExtFS(); + DeinitSDCardFS(); + PXI_DoCMD(PXICMD_LEGACY_BOOT, NULL, 0); PXI_Barrier(PXI_FIRMLAUNCH_BARRIER); BootFirm(firm_in_mem, "sdmc:/bootonce.firm"); } for (u32 i = 0; i < sizeof(bootfirm_paths) / sizeof(char*); i++) { BootFirmHandler(bootfirm_paths[i], false, (BOOTFIRM_TEMPS >> i) & 0x1); } - ShowPrompt(false, "No bootable FIRM found.\nNow resuming GodMode9..."); + ShowPrompt(false, "%s", STR_NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9); godmode9 = true; } @@ -2485,7 +2584,7 @@ u32 GodMode(int entrypoint) { clipboard = (DirStruct*) malloc(sizeof(DirStruct)); panedata = (PaneData*) malloc(N_PANES * sizeof(PaneData)); if (!current_dir || !clipboard || !panedata) { - ShowPrompt(false, "Out of memory."); // just to be safe + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); // just to be safe return exit_mode; } @@ -2499,7 +2598,7 @@ u32 GodMode(int entrypoint) { while (godmode9) { // this is the main loop // basic sanity checking if (!current_dir->n_entries) { // current dir is empty -> revert to root - ShowPrompt(false, "Invalid directory object"); + ShowPrompt(false, "%s", STR_INVALID_DIRECTORY_OBJECT); *current_path = '\0'; SetTitleManagerMode(false); DeinitExtFS(); // deinit and... @@ -2507,7 +2606,7 @@ u32 GodMode(int entrypoint) { GetDirContents(current_dir, current_path); cursor = 0; if (!current_dir->n_entries) { // should not happen, if it does fail gracefully - ShowPrompt(false, "Invalid root directory."); + ShowPrompt(false, "%s", STR_INVALID_ROOT_DIRECTORY); return exit_mode; } } @@ -2526,7 +2625,7 @@ u32 GodMode(int entrypoint) { // check write permissions if (~last_write_perm & GetWritePermissions()) { - if (ShowPrompt(true, "Write permissions were changed.\nRelock them?")) SetWritePermissions(last_write_perm, false); + if (ShowPrompt(true, "%s", STR_WRITE_PERMISSIONS_WERE_CHANGED_RELOCK)) SetWritePermissions(last_write_perm, false); last_write_perm = GetWritePermissions(); continue; } @@ -2539,8 +2638,10 @@ u32 GodMode(int entrypoint) { if ((pad_state & BUTTON_A) && (curr_entry->type != T_FILE) && (curr_entry->type != T_DOTDOT)) { // for dirs if (switched && !(DriveType(curr_entry->path) & (DRV_SEARCH|DRV_TITLEMAN))) { // exclude Y/Z const char* optionstr[8] = { NULL }; - char tpath[16] = { 0 }; - snprintf(tpath, 16, "%2.2s/dbs/title.db", curr_entry->path); + char tpath[16], copyToOut[UTF_BUFFER_BYTESIZE(64)], dumpToOut[UTF_BUFFER_BYTESIZE(64)]; + snprintf(tpath, sizeof(tpath), "%2.2s/dbs/title.db", curr_entry->path); + snprintf(copyToOut, sizeof(copyToOut), STR_COPY_TO_OUT, OUTPUT_PATH); + snprintf(dumpToOut, sizeof(dumpToOut), STR_DUMP_TO_OUT, OUTPUT_PATH); int n_opt = 0; int tman = (!(DriveType(curr_entry->path) & DRV_IMAGE) && ((strncmp(curr_entry->path, tpath, 16) == 0) || @@ -2551,43 +2652,41 @@ u32 GodMode(int entrypoint) { int dirnfo = ++n_opt; int stdcpy = (*current_path && strncmp(current_path, OUTPUT_PATH, 256) != 0) ? ++n_opt : -1; int rawdump = (!*current_path && (DriveType(curr_entry->path) & DRV_CART)) ? ++n_opt : -1; - if (tman > 0) optionstr[tman-1] = "Open title manager"; - if (srch_f > 0) optionstr[srch_f-1] = "Search for files..."; - if (fixcmac > 0) optionstr[fixcmac-1] = "Fix CMACs for drive"; - if (dirnfo > 0) optionstr[dirnfo-1] = (*current_path) ? "Show directory info" : "Show drive info"; - if (stdcpy > 0) optionstr[stdcpy-1] = "Copy to " OUTPUT_PATH; - if (rawdump > 0) optionstr[rawdump-1] = "Dump to " OUTPUT_PATH; + if (tman > 0) optionstr[tman-1] = STR_OPEN_TITLE_MANAGER; + if (srch_f > 0) optionstr[srch_f-1] = STR_SEARCH_FOR_FILES; + if (fixcmac > 0) optionstr[fixcmac-1] = STR_FIX_CMACS_FOR_DRIVE; + if (dirnfo > 0) optionstr[dirnfo-1] = (*current_path) ? STR_SHOW_DIRECTORY_INFO : STR_SHOW_DRIVE_INFO; + if (stdcpy > 0) optionstr[stdcpy-1] = copyToOut; + if (rawdump > 0) optionstr[rawdump-1] = dumpToOut; char namestr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(namestr, (*current_path) ? curr_entry->path : curr_entry->name, 32, 8); int user_select = ShowSelectPrompt(n_opt, optionstr, "%s", namestr); if (user_select == tman) { if (InitImgFS(tpath)) { SetTitleManagerMode(true); - snprintf(current_path, 256, "Y:"); + snprintf(current_path, sizeof(current_path), "Y:"); GetDirContents(current_dir, current_path); cursor = 1; scroll = 0; - } else ShowPrompt(false, "Failed setting up title manager!"); + } else ShowPrompt(false, "%s", STR_FAILED_SETTING_UP_TITLE_MANAGER); } else if (user_select == srch_f) { char searchstr[256]; - snprintf(searchstr, 256, "*"); + snprintf(searchstr, sizeof(searchstr), "*"); TruncateString(namestr, curr_entry->name, 20, 8); - if (ShowKeyboardOrPrompt(searchstr, 256, "Search %s?\nEnter search below.", namestr)) { + if (ShowKeyboardOrPrompt(searchstr, 256, STR_SEARCH_FILE_ENTER_SEARCH_BELOW, namestr)) { SetFSSearch(searchstr, curr_entry->path); - snprintf(current_path, 256, "Z:"); + snprintf(current_path, sizeof(current_path), "Z:"); GetDirContents(current_dir, current_path); - if (current_dir->n_entries) ShowPrompt(false, "Found %lu results.", current_dir->n_entries - 1); + if (current_dir->n_entries) ShowPrompt(false, STR_FOUND_N_RESULTS, current_dir->n_entries - 1); cursor = 1; scroll = 0; } } else if (user_select == fixcmac) { RecursiveFixFileCmac(curr_entry->path); - ShowPrompt(false, "Fix CMACs for drive finished."); + ShowPrompt(false, "%s", STR_FIX_CMACS_FOR_DRIVE_FINISHED); } else if (user_select == dirnfo) { if (DirFileAttrMenu(curr_entry->path, curr_entry->name)) { - ShowPrompt(false, "Failed to analyze %s\n", - (current_path[0] == '\0') ? "drive" : "dir" - ); + ShowPrompt(false, "%s",(current_path[0] == '\0') ? STR_FAILED_TO_ANALYZE_DRIVE : STR_FAILED_TO_ANALYZE_DIR); } } else if (user_select == stdcpy) { StandardCopy(&cursor, &scroll); @@ -2597,7 +2696,7 @@ u32 GodMode(int entrypoint) { } else { // one level up u32 user_select = 1; if (curr_drvtype & DRV_SEARCH) { // special menu for search drive - static const char* optionstr[2] = { "Open this folder", "Open containing folder" }; + const char* optionstr[2] = { STR_OPEN_THIS_FOLDER, STR_OPEN_CONTAINING_FOLDER }; char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, curr_entry->path, 32, 8); user_select = ShowSelectPrompt(2, optionstr, "%s", pathstr); @@ -2644,7 +2743,7 @@ u32 GodMode(int entrypoint) { } else if (switched && (pad_state & BUTTON_B)) { // unmount SD card if (!CheckSDMountState()) { while (!InitSDCardFS() && - ShowPrompt(true, "Initialising SD card failed! Retry?")); + ShowPrompt(true, "%s", STR_INITIALIZING_SD_FAILED_RETRY)); } else { DeinitSDCardFS(); if (clipboard->n_entries && !PathExist(clipboard->entry[0].path)) @@ -2711,7 +2810,7 @@ u32 GodMode(int entrypoint) { } } else if (!switched) { // standard unswitched command set if ((curr_drvtype & DRV_VIRTUAL) && (pad_state & BUTTON_X) && (*current_path != 'T')) { - ShowPrompt(false, "Not allowed in virtual path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_VIRTUAL_PATH); } else if (pad_state & BUTTON_X) { // delete a file u32 n_marked = 0; if (curr_entry->marked) { @@ -2719,22 +2818,22 @@ u32 GodMode(int entrypoint) { if (current_dir->entry[c].marked) n_marked++; } if (n_marked) { - if (ShowPrompt(true, "Delete %u path(s)?", n_marked)) { + if (ShowPrompt(true, STR_DELETE_N_PATHS, n_marked)) { u32 n_errors = 0; - ShowString("Deleting files, please wait..."); + ShowString("%s", STR_DELETING_FILES_PLEASE_WAIT); for (u32 c = 0; c < current_dir->n_entries; c++) if (current_dir->entry[c].marked && !PathDelete(current_dir->entry[c].path)) n_errors++; ClearScreenF(true, false, COLOR_STD_BG); - if (n_errors) ShowPrompt(false, "Failed deleting %u/%u path(s)", n_errors, n_marked); + if (n_errors) ShowPrompt(false, STR_FAILED_DELETING_N_OF_N_PATHS, n_errors, n_marked); } } else if (curr_entry->type != T_DOTDOT) { char namestr[UTF_BUFFER_BYTESIZE(28)]; TruncateString(namestr, curr_entry->name, 28, 12); - if (ShowPrompt(true, "Delete \"%s\"?", namestr)) { - ShowString("Deleting files, please wait..."); + if (ShowPrompt(true, STR_DELETE_FILE, namestr)) { + ShowString("%s", STR_DELETING_FILES_PLEASE_WAIT); if (!PathDelete(curr_entry->path)) - ShowPrompt(false, "Failed deleting:\n%s", namestr); + ShowPrompt(false, STR_FAILED_DELETING_PATH, namestr); ClearScreenF(true, false, COLOR_STD_BG); } } @@ -2754,23 +2853,23 @@ u32 GodMode(int entrypoint) { if (clipboard->n_entries) last_clipboard_size = clipboard->n_entries; } else if ((curr_drvtype & DRV_SEARCH) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in search drive"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_SEARCH_DRIVE); } else if ((curr_drvtype & DRV_GAME) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in virtual game path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_VIRTUAL_GAME_PATH); } else if ((curr_drvtype & DRV_XORPAD) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in XORpad drive"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_XORPAD_DRIVE); } else if ((curr_drvtype & DRV_CART) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in gamecart drive"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_GAMECART_DRIVE); } else if (pad_state & BUTTON_Y) { // paste files - static const char* optionstr[2] = { "Copy path(s)", "Move path(s)" }; - char promptstr[64]; + const char* optionstr[2] = { STR_COPY_PATHS, STR_MOVE_PATHS }; + char promptstr[UTF_BUFFER_BYTESIZE(64)]; u32 flags = 0; u32 user_select; if (clipboard->n_entries == 1) { char namestr[UTF_BUFFER_BYTESIZE(20)]; TruncateString(namestr, clipboard->entry[0].name, 20, 12); - snprintf(promptstr, 64, "Paste \"%s\" here?", namestr); - } else snprintf(promptstr, 64, "Paste %lu paths here?", clipboard->n_entries); + snprintf(promptstr, sizeof(promptstr), STR_PASTE_FILE_HERE, namestr); + } else snprintf(promptstr, sizeof(promptstr), STR_PASTE_N_PATHS_HERE, clipboard->n_entries); user_select = ((DriveType(clipboard->entry[0].path) & curr_drvtype & DRV_STDFAT)) ? ShowSelectPrompt(2, optionstr, "%s", promptstr) : (ShowPrompt(true, "%s", promptstr) ? 1 : 0); if (user_select) { @@ -2781,12 +2880,12 @@ u32 GodMode(int entrypoint) { if (c < clipboard->n_entries - 1) flags |= ASK_ALL; if ((user_select == 1) && !PathCopy(current_path, clipboard->entry[c].path, &flags)) { if (c + 1 < clipboard->n_entries) { - if (!ShowPrompt(true, "Failed copying path:\n%s\nProcess remaining?", namestr)) break; - } else ShowPrompt(false, "Failed copying path:\n%s", namestr); + if (!ShowPrompt(true, STR_FAILED_COPYING_PATH_PROCESS_REMAINING, namestr)) break; + } else ShowPrompt(false, STR_FAILED_COPYING_PATH, namestr); } else if ((user_select == 2) && !PathMove(current_path, clipboard->entry[c].path, &flags)) { if (c + 1 < clipboard->n_entries) { - if (!ShowPrompt(true, "Failed moving path:\n%s\nProcess remaining?", namestr)) break; - } else ShowPrompt(false, "Failed moving path:\n%s", namestr); + if (!ShowPrompt(true, STR_FAILED_MOVING_PATH_PROCESS_REMAINING, namestr)) break; + } else ShowPrompt(false, STR_FAILED_MOVING_PATH, namestr); } } clipboard->n_entries = 0; @@ -2796,17 +2895,17 @@ u32 GodMode(int entrypoint) { } } else { // switched command set if ((curr_drvtype & DRV_VIRTUAL) && (pad_state & (BUTTON_X|BUTTON_Y))) { - ShowPrompt(false, "Not allowed in virtual path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_VIRTUAL_PATH); } else if ((curr_drvtype & DRV_ALIAS) && (pad_state & (BUTTON_X))) { - ShowPrompt(false, "Not allowed in alias path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_ALIAS_PATH); } else if ((pad_state & BUTTON_X) && (curr_entry->type != T_DOTDOT)) { // rename a file char newname[256]; char namestr[UTF_BUFFER_BYTESIZE(20)]; TruncateString(namestr, curr_entry->name, 20, 12); - snprintf(newname, 255, "%s", curr_entry->name); - if (ShowKeyboardOrPrompt(newname, 256, "Rename %s?\nEnter new name below.", namestr)) { + snprintf(newname, sizeof(newname), "%s", curr_entry->name); + if (ShowKeyboardOrPrompt(newname, 256, STR_RENAME_FILE_ENTER_NEW_NAME_BELOW, namestr)) { if (!PathRename(curr_entry->path, newname)) - ShowPrompt(false, "Failed renaming path:\n%s", namestr); + ShowPrompt(false, STR_FAILED_RENAMING_PATH, namestr); else { GetDirContents(current_dir, current_path); for (cursor = (current_dir->n_entries) ? current_dir->n_entries - 1 : 0; @@ -2814,20 +2913,19 @@ u32 GodMode(int entrypoint) { } } } else if (pad_state & BUTTON_Y) { // create an entry - static const char* optionstr[] = { "Create a folder", "Create a dummy file" }; - u32 type = ShowSelectPrompt(2, optionstr, "Create a new entry here?\nSelect type."); + const char* optionstr[] = { STR_CREATE_A_FOLDER, STR_CREATE_A_DUMMY_FILE }; + u32 type = ShowSelectPrompt(2, optionstr, "%s", STR_CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE); if (type) { - const char* typestr = (type == 1) ? "folder" : (type == 2) ? "file" : NULL; char ename[256]; u64 fsize = 0; - snprintf(ename, 255, (type == 1) ? "newdir" : "dummy.bin"); - if ((ShowKeyboardOrPrompt(ename, 256, "Create a new %s here?\nEnter name below.", typestr)) && - ((type != 2) || ((fsize = ShowNumberPrompt(0, "Create a new %s here?\nEnter file size below.", typestr)) != (u64) -1))) { + snprintf(ename, sizeof(ename), (type == 1) ? "newdir" : "dummy.bin"); + if ((ShowKeyboardOrPrompt(ename, 256, "%s", (type == 1) ? STR_CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW : STR_CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW)) && + ((type != 2) || ((fsize = ShowNumberPrompt(0, "%s", STR_CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW)) != (u64) -1))) { if (((type == 1) && !DirCreate(current_path, ename)) || ((type == 2) && !FileCreateDummy(current_path, ename, fsize))) { char namestr[UTF_BUFFER_BYTESIZE(36)]; TruncateString(namestr, ename, 36, 12); - ShowPrompt(false, "Failed creating %s:\n%s", typestr, namestr); + ShowPrompt(false, (type == 1) ? STR_FAILED_CREATING_FOLDER_PATH : STR_FAILED_CREATING_FILE_PATH, namestr); } else { GetDirContents(current_dir, current_path); for (cursor = (current_dir->n_entries) ? current_dir->n_entries - 1 : 0; @@ -2842,35 +2940,43 @@ u32 GodMode(int entrypoint) { exit_mode = (switched || (pad_state & BUTTON_LEFT)) ? GODMODE_EXIT_POWEROFF : GODMODE_EXIT_REBOOT; break; } else if (pad_state & (BUTTON_HOME|BUTTON_POWER)) { // Home menu - const char* optionstr[8]; - const char* buttonstr = (pad_state & BUTTON_HOME) ? "HOME" : "POWER"; + const char* optionstr[9]; + bool buttonhome = (pad_state & BUTTON_HOME); u32 n_opt = 0; int poweroff = ++n_opt; int reboot = ++n_opt; + int language = ++n_opt; int brick = (HID_ReadState() & BUTTON_R1) ? ++n_opt : 0; int titleman = ++n_opt; int scripts = ++n_opt; +#ifndef NO_LUA + int luascripts = ++n_opt; +#endif int payloads = ++n_opt; int more = ++n_opt; - if (poweroff > 0) optionstr[poweroff - 1] = "Poweroff system"; - if (reboot > 0) optionstr[reboot - 1] = "Reboot system"; - if (titleman > 0) optionstr[titleman - 1] = "Title manager"; - if (brick > 0) optionstr[brick - 1] = "Brick my 3DS"; - if (scripts > 0) optionstr[scripts - 1] = "Scripts..."; - if (payloads > 0) optionstr[payloads - 1] = "Payloads..."; - if (more > 0) optionstr[more - 1] = "More..."; + if (poweroff > 0) optionstr[poweroff - 1] = STR_POWEROFF_SYSTEM; + if (reboot > 0) optionstr[reboot - 1] = STR_REBOOT_SYSTEM; + if (titleman > 0) optionstr[titleman - 1] = STR_TITLE_MANAGER; + if (language > 0) optionstr[language - 1] = STR_LANGUAGE; + if (brick > 0) optionstr[brick - 1] = STR_BRICK_MY_3DS; + if (scripts > 0) optionstr[scripts - 1] = STR_SCRIPTS; +#ifndef NO_LUA + if (luascripts > 0) optionstr[luascripts - 1] = STR_LUA_SCRIPTS; +#endif + if (payloads > 0) optionstr[payloads - 1] = STR_PAYLOADS; + if (more > 0) optionstr[more - 1] = STR_MORE; int user_select = 0; - while ((user_select = ShowSelectPrompt(n_opt, optionstr, "%s button pressed.\nSelect action:", buttonstr)) && + while ((user_select = ShowSelectPrompt(n_opt, optionstr, "%s", buttonhome ? STR_HOME_BUTTON_PRESSED_SELECT_ACTION : STR_POWER_BUTTON_PRESSED_SELECT_ACTION)) && (user_select != poweroff) && (user_select != reboot)) { char loadpath[256]; if ((user_select == more) && (HomeMoreMenu(current_path) == 0)) break; // more... menu else if (user_select == titleman) { - static const char* tmoptionstr[4] = { - "[A:] SD CARD", - "[1:] NAND / TWL", - "[B:] SD CARD", - "[4:] NAND / TWL" + const char* tmoptionstr[4] = { + STR_A_DRIVE_SD_CARD, + STR_1_DRIVE_NAND_TWL, + STR_B_DRIVE_SD_CARD, + STR_4_DRIVE_NAND_TWL }; static const char* tmpaths[4] = { "A:/dbs/title.db", @@ -2880,31 +2986,74 @@ u32 GodMode(int entrypoint) { }; u32 tmnum = 2; if (!CheckSDMountState() || (tmnum = ShowSelectPrompt( - (CheckVirtualDrive("E:")) ? 4 : 2, tmoptionstr, - "Title manager menu.\nSelect titles source:", buttonstr))) { + (CheckVirtualDrive("E:")) ? 4 : 2, tmoptionstr, "%s", + STR_TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE))) { const char* tpath = tmpaths[tmnum-1]; if (InitImgFS(tpath)) { SetTitleManagerMode(true); - snprintf(current_path, 256, "Y:"); + snprintf(current_path, sizeof(current_path), "Y:"); GetDirContents(current_dir, current_path); ClearScreenF(true, true, COLOR_STD_BG); cursor = 1; scroll = 0; break; - } else ShowPrompt(false, "Failed setting up title manager!"); + } else ShowPrompt(false, "%s", STR_FAILED_SETTING_UP_TITLE_MANAGER); + } + } else if (user_select == language) { + if (!CheckSupportDir(LANGUAGES_DIR)) { + ShowPrompt(false, STR_LANGUAGES_DIRECTORY_NOT_FOUND, LANGUAGES_DIR); + } else if (LanguageMenu(loadpath, STR_HOME_LANGUAGE_MENU_SELECT_LANGUAGE)) { + size_t fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("language.trf", data, fsize); + SetLanguage(data, fsize); + free(data); + } + + // Try load font with the same name + char *ext = strstr(loadpath, ".trf"); + strcpy(ext, ".frf"); + fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("font.frf", data, fsize); + SetFont(data, fsize); + free(data); + } + } + } + GetDirContents(current_dir, current_path); + ClearScreenF(true, true, COLOR_STD_BG); + break; } } else if (user_select == scripts) { if (!CheckSupportDir(SCRIPTS_DIR)) { - ShowPrompt(false, "Scripts directory not found.\n(default path: 0:/gm9/" SCRIPTS_DIR ")"); - } else if (FileSelectorSupport(loadpath, "HOME scripts... menu.\nSelect script:", SCRIPTS_DIR, "*.gm9")) { + ShowPrompt(false, STR_SCRIPTS_DIRECTORY_NOT_FOUND, SCRIPTS_DIR); + } else if (FileSelectorSupport(loadpath, STR_HOME_SCRIPTS_MENU_SELECT_SCRIPT, SCRIPTS_DIR, "*.gm9")) { ExecuteGM9Script(loadpath); GetDirContents(current_dir, current_path); ClearScreenF(true, true, COLOR_STD_BG); break; } +#ifndef NO_LUA + } else if (user_select == luascripts) { + if (!CheckSupportDir(LUASCRIPTS_DIR)) { + ShowPrompt(false, STR_LUA_SCRIPTS_DIRECTORY_NOT_FOUND, LUASCRIPTS_DIR); + } else if (FileSelectorSupport(loadpath, STR_HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT, LUASCRIPTS_DIR, "*.lua")) { + ExecuteLuaScript(loadpath); + GetDirContents(current_dir, current_path); + ClearScreenF(true, true, COLOR_STD_BG); + break; + } +#endif } else if (user_select == payloads) { - if (!CheckSupportDir(PAYLOADS_DIR)) ShowPrompt(false, "Payloads directory not found.\n(default path: 0:/gm9/" PAYLOADS_DIR ")"); - else if (FileSelectorSupport(loadpath, "HOME payloads... menu.\nSelect payload:", PAYLOADS_DIR, "*.firm")) + if (!CheckSupportDir(PAYLOADS_DIR)) ShowPrompt(false, STR_PAYLOADS_DIRECTORY_NOT_FOUND, PAYLOADS_DIR); + else if (FileSelectorSupport(loadpath, STR_HOME_PAYLOADS_MENU_SELECT_PAYLOAD, PAYLOADS_DIR, "*.firm")) BootFirmHandler(loadpath, false, false); } else if (user_select == brick) { Paint9(); // hiding a secret here @@ -2923,17 +3072,17 @@ u32 GodMode(int entrypoint) { } else if (pad_state & (CART_INSERT|CART_EJECT)) { if (!InitVCartDrive() && (pad_state & CART_INSERT) && (curr_drvtype & DRV_CART)) // reinit virtual cart drive - ShowPrompt(false, "Cart init failed!"); + ShowPrompt(false, "%s", STR_CART_INIT_FAILED); if (!(*current_path) || (curr_drvtype & DRV_CART)) GetDirContents(current_dir, current_path); // refresh dir contents } else if (pad_state & SD_INSERT) { - while (!InitSDCardFS() && ShowPrompt(true, "Initialising SD card failed! Retry?")); + while (!InitSDCardFS() && ShowPrompt(true, "%s", STR_INITIALIZING_SD_FAILED_RETRY)); ClearScreenF(true, true, COLOR_STD_BG); AutoEmuNandBase(true); InitExtFS(); GetDirContents(current_dir, current_path); } else if ((pad_state & SD_EJECT) && CheckSDMountState()) { - ShowPrompt(false, "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card."); + ShowPrompt(false, "%s", STR_UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT); DeinitExtFS(); DeinitSDCardFS(); InitExtFS(); @@ -2959,6 +3108,7 @@ u32 GodMode(int entrypoint) { u32 ScriptRunner(int entrypoint) { // init font and show splash if (!SetFont(NULL, 0)) return GODMODE_EXIT_POWEROFF; + SetLanguage(NULL, 0); SplashInit("scriptrunner mode"); u64 timer = timer_start(); @@ -2984,11 +3134,22 @@ u32 ScriptRunner(int entrypoint) { if (PathExist("V:/" VRAM0_AUTORUN_GM9)) { ClearScreenF(true, true, COLOR_STD_BG); // clear splash ExecuteGM9Script("V:/" VRAM0_AUTORUN_GM9); + } else if (PathExist("V:/" VRAM0_AUTORUN_LUA)) { + ClearScreenF(true, true, COLOR_STD_BG); // clear splash + ExecuteLuaScript("V:/" VRAM0_AUTORUN_LUA); } else if (PathExist("V:/" VRAM0_SCRIPTS)) { char loadpath[256]; - if (FileSelector(loadpath, FLAVOR " scripts menu.\nSelect script:", "V:/" VRAM0_SCRIPTS, "*.gm9", HIDE_EXT, false)) + char title[256]; + snprintf(title, sizeof(title), STR_FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT, FLAVOR); + if (FileSelector(loadpath, title, "V:/" VRAM0_SCRIPTS, "*.gm9", HIDE_EXT, false)) ExecuteGM9Script(loadpath); - } else ShowPrompt(false, "Compiled as script autorunner\nbut no script provided.\n \nDerp!"); + } else if (PathExist("V:/" VRAM0_LUASCRIPTS)) { + char loadpath[256]; + char title[256]; + snprintf(title, sizeof(title), STR_FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT, FLAVOR); + if (FileSelector(loadpath, title, "V:/" VRAM0_LUASCRIPTS, "*.lua", HIDE_EXT, false)) + ExecuteLuaScript(loadpath); + } else ShowPrompt(false, STR_COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP); // deinit DeinitExtFS(); diff --git a/arm9/source/language.c b/arm9/source/language.c new file mode 100644 index 000000000..d8cb65da8 --- /dev/null +++ b/arm9/source/language.c @@ -0,0 +1,188 @@ +#include "language.h" +#include "fsdrive.h" +#include "fsutil.h" +#include "support.h" +#include "ui.h" + +#define STRING(what, def) const char* STR_##what = NULL; +#include "language.inl" +#undef STRING + +static const char** translation_ptrs[] = { + #define STRING(what, def) &STR_##what, + #include "language.inl" + #undef STRING +}; + +static const char* translation_fallbacks[] = { + #define STRING(what, def) def, + #include "language.inl" + #undef STRING +}; + +static char* translation_data = NULL; + +typedef struct { + char name[32]; + char path[256]; +} Language; + +typedef struct { + char chunk_id[4]; // NOT null terminated + u32 size; +} RiffChunkHeader; + +typedef struct { + u32 version; + u32 count; + char languageName[32]; +} LanguageMeta; +STATIC_ASSERT(sizeof(LanguageMeta) == 40); + +bool SetLanguage(const void* translation, u32 translation_size) { + u32 str_count; + const void* ptr = translation; + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; + + // Free old translation data + if (translation_data) { + free(translation_data); + translation_data = NULL; + } + + if ((ptr = GetLanguage(translation, translation_size, NULL, &str_count, NULL))) { + // load total size + riff_header = translation; + + while ((u32)(ptr - translation) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = ptr; + + if (memcmp(chunk_header->chunk_id, "SDAT", 4) == 0) { // string data + if (chunk_header->size > 0) { + translation_data = malloc(chunk_header->size); + if (!translation_data) goto fallback; + + memcpy(translation_data, ptr + sizeof(RiffChunkHeader), chunk_header->size); + } + } else if (memcmp(chunk_header->chunk_id, "SMAP", 4) == 0) { // string map + // string data must come before the map + if (!translation_data && str_count > 0) goto fallback; + + u16* string_map = (u16*)(ptr + sizeof(RiffChunkHeader)); + + // Load all the strings + for (u32 i = 0; i < countof(translation_ptrs); i++) { + if (i < str_count) { + *translation_ptrs[i] = (translation_data + string_map[i]); + } else { + *translation_ptrs[i] = translation_fallbacks[i]; + } + } + } + + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } + + return true; + } + +fallback: + if (translation_data) { + free(translation_data); + translation_data = NULL; + } + + for (u32 i = 0; i < countof(translation_ptrs); i++) { + *translation_ptrs[i] = translation_fallbacks[i]; + } + + return false; +} + +const void* GetLanguage(const void* riff, const u32 riff_size, u32* version, u32* count, char* language_name) { + const void* ptr = riff; + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; + + // check header magic and load size + if (!ptr) return NULL; + riff_header = ptr; + if (memcmp(riff_header->chunk_id, "RIFF", 4) != 0) return NULL; + + // ensure enough space is allocated + if (riff_header->size > riff_size) return NULL; + + ptr += sizeof(RiffChunkHeader); + + while ((u32)(ptr - riff) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = ptr; + + // check for and load META section + if (memcmp(chunk_header->chunk_id, "META", 4) == 0) { + if (chunk_header->size != sizeof(LanguageMeta)) return NULL; + + const LanguageMeta *meta = ptr + sizeof(RiffChunkHeader); + if (meta->version != TRANSLATION_VER || meta->count > countof(translation_ptrs)) return NULL; + + // all good + if (version) *version = meta->version; + if (count) *count = meta->count; + if (language_name) strcpy(language_name, meta->languageName); + return ptr; + } + + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } + + return NULL; +} + +int compLanguage(const void* e1, const void* e2) { + const Language* entry2 = (const Language*) e2; + const Language* entry1 = (const Language*) e1; + return strncasecmp(entry1->name, entry2->name, 32); +} + +bool LanguageMenu(char* result, const char* title) { + DirStruct* langDir = (DirStruct*)malloc(sizeof(DirStruct)); + if (!langDir) return false; + + char path[256]; + if (!GetSupportDir(path, LANGUAGES_DIR)) return false; + GetDirContents(langDir, path); + + char* header = (char*)malloc(0x2C0); + Language* langs = (Language*)malloc(langDir->n_entries * sizeof(Language)); + int langCount = 0; + + // Find all valid files and get their language names + for (u32 i = 0; i < langDir->n_entries; i++) { + if (langDir->entry[i].type == T_FILE) { + size_t fsize = FileGetSize(langDir->entry[i].path); + FileGetData(langDir->entry[i].path, header, 0x2C0, 0); + if (GetLanguage(header, fsize, NULL, NULL, langs[langCount].name)) { + memcpy(langs[langCount].path, langDir->entry[i].path, 256); + langCount++; + } + } + } + + free(langDir); + free(header); + + qsort(langs, langCount, sizeof(Language), compLanguage); + + // Make an array of just the names for the select promt + const char* langNames[langCount]; + for (int i = 0; i < langCount; i++) { + langNames[i] = langs[i].name; + } + + u32 selected = ShowSelectPrompt(langCount, langNames, "%s", title); + if (selected > 0 && result) { + memcpy(result, langs[selected - 1].path, 256); + } + + return selected > 0; +} diff --git a/arm9/source/language.h b/arm9/source/language.h new file mode 100644 index 000000000..d2972ee92 --- /dev/null +++ b/arm9/source/language.h @@ -0,0 +1,12 @@ +#pragma once + +#include "common.h" + +#define STRING(what, def) extern const char* STR_##what; +#include "language.inl" +#undef STRING + +bool SetLanguage(const void* translation, u32 translation_size); +const void* GetLanguage(const void* riff, u32 riff_size, u32* version, u32* count, char* language_name); + +bool LanguageMenu(char* result, const char* title); diff --git a/arm9/source/lua/README.md b/arm9/source/lua/README.md new file mode 100644 index 000000000..91d99eece --- /dev/null +++ b/arm9/source/lua/README.md @@ -0,0 +1,14 @@ +This is Lua 5.4.7 with a few modifications: +* Patches made to silence warnings: https://github.com/ihaveamac/GodMode9/commit/9905b939b26aae3422c906c7858d8852764fa279 +* lua.c, luac.c, lua.hpp removed (not useful in GodMode9) +* liolib.c, loslib.c removed (replaced with custom implementations) + +## License of Lua 5.4.7 + +Copyright © 1994–2024 Lua.org, PUC-Rio. + +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/arm9/source/lua/gm9internalfs.c b/arm9/source/lua/gm9internalfs.c new file mode 100644 index 000000000..a9a56f276 --- /dev/null +++ b/arm9/source/lua/gm9internalfs.c @@ -0,0 +1,800 @@ +#ifndef NO_LUA +#include "gm9internalfs.h" +#include "fs.h" +#include "ui.h" +#include "utils.h" +#include "sha.h" +#include "nand.h" +#include "language.h" +#include "hid.h" +#include "game.h" +#include "gamecart.h" + +#define _MAX_FOR_DEPTH 16 + +static u8 no_data_hash_256[32] = { SHA256_EMPTY_HASH }; +static u8 no_data_hash_1[32] = { SHA1_EMPTY_HASH }; + +static bool PathIsDirectory(const char* path) { + FRESULT res; + FILINFO fno; + res = fvx_stat(path, &fno); + if (res != FR_OK) return false; + return fno.fattrib & AM_DIR; +} + +static void CreateStatTable(lua_State* L, FILINFO* fno) { + lua_createtable(L, 0, 4); // create nested table + lua_pushstring(L, fno->fname); + lua_setfield(L, -2, "name"); + lua_pushstring(L, (fno->fattrib & AM_DIR) ? "dir" : "file"); + lua_setfield(L, -2, "type"); + lua_pushinteger(L, fno->fsize); + lua_setfield(L, -2, "size"); + lua_pushboolean(L, fno->fattrib & AM_RDO); + lua_setfield(L, -2, "read_only"); + // ... and leave this table on the stack for the caller to deal with +} + +static int internalfs_move(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 2, "_fs.move"); + const char* path_src = luaL_checkstring(L, 1); + const char* path_dst = luaL_checkstring(L, 2); + FILINFO fno; + + CheckWritePermissionsLuaError(L, path_src); + CheckWritePermissionsLuaError(L, path_dst); + + u32 flags = BUILD_PATH; + if (extra) { + flags = GetFlagsFromTable(L, 3, flags, NO_CANCEL | SILENT | OVERWRITE_ALL | SKIP_ALL); + } + + if (!(flags & OVERWRITE_ALL) && (fvx_stat(path_dst, &fno) == FR_OK)) { + return luaL_error(L, "destination already exists on %s -> %s and {overwrite=true} was not used", path_src, path_dst); + } + + if (!(PathMoveCopy(path_dst, path_src, &flags, true))) { + return luaL_error(L, "PathMoveCopy failed on %s -> %s", path_src, path_dst); + } + return 0; +} + +static int internalfs_remove(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 1, "_fs.remove"); + const char* path = luaL_checkstring(L, 1); + + CheckWritePermissionsLuaError(L, path); + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 2, flags, RECURSIVE); + } + + if (!(flags & RECURSIVE)) { + if (PathIsDirectory(path)) { + return luaL_error(L, "requested directory remove without {recursive=true} on %s", path); + } + } + + if (!(PathDelete(path))) { + return luaL_error(L, "PathDelete failed on %s", path); + } + + return 0; +} + +static int internalfs_copy(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 2, "_fs.copy"); + const char* path_src = luaL_checkstring(L, 1); + const char* path_dst = luaL_checkstring(L, 2); + FILINFO fno; + + CheckWritePermissionsLuaError(L, path_dst); + + u32 flags = BUILD_PATH; + if (extra) { + flags = GetFlagsFromTable(L, 3, flags, CALC_SHA | USE_SHA1 | NO_CANCEL | SILENT | OVERWRITE_ALL | SKIP_ALL | APPEND_ALL | RECURSIVE); + } + + if (!(flags & RECURSIVE)) { + if (PathIsDirectory(path_src)) { + return luaL_error(L, "requested directory copy without {recursive=true} on %s -> %s", path_src, path_dst); + } + } + + if (!(flags & OVERWRITE_ALL) && (fvx_stat(path_dst, &fno) == FR_OK)) { + return luaL_error(L, "destination already exists on %s -> %s and {overwrite=true} was not used", path_src, path_dst); + } + + if (!(PathMoveCopy(path_dst, path_src, &flags, false))) { + return luaL_error(L, "PathMoveCopy failed on %s -> %s", path_src, path_dst); + } + + return 0; +} + +static int internalfs_mkdir(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.mkdir"); + const char* path = luaL_checkstring(L, 1); + + CheckWritePermissionsLuaError(L, path); + + FRESULT res = fvx_rmkdir(path); + if (res != FR_OK) { + return luaL_error(L, "could not mkdir %s (%d)", path, res); + } + + return 0; +} + +static int internalfs_list_dir(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.list_dir"); + const char* path = luaL_checkstring(L, 1); + lua_newtable(L); + + DIR dir; + FILINFO fno; + + FRESULT res = fvx_opendir(&dir, path); + if (res != FR_OK) { + lua_pop(L, 1); // remove final table from stack + return luaL_error(L, "could not opendir %s (%d)", path, res); + } + + for (int i = 1; true; i++) { + res = fvx_readdir(&dir, &fno); + if (res != FR_OK) { + fvx_closedir(&dir); + lua_pop(L, 1); // remove final table from stack + return luaL_error(L, "could not readdir %s (%d)", path, res); + } + if (fno.fname[0] == 0) break; + CreateStatTable(L, &fno); + lua_seti(L, -2, i); // add nested table to final table + } + fvx_closedir(&dir); + + return 1; +} + +static int internalfs_stat(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.stat"); + const char* path = luaL_checkstring(L, 1); + FILINFO fno; + + FRESULT res = fvx_stat(path, &fno); + if (res != FR_OK) { + return luaL_error(L, "could not stat %s (%d)", path, res); + } + CreateStatTable(L, &fno); + return 1; +} + +// TODO: make this manually check for permissions recursively +static int internalfs_fix_cmacs(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.fix_cmacs"); + const char* path = luaL_checkstring(L, 1); + + ShowString("%s", STR_FIXING_CMACS_PLEASE_WAIT); + if (RecursiveFixFileCmac(path) != 0) { + return luaL_error(L, "fixcmac failed"); + } + + return 0; +} + +static int internalfs_stat_fs(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.stat_fs"); + const char* path = luaL_checkstring(L, 1); + + u64 freespace = GetFreeSpace(path); + u64 totalspace = GetTotalSpace(path); + u64 usedspace = totalspace - freespace; + + lua_createtable(L, 0, 3); + lua_pushinteger(L, freespace); + lua_setfield(L, -2, "free"); + lua_pushinteger(L, totalspace); + lua_setfield(L, -2, "total"); + lua_pushinteger(L, usedspace); + lua_setfield(L, -2, "used"); + + return 1; +} + +static int internalfs_dir_info(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.dir_info"); + const char* path = luaL_checkstring(L, 1); + + u64 tsize = 0; + u32 tdirs = 0; + u32 tfiles = 0; + if (!DirInfo(path, &tsize, &tdirs, &tfiles)) { + return luaL_error(L, "error when running DirInfo"); + } + + lua_createtable(L, 0, 3); + lua_pushinteger(L, tsize); + lua_setfield(L, -2, "size"); + lua_pushinteger(L, tdirs); + lua_setfield(L, -2, "dirs"); + lua_pushinteger(L, tfiles); + lua_setfield(L, -2, "files"); + + return 1; +} + +static int FileDirSelector(lua_State* L, const char* path_orig, const char* prompt, bool is_dir, bool include_dirs, bool explorer) { + bool ret; + char path[_VAR_CNT_LEN] = { 0 }; + char choice[_VAR_CNT_LEN] = { 0 }; + strncpy(path, path_orig, _VAR_CNT_LEN); + if (strncmp(path, "Z:", 2) == 0) { + return luaL_error(L, "forbidden drive"); + } else if (!is_dir) { + u32 flags_ext = include_dirs ? 0 : NO_DIRS; + char *npattern = strrchr(path, '/'); + if (!npattern) { + return luaL_error(L, "invalid path"); + } + *(npattern++) = '\0'; + ret = FileSelector(choice, prompt, path, npattern, flags_ext, explorer); + } else { + ret = FileSelector(choice, prompt, path, NULL, NO_FILES | SELECT_DIRS, explorer); + } + + if (ret) { + lua_pushstring(L, choice); + } else { + lua_pushnil(L); + } + return 1; +} + +static int internalfs_ask_select_file(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 2, "_fs.ask_select_file"); + const char* prompt = luaL_checkstring(L, 1); + const char* path = luaL_checkstring(L, 2); + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 3, flags, INCLUDE_DIRS | EXPLORER); + }; + + return FileDirSelector(L, path, prompt, false, (flags & INCLUDE_DIRS), (flags & EXPLORER)); +} + +static int internalfs_ask_select_dir(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 2, "_fs.ask_select_dir"); + const char* prompt = luaL_checkstring(L, 1); + const char* path = luaL_checkstring(L, 2); + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 3, flags, EXPLORER); + }; + + return FileDirSelector(L, path, prompt, true, true, (flags & EXPLORER)); +} + +static int internalfs_find(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 1, "_fs.find"); + const char* pattern = luaL_checkstring(L, 1); + char path[_VAR_CNT_LEN] = { 0 }; + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 2, flags, FIND_FIRST); + } + + u8 mode = (flags & FIND_FIRST) ? FN_LOWEST : FN_HIGHEST; + FRESULT res = fvx_findpath(path, pattern, mode); + if (res == FR_NO_PATH) { + lua_pushnil(L); + } else if (res != FR_OK) { + return luaL_error(L, "failed to find %s (%d)", pattern, res); + } else { + lua_pushstring(L, path); + } + return 1; +} + +// this should probably be rewritten +static int internalfs_find_all(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 2, "_fs.find_all"); + const char* dir = luaL_checkstring(L, 1); + const char* pattern = luaL_checkstring(L, 2); + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 3, flags, RECURSIVE); + } + + char forpath[_VAR_CNT_LEN] = { 0 }; + + // without re-implementing for_handler, i need to give it a "*" pattern + // and then manually compare each filename to see if it matches + // so that a recursive search actually works + bool forstatus = for_handler(NULL, dir, "*", flags & RECURSIVE); + if (!forstatus) { + return luaL_error(L, "could not open directory"); + } + + lua_newtable(L); + int i = 1; + char* slash; + + while (true) { + forstatus = for_handler(forpath, NULL, NULL, false); + if (!forstatus) { + forpath[0] = '\0'; + } + if (!forpath[0]) { + // finish for_handler + for_handler(NULL, NULL, NULL, false); + break; + } else { + slash = strrchr(forpath, '/'); + if (!slash) bkpt; // this should never, ever happen + if (fvx_match_name(slash+1, pattern) == FR_OK) { + lua_pushstring(L, forpath); + lua_seti(L, -2, i++); + } + } + } + + return 1; +} + +static int internalfs_find_not(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.find_not"); + const char* pattern = luaL_checkstring(L, 1); + char path[_VAR_CNT_LEN] = { 0 }; + + FRESULT res = fvx_findnopath(path, pattern); + if (res != FR_OK) { + return luaL_error(L, "failed to find %s (%d)", pattern, res); + } + + lua_pushstring(L, path); + return 1; +} + +static int internalfs_exists(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.exists"); + const char* path = luaL_checkstring(L, 1); + FILINFO fno; + + lua_pushboolean(L, (fvx_stat(path, &fno) == FR_OK)); + return 1; +} + +static int internalfs_is_dir(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.is_dir"); + const char* path = luaL_checkstring(L, 1); + + lua_pushboolean(L, PathIsDirectory(path)); + return 1; +} + +static int internalfs_is_file(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.is_file"); + const char* path = luaL_checkstring(L, 1); + FILINFO fno; + + FRESULT res = fvx_stat(path, &fno); + if (res != FR_OK) { + lua_pushboolean(L, false); + } else { + lua_pushboolean(L, !(fno.fattrib & AM_DIR)); + } + return 1; +} + +static int internalfs_read_file(lua_State* L) { + CheckLuaArgCount(L, 3, "_fs.read_file"); + const char* path = luaL_checkstring(L, 1); + lua_Integer offset = luaL_checkinteger(L, 2); + lua_Integer size = luaL_checkinteger(L, 3); + + char *buf = malloc(size); + if (!buf) { + return luaL_error(L, "could not allocate memory to read file"); + } + UINT bytes_read = 0; + FRESULT res = fvx_qread(path, buf, offset, size, &bytes_read); + if (res != FR_OK) { + free(buf); + return luaL_error(L, "could not read %s (%d)", path, res); + } + lua_pushlstring(L, buf, bytes_read); + free(buf); + return 1; +} + +static int internalfs_write_file(lua_State* L) { + CheckLuaArgCount(L, 3, "_fs.write_file"); + const char* path = luaL_checkstring(L, 1); + lua_Integer offset = luaL_checkinteger(L, 2); + size_t data_length = 0; + const char* data = luaL_checklstring(L, 3, &data_length); + + CheckWritePermissionsLuaError(L, path); + + UINT bytes_written = 0; + FRESULT res = fvx_qwrite(path, data, offset, data_length, &bytes_written); + if (res != FR_OK) { + return luaL_error(L, "error writing %s (%d)", path, res); + } + + lua_pushinteger(L, bytes_written); + return 1; +} + +static int internalfs_fill_file(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 4, "_fs.fill_file"); + const char* path = luaL_checkstring(L, 1); + lua_Integer offset = luaL_checkinteger(L, 2); + lua_Integer size = luaL_checkinteger(L, 3); + lua_Integer byte = luaL_checkinteger(L, 4); + + u8 real_byte = byte & 0xFF; + + u32 flags = ALLOW_EXPAND; + if (extra) { + flags = GetFlagsFromTable(L, 4, flags, NO_CANCEL); + }; + + if ((byte < 0) || (byte > 0xFF)) { + return luaL_error(L, "byte is not between 0x00 and 0xFF (got: %I)", byte); + } + + CheckWritePermissionsLuaError(L, path); + + if (!(FileSetByte(path, offset, size, real_byte, &flags))) { + return luaL_error(L, "FileSetByte failed on %s", path); + } + + return 0; +} + +static int internalfs_make_dummy_file(lua_State* L) { + CheckLuaArgCount(L, 2, "_fs.make_dummy_file"); + const char* path = luaL_checkstring(L, 1); + lua_Integer size = luaL_checkinteger(L, 2); + + CheckWritePermissionsLuaError(L, path); + + if (!(FileCreateDummy(path, NULL, size))) { + return luaL_error(L, "FileCreateDummy failed on %s", path); + } + + return 0; +} + +static int internalfs_truncate(lua_State* L) { + CheckLuaArgCount(L, 2, "_fs.truncate"); + const char* path = luaL_checkstring(L, 1); + lua_Integer size = luaL_checkinteger(L, 2); + FIL fp; + FRESULT res; + + CheckWritePermissionsLuaError(L, path); + + res = f_open(&fp, path, FA_READ | FA_WRITE); + if (res != FR_OK) { + return luaL_error(L, "failed to open %s (note: this only works on FAT filesystems, not virtual)", path); + } + + res = f_lseek(&fp, size); + if (res != FR_OK) { + f_close(&fp); + return luaL_error(L, "failed to seek on %s", path); + } + + res = f_truncate(&fp); + if (res != FR_OK) { + f_close(&fp); + return luaL_error(L, "failed to truncate %s", path); + } + + f_close(&fp); + return 0; +} + +static int internalfs_img_mount(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.img_mount"); + const char* path = luaL_checkstring(L, 1); + + bool res = InitImgFS(path); + if (!res) { + return luaL_error(L, "failed to mount %s", path); + } + + return 0; +} + +static int internalfs_img_umount(lua_State* L) { + CheckLuaArgCount(L, 0, "_fs.img_umount"); + + InitImgFS(NULL); + + return 0; +} + +static int internalfs_get_img_mount(lua_State* L) { + CheckLuaArgCount(L, 0, "_fs.get_img_mount"); + + char path[256] = { 0 }; + strncpy(path, GetMountPath(), 256); + if (path[0] == 0) { + // since lua treats "" as true, return a nil to make if/else easier + lua_pushnil(L); + } else { + lua_pushstring(L, path); + } + + return 1; +} + +// TODO: what if someone does offset != 0 but size = 0 (end of file)? +static int internalfs_hash_file(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 3, "_fs.hash_file"); + const char* path = luaL_checkstring(L, 1); + lua_Integer offset = luaL_checkinteger(L, 2); + lua_Integer size = luaL_checkinteger(L, 3); + FRESULT res; + FILINFO fno; + + if (size == 0) { + res = fvx_stat(path, &fno); + if (res != FR_OK) { + return luaL_error(L, "failed to stat %s", path); + } + + size = fno.fsize; + } + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 4, flags, USE_SHA1); + } + + const u8 hashlen = (flags & USE_SHA1) ? 20 : 32; + u8 hash_fil[0x20]; + + if (size == 0) { + // shortcut by just returning the hash of empty data + memcpy(hash_fil, (flags & USE_SHA1) ? no_data_hash_1 : no_data_hash_256, hashlen); + } else if (!(FileGetSha(path, hash_fil, offset, size, (flags & USE_SHA1)))) { + return luaL_error(L, "FileGetSha failed on %s", path); + } + + lua_pushlstring(L, (char*)hash_fil, hashlen); + return 1; +} + +static int internalfs_hash_data(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 1, "_fs.hash_data"); + size_t data_length = 0; + const char* data = luaL_checklstring(L, 1, &data_length); + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 2, flags, USE_SHA1); + } + + const u8 hashlen = (flags & USE_SHA1) ? 20 : 32; + u8 hash_fil[0x20]; + + if (data_length == 0) { + // shortcut by just returning the hash of empty data + memcpy(hash_fil, (flags & USE_SHA1) ? no_data_hash_1 : no_data_hash_256, hashlen); + } else { + sha_quick(hash_fil, data, data_length, (flags & USE_SHA1) ? SHA1_MODE : SHA256_MODE); + } + + lua_pushlstring(L, (char*)hash_fil, hashlen); + return 1; +} + +static int internalfs_allow(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 1, "_fs.allow"); + const char* path = luaL_checkstring(L, 1); + u32 flags = 0; + bool allowed; + if (extra) { + flags = GetFlagsFromTable(L, 2, 0, ASK_ALL); + } + + if (flags & ASK_ALL) { + allowed = CheckDirWritePermissions(path); + } else { + allowed = CheckWritePermissions(path); + } + lua_pushboolean(L, allowed); + return 1; +}; + +static int internalfs_verify(lua_State* L) { + CheckLuaArgCount(L, 1, "_fs.verify"); + const char* path = luaL_checkstring(L, 1); + bool res; + + u64 filetype = IdentifyFileType(path); + if (filetype & IMG_NAND) res = (ValidateNandDump(path) == 0); + else res = (VerifyGameFile(path) == 0); + + lua_pushboolean(L, res); + return 1; +} + +static int internalfs_sd_is_mounted(lua_State* L) { + CheckLuaArgCount(L, 0, "_fs.sd_is_mounted"); + + lua_pushboolean(L, CheckSDMountState()); + return 1; +} + +static int internalfs_sd_switch(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 0, "_fs.sd_switch"); + const char* message; + + if (extra) { + message = luaL_checkstring(L, 1); + } else { + message = "Please switch the SD card now."; + } + + bool ret; + + DeinitExtFS(); + if (!(ret = CheckSDMountState())) { + return luaL_error(L, "%s", STR_SCRIPTERR_SD_NOT_MOUNTED); + } + + u32 pad_state; + DeinitSDCardFS(); + ShowString("%s\n \n%s", message, STR_EJECT_SD_CARD); + while (!((pad_state = InputWait(0)) & (BUTTON_B|SD_EJECT))); + if (pad_state & SD_EJECT) { + ShowString("%s\n \n%s", message, STR_INSERT_SD_CARD); + while (!((pad_state = InputWait(0)) & (BUTTON_B|SD_INSERT))); + } + if (pad_state & BUTTON_B) { + return luaL_error(L, "user canceled"); + } + + InitSDCardFS(); + AutoEmuNandBase(true); + InitExtFS(); + + return 0; +} + +static int internalfs_key_dump(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 1, "_fs.key_dump"); + const char* opts[] = {SEEDINFO_NAME, TIKDB_NAME_ENC, TIKDB_NAME_DEC, NULL}; + int opt = luaL_checkoption(L, 1, NULL, opts); + bool ret = false; + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 2, 0, OVERWRITE_ALL); + } + + if (opt == 1 || opt == 2) { + bool tik_dec = opt == 2; + if (flags & OVERWRITE_ALL) fvx_unlink(tik_dec ? OUTPUT_PATH "/" TIKDB_NAME_DEC : OUTPUT_PATH "/" TIKDB_NAME_ENC); + if (BuildTitleKeyInfo(NULL, tik_dec, false) == 0) { + ShowString(STR_BUILDING_TO_OUT_ARG, OUTPUT_PATH, opts[opt]); + if (((BuildTitleKeyInfo("1:/dbs/ticket.db", tik_dec, false) == 0) || + (BuildTitleKeyInfo("4:/dbs/ticket.db", tik_dec, false) == 0)) && + (BuildTitleKeyInfo(NULL, tik_dec, true) == 0)) + ret = true; + } + } else if (opt == 0) { + if (flags & OVERWRITE_ALL) fvx_unlink(OUTPUT_PATH "/" SEEDINFO_NAME); + if (BuildSeedInfo(NULL, false) == 0) { + ShowString(STR_BUILDING_TO_OUT_ARG, OUTPUT_PATH, opts[opt]); + if (((BuildSeedInfo("1:", false) == 0) || + (BuildSeedInfo("4:", false) == 0)) && + (BuildSeedInfo(NULL, true) == 0)) + ret = true; + } + } + + if (!ret) { + return luaL_error(L, "building %s failed", opts[opt]); + } + + return 0; +} + +static int internalfs_cart_dump(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 2, "_fs.cart_dump"); + const char* path = luaL_checkstring(L, 1); + u64 fsize = (u64)luaL_checkinteger(L, 2); + bool ret = false; + const char* errstr = ""; + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 3, flags, ENCRYPTED); + } + + CartData* cdata = (CartData*) malloc(sizeof(CartData)); + u8* buf = (u8*) malloc(STD_BUFFER_SIZE); + ret = false; + if (!cdata || !buf) { + errstr = "out of memory"; + } else if (InitCartRead(cdata) != 0){ + errstr = "cart init fail"; + } else { + SetSecureAreaEncryption(flags & ENCRYPTED); + fvx_unlink(path); + ret = true; + errstr = "cart dump failed or canceled"; + for (u64 p = 0; p < fsize; p += STD_BUFFER_SIZE) { + u64 len = min((fsize - p), STD_BUFFER_SIZE); + ShowProgress(p, fsize, path); + if (!ShowProgress(p, fsize, path) || + (ReadCartBytes(buf, p, len, cdata, false) != 0) || + (fvx_qwrite(path, buf, p, len, NULL) != FR_OK)) { + ret = false; + break; + } + } + } + free(buf); + free(cdata); + + if (!ret) { + return luaL_error(L, "%s", errstr); + } + return 0; +} + +static const luaL_Reg internalfs_lib[] = { + {"move", internalfs_move}, + {"remove", internalfs_remove}, + {"copy", internalfs_copy}, + {"mkdir", internalfs_mkdir}, + {"list_dir", internalfs_list_dir}, + {"stat", internalfs_stat}, + {"stat_fs", internalfs_stat_fs}, + {"dir_info", internalfs_dir_info}, + {"ask_select_file", internalfs_ask_select_file}, + {"ask_select_dir", internalfs_ask_select_dir}, + {"find", internalfs_find}, + {"find_all", internalfs_find_all}, + {"find_not", internalfs_find_not}, + {"exists", internalfs_exists}, + {"is_dir", internalfs_is_dir}, + {"is_file", internalfs_is_file}, + {"read_file", internalfs_read_file}, + {"write_file", internalfs_write_file}, + {"fill_file", internalfs_fill_file}, + {"make_dummy_file", internalfs_make_dummy_file}, + {"truncate", internalfs_truncate}, + {"img_mount", internalfs_img_mount}, + {"img_umount", internalfs_img_umount}, + {"get_img_mount", internalfs_get_img_mount}, + {"hash_file", internalfs_hash_file}, + {"hash_data", internalfs_hash_data}, + {"verify", internalfs_verify}, + {"allow", internalfs_allow}, + {"sd_is_mounted", internalfs_sd_is_mounted}, + {"sd_switch", internalfs_sd_switch}, + {"fix_cmacs", internalfs_fix_cmacs}, + {"key_dump", internalfs_key_dump}, + {"cart_dump", internalfs_cart_dump}, + {NULL, NULL} +}; + +int gm9lua_open_internalfs(lua_State* L) { + luaL_newlib(L, internalfs_lib); + return 1; +} +#endif diff --git a/arm9/source/lua/gm9internalfs.h b/arm9/source/lua/gm9internalfs.h new file mode 100644 index 000000000..99f1c18a2 --- /dev/null +++ b/arm9/source/lua/gm9internalfs.h @@ -0,0 +1,23 @@ +#pragma once +#include "gm9lua.h" + +#define GM9LUA_INTERNALFSLIBNAME "_fs" + +#define SHA256_EMPTY_HASH \ + 0xE3, 0xB0, 0xC4, 0x42, \ + 0x98, 0xFC, 0x1C, 0x14, \ + 0x9A, 0xFB, 0xF4, 0xC8, \ + 0x99, 0x6F, 0xB9, 0x24, \ + 0x27, 0xAE, 0x41, 0xE4, \ + 0x64, 0x9B, 0x93, 0x4C, \ + 0xA4, 0x95, 0x99, 0x1B, \ + 0x78, 0x52, 0xB8, 0x55 + +#define SHA1_EMPTY_HASH \ + 0xDA, 0x39, 0xA3, 0xEE, \ + 0x5E, 0x6B, 0x4B, 0x0D, \ + 0x32, 0x55, 0xBF, 0xEF, \ + 0x95, 0x60, 0x18, 0x90, \ + 0xAF, 0xD8, 0x07, 0x09 + +int gm9lua_open_internalfs(lua_State* L); diff --git a/arm9/source/lua/gm9internalsys.c b/arm9/source/lua/gm9internalsys.c new file mode 100644 index 000000000..28c2a5c4e --- /dev/null +++ b/arm9/source/lua/gm9internalsys.c @@ -0,0 +1,181 @@ +#ifndef NO_LUA +#include "gm9internalsys.h" +#include "bootfirm.h" +#include "fs.h" +#include "pxi.h" +#include "game.h" +#include "power.h" +#include "sha.h" +#include "nand.h" +#include "utils.h" +#include "ui.h" +#include "rtc.h" +#include "godmode.h" + +#define UNUSED(x) ((void)(x)) + +static int internalsys_boot(lua_State* L) { + CheckLuaArgCount(L, 1, "_sys.boot"); + const char* path = lua_tostring(L, 1); + + u8* firm = (u8*) malloc(FIRM_MAX_SIZE); + if (!firm) { + return luaL_error(L, "out of memory"); + } + + size_t firm_size = FileGetData(path, firm, FIRM_MAX_SIZE, 0); + if (!(firm_size && IsBootableFirm(firm, firm_size))) { + return luaL_error(L, "not a bootable firm"); + } + + char fixpath[256] = { 0 }; + if ((*path == '0') || (*path == '1')) + snprintf(fixpath, sizeof(fixpath), "%s%s", (*path == '0') ? "sdmc" : "nand", path + 1); + else strncpy(fixpath, path, 256); + fixpath[255] = '\0'; + DeinitExtFS(); + DeinitSDCardFS(); + PXI_DoCMD(PXICMD_LEGACY_BOOT, NULL, 0); + PXI_Barrier(PXI_FIRMLAUNCH_BARRIER); + BootFirm((FirmHeader*)(void*)firm, fixpath); + while(1); +} + +static int internalsys_reboot(lua_State* L) { + CheckLuaArgCount(L, 0, "_sys.reboot"); + DeinitExtFS(); + DeinitSDCardFS(); + Reboot(); + return 0; +} + +static int internalsys_power_off(lua_State* L) { + CheckLuaArgCount(L, 0, "_sys.power_off"); + DeinitExtFS(); + DeinitSDCardFS(); + PowerOff(); + return 0; +} + +static int internalsys_get_id0(lua_State* L) { + CheckLuaArgCount(L, 1, "_sys.get_id0"); + const char* path = lua_tostring(L, 1); + + char env_id0[32+1]; + u8 sd_keyy[0x10] __attribute__((aligned(4))); + if (FileGetData(path, sd_keyy, 0x10, 0x110) == 0x10) { + u32 sha256sum[8]; + sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE); + snprintf(env_id0, sizeof(env_id0), "%08lx%08lx%08lx%08lx", + sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); + lua_pushstring(L, env_id0); + } else { + lua_pushnil(L); + } + return 1; +} + +static int internalsys_next_emu(lua_State* L) { + CheckLuaArgCount(L, 0, "_sys.next_emu"); + + DismountDriveType(DRV_EMUNAND); + AutoEmuNandBase(false); + InitExtFS(); + + return 0; +} + +static int internalsys_get_emu_base(lua_State* L) { + CheckLuaArgCount(L, 0, "_sys.get_emu_base"); + + lua_pushinteger(L, GetEmuNandBase()); + return 1; +} + +static int internalsys_check_embedded_backup(lua_State* L) { + CheckLuaArgCount(L, 0, "_sys.check_embedded_backup"); + + if (PathExist("S:/essential.exefs")) { + lua_pushboolean(L, true); + return 1; + } + + bool ncsd_check = CheckGenuineNandNcsd(); + if (!ncsd_check) { + lua_pushnil(L); + return 1; + } + + bool ret = false; + + if (ncsd_check && ShowPrompt(true, "%s", STR_ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW)) { + if (EmbedEssentialBackup("S:/nand.bin") == 0) { + u32 flags = BUILD_PATH | SKIP_ALL; + PathCopy(OUTPUT_PATH, "S:/essential.exefs", &flags); + ShowPrompt(false, STR_BACKUP_EMBEDDED_WRITTEN_TO_OUT, OUTPUT_PATH); + ret = true; + } else { + ret = false; + } + } else { + ret = false; + } + + lua_pushboolean(L, ret); + return 1; +} + +static int internalsys_check_raw_rtc(lua_State* L) { + CheckLuaArgCount(L, 0, "_sys.check_raw_rtc"); + + bool result = false; + + DsTime dstime; + get_dstime(&dstime); + if (DSTIMEGET(&dstime, bcd_Y) >= 18) { + result = true; + } else if (ShowPrompt(true, "%s", STR_RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW) && + ShowRtcSetterPrompt(&dstime, "%s", STR_TITLE_SET_RTC_DATE_TIME)) { + //char timestr[UTF_BUFFER_BYTESIZE(32)]; + set_dstime(&dstime); + // this is only in godmode.h + //GetTimeString(timestr, true, true); + // ShowPrompt(false, STR_NEW_RTC_DATE_TIME_IS_TIME, timestr); + result = true; + } + + lua_pushboolean(L, result); + return 1; +} + +static int internalsys_global_bkpt(lua_State* L) { + UNUSED(L); + bkpt; + while(1); +} + +static const luaL_Reg internalsys_lib[] = { + {"boot", internalsys_boot}, + {"reboot", internalsys_reboot}, + {"power_off", internalsys_power_off}, + {"get_id0", internalsys_get_id0}, + {"next_emu", internalsys_next_emu}, + {"get_emu_base", internalsys_get_emu_base}, + {"check_embedded_backup", internalsys_check_embedded_backup}, + {"check_raw_rtc", internalsys_check_raw_rtc}, + {NULL, NULL} +}; + +static const luaL_Reg internalsys_global_lib[] = { + {"bkpt", internalsys_global_bkpt}, + {NULL, NULL} +}; + +int gm9lua_open_internalsys(lua_State* L) { + luaL_newlib(L, internalsys_lib); + lua_pushglobaltable(L); // push global table to stack + luaL_setfuncs(L, internalsys_global_lib, 0); // set global funcs + lua_pop(L, 1); // pop global table from stack + return 1; +} +#endif diff --git a/arm9/source/lua/gm9internalsys.h b/arm9/source/lua/gm9internalsys.h new file mode 100644 index 000000000..7158ff10c --- /dev/null +++ b/arm9/source/lua/gm9internalsys.h @@ -0,0 +1,6 @@ +#pragma once +#include "gm9lua.h" + +#define GM9LUA_INTERNALSYSLIBNAME "_sys" + +int gm9lua_open_internalsys(lua_State* L); diff --git a/arm9/source/lua/gm9loader.c b/arm9/source/lua/gm9loader.c new file mode 100644 index 000000000..abfead45c --- /dev/null +++ b/arm9/source/lua/gm9loader.c @@ -0,0 +1,128 @@ +#ifndef NO_LUA +#include "gm9loader.h" +#include "gm9lua.h" +#include "vff.h" +#include "ui.h" + +// a lot of this code is based on stuff in loadlib.c but adapted for GM9 + +// similar to readable +static int Readable(const char* filename) { + FIL f; + FRESULT res = fvx_open(&f, filename, FA_READ | FA_OPEN_EXISTING); + if (res != FR_OK) return 0; + fvx_close(&f); + return 1; +} + +// similar to getnextfilename +static const char* GetNextFileName(char** path, char* end) { + char *sep; + char *name = *path; + if (name == end) + return NULL; /* no more names */ + else if (*name == '\0') { /* from previous iteration? */ + *name = *LUA_PATH_SEP; /* restore separator */ + name++; /* skip it */ + } + sep = strchr(name, *LUA_PATH_SEP); /* find next separator */ + if (sep == NULL) /* separator not found? */ + sep = end; /* name goes until the end */ + *sep = '\0'; /* finish file name */ + *path = sep; /* will start next search from here */ + return name; +} + +// similar to pusherrornotfound +static void PushErrorNotFound(lua_State* L, const char* path) { + luaL_Buffer b; + luaL_buffinit(L, &b); + luaL_addstring(&b, "no file '"); + luaL_addgsub(&b, path, LUA_PATH_SEP, "'\n\tno file '"); + luaL_addstring(&b, "'"); + luaL_pushresult(&b); +} + +// similar to searchpath +static const char* SearchPath(lua_State* L, const char* name, const char* path, const char* sep) { + luaL_Buffer buff; + char* pathname; + char* endpathname; + const char* filename; + if (*sep != '\0' && strchr(name, *sep) != NULL) + name = luaL_gsub(L, name, sep, "/"); + + luaL_buffinit(L, &buff); + // add path to the buffer, replacing marks ('?') with the file name + luaL_addgsub(&buff, path, LUA_PATH_MARK, name); + luaL_addchar(&buff, '\0'); + pathname = luaL_buffaddr(&buff); + endpathname = pathname + luaL_bufflen(&buff) + 1; + while ((filename = GetNextFileName(&pathname, endpathname)) != NULL) { + if (Readable(filename)) + return lua_pushstring(L, filename); + } + luaL_pushresult(&buff); + PushErrorNotFound(L, lua_tostring(L, -1)); + return NULL; +} + +// similar to findfile +static const char* FindLuaFile(lua_State* L, const char* name, const char* pname) { + const char* path; + lua_getfield(L, lua_upvalueindex(1), pname); // gets 'package' table + path = lua_tostring(L, -1); + if (path == NULL) luaL_error(L, "'package.%s' must be a string", pname); + return SearchPath(L, name, path, "."); +} + +// similar to checkload +static int CheckLoad(lua_State* L, int stat, const char* filename) { + if (stat) { + lua_pushstring(L, filename); + return 2; // return open function and filename + } else { + return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); + } +} + +// similar to searcher_Lua +static int PackageSearcher(lua_State* L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + + filename = FindLuaFile(L, name, "path"); + + if (filename == NULL) return 1; // module not found in this path + return CheckLoad(L, (LoadLuaFile(L, filename) == LUA_OK), filename); +} + +void ResetPackageSearchersAndPath(lua_State* L) { + // get package module + lua_getglobal(L, "package"); + + // the default package.path only makes sense on a full OS + // maybe this should include the lua script's current directory somehow... + lua_pushliteral(L, GM9LUA_DEFAULT_PATH); + lua_setfield(L, -2, "path"); + + // package.cpath is for loading binary modules, useless on GM9 + lua_pushliteral(L, ""); + lua_setfield(L, -2, "cpath"); + + // the default package searchers only make sense on a full OS + // so here we replace the lua loader with a custom one, and remove the C/Croot loaders + // leaving the initial one (preload) + lua_getfield(L, -1, "searchers"); + lua_pushvalue(L, -2); // copy 'package' to the top of the stack, to set 'package' as upvalue for all searchers + lua_pushcclosure(L, PackageSearcher, 1); // push PackageSearcher with one upvalue being the "packages" module/table + lua_rawseti(L, -2, 2); // replace default lua loader + lua_pushnil(L); + lua_rawseti(L, -2, 3); // remove C loader + lua_pushnil(L); + lua_rawseti(L, -2, 4); // remove C root loader + lua_pop(L, 1); // remove "searchers" + lua_pop(L, 1); // remove "packages" +} +#endif diff --git a/arm9/source/lua/gm9loader.h b/arm9/source/lua/gm9loader.h new file mode 100644 index 000000000..b1ebcd500 --- /dev/null +++ b/arm9/source/lua/gm9loader.h @@ -0,0 +1,15 @@ +#include "gm9lua.h" + +/* + * 0:/gm9/luapackages/?.lua; + * 0:/gm9/luapackages/?/init.lua; + * V:/luapackages/?.lua; + * V:/luapackages/?/init.lua + */ +#define GM9LUA_DEFAULT_PATH \ + "0:/gm9/luapackages/"LUA_PATH_MARK".lua" LUA_PATH_SEP \ + "0:/gm9/luapackages/"LUA_PATH_MARK"/init.lua" LUA_PATH_SEP \ + "V:/luapackages/"LUA_PATH_MARK".lua" LUA_PATH_SEP \ + "V:/luapackages/"LUA_PATH_MARK"/init.lua" + +void ResetPackageSearchersAndPath(lua_State* L); diff --git a/arm9/source/lua/gm9lua.c b/arm9/source/lua/gm9lua.c new file mode 100644 index 000000000..c90b0ffc3 --- /dev/null +++ b/arm9/source/lua/gm9lua.c @@ -0,0 +1,216 @@ +#include "gm9lua.h" +#include "ui.h" +#include "language.h" +#ifndef NO_LUA +#include "fs.h" +#include "ff.h" +#include "vff.h" +#include "fsutil.h" +#include "unittype.h" +#include "nand.h" +#include "gm9loader.h" +#include "gm9os.h" +#include "gm9ui.h" +#include "gm9title.h" +#include "gm9internalfs.h" +#include "gm9internalsys.h" + +#define DEBUGSP(x) ShowPrompt(false, (x)) + +typedef struct GM9LuaLoadF { + int n; // pre-read characters + FIL f; + FRESULT res; + char buff[BUFSIZ]; +} GM9LuaLoadF; + +// similar to "getF" in lauxlib.c +static const char* GetF(lua_State* L, void* ud, size_t* size) { + GM9LuaLoadF* lf = (GM9LuaLoadF*)ud; + UINT br = 0; + (void)L; // unused + if (lf->n > 0) { // check for pre-read characters + *size = lf->n; // return those + lf->n = 0; + } else { + if (fvx_eof(&lf->f)) return NULL; + lf->res = fvx_read(&lf->f, lf->buff, BUFSIZ, &br); + *size = (size_t)br; + if (lf->res != FR_OK) return NULL; + } + return lf->buff; +} + +// similar to "errfile" in lauxlib.c +static int ErrFile(lua_State* L, const char* what, int fnameindex, FRESULT res) { + const char* filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s:\nfatfs error %d", what, filename, res); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + +int LoadLuaFile(lua_State* L, const char* filename) { + GM9LuaLoadF lf; + lf.n = 0; + int status; + int fnameindex = lua_gettop(L) + 1; // index of filename on the stack + lua_pushfstring(L, "@%s", filename); + lf.res = fvx_open(&lf.f, filename, FA_READ | FA_OPEN_EXISTING); + if (lf.res != FR_OK) return ErrFile(L, "open", fnameindex, lf.res); + + status = lua_load(L, GetF, &lf, lua_tostring(L, -1), NULL); + fvx_close(&lf.f); + if (lf.res != FR_OK) { + lua_settop(L, fnameindex); + return ErrFile(L, "read", fnameindex, lf.res); + } + lua_remove(L, fnameindex); + return status; +} + +u32 GetFlagsFromTable(lua_State* L, int pos, u32 flags_ext_starter, u32 allowed_flags) { + char types[FLAGS_COUNT][14] = { FLAGS_STR }; + int types_int[FLAGS_COUNT] = { FLAGS_CONSTS }; + u32 flags_ext = flags_ext_starter; + + for (int i = 0; i < FLAGS_COUNT; i++) { + if (!(allowed_flags & types_int[i])) continue; + lua_getfield(L, pos, types[i]); + if (lua_toboolean(L, -1)) flags_ext |= types_int[i]; + lua_pop(L, 1); + } + + return flags_ext; +} + +void CheckWritePermissionsLuaError(lua_State* L, const char* path) { + if (!CheckWritePermissions(path)) { + luaL_error(L, "writing not allowed: %s", path); + } +} + +static const luaL_Reg gm9lualibs[] = { + // built-ins + {LUA_GNAME, luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_UTF8LIBNAME, luaopen_utf8}, + {LUA_DBLIBNAME, luaopen_debug}, + + // gm9 custom + {GM9LUA_OSLIBNAME, gm9lua_open_os}, + {GM9LUA_UILIBNAME, gm9lua_open_ui}, + {GM9LUA_TITLELIBNAME, gm9lua_open_title}, + + // gm9 custom internals (usually wrapped by a pure lua module) + {GM9LUA_INTERNALFSLIBNAME, gm9lua_open_internalfs}, + {GM9LUA_INTERNALSYSLIBNAME, gm9lua_open_internalsys}, + + {NULL, NULL} +}; + +static void loadlibs(lua_State* L) { + const luaL_Reg* lib; + for (lib = gm9lualibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); // remove lib from stack + } +} + +static bool RunFile(lua_State* L, const char* file) { + int result = LoadLuaFile(L, file); + if (result != LUA_OK) { + char errstr[BUFSIZ] = {0}; + strlcpy(errstr, lua_tostring(L, -1), BUFSIZ); + WordWrapString(errstr, 0); + ShowPrompt(false, "Error during loading:\n%s", errstr); + return false; + } + + if (lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK) { + char errstr[BUFSIZ] = {0}; + strlcpy(errstr, lua_tostring(L, -1), BUFSIZ); + WordWrapString(errstr, 0); + ShowPrompt(false, "Error during execution:\n%s", errstr); + return false; + } + + return true; +} + +// this is also taken from scripting.c +static inline bool isntrboot(void) { + // taken over from Luma 3DS: + // https://github.com/AuroraWright/Luma3DS/blob/bb5518b0f68d89bcd8efaf326355a770d5e57856/source/main.c#L58-L62 + const vu8 *bootMediaStatus = (const vu8 *) 0x1FFFE00C; + const vu32 *bootPartitionsStatus = (const vu32 *) 0x1FFFE010; + + // shell closed, no error booting NTRCARD, NAND partitions not even considered + return (bootMediaStatus[3] == 2) && !bootMediaStatus[1] && !bootPartitionsStatus[0] && !bootPartitionsStatus[1]; +} + +bool ExecuteLuaScript(const char* path_script) { + lua_State* L = luaL_newstate(); + loadlibs(L); + + ResetPackageSearchersAndPath(L); + ClearOutputBuffer(); + + // current path + char curr_dir[_VAR_CNT_LEN]; + if (path_script) { + strncpy(curr_dir, path_script, _VAR_CNT_LEN); + curr_dir[_VAR_CNT_LEN-1] = '\0'; + char* slash = strrchr(curr_dir, '/'); + if (slash) *slash = '\0'; + + lua_pushstring(L, curr_dir); + } else { + lua_pushnil(L); + } + lua_setglobal(L, "CURRDIR"); + + lua_pushliteral(L, VERSION); + lua_setglobal(L, "GM9VER"); + + lua_pushstring(L, path_script); + lua_setglobal(L, "SCRIPT"); + + lua_pushliteral(L, OUTPUT_PATH); + lua_setglobal(L, "GM9OUT"); + + lua_pushstring(L, IS_UNLOCKED ? (isntrboot() ? "ntrboot" : "sighax") : ""); + lua_setglobal(L, "HAX"); + + lua_pushinteger(L, GetNandSizeSectors(NAND_SYSNAND) * 0x200); + lua_setglobal(L, "NANDSIZE"); + + lua_pushboolean(L, IS_DEVKIT); + lua_setglobal(L, "IS_DEVKIT"); + + lua_pushstring(L, IS_O3DS ? "O3DS" : "N3DS"); + lua_setglobal(L, "CONSOLE_TYPE"); + + bool result = RunFile(L, "V:/preload.lua"); + if (!result) { + ShowPrompt(false, "A fatal error happened in GodMode9's preload script.\n \nThis is not an error with your code, but with\nGodMode9. Please report it on GitHub."); + lua_close(L); + return false; + } + + RunFile(L, path_script); + + lua_close(L); + return true; +} +#else +// No-Lua version +bool ExecuteLuaScript(const char* path_script) { + (void)path_script; // unused + ShowPrompt(false, "%s", STR_LUA_NOT_INCLUDED); + return false; +} +#endif diff --git a/arm9/source/lua/gm9lua.h b/arm9/source/lua/gm9lua.h new file mode 100644 index 000000000..371d08990 --- /dev/null +++ b/arm9/source/lua/gm9lua.h @@ -0,0 +1,47 @@ +#pragma once +#include "common.h" +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#include "scripting.h" + +// this should probably go in filesys/fsutil.h +#define RECURSIVE (1UL<<11) +#define TO_EMUNAND (1UL<<12) +#define LEGIT (1UL<<13) +#define FIND_FIRST (1UL<<14) +#define INCLUDE_DIRS (1UL<<15) +#define EXPLORER (1UL<<16) +#define ENCRYPTED (1UL<<17) + +#define FLAGS_STR "no_cancel", "silent", "calc_sha", "sha1", "skip", "overwrite", "append", "all", "recursive", "to_emunand", "legit", "first", "include_dirs", "explorer", "encrypted" +#define FLAGS_CONSTS NO_CANCEL, SILENT, CALC_SHA, USE_SHA1, SKIP_ALL, OVERWRITE_ALL, APPEND_ALL, ASK_ALL, RECURSIVE, TO_EMUNAND, LEGIT, FIND_FIRST, INCLUDE_DIRS, EXPLORER, ENCRYPTED +#define FLAGS_COUNT 15 + +#define LUASCRIPT_EXT "lua" +#define LUASCRIPT_MAX_SIZE STD_BUFFER_SIZE + +// taken from arm9/source/utils/scripting.c +#define _VAR_CNT_LEN 256 + +#ifndef NO_LUA +static inline void CheckLuaArgCount(lua_State* L, int argcount, const char* cmd) { + int args = lua_gettop(L); + if (args != argcount) { + luaL_error(L, "bad number of arguments passed to '%s' (expected %d, got %d)", cmd, argcount, args); + } +} +// this is used in cases where a function accepts a flags table or something else +static inline bool CheckLuaArgCountPlusExtra(lua_State* L, int argcount, const char* cmd) { + int args = lua_gettop(L); + if (args != argcount && args != argcount + 1) { + luaL_error(L, "bad number of arguments passed to '%s' (expected %d or %d, got %d)", cmd, argcount, argcount + 1, args); + } + return args == argcount + 1; +} + +int LoadLuaFile(lua_State* L, const char* filename); +u32 GetFlagsFromTable(lua_State* L, int pos, u32 flags_ext_starter, u32 allowed_flags); +void CheckWritePermissionsLuaError(lua_State* L, const char* path); +#endif +bool ExecuteLuaScript(const char* path_script); diff --git a/arm9/source/lua/gm9os.c b/arm9/source/lua/gm9os.c new file mode 100644 index 000000000..64cb5a80b --- /dev/null +++ b/arm9/source/lua/gm9os.c @@ -0,0 +1,686 @@ +#ifndef NO_LUA +#include "gm9os.h" +#include "timer.h" +#include "rtc.h" +#include "ui.h" + +u64 osclock; + +static inline bool isLeapYear(u32 year) { + return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); +} + +size_t getWeekday(bool abbreviated, char* out, u8 weekday) { + if (abbreviated) { + switch(weekday) { + case 1: + strcat(out, "Mon"); + break; + case 2: + strcat(out, "Tue"); + break; + case 3: + strcat(out, "Wed"); + break; + case 4: + strcat(out, "Thu"); + break; + case 5: + strcpy(out, "Fri"); + break; + case 6: + strcat(out, "Sat"); + break; + case 0: + case 7: + strcat(out, "Sun"); + break; + default: + strcat(out, ""); + return 0; + } + return 3; + } + switch(weekday) { + case 1: + strcat(out, "Monday"); + return 6; + case 2: + strcat(out, "Tuesday"); + return 7; + case 3: + strcat(out, "Wednesday"); + return 9; + case 4: + strcat(out, "Thursday"); + return 8; + case 5: + strcpy(out, "Friday"); + return 6; + case 6: + strcat(out, "Saturday"); + return 8; + case 7: + case 0: + strcat(out, "Sunday"); + return 6; + default: + strcat(out, ""); + return 0; + } + return 0; + +} + +size_t getMonthName(bool abbreviated, char* out, u8 month) { + if (abbreviated) { + switch(month) { + case 1: + strcat(out, "Jan"); + break; + case 2: + strcat(out, "Feb"); + break; + case 3: + strcat(out, "Mar"); + break; + case 4: + strcat(out, "Apr"); + break; + case 5: + strcat(out, "May"); + break; + case 6: + strcat(out, "Jun"); + break; + case 7: + strcat(out, "Jul"); + break; + case 8: + strcat(out, "Aug"); + break; + case 9: + strcat(out, "Sep"); + break; + case 10: + strcat(out, "Oct"); + break; + case 11: + strcat(out, "Nov"); + break; + case 12: + strcat(out, "Dec"); + break; + default: + strcat(out, ""); + return 0; + } + return 3; + } + switch(month) { + case 1: + strcat(out, "January"); + return 7; + case 2: + strcat(out, "February"); + return 8; + case 3: + strcat(out, "March"); + return 5; + case 4: + strcat(out, "April"); + return 5; + case 5: + strcat(out, "May"); + return 3; + case 6: + strcat(out, "Juny"); + return 4; + case 7: + strcat(out, "July"); + return 4; + case 8: + strcat(out, "August"); + return 6; + case 9: + strcat(out, "September"); + return 9; + case 10: + strcat(out, "October"); + return 7; + case 11: + strcat(out, "November"); + return 8; + case 12: + strcat(out, "December"); + return 8; + default: + strcat(out, ""); + return 0; + } + return 0; +} + +u16 getDaysMonths(u32 months, u8 years) { + u8 daysInMonth[12] = {31, isLeapYear(2000 + years) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //is this ?: bad practice? + u16 ret; + for (u32 month = 0; month < months - 1; month++) { + ret += daysInMonth[month]; + } + return ret; +} + +u64 calcUnixTime(u8 years, u8 months, u8 days, u8 hours, u8 minutes, u8 seconds) { + u8 daysInMonth[12] = {31, isLeapYear(2000 + years) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //is this ?: bad practice? + u32 curdays; + u64 ret = 0; + + ret += seconds; + ret += minutes * 60; + ret += hours * 60 * 60; + ret += (days - 1) * 24 * 60 * 60; + + for (u16 year = 0; year < years + 30; year++) { //+30 because unix time starting in 1970 but rtc starts in 2000 + if (isLeapYear(2000 + year)) { + curdays = 366; + } else { + curdays = 365; + } + ret += curdays * 24 * 60 * 60; + } + + for (u16 month = 0; month < months - 1; month++) { + ret += daysInMonth[month] * 24 * 60 * 60; + } + + return ret; +} + +u64 getUnixTimeFromRtc(DsTime *dstime) { + + u8 + seconds = DSTIMEGET(dstime, bcd_s), + minutes = DSTIMEGET(dstime, bcd_m), + hours = DSTIMEGET(dstime, bcd_h), + days = DSTIMEGET(dstime, bcd_D), + months = DSTIMEGET(dstime, bcd_M), + years = DSTIMEGET(dstime, bcd_Y); + return calcUnixTime(years, months, days, hours, minutes, seconds); + +} + +u64 timer_usec( u64 start_time ) { + return timer_ticks( start_time ) / (TICKS_PER_SEC/1000000); +} + +void weekdayfix(DsTime *dstime) { + int days = getUnixTimeFromRtc(dstime) / 86400; //days since thursday 1 1 1970 + u8 weekday = (days + 5) % 7; + dstime->weekday = NUM2BCD(weekday); +} + +void unixtodstime(u64 unixtime, DsTime *dstime) { + u32 seconds, minutes, hours, days, year, month; + seconds = unixtime; + minutes = seconds / 60; + seconds %= 60; + hours = minutes / 60; + minutes %= 60; + days = hours / 24; + hours %= 24; + year = 1970; + + while(true) + { + bool leapYear = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); + u16 daysInYear = leapYear ? 366 : 365; + if(days >= daysInYear) + { + days -= daysInYear; + ++year; + } + else + { + static const u8 daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + for(month = 0; month < 12; ++month) + { + u8 dim = daysInMonth[month]; + + if (month == 1 && leapYear) + ++dim; + + if (days >= dim) + days -= dim; + else + break; + } + break; + } + } + days++; + month++; + u8 bcd_year = year-2000; + dstime->bcd_Y = NUM2BCD(bcd_year); + dstime->bcd_M = NUM2BCD(month); + dstime->bcd_D = NUM2BCD(days); + dstime->bcd_h = NUM2BCD(hours); + dstime->bcd_m = NUM2BCD(minutes); + dstime->bcd_s = NUM2BCD(seconds); + dstime->weekday = 0; +} + +bool my_strftime(char* _out, size_t _maxsize, const char* str, DsTime *dstime) { //my refers to github.com/Gruetzig + weekdayfix(dstime); + size_t strl = strlen(str); + size_t outpos = 0; + char out[_maxsize+10]; + memset(out, 0, _maxsize+10); + u8 minute, hour, day, month, year, weekday, second, weeknumber; + u16 currentday, nextsunday, fyear; + char numbuf[3], numbuf2[5], numbuf3[9], numnum1[3], numnum2[3], numnum3[3]; + if (!is_valid_dstime(dstime)) { + return false; + } + for (size_t i = 0;i 12) { + hour = hour - 12; + } + if (!hour) { + hour = 12; + } + if (hour < 10) { + sprintf(numbuf, "0%d", hour); + } else { + sprintf(numbuf, "%d", hour); + } + strcat(out, numbuf); + outpos += 2; + break; + case 'j': + currentday = getDaysMonths(DSTIMEGET(dstime, bcd_M), DSTIMEGET(dstime, bcd_Y))+DSTIMEGET(dstime, bcd_D); + if (currentday < 10) { + sprintf(numbuf, "00%d", currentday); + } else if (currentday < 100) { + sprintf(numbuf, "0%d", currentday); + } else { + sprintf(numbuf, "%d", currentday); + } + strcat(out, numbuf); + outpos += 3; + break; + case 'm': + month = DSTIMEGET(dstime, bcd_M); + if (month < 10) { + sprintf(numbuf, "0%d", month); + } else { + sprintf(numbuf, "%d", month); + } + strcat(out, numbuf); + outpos += 2; + break; + case 'M': + minute = DSTIMEGET(dstime, bcd_m); + if (minute < 10) { + sprintf(numbuf, "0%d", minute); + } else { + sprintf(numbuf, "%d", minute); + } + strcat(out, numbuf); + outpos += 2; + break; + case 'p': + hour = DSTIMEGET(dstime, bcd_h); + if (hour >= 12) { + strcat(out, "PM"); + } else { + strcat(out, "AM"); + } + outpos += 2; + break; + case 'S': + second = DSTIMEGET(dstime, bcd_m); + if (second < 10) { + sprintf(numbuf, "0%d", second); + } else { + sprintf(numbuf, "%d", second); + } + strcat(out, numbuf); + outpos += 2; + break; + case 'U': + currentday = getDaysMonths(DSTIMEGET(dstime, bcd_M), DSTIMEGET(dstime, bcd_Y))+DSTIMEGET(dstime, bcd_D); + weekday = DSTIMEGET(dstime, weekday); + nextsunday = ((7-weekday)+currentday); + weeknumber = (nextsunday/7)+1; + if (weeknumber < 10) { + sprintf(numbuf, "0%d", weeknumber); + } else { + sprintf(numbuf, "%d", weeknumber); + } + strcat(out, numbuf); + outpos += 2; + break; + case 'w': + weekday = DSTIMEGET(dstime, weekday); + if (weekday == 7) { + weekday = 0; + } + sprintf(out, "%d", weekday); + strcat(out, numbuf); + outpos++; + break; + case 'W': + currentday = getDaysMonths(DSTIMEGET(dstime, bcd_M), DSTIMEGET(dstime, bcd_Y))+DSTIMEGET(dstime, bcd_D); + weekday = DSTIMEGET(dstime, weekday); + nextsunday = ((8-weekday)+currentday); + weeknumber = (nextsunday/7); + if (weeknumber < 10) { + sprintf(numbuf, "0%d", weeknumber); + } else { + sprintf(numbuf, "%d", weeknumber); + } + strcat(out, numbuf); + outpos += 2; + break; + case 'x': + month = DSTIMEGET(dstime, bcd_M); + day = DSTIMEGET(dstime, bcd_D); + year = DSTIMEGET(dstime, bcd_Y); + + if (month < 10) { + sprintf(numnum1, "0%d", month); + } else { + sprintf(numnum1, "%d", month); + } + + if (day < 10) { + sprintf(numnum2, "0%d", day); + } else { + sprintf(numnum2, "%d", day); + } + + if (year < 10) { + sprintf(numnum3, "0%d", year); + } else { + sprintf(numnum3, "%d", year); + } + sprintf(numbuf3, "%s/%s/%s", numnum1, numnum2, numnum3); + strcat(out, numbuf3); + outpos += 8; + break; + case 'X': + hour = DSTIMEGET(dstime, bcd_h); + minute = DSTIMEGET(dstime, bcd_m); + second = DSTIMEGET(dstime, bcd_s); + + if (hour < 10) { + sprintf(numnum1, "0%d", hour); + } else { + sprintf(numnum1, "%d", hour); + } + + if (minute < 10) { + sprintf(numnum2, "0%d", minute); + } else { + sprintf(numnum2, "%d", minute); + } + + if (second < 10) { + sprintf(numnum3, "0%d", second); + } else { + sprintf(numnum3, "%d", second); + } + sprintf(numbuf3, "%s:%s:%s", numnum1, numnum2, numnum3); + strcat(out, numbuf3); + outpos += 8; + break; + case 'y': + year = DSTIMEGET(dstime, bcd_Y); + if (year < 10) { + sprintf(numbuf, "0%d", year); + } else { + sprintf(numbuf, "%d", year); + } + strcat(out, numbuf); + outpos += 2; + break; + case 'Y': + fyear = DSTIMEGET(dstime, bcd_Y); + fyear += 2000; + sprintf(numbuf2, "%d", fyear); + strcat(out, numbuf2); + outpos += 4; + break; + case '%': + strcat(out, "%"); + outpos++; + break; + default: + break; //not implemented + + + } + + } else { + out[outpos] = str[i]; + outpos++; + } + if (outpos > _maxsize) { + break; + } + + } + strncpy(_out, out, _maxsize); + return true; +} + +static int os_time(lua_State *L) { + int args = lua_gettop(L); + u64 unixtime; + switch(args) { + case 0: + DsTime dstime; + get_dstime(&dstime); + unixtime = getUnixTimeFromRtc(&dstime); + lua_pushinteger(L, unixtime); + return 1; + case 1: + lua_geti(L, 1, 1); + int year = lua_tointeger(L, -1); + lua_pop(L, 1); + if (year >= 2000) year -= 2000; + + lua_geti(L, 1, 2); + int month = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_geti(L, 1, 3); + int day = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_geti(L, 1, 4); + int hour = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_geti(L, 1, 5); + int minute = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_geti(L, 1, 6); + int second = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_pushinteger(L, calcUnixTime(year, month, day, hour, minute, second)); + + return 1; + default: + return luaL_error(L, "not a valid amount of arguments"); + + } +} + +static int os_date(lua_State *L) { + DsTime dstime; + + get_dstime(&dstime); + char retbuf[100]; + memset(retbuf, 0, 100); + int args = lua_gettop(L); + switch(args) { + case 0: + my_strftime(retbuf, 100, "%c", &dstime); + lua_pushstring(L, retbuf); + return 1; + case 1: + const char* str = lua_tostring(L, 1); + if ((strcmp(str, "*t") == 0 || strcmp(str, "!*t") == 0)) { + weekdayfix(&dstime); + //return table with date values + lua_newtable(L); + //year + lua_pushinteger(L, 2000+DSTIMEGET(&dstime, bcd_Y)); + lua_setfield(L, -2, "year"); + //month + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_M)); + lua_setfield(L, -2, "month"); + //wday (weekday) + lua_pushinteger(L, DSTIMEGET(&dstime, weekday)); + lua_setfield(L, -2, "wday"); + //yday (yearday) + lua_pushinteger(L, getDaysMonths(DSTIMEGET(&dstime, bcd_M), DSTIMEGET(&dstime, bcd_Y))+DSTIMEGET(&dstime, bcd_D)); + lua_setfield(L, -2, "yday"); + //day + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_D)); + lua_setfield(L, -2, "day"); + //hour + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_h)); + lua_setfield(L, -2, "hour"); + //minute + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_m)); + lua_setfield(L, -2, "min"); + //second + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_s)); + lua_setfield(L, -2, "sec"); + return 1; + } else { + my_strftime(retbuf, 100, lua_tostring(L, 1), &dstime); + lua_pushstring(L, retbuf); + return 1; + } + case 2: + if (lua_tointeger(L, 2) < 946684800) { //unix timestamp is 01.01.2000 00:00:00, so everything before is previous century and not supported + return luaL_error(L, "unix timestamp from before 2000 is not supported"); + } + const char* str2 = lua_tostring(L, 1); + if ((strcmp(str2, "*t") == 0 || strcmp(str2, "!*t") == 0)) { + unixtodstime( lua_tointeger(L, 2) , &dstime); + weekdayfix(&dstime); + //return table with date values + lua_newtable(L); + //year + lua_pushinteger(L, 2000+DSTIMEGET(&dstime, bcd_Y)); + lua_setfield(L, -2, "year"); + //month + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_M)); + lua_setfield(L, -2, "month"); + //wday (weekday) + lua_pushinteger(L, DSTIMEGET(&dstime, weekday)); + lua_setfield(L, -2, "wday"); + //yday (yearday) + lua_pushinteger(L, getDaysMonths(DSTIMEGET(&dstime, bcd_M), DSTIMEGET(&dstime, bcd_Y))+DSTIMEGET(&dstime, bcd_D)); + lua_setfield(L, -2, "yday"); + //day + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_D)); + lua_setfield(L, -2, "day"); + //hour + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_h)); + lua_setfield(L, -2, "hour"); + //minute + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_m)); + lua_setfield(L, -2, "min"); + //second + lua_pushinteger(L, DSTIMEGET(&dstime, bcd_s)); + lua_setfield(L, -2, "sec"); + return 1; + } else { + unixtodstime( lua_tointeger(L, 2) , &dstime); + my_strftime(retbuf, 100, str2, &dstime); + lua_pushstring(L, retbuf); + return 1; + } + + default: + return luaL_error(L, "not a valid amount of arguments"); + } +} + +static int os_clock(lua_State *L) { + lua_pushnumber(L, timer_usec(osclock)/10000000.0); + return 1; +} + +static int os_difftime(lua_State *L) { + u64 t2 = lua_tointeger(L, 1); + u64 t1 = lua_tointeger(L, 2); + lua_pushinteger(L, t2-t1); + return 1; +} + +// os.remove and os.rename are done in data/luapackages/fs.lua +static const luaL_Reg os[] = { + {"clock", os_clock}, + {"time", os_time}, + {"date", os_date}, + {"difftime", os_difftime}, + {NULL, NULL} +}; + +int gm9lua_open_os(lua_State* L) { + luaL_newlib(L, os); + osclock = timer_start(); + return 1; +} +#endif diff --git a/arm9/source/lua/gm9os.h b/arm9/source/lua/gm9os.h new file mode 100644 index 000000000..b737953b5 --- /dev/null +++ b/arm9/source/lua/gm9os.h @@ -0,0 +1,6 @@ +#pragma once +#include "gm9lua.h" + +#define GM9LUA_OSLIBNAME "os" + +int gm9lua_open_os(lua_State* L); \ No newline at end of file diff --git a/arm9/source/lua/gm9title.c b/arm9/source/lua/gm9title.c new file mode 100644 index 000000000..66ac07431 --- /dev/null +++ b/arm9/source/lua/gm9title.c @@ -0,0 +1,183 @@ +#ifndef NO_LUA +#include "gm9lua.h" +#include "utils.h" +#include "fs.h" +#include "language.h" +#include "ui.h" +#include "game.h" +#include "ips.h" +#include "bps.h" + +static int title_decrypt(lua_State* L) { + CheckLuaArgCount(L, 1, "title.decrypt"); + const char* path = luaL_checkstring(L, 1); + const char* whichfailed = ""; + + u64 filetype = IdentifyFileType(path); + bool ret; + if (filetype & BIN_KEYDB) { + ret = (CryptAesKeyDb(path, true, false) == 0); + whichfailed = "CryptAesKeyDb"; + } else { + ret = (CryptGameFile(path, true, false) == 0); + whichfailed = "CryptGameFile"; + } + + if (!ret) { + return luaL_error(L, "%s failed on %s", whichfailed, path); + } + + return 0; +} + +static int title_encrypt(lua_State* L) { + CheckLuaArgCount(L, 1, "title.encrypt"); + const char* path = luaL_checkstring(L, 1); + const char* whichfailed = ""; + + u64 filetype = IdentifyFileType(path); + bool ret; + if (filetype & BIN_KEYDB) { + ret = (CryptAesKeyDb(path, true, true) == 0); + whichfailed = "CryptAesKeyDb"; + } else { + ret = (CryptGameFile(path, true, true) == 0); + whichfailed = "CryptGameFile"; + } + + if (!ret) { + return luaL_error(L, "%s failed on %s", whichfailed, path); + } + + return 0; +} + +static int title_install(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 1, "title.install"); + const char* path = luaL_checkstring(L, 1); + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 2, flags, TO_EMUNAND); + }; + + bool ret = (InstallGameFile(path, (flags & TO_EMUNAND)) == 0); + if (!ret) { + return luaL_error(L, "InstallGameFile failed on %s", path); + } + + return 0; +} + +static int title_build_cia(lua_State* L) { + bool extra = CheckLuaArgCountPlusExtra(L, 1, "title.build_cia"); + const char* path = luaL_checkstring(L, 1); + + u32 flags = 0; + if (extra) { + flags = GetFlagsFromTable(L, 2, flags, LEGIT); + }; + + bool ret = (BuildCiaFromGameFile(path, (flags & LEGIT)) == 0); + if (!ret) { + return luaL_error(L, "BuildCiaFromGameFile failed on %s", path); + } + + return 0; +} + +static int title_extract_code(lua_State* L) { + CheckLuaArgCount(L, 2, "title.extract_code"); + const char* path_src = luaL_checkstring(L, 1); + const char* path_dst = luaL_checkstring(L, 2); + + u64 filetype = IdentifyFileType(path_src); + if (!FTYPE_HASCODE(filetype)) { + return luaL_error(L, "%s does not have code", path_src); + } else { + CheckWritePermissionsLuaError(L, path_dst); + ShowString("%s", STR_EXTRACTING_DOT_CODE); + bool ret = (ExtractCodeFromCxiFile(path_src, path_dst, NULL) == 0); + if (!ret) { + return luaL_error(L, "failed to extract code from %s", path_src); + } + } + + return 0; +} + +static int title_compress_code(lua_State* L) { + CheckLuaArgCount(L, 2, "title.compress_code"); + const char* path_src = luaL_checkstring(L, 1); + const char* path_dst = luaL_checkstring(L, 2); + + CheckWritePermissionsLuaError(L, path_dst); + ShowString("%s", STR_COMPRESSING_DOT_CODE); + bool ret = (CompressCode(path_src, path_dst) == 0); + if (!ret) { + return luaL_error(L, "failed to compress code from %s", path_src); + } + + return 0; +} + +static int title_apply_ips(lua_State* L) { + CheckLuaArgCount(L, 3, "title.apply_ips"); + const char* path_patch = luaL_checkstring(L, 1); + const char* path_src = luaL_checkstring(L, 2); + const char* path_target = luaL_checkstring(L, 3); + + bool ret = (ApplyIPSPatch(path_patch, path_src, path_target) == 0); + if (!ret) { + return luaL_error(L, "ApplyIPSPatch failed"); + } + + return 0; +} + +static int title_apply_bps(lua_State* L) { + CheckLuaArgCount(L, 3, "title.apply_bps"); + const char* path_patch = luaL_checkstring(L, 1); + const char* path_src = luaL_checkstring(L, 2); + const char* path_target = luaL_checkstring(L, 3); + + bool ret = (ApplyBPSPatch(path_patch, path_src, path_target) == 0); + if (!ret) { + return luaL_error(L, "ApplyBPSPatch failed"); + } + + return 0; +} + +static int title_apply_bpm(lua_State* L) { + CheckLuaArgCount(L, 3, "title.apply_bpm"); + const char* path_patch = luaL_checkstring(L, 1); + const char* path_src = luaL_checkstring(L, 2); + const char* path_target = luaL_checkstring(L, 3); + + bool ret = (ApplyBPMPatch(path_patch, path_src, path_target) == 0); + if (!ret) { + return luaL_error(L, "ApplyBPMPatch failed"); + } + + return 0; +} + +static const luaL_Reg title_lib[] = { + {"decrypt", title_decrypt}, + {"encrypt", title_encrypt}, + {"install", title_install}, + {"build_cia", title_build_cia}, + {"extract_code", title_extract_code}, + {"compress_code", title_compress_code}, + {"apply_ips", title_apply_ips}, + {"apply_bps", title_apply_bps}, + {"apply_bpm", title_apply_bpm}, + {NULL, NULL} +}; + +int gm9lua_open_title(lua_State* L) { + luaL_newlib(L, title_lib); + return 1; +} +#endif diff --git a/arm9/source/lua/gm9title.h b/arm9/source/lua/gm9title.h new file mode 100644 index 000000000..530c7c83c --- /dev/null +++ b/arm9/source/lua/gm9title.h @@ -0,0 +1,6 @@ +#pragma once +#include "gm9lua.h" + +#define GM9LUA_TITLELIBNAME "title" + +int gm9lua_open_title(lua_State* L); diff --git a/arm9/source/lua/gm9ui.c b/arm9/source/lua/gm9ui.c new file mode 100644 index 000000000..09df39529 --- /dev/null +++ b/arm9/source/lua/gm9ui.c @@ -0,0 +1,360 @@ +#ifndef NO_LUA +#include "gm9ui.h" +#include "ui.h" +#include "fs.h" +#include "png.h" +#include "swkbd.h" +#include "qrcodegen.h" +#include "utils.h" +#include "hid.h" + +#define MAXOPTIONS 256 +#define MAXOPTIONS_STR "256" + +#define OUTPUTMAXLINES 24 +#define OUTPUTMAXCHARSPERLINE 80 // make sure this includes space for '\0' + +// this output buffer stuff is especially a test, it needs to take into account newlines and fonts that are not 8x10 + +char output_buffer[OUTPUTMAXLINES][OUTPUTMAXCHARSPERLINE]; // hold 24 lines + +void ShiftOutputBufferUp(void) { + for (int i = 0; i < OUTPUTMAXLINES - 1; i++) { + memcpy(output_buffer[i], output_buffer[i + 1], OUTPUTMAXCHARSPERLINE); + } +} + +void ClearOutputBuffer(void) { + memset(output_buffer, 0, sizeof(output_buffer)); +} + +void WriteToOutputBuffer(char* text) { + strlcpy(output_buffer[OUTPUTMAXLINES - 1], text, OUTPUTMAXCHARSPERLINE); +} + +void RenderOutputBuffer(void) { + ClearScreenF(false, true, COLOR_STD_BG); + for (int i = 0; i < OUTPUTMAXLINES; i++) { + DrawString(ALT_SCREEN, output_buffer[i], 0, i * 10, COLOR_STD_FONT, COLOR_TRANSPARENT); + } +} + +static int ui_echo(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.echo"); + const char* text = lua_tostring(L, 1); + + ShowPrompt(false, "%s", text); + return 0; +} + +static int ui_ask(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.ask"); + const char* text = lua_tostring(L, 1); + + bool ret = ShowPrompt(true, "%s", text); + lua_pushboolean(L, ret); + return 1; +} + +static int ui_ask_hex(lua_State* L) { + CheckLuaArgCount(L, 3, "ui.ask_hex"); + const char* text = lua_tostring(L, 1); + u64 initial_hex = lua_tonumber(L, 2); + u32 n_digits = lua_tonumber(L, 3); + + u64 ret = ShowHexPrompt(initial_hex, n_digits, "%s", text); + if (ret == (u64) -1) { + lua_pushnil(L); + } else { + lua_pushnumber(L, ret); + } + return 1; +} + +static int ui_ask_number(lua_State* L) { + CheckLuaArgCount(L, 2, "ui.ask_number"); + const char* text = lua_tostring(L, 1); + u64 initial_num = lua_tonumber(L, 2); + + u64 ret = ShowNumberPrompt(initial_num, "%s", text); + if (ret == (u64) -1) { + lua_pushnil(L); + } else { + lua_pushnumber(L, ret); + } + return 1; + +} + +static int ui_ask_text(lua_State* L) { + CheckLuaArgCount(L, 3, "ui.ask_text"); + const char* prompt = lua_tostring(L, 1); + const char* _initial_text = lua_tostring(L, 2); + u32 initial_text_size = strlen(_initial_text)+1; + char initial_text[initial_text_size]; + snprintf(initial_text, initial_text_size, "%s", _initial_text); + u32 max_size = lua_tonumber(L, 3); + bool result = ShowKeyboardOrPrompt(initial_text, max_size, "%s", prompt); + if (result) + lua_pushstring(L, initial_text); + else + lua_pushnil(L); + return 1; +} + +static int ui_clear(lua_State* L) { + CheckLuaArgCount(L, 0, "ui.clear"); + + ClearScreen(ALT_SCREEN, COLOR_STD_BG); + + return 0; +} + +static int ui_show_png(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.show_png"); + const char* path = luaL_checkstring(L, 1); + u16 *screen = ALT_SCREEN; + u16 *bitmap = NULL; + u8* png = (u8*) malloc(SCREEN_SIZE(screen)); + u32 bitmap_width, bitmap_height; + if (png) { + u32 png_size = FileGetData(path, png, SCREEN_SIZE(screen), 0); + if (!png_size) { + free(png); + return luaL_error(L, "Could not read %s", path); + } + if (png_size && png_size < SCREEN_SIZE(screen)) { + bitmap = PNG_Decompress(png, png_size, &bitmap_width, &bitmap_height); + if (!bitmap) { + free(png); + return luaL_error(L, "Invalid PNG file"); + } + } + free(png); + if (!bitmap) { + return luaL_error(L, "PNG too large"); + } else if ((SCREEN_WIDTH(screen) < bitmap_width) || (SCREEN_HEIGHT < bitmap_height)) { + free(bitmap); + return luaL_error(L, "PNG too large"); + } else { + ClearScreen(ALT_SCREEN, COLOR_STD_BG); + DrawBitmap( + screen, // screen + -1, // x coordinate from argument + -1, // y coordinate from argument + bitmap_width, // width + bitmap_height, // height + bitmap // bitmap + ); + free(bitmap); + } + } + return 0; +} + +static int ui_show_text(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.show_text"); + + const char* text = lua_tostring(L, 1); + + ClearScreen(ALT_SCREEN, COLOR_STD_BG); + DrawStringCenter(ALT_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", text); + return 0; +} + +static int ui_show_game_info(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.show_game_info"); + const char* path = luaL_checkstring(L, 1); + + bool ret = (ShowGameFileIcon(path, ALT_SCREEN) == 0); + if (!ret) { + return luaL_error(L, "ShowGameFileIcon failed on %s", path); + } + + return 0; +} + +static int ui_show_qr(lua_State* L) { + CheckLuaArgCount(L, 2, "ui.show_qr"); + size_t data_len; + const char* text = luaL_checkstring(L, 1); + const char* data = luaL_checklstring(L, 2, &data_len); + + const u32 screen_size = SCREEN_SIZE(ALT_SCREEN); + u8* screen_copy = (u8*) malloc(screen_size); + u8 qrcode[qrcodegen_BUFFER_LEN_MAX]; + u8 temp[qrcodegen_BUFFER_LEN_MAX]; + bool ret = screen_copy && qrcodegen_encodeText(data, temp, qrcode, qrcodegen_Ecc_LOW, + qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true); + if (ret) { + memcpy(screen_copy, ALT_SCREEN, screen_size); + DrawQrCode(ALT_SCREEN, qrcode); + ShowPrompt(false, "%s", text); + memcpy(ALT_SCREEN, screen_copy, screen_size); + } else { + return luaL_error(L, "could not allocate memory"); + } + free(screen_copy); + + return 0; +} + +static int ui_show_text_viewer(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.show_text_viewer"); + size_t len = 0; + const char* text = luaL_tolstring(L, 1, &len); + + // validate text ourselves so we can return a better error + // MemTextViewer calls ShowPrompt if it's bad, and i don't want that + + if (!(ValidateText(text, len))) { + return luaL_error(L, "text validation failed"); + } + + if (!(MemTextViewer(text, len, 1, false))) { + return luaL_error(L, "failed to run MemTextViewer"); + } + + return 0; +} + +static int ui_show_file_text_viewer(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.show_file_text_viewer"); + const char* path = luaL_checkstring(L, 1); + + // validate text ourselves so we can return a better error + // MemTextViewer calls ShowPrompt if it's bad, and i don't want that + // and FileTextViewer calls the above function + + char* text = malloc(STD_BUFFER_SIZE); + if (!text) { + return luaL_error(L, "could not allocate memory"); + }; + + // TODO: replace this with something that can detect file read errors and actual 0-length files + size_t flen = FileGetData(path, text, STD_BUFFER_SIZE - 1, 0); + + text[flen] = '\0'; + u32 len = (ptrdiff_t)memchr(text, '\0', flen + 1) - (ptrdiff_t)text; + + if (!(ValidateText(text, len))) { + free(text); + return luaL_error(L, "text validation failed"); + } + + if (!(MemTextViewer(text, len, 1, false))) { + free(text); + return luaL_error(L, "failed to run MemTextViewer"); + } + + free(text); + + return 0; +} + +static int ui_ask_selection(lua_State* L) { + CheckLuaArgCount(L, 2, "ui.ask_selection"); + const char* text = lua_tostring(L, 1); + char* options[MAXOPTIONS]; + const char* tmpstr; + size_t len; + int i; + + luaL_argcheck(L, lua_istable(L, 2), 2, "table expected"); + + lua_Integer opttablesize = luaL_len(L, 2); + luaL_argcheck(L, opttablesize <= MAXOPTIONS, 2, "more than " MAXOPTIONS_STR " options given"); + for (i = 0; i < opttablesize; i++) { + lua_geti(L, 2, i + 1); + tmpstr = lua_tolstring(L, -1, &len); + options[i] = malloc(len + 1); + strlcpy(options[i], tmpstr, len + 1); + lua_pop(L, 1); + } + int result = ShowSelectPrompt(opttablesize, (const char**)options, "%s", text); + for (i = 0; i < opttablesize; i++) free(options[i]); + // lua only treats "false" and "nil" as false values + // so to make this easier, return nil and not 0 if no choice was made + // https://www.lua.org/manual/5.4/manual.html#3.3.4 + if (result) + lua_pushinteger(L, result); + else + lua_pushnil(L); + return 1; +} + +static int ui_format_bytes(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.format_bytes"); + lua_Integer size = luaL_checkinteger(L, 1); + + char bytesstr[32] = { 0 }; + FormatBytes(bytesstr, (u64)size); + + lua_pushstring(L, bytesstr); + return 1; +} + +static int ui_global_print(lua_State* L) { + //const char* text = lua_tostring(L, 1); + char buf[OUTPUTMAXCHARSPERLINE] = {0}; + int argcount = lua_gettop(L); + for (int i = 0; i < lua_gettop(L); i++) { + const char* str = luaL_tolstring(L, i+1, NULL); + if (str) { + strlcat(buf, str, OUTPUTMAXCHARSPERLINE); + lua_pop(L, 1); + } else { + // idk + strlcat(buf, "(unknown)", OUTPUTMAXCHARSPERLINE); + } + if (i < argcount) strlcat(buf, " ", OUTPUTMAXCHARSPERLINE); + } + ShiftOutputBufferUp(); + WriteToOutputBuffer((char*)buf); + RenderOutputBuffer(); + return 0; +} + +// TODO: use luaL_checkoption which will auto-raise an error +// use BUTTON_STRINGS from common/hid_map.h +static int ui_check_key(lua_State* L) { + CheckLuaArgCount(L, 1, "ui.check_key"); + const char* key = luaL_checkstring(L, 1); + + lua_pushboolean(L, CheckButton(StringToButton((char*)key))); + + return 1; +} + +static const luaL_Reg ui_lib[] = { + {"echo", ui_echo}, + {"ask", ui_ask}, + {"ask_hex", ui_ask_hex}, + {"ask_number", ui_ask_number}, + {"ask_text", ui_ask_text}, + {"ask_selection", ui_ask_selection}, + {"clear", ui_clear}, + {"show_png", ui_show_png}, + {"show_text", ui_show_text}, + {"show_game_info", ui_show_game_info}, + {"show_qr", ui_show_qr}, + {"show_text_viewer", ui_show_text_viewer}, + {"show_file_text_viewer", ui_show_file_text_viewer}, + {"format_bytes", ui_format_bytes}, + {"check_key", ui_check_key}, + {NULL, NULL} +}; + +static const luaL_Reg ui_global_lib[] = { + {"print", ui_global_print}, + {NULL, NULL} +}; + +int gm9lua_open_ui(lua_State* L) { + luaL_newlib(L, ui_lib); + lua_pushglobaltable(L); // push global table to stack + luaL_setfuncs(L, ui_global_lib, 0); // set global funcs + lua_pop(L, 1); // pop global table from stack + return 1; +} +#endif diff --git a/arm9/source/lua/gm9ui.h b/arm9/source/lua/gm9ui.h new file mode 100644 index 000000000..00f3ffa8f --- /dev/null +++ b/arm9/source/lua/gm9ui.h @@ -0,0 +1,10 @@ +#pragma once +#include "gm9lua.h" + +#define GM9LUA_UILIBNAME "ui" + +void ShiftOutputBufferUp(void); +void ClearOutputBuffer(void); +void RenderOutputBuffer(void); +void WriteToOutputBuffer(char* text); +int gm9lua_open_ui(lua_State* L); diff --git a/arm9/source/lua/lapi.c b/arm9/source/lua/lapi.c new file mode 100644 index 000000000..332e97d16 --- /dev/null +++ b/arm9/source/lua/lapi.c @@ -0,0 +1,1463 @@ +/* +** $Id: lapi.c $ +** Lua API +** See Copyright Notice in lua.h +*/ + +#define lapi_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$LuaVersion: " LUA_COPYRIGHT " $" + "$LuaAuthors: " LUA_AUTHORS " $"; + + + +/* +** Test for a valid index (one that is not the 'nilvalue'). +** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed. +** However, it covers the most common cases in a faster way. +*/ +#define isvalid(L, o) (!ttisnil(o) || o != &G(L)->nilvalue) + + +/* test for pseudo index */ +#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) + +/* test for upvalue */ +#define isupvalue(i) ((i) < LUA_REGISTRYINDEX) + + +/* +** Convert an acceptable index to a pointer to its respective value. +** Non-valid indices return the special nil value 'G(L)->nilvalue'. +*/ +static TValue *index2value (lua_State *L, int idx) { + CallInfo *ci = L->ci; + if (idx > 0) { + StkId o = ci->func.p + idx; + api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index"); + if (o >= L->top.p) return &G(L)->nilvalue; + else return s2v(o); + } + else if (!ispseudo(idx)) { /* negative index */ + api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1), + "invalid index"); + return s2v(L->top.p + idx); + } + else if (idx == LUA_REGISTRYINDEX) + return &G(L)->l_registry; + else { /* upvalues */ + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); + if (ttisCclosure(s2v(ci->func.p))) { /* C closure? */ + CClosure *func = clCvalue(s2v(ci->func.p)); + return (idx <= func->nupvalues) ? &func->upvalue[idx-1] + : &G(L)->nilvalue; + } + else { /* light C function or Lua function (through a hook)?) */ + api_check(L, ttislcf(s2v(ci->func.p)), "caller not a C function"); + return &G(L)->nilvalue; /* no upvalues */ + } + } +} + + + +/* +** Convert a valid actual index (not a pseudo-index) to its address. +*/ +l_sinline StkId index2stack (lua_State *L, int idx) { + CallInfo *ci = L->ci; + if (idx > 0) { + StkId o = ci->func.p + idx; + api_check(L, o < L->top.p, "invalid index"); + return o; + } + else { /* non-positive index */ + api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1), + "invalid index"); + api_check(L, !ispseudo(idx), "invalid index"); + return L->top.p + idx; + } +} + + +LUA_API int lua_checkstack (lua_State *L, int n) { + int res; + CallInfo *ci; + lua_lock(L); + ci = L->ci; + api_check(L, n >= 0, "negative 'n'"); + if (L->stack_last.p - L->top.p > n) /* stack large enough? */ + res = 1; /* yes; check is OK */ + else /* need to grow stack */ + res = luaD_growstack(L, n, 0); + if (res && ci->top.p < L->top.p + n) + ci->top.p = L->top.p + n; /* adjust frame top */ + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to), "moving among independent states"); + api_check(from, to->ci->top.p - to->top.p >= n, "stack overflow"); + from->top.p -= n; + for (i = 0; i < n; i++) { + setobjs2s(to, to->top.p, from->top.p + i); + to->top.p++; /* stack already checked by previous 'api_check' */ + } + lua_unlock(to); +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_Number lua_version (lua_State *L) { + UNUSED(L); + return LUA_VERSION_NUM; +} + + + +/* +** basic stack manipulation +*/ + + +/* +** convert an acceptable stack index into an absolute index +*/ +LUA_API int lua_absindex (lua_State *L, int idx) { + return (idx > 0 || ispseudo(idx)) + ? idx + : cast_int(L->top.p - L->ci->func.p) + idx; +} + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top.p - (L->ci->func.p + 1)); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + CallInfo *ci; + StkId func, newtop; + ptrdiff_t diff; /* difference for new top */ + lua_lock(L); + ci = L->ci; + func = ci->func.p; + if (idx >= 0) { + api_check(L, idx <= ci->top.p - (func + 1), "new top too large"); + diff = ((func + 1) + idx) - L->top.p; + for (; diff > 0; diff--) + setnilvalue(s2v(L->top.p++)); /* clear new slots */ + } + else { + api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top"); + diff = idx + 1; /* will "subtract" index (as it is negative) */ + } + api_check(L, L->tbclist.p < L->top.p, "previous pop of an unclosed slot"); + newtop = L->top.p + diff; + if (diff < 0 && L->tbclist.p >= newtop) { + lua_assert(hastocloseCfunc(ci->nresults)); + newtop = luaF_close(L, newtop, CLOSEKTOP, 0); + } + L->top.p = newtop; /* correct top only after closing any upvalue */ + lua_unlock(L); +} + + +LUA_API void lua_closeslot (lua_State *L, int idx) { + StkId level; + lua_lock(L); + level = index2stack(L, idx); + api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist.p == level, + "no variable to close at given level"); + level = luaF_close(L, level, CLOSEKTOP, 0); + setnilvalue(s2v(level)); + lua_unlock(L); +} + + +/* +** Reverse the stack segment from 'from' to 'to' +** (auxiliary to 'lua_rotate') +** Note that we move(copy) only the value inside the stack. +** (We do not move additional fields that may exist.) +*/ +l_sinline void reverse (lua_State *L, StkId from, StkId to) { + for (; from < to; from++, to--) { + TValue temp; + setobj(L, &temp, s2v(from)); + setobjs2s(L, from, to); + setobj2s(L, to, &temp); + } +} + + +/* +** Let x = AB, where A is a prefix of length 'n'. Then, +** rotate x n == BA. But BA == (A^r . B^r)^r. +*/ +LUA_API void lua_rotate (lua_State *L, int idx, int n) { + StkId p, t, m; + lua_lock(L); + t = L->top.p - 1; /* end of stack segment being rotated */ + p = index2stack(L, idx); /* start of segment */ + api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'"); + m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */ + reverse(L, p, m); /* reverse the prefix with length 'n' */ + reverse(L, m + 1, t); /* reverse the suffix */ + reverse(L, p, t); /* reverse the entire segment */ + lua_unlock(L); +} + + +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { + TValue *fr, *to; + lua_lock(L); + fr = index2value(L, fromidx); + to = index2value(L, toidx); + api_check(L, isvalid(L, to), "invalid index"); + setobj(L, to, fr); + if (isupvalue(toidx)) /* function upvalue? */ + luaC_barrier(L, clCvalue(s2v(L->ci->func.p)), fr); + /* LUA_REGISTRYINDEX does not need gc barrier + (collector revisits it before finishing collection) */ + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top.p, index2value(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (isvalid(L, o) ? ttype(o) : LUA_TNONE); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type"); + return ttypename(t); +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (ttislcf(o) || (ttisCclosure(o))); +} + + +LUA_API int lua_isinteger (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return ttisinteger(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + lua_Number n; + const TValue *o = index2value(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (ttisstring(o) || cvt2str(o)); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (ttisfulluserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + const TValue *o1 = index2value(L, index1); + const TValue *o2 = index2value(L, index2); + return (isvalid(L, o1) && isvalid(L, o2)) ? luaV_rawequalobj(o1, o2) : 0; +} + + +LUA_API void lua_arith (lua_State *L, int op) { + lua_lock(L); + if (op != LUA_OPUNM && op != LUA_OPBNOT) + api_checknelems(L, 2); /* all other operations expect two operands */ + else { /* for unary operations, add fake 2nd operand */ + api_checknelems(L, 1); + setobjs2s(L, L->top.p, L->top.p - 1); + api_incr_top(L); + } + /* first operand at top - 2, second at top - 1; result go to top - 2 */ + luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2); + L->top.p--; /* remove second operand */ + lua_unlock(L); +} + + +LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { + const TValue *o1; + const TValue *o2; + int i = 0; + lua_lock(L); /* may call tag method */ + o1 = index2value(L, index1); + o2 = index2value(L, index2); + if (isvalid(L, o1) && isvalid(L, o2)) { + switch (op) { + case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break; + case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; + case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; + default: api_check(L, 0, "invalid option"); + } + } + lua_unlock(L); + return i; +} + + +LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { + size_t sz = luaO_str2num(s, s2v(L->top.p)); + if (sz != 0) + api_incr_top(L); + return sz; +} + + +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { + lua_Number n = 0; + const TValue *o = index2value(L, idx); + int isnum = tonumber(o, &n); + if (pisnum) + *pisnum = isnum; + return n; +} + + +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { + lua_Integer res = 0; + const TValue *o = index2value(L, idx); + int isnum = tointeger(o, &res); + if (pisnum) + *pisnum = isnum; + return res; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + TValue *o; + lua_lock(L); + o = index2value(L, idx); + if (!ttisstring(o)) { + if (!cvt2str(o)) { /* not convertible? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaO_tostring(L, o); + luaC_checkGC(L); + o = index2value(L, idx); /* previous call may reallocate the stack */ + } + if (len != NULL) + *len = tsslen(tsvalue(o)); + lua_unlock(L); + return getstr(tsvalue(o)); +} + + +LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + switch (ttypetag(o)) { + case LUA_VSHRSTR: return tsvalue(o)->shrlen; + case LUA_VLNGSTR: return tsvalue(o)->u.lnglen; + case LUA_VUSERDATA: return uvalue(o)->len; + case LUA_VTABLE: return luaH_getn(hvalue(o)); + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + if (ttislcf(o)) return fvalue(o); + else if (ttisCclosure(o)) + return clCvalue(o)->f; + else return NULL; /* not a C function */ +} + + +l_sinline void *touserdata (const TValue *o) { + switch (ttype(o)) { + case LUA_TUSERDATA: return getudatamem(uvalue(o)); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return touserdata(o); +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +/* +** Returns a pointer to the internal representation of an object. +** Note that ANSI C does not allow the conversion of a pointer to +** function to a 'void*', so the conversion here goes through +** a 'size_t'. (As the returned pointer is only informative, this +** conversion should not be a problem.) +*/ +LUA_API const void *lua_topointer (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + switch (ttypetag(o)) { + case LUA_VLCF: return cast_voidp(cast_sizet(fvalue(o))); + case LUA_VUSERDATA: case LUA_VLIGHTUSERDATA: + return touserdata(o); + default: { + if (iscollectable(o)) + return gcvalue(o); + else + return NULL; + } + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(s2v(L->top.p)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setfltvalue(s2v(L->top.p), n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setivalue(s2v(L->top.p), n); + api_incr_top(L); + lua_unlock(L); +} + + +/* +** Pushes on the stack a string with given length. Avoid using 's' when +** 'len' == 0 (as 's' can be NULL in that case), due to later use of +** 'memcmp' and 'memcpy'. +*/ +LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { + TString *ts; + lua_lock(L); + ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len); + setsvalue2s(L, L->top.p, ts); + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return getstr(ts); +} + + +LUA_API const char *lua_pushstring (lua_State *L, const char *s) { + lua_lock(L); + if (s == NULL) + setnilvalue(s2v(L->top.p)); + else { + TString *ts; + ts = luaS_new(L, s); + setsvalue2s(L, L->top.p, ts); + s = getstr(ts); /* internal copy's address */ + } + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return s; +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + ret = luaO_pushvfstring(L, fmt, argp); + luaC_checkGC(L); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + luaC_checkGC(L); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + lua_lock(L); + if (n == 0) { + setfvalue(s2v(L->top.p), fn); + api_incr_top(L); + } + else { + CClosure *cl; + api_checknelems(L, n); + api_check(L, n <= MAXUPVAL, "upvalue index too large"); + cl = luaF_newCclosure(L, n); + cl->f = fn; + L->top.p -= n; + while (n--) { + setobj2n(L, &cl->upvalue[n], s2v(L->top.p + n)); + /* does not need barrier because closure is white */ + lua_assert(iswhite(cl)); + } + setclCvalue(L, s2v(L->top.p), cl); + api_incr_top(L); + luaC_checkGC(L); + } + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + if (b) + setbtvalue(s2v(L->top.p)); + else + setbfvalue(s2v(L->top.p)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(s2v(L->top.p), p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, s2v(L->top.p), L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + if (luaV_fastget(L, t, str, slot, luaH_getstr)) { + setobj2s(L, L->top.p, slot); + api_incr_top(L); + } + else { + setsvalue2s(L, L->top.p, str); + api_incr_top(L); + luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot); + } + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +/* +** Get the global table in the registry. Since all predefined +** indices in the registry were inserted right when the registry +** was created and never removed, they must always be in the array +** part of the registry. +*/ +#define getGtable(L) \ + (&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1]) + + +LUA_API int lua_getglobal (lua_State *L, const char *name) { + const TValue *G; + lua_lock(L); + G = getGtable(L); + return auxgetstr(L, G, name); +} + + +LUA_API int lua_gettable (lua_State *L, int idx) { + const TValue *slot; + TValue *t; + lua_lock(L); + t = index2value(L, idx); + if (luaV_fastget(L, t, s2v(L->top.p - 1), slot, luaH_get)) { + setobj2s(L, L->top.p - 1, slot); + } + else + luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot); + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { + lua_lock(L); + return auxgetstr(L, index2value(L, idx), k); +} + + +LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { + TValue *t; + const TValue *slot; + lua_lock(L); + t = index2value(L, idx); + if (luaV_fastgeti(L, t, n, slot)) { + setobj2s(L, L->top.p, slot); + } + else { + TValue aux; + setivalue(&aux, n); + luaV_finishget(L, t, &aux, L->top.p, slot); + } + api_incr_top(L); + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +l_sinline int finishrawget (lua_State *L, const TValue *val) { + if (isempty(val)) /* avoid copying empty items to the stack */ + setnilvalue(s2v(L->top.p)); + else + setobj2s(L, L->top.p, val); + api_incr_top(L); + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +static Table *gettable (lua_State *L, int idx) { + TValue *t = index2value(L, idx); + api_check(L, ttistable(t), "table expected"); + return hvalue(t); +} + + +LUA_API int lua_rawget (lua_State *L, int idx) { + Table *t; + const TValue *val; + lua_lock(L); + api_checknelems(L, 1); + t = gettable(L, idx); + val = luaH_get(t, s2v(L->top.p - 1)); + L->top.p--; /* remove key */ + return finishrawget(L, val); +} + + +LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { + Table *t; + lua_lock(L); + t = gettable(L, idx); + return finishrawget(L, luaH_getint(t, n)); +} + + +LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { + Table *t; + TValue k; + lua_lock(L); + t = gettable(L, idx); + setpvalue(&k, cast_voidp(p)); + return finishrawget(L, luaH_get(t, &k)); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + Table *t; + lua_lock(L); + t = luaH_new(L); + sethvalue2s(L, L->top.p, t); + api_incr_top(L); + if (narray > 0 || nrec > 0) + luaH_resize(L, t, narray, nrec); + luaC_checkGC(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt; + int res = 0; + lua_lock(L); + obj = index2value(L, objindex); + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt != NULL) { + sethvalue2s(L, L->top.p, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) { + TValue *o; + int t; + lua_lock(L); + o = index2value(L, idx); + api_check(L, ttisfulluserdata(o), "full userdata expected"); + if (n <= 0 || n > uvalue(o)->nuvalue) { + setnilvalue(s2v(L->top.p)); + t = LUA_TNONE; + } + else { + setobj2s(L, L->top.p, &uvalue(o)->uv[n - 1].uv); + t = ttype(s2v(L->top.p)); + } + api_incr_top(L); + lua_unlock(L); + return t; +} + + +/* +** set functions (stack -> Lua) +*/ + +/* +** t[k] = value at the top of the stack (where 'k' is a string) +*/ +static void auxsetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + api_checknelems(L, 1); + if (luaV_fastget(L, t, str, slot, luaH_getstr)) { + luaV_finishfastset(L, t, slot, s2v(L->top.p - 1)); + L->top.p--; /* pop value */ + } + else { + setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */ + api_incr_top(L); + luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), slot); + L->top.p -= 2; /* pop value and key */ + } + lua_unlock(L); /* lock done by caller */ +} + + +LUA_API void lua_setglobal (lua_State *L, const char *name) { + const TValue *G; + lua_lock(L); /* unlock done in 'auxsetstr' */ + G = getGtable(L); + auxsetstr(L, G, name); +} + + +LUA_API void lua_settable (lua_State *L, int idx) { + TValue *t; + const TValue *slot; + lua_lock(L); + api_checknelems(L, 2); + t = index2value(L, idx); + if (luaV_fastget(L, t, s2v(L->top.p - 2), slot, luaH_get)) { + luaV_finishfastset(L, t, slot, s2v(L->top.p - 1)); + } + else + luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), slot); + L->top.p -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + lua_lock(L); /* unlock done in 'auxsetstr' */ + auxsetstr(L, index2value(L, idx), k); +} + + +LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { + TValue *t; + const TValue *slot; + lua_lock(L); + api_checknelems(L, 1); + t = index2value(L, idx); + if (luaV_fastgeti(L, t, n, slot)) { + luaV_finishfastset(L, t, slot, s2v(L->top.p - 1)); + } + else { + TValue aux; + setivalue(&aux, n); + luaV_finishset(L, t, &aux, s2v(L->top.p - 1), slot); + } + L->top.p--; /* pop value */ + lua_unlock(L); +} + + +static void aux_rawset (lua_State *L, int idx, TValue *key, int n) { + Table *t; + lua_lock(L); + api_checknelems(L, n); + t = gettable(L, idx); + luaH_set(L, t, key, s2v(L->top.p - 1)); + invalidateTMcache(t); + luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1)); + L->top.p -= n; + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + aux_rawset(L, idx, s2v(L->top.p - 2), 2); +} + + +LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { + TValue k; + setpvalue(&k, cast_voidp(p)); + aux_rawset(L, idx, &k, 1); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { + Table *t; + lua_lock(L); + api_checknelems(L, 1); + t = gettable(L, idx); + luaH_setint(L, t, n, s2v(L->top.p - 1)); + luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1)); + L->top.p--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2value(L, objindex); + if (ttisnil(s2v(L->top.p - 1))) + mt = NULL; + else { + api_check(L, ttistable(s2v(L->top.p - 1)), "table expected"); + mt = hvalue(s2v(L->top.p - 1)); + } + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, gcvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, uvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + default: { + G(L)->mt[ttype(obj)] = mt; + break; + } + } + L->top.p--; + lua_unlock(L); + return 1; +} + + +LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) { + TValue *o; + int res; + lua_lock(L); + api_checknelems(L, 1); + o = index2value(L, idx); + api_check(L, ttisfulluserdata(o), "full userdata expected"); + if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue))) + res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */ + else { + setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top.p - 1)); + luaC_barrierback(L, gcvalue(o), s2v(L->top.p - 1)); + res = 1; + } + L->top.p--; + lua_unlock(L); + return res; +} + + +/* +** 'load' and 'call' functions (run Lua code) +*/ + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET \ + || (L->ci->top.p - L->top.p >= (nr) - (na)), \ + "results from function overflow current stack size") + + +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k) { + StkId func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + func = L->top.p - (nargs+1); + if (k != NULL && yieldable(L)) { /* need to prepare continuation? */ + L->ci->u.c.k = k; /* save continuation */ + L->ci->u.c.ctx = ctx; /* save context */ + luaD_call(L, func, nresults); /* do the call */ + } + else /* no continuation or no yieldable */ + luaD_callnoyield(L, func, nresults); /* just do the call */ + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to 'f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_callnoyield(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, + lua_KContext ctx, lua_KFunction k) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2stack(L, errfunc); + api_check(L, ttisfunction(s2v(o)), "error handler must be a function"); + func = savestack(L, o); + } + c.func = L->top.p - (nargs+1); /* function to be called */ + if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */ + c.nresults = nresults; /* do a 'conventional' protected call */ + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + } + else { /* prepare continuation (call is already protected by 'resume') */ + CallInfo *ci = L->ci; + ci->u.c.k = k; /* save continuation */ + ci->u.c.ctx = ctx; /* save context */ + /* save information for error recovery */ + ci->u2.funcidx = cast_int(savestack(L, c.func)); + ci->u.c.old_errfunc = L->errfunc; + L->errfunc = func; + setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ + ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ + luaD_call(L, c.func, nresults); /* do the call */ + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + status = LUA_OK; /* if it is here, there were no errors */ + } + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname, const char *mode) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname, mode); + if (status == LUA_OK) { /* no errors? */ + LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new function */ + if (f->nupvalues >= 1) { /* does it have an upvalue? */ + /* get global table from registry */ + const TValue *gt = getGtable(L); + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ + setobj(L, f->upvals[0]->v.p, gt); + luaC_barrier(L, f->upvals[0], gt); + } + } + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = s2v(L->top.p - 1); + if (isLfunction(o)) + status = luaU_dump(L, getproto(o), writer, data, strip); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ +LUA_API int lua_gc (lua_State *L, int what, ...) { + va_list argp; + int res = 0; + global_State *g = G(L); + if (g->gcstp & GCSTPGC) /* internal stop? */ + return -1; /* all options are invalid when stopped */ + lua_lock(L); + va_start(argp, what); + switch (what) { + case LUA_GCSTOP: { + g->gcstp = GCSTPUSR; /* stopped by the user */ + break; + } + case LUA_GCRESTART: { + luaE_setdebt(g, 0); + g->gcstp = 0; /* (GCSTPGC must be already zero here) */ + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L, 0); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(gettotalbytes(g) >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(gettotalbytes(g) & 0x3ff); + break; + } + case LUA_GCSTEP: { + int data = va_arg(argp, int); + l_mem debt = 1; /* =1 to signal that it did an actual step */ + lu_byte oldstp = g->gcstp; + g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */ + if (data == 0) { + luaE_setdebt(g, 0); /* do a basic step */ + luaC_step(L); + } + else { /* add 'data' to total debt */ + debt = cast(l_mem, data) * 1024 + g->GCdebt; + luaE_setdebt(g, debt); + luaC_checkGC(L); + } + g->gcstp = oldstp; /* restore previous state */ + if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + break; + } + case LUA_GCSETPAUSE: { + int data = va_arg(argp, int); + res = getgcparam(g->gcpause); + setgcparam(g->gcpause, data); + break; + } + case LUA_GCSETSTEPMUL: { + int data = va_arg(argp, int); + res = getgcparam(g->gcstepmul); + setgcparam(g->gcstepmul, data); + break; + } + case LUA_GCISRUNNING: { + res = gcrunning(g); + break; + } + case LUA_GCGEN: { + int minormul = va_arg(argp, int); + int majormul = va_arg(argp, int); + res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; + if (minormul != 0) + g->genminormul = minormul; + if (majormul != 0) + setgcparam(g->genmajormul, majormul); + luaC_changemode(L, KGC_GEN); + break; + } + case LUA_GCINC: { + int pause = va_arg(argp, int); + int stepmul = va_arg(argp, int); + int stepsize = va_arg(argp, int); + res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; + if (pause != 0) + setgcparam(g->gcpause, pause); + if (stepmul != 0) + setgcparam(g->gcstepmul, stepmul); + if (stepsize != 0) + g->gcstepsize = stepsize; + luaC_changemode(L, KGC_INC); + break; + } + default: res = -1; /* invalid option */ + } + va_end(argp); + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + TValue *errobj; + lua_lock(L); + errobj = s2v(L->top.p - 1); + api_checknelems(L, 1); + /* error object is the memory error message? */ + if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg)) + luaM_error(L); /* raise a memory error */ + else + luaG_errormsg(L); /* raise a regular error */ + /* code unreachable; will unlock when control actually leaves the kernel */ + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + Table *t; + int more; + lua_lock(L); + api_checknelems(L, 1); + t = gettable(L, idx); + more = luaH_next(L, t, L->top.p - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top.p -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_toclose (lua_State *L, int idx) { + int nresults; + StkId o; + lua_lock(L); + o = index2stack(L, idx); + nresults = L->ci->nresults; + api_check(L, L->tbclist.p < o, "given index below or equal a marked one"); + luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */ + if (!hastocloseCfunc(nresults)) /* function not marked yet? */ + L->ci->nresults = codeNresults(nresults); /* mark it */ + lua_assert(hastocloseCfunc(L->ci->nresults)); + lua_unlock(L); +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n > 0) + luaV_concat(L, n); + else { /* nothing to concatenate */ + setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0)); /* push empty string */ + api_incr_top(L); + } + luaC_checkGC(L); + lua_unlock(L); +} + + +LUA_API void lua_len (lua_State *L, int idx) { + TValue *t; + lua_lock(L); + t = index2value(L, idx); + luaV_objlen(L, L->top.p, t); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) { + lua_lock(L); + G(L)->ud_warn = ud; + G(L)->warnf = f; + lua_unlock(L); +} + + +void lua_warning (lua_State *L, const char *msg, int tocont) { + lua_lock(L); + luaE_warning(L, msg, tocont); + lua_unlock(L); +} + + + +LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) { + Udata *u; + lua_lock(L); + api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value"); + u = luaS_newudata(L, size, nuvalue); + setuvalue(L, s2v(L->top.p), u); + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return getudatamem(u); +} + + + +static const char *aux_upvalue (TValue *fi, int n, TValue **val, + GCObject **owner) { + switch (ttypetag(fi)) { + case LUA_VCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues))) + return NULL; /* 'n' not in [1, f->nupvalues] */ + *val = &f->upvalue[n-1]; + if (owner) *owner = obj2gco(f); + return ""; + } + case LUA_VLCL: { /* Lua closure */ + LClosure *f = clLvalue(fi); + TString *name; + Proto *p = f->p; + if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues))) + return NULL; /* 'n' not in [1, p->sizeupvalues] */ + *val = f->upvals[n-1]->v.p; + if (owner) *owner = obj2gco(f->upvals[n - 1]); + name = p->upvalues[n-1].name; + return (name == NULL) ? "(no name)" : getstr(name); + } + default: return NULL; /* not a closure */ + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + lua_lock(L); + name = aux_upvalue(index2value(L, funcindex), n, &val, NULL); + if (name) { + setobj2s(L, L->top.p, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + GCObject *owner = NULL; /* to avoid warnings */ + TValue *fi; + lua_lock(L); + fi = index2value(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val, &owner); + if (name) { + L->top.p--; + setobj(L, val, s2v(L->top.p)); + luaC_barrier(L, owner, val); + } + lua_unlock(L); + return name; +} + + +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { + static const UpVal *const nullup = NULL; + LClosure *f; + TValue *fi = index2value(L, fidx); + api_check(L, ttisLclosure(fi), "Lua function expected"); + f = clLvalue(fi); + if (pf) *pf = f; + if (1 <= n && n <= f->p->sizeupvalues) + return &f->upvals[n - 1]; /* get its upvalue pointer */ + else + return (UpVal**)&nullup; +} + + +LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { + TValue *fi = index2value(L, fidx); + switch (ttypetag(fi)) { + case LUA_VLCL: { /* lua closure */ + return *getupvalref(L, fidx, n, NULL); + } + case LUA_VCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (1 <= n && n <= f->nupvalues) + return &f->upvalue[n - 1]; + /* else */ + } /* FALLTHROUGH */ + case LUA_VLCF: + return NULL; /* light C functions have no upvalues */ + default: { + api_check(L, 0, "function expected"); + return NULL; + } + } +} + + +LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + int fidx2, int n2) { + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index"); + *up1 = *up2; + luaC_objbarrier(L, f1, *up1); +} + + diff --git a/arm9/source/lua/lapi.h b/arm9/source/lua/lapi.h new file mode 100644 index 000000000..a742427cd --- /dev/null +++ b/arm9/source/lua/lapi.h @@ -0,0 +1,52 @@ +/* +** $Id: lapi.h $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "llimits.h" +#include "lstate.h" + + +/* Increments 'L->top.p', checking for stack overflows */ +#define api_incr_top(L) {L->top.p++; \ + api_check(L, L->top.p <= L->ci->top.p, \ + "stack overflow");} + + +/* +** If a call returns too many multiple returns, the callee may not have +** stack space to accommodate all results. In this case, this macro +** increases its stack space ('L->ci->top.p'). +*/ +#define adjustresults(L,nres) \ + { if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \ + L->ci->top.p = L->top.p; } + + +/* Ensure the stack has at least 'n' elements */ +#define api_checknelems(L,n) \ + api_check(L, (n) < (L->top.p - L->ci->func.p), \ + "not enough elements in the stack") + + +/* +** To reduce the overhead of returning from C functions, the presence of +** to-be-closed variables in these functions is coded in the CallInfo's +** field 'nresults', in a way that functions with no to-be-closed variables +** with zero, one, or "all" wanted results have no overhead. Functions +** with other number of wanted results, as well as functions with +** variables to be closed, have an extra check. +*/ + +#define hastocloseCfunc(n) ((n) < LUA_MULTRET) + +/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ +#define codeNresults(n) (-(n) - 3) +#define decodeNresults(n) (-(n) - 3) + +#endif diff --git a/arm9/source/lua/lauxlib.c b/arm9/source/lua/lauxlib.c new file mode 100644 index 000000000..923105ed3 --- /dev/null +++ b/arm9/source/lua/lauxlib.c @@ -0,0 +1,1126 @@ +/* +** $Id: lauxlib.c $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include + + +/* +** This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#include "lua.h" + +#include "lauxlib.h" + + +#if !defined(MAX_SIZET) +/* maximum value for size_t */ +#define MAX_SIZET ((size_t)(~(size_t)0)) +#endif + + +/* +** {====================================================== +** Traceback +** ======================================================= +*/ + + +#define LEVELS1 10 /* size of the first part of the stack */ +#define LEVELS2 11 /* size of the second part of the stack */ + + + +/* +** Search for 'objidx' in table at index -1. ('objidx' must be an +** absolute index.) Return 1 + string at top if it found a good name. +*/ +static int findfield (lua_State *L, int objidx, int level) { + if (level == 0 || !lua_istable(L, -1)) + return 0; /* not found */ + lua_pushnil(L); /* start 'next' loop */ + while (lua_next(L, -2)) { /* for each pair in table */ + if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } + else if (findfield(L, objidx, level - 1)) { /* try recursively */ + /* stack: lib_name, lib_table, field_name (top) */ + lua_pushliteral(L, "."); /* place '.' between the two names */ + lua_replace(L, -3); /* (in the slot occupied by table) */ + lua_concat(L, 3); /* lib_name.field_name */ + return 1; + } + } + lua_pop(L, 1); /* remove value */ + } + return 0; /* not found */ +} + + +/* +** Search for a name for a function in all loaded modules +*/ +static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { + int top = lua_gettop(L); + lua_getinfo(L, "f", ar); /* push function */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + luaL_checkstack(L, 6, "not enough stack"); /* slots for 'findfield' */ + if (findfield(L, top + 1, 2)) { + const char *name = lua_tostring(L, -1); + if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */ + lua_pushstring(L, name + 3); /* push name without prefix */ + lua_remove(L, -2); /* remove original name */ + } + lua_copy(L, -1, top + 1); /* copy name to proper place */ + lua_settop(L, top + 1); /* remove table "loaded" and name copy */ + return 1; + } + else { + lua_settop(L, top); /* remove function and global table */ + return 0; + } +} + + +static void pushfuncname (lua_State *L, lua_Debug *ar) { + if (pushglobalfuncname(L, ar)) { /* try first a global name */ + lua_pushfstring(L, "function '%s'", lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ + } + else if (*ar->namewhat != '\0') /* is there a name from code? */ + lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */ + else if (*ar->what == 'm') /* main? */ + lua_pushliteral(L, "main chunk"); + else if (*ar->what != 'C') /* for Lua functions, use */ + lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); + else /* nothing left... */ + lua_pushliteral(L, "?"); +} + + +static int lastlevel (lua_State *L) { + lua_Debug ar; + int li = 1, le = 1; + /* find an upper bound */ + while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } + /* do a binary search */ + while (li < le) { + int m = (li + le)/2; + if (lua_getstack(L, m, &ar)) li = m + 1; + else le = m; + } + return le - 1; +} + + +LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, + const char *msg, int level) { + luaL_Buffer b; + lua_Debug ar; + int last = lastlevel(L1); + int limit2show = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; + luaL_buffinit(L, &b); + if (msg) { + luaL_addstring(&b, msg); + luaL_addchar(&b, '\n'); + } + luaL_addstring(&b, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (limit2show-- == 0) { /* too many levels? */ + int n = last - level - LEVELS2 + 1; /* number of levels to skip */ + lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n); + luaL_addvalue(&b); /* add warning about skip */ + level += n; /* and skip to last levels */ + } + else { + lua_getinfo(L1, "Slnt", &ar); + if (ar.currentline <= 0) + lua_pushfstring(L, "\n\t%s: in ", ar.short_src); + else + lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline); + luaL_addvalue(&b); + pushfuncname(L, &ar); + luaL_addvalue(&b); + if (ar.istailcall) + luaL_addstring(&b, "\n\t(...tail calls...)"); + } + } + luaL_pushresult(&b); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + +LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", arg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + arg--; /* do not count 'self' */ + if (arg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling '%s' on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; + return luaL_error(L, "bad argument #%d to '%s' (%s)", + arg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) { + const char *msg; + const char *typearg; /* name for the type of the actual argument */ + if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) + typearg = lua_tostring(L, -1); /* use the given type name */ + else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA) + typearg = "light userdata"; /* special name for messages */ + else + typearg = luaL_typename(L, arg); /* standard name */ + msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg); + return luaL_argerror(L, arg, msg); +} + + +static void tag_error (lua_State *L, int arg, int tag) { + luaL_typeerror(L, arg, lua_typename(L, tag)); +} + + +/* +** The use of 'lua_pushfstring' ensures this function does not +** need reserved stack space when called. +*/ +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushfstring(L, ""); /* else, no information available... */ +} + + +/* +** Again, the use of 'lua_pushvfstring' ensures this function does +** not need reserved stack space when called. (At worst, it generates +** an error with "stack overflow" instead of the given message.) +*/ +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + + +LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { + int en = errno; /* calls to Lua API may change this value */ + if (stat) { + lua_pushboolean(L, 1); + return 1; + } + else { + const char *msg; + luaL_pushfail(L); + msg = (en != 0) ? strerror(en) : "(no extra info)"; + if (fname) + lua_pushfstring(L, "%s: %s", fname, msg); + else + lua_pushstring(L, msg); + lua_pushinteger(L, en); + return 3; + } +} + + +#if !defined(l_inspectstat) /* { */ + +#if defined(LUA_USE_POSIX) + +#include + +/* +** use appropriate macros to interpret 'pclose' return status +*/ +#define l_inspectstat(stat,what) \ + if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ + else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } + +#else + +#define l_inspectstat(stat,what) /* no op */ + +#endif + +#endif /* } */ + + +LUALIB_API int luaL_execresult (lua_State *L, int stat) { + if (stat != 0 && errno != 0) /* error with an 'errno'? */ + return luaL_fileresult(L, 0, NULL); + else { + const char *what = "exit"; /* type of termination */ + l_inspectstat(stat, what); /* interpret result */ + if (*what == 'e' && stat == 0) /* successful termination? */ + lua_pushboolean(L, 1); + else + luaL_pushfail(L); + lua_pushstring(L, what); + lua_pushinteger(L, stat); + return 3; /* return true/fail,what,code */ + } +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Userdata's metatable manipulation +** ======================================================= +*/ + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_createtable(L, 0, 2); /* create metatable */ + lua_pushstring(L, tname); + lua_setfield(L, -2, "__name"); /* metatable.__name = tname */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); + lua_setmetatable(L, -2); +} + + +LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + luaL_getmetatable(L, tname); /* get correct metatable */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ + p = NULL; /* value is a userdata with wrong metatable */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + return NULL; /* value is not a userdata with a metatable */ +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = luaL_testudata(L, ud, tname); + luaL_argexpected(L, p != NULL, ud, tname); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Argument check functions +** ======================================================= +*/ + +LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, arg, def) : + luaL_checkstring(L, arg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, arg, + lua_pushfstring(L, "invalid option '%s'", name)); +} + + +/* +** Ensures the stack has at least 'space' extra slots, raising an error +** if it cannot fulfill the request. (The error handling needs a few +** extra slots to format the error message. In case of an error without +** this extra space, Lua will generate the same 'stack overflow' error, +** but without 'msg'.) +*/ +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { + if (l_unlikely(!lua_checkstack(L, space))) { + if (msg) + luaL_error(L, "stack overflow (%s)", msg); + else + luaL_error(L, "stack overflow"); + } +} + + +LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) { + if (l_unlikely(lua_type(L, arg) != t)) + tag_error(L, arg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int arg) { + if (l_unlikely(lua_type(L, arg) == LUA_TNONE)) + luaL_argerror(L, arg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) { + const char *s = lua_tolstring(L, arg, len); + if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int arg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, arg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, arg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) { + int isnum; + lua_Number d = lua_tonumberx(L, arg, &isnum); + if (l_unlikely(!isnum)) + tag_error(L, arg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, arg, def); +} + + +static void interror (lua_State *L, int arg) { + if (lua_isnumber(L, arg)) + luaL_argerror(L, arg, "number has no integer representation"); + else + tag_error(L, arg, LUA_TNUMBER); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) { + int isnum; + lua_Integer d = lua_tointegerx(L, arg, &isnum); + if (l_unlikely(!isnum)) { + interror(L, arg); + } + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, arg, def); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +/* userdata to box arbitrary data */ +typedef struct UBox { + void *box; + size_t bsize; +} UBox; + + +static void *resizebox (lua_State *L, int idx, size_t newsize) { + void *ud; + lua_Alloc allocf = lua_getallocf(L, &ud); + UBox *box = (UBox *)lua_touserdata(L, idx); + void *temp = allocf(ud, box->box, box->bsize, newsize); + if (l_unlikely(temp == NULL && newsize > 0)) { /* allocation error? */ + lua_pushliteral(L, "not enough memory"); + lua_error(L); /* raise a memory error */ + } + box->box = temp; + box->bsize = newsize; + return temp; +} + + +static int boxgc (lua_State *L) { + resizebox(L, 1, 0); + return 0; +} + + +static const luaL_Reg boxmt[] = { /* box metamethods */ + {"__gc", boxgc}, + {"__close", boxgc}, + {NULL, NULL} +}; + + +static void newbox (lua_State *L) { + UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); + box->box = NULL; + box->bsize = 0; + if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ + luaL_setfuncs(L, boxmt, 0); /* set its metamethods */ + lua_setmetatable(L, -2); +} + + +/* +** check whether buffer is using a userdata on the stack as a temporary +** buffer +*/ +#define buffonstack(B) ((B)->b != (B)->init.b) + + +/* +** Whenever buffer is accessed, slot 'idx' must either be a box (which +** cannot be NULL) or it is a placeholder for the buffer. +*/ +#define checkbufferlevel(B,idx) \ + lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \ + : lua_touserdata(B->L, idx) == (void*)B) + + +/* +** Compute new size for buffer 'B', enough to accommodate extra 'sz' +** bytes. (The test for "not big enough" also gets the case when the +** computation of 'newsize' overflows.) +*/ +static size_t newbuffsize (luaL_Buffer *B, size_t sz) { + size_t newsize = (B->size / 2) * 3; /* buffer size * 1.5 */ + if (l_unlikely(MAX_SIZET - sz < B->n)) /* overflow in (B->n + sz)? */ + return luaL_error(B->L, "buffer too large"); + if (newsize < B->n + sz) /* not big enough? */ + newsize = B->n + sz; + return newsize; +} + + +/* +** Returns a pointer to a free area with at least 'sz' bytes in buffer +** 'B'. 'boxidx' is the relative position in the stack where is the +** buffer's box or its placeholder. +*/ +static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { + checkbufferlevel(B, boxidx); + if (B->size - B->n >= sz) /* enough space? */ + return B->b + B->n; + else { + lua_State *L = B->L; + char *newbuff; + size_t newsize = newbuffsize(B, sz); + /* create larger buffer */ + if (buffonstack(B)) /* buffer already has a box? */ + newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ + else { /* no box yet */ + lua_remove(L, boxidx); /* remove placeholder */ + newbox(L); /* create a new box */ + lua_insert(L, boxidx); /* move box to its intended position */ + lua_toclose(L, boxidx); + newbuff = (char *)resizebox(L, boxidx, newsize); + memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ + } + B->b = newbuff; + B->size = newsize; + return newbuff + B->n; + } +} + +/* +** returns a pointer to a free area with at least 'sz' bytes +*/ +LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { + return prepbuffsize(B, sz, -1); +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ + char *b = prepbuffsize(B, l, -1); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); + } +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + lua_State *L = B->L; + checkbufferlevel(B, -1); + lua_pushlstring(L, B->b, B->n); + if (buffonstack(B)) + lua_closeslot(L, -2); /* close the box */ + lua_remove(L, -2); /* remove box or placeholder from the stack */ +} + + +LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { + luaL_addsize(B, sz); + luaL_pushresult(B); +} + + +/* +** 'luaL_addvalue' is the only function in the Buffer system where the +** box (if existent) is not on the top of the stack. So, instead of +** calling 'luaL_addlstring', it replicates the code using -2 as the +** last argument to 'prepbuffsize', signaling that the box is (or will +** be) below the string being added to the buffer. (Box creation can +** trigger an emergency GC, so we should not remove the string from the +** stack before we have the space guaranteed.) +*/ +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t len; + const char *s = lua_tolstring(L, -1, &len); + char *b = prepbuffsize(B, len, -2); + memcpy(b, s, len * sizeof(char)); + luaL_addsize(B, len); + lua_pop(L, 1); /* pop string */ +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->b = B->init.b; + B->n = 0; + B->size = LUAL_BUFFERSIZE; + lua_pushlightuserdata(L, (void*)B); /* push placeholder */ +} + + +LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { + luaL_buffinit(L, B); + return prepbuffsize(B, sz, -1); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Reference system +** ======================================================= +*/ + +/* index of free-list header (after the predefined values) */ +#define freelist (LUA_RIDX_LAST + 1) + +/* +** The previously freed references form a linked list: +** t[freelist] is the index of a first free index, or zero if list is +** empty; t[t[freelist]] is the index of the second element; etc. +*/ +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* 'nil' has a unique fixed reference */ + } + t = lua_absindex(L, t); + if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */ + ref = 0; /* list is empty */ + lua_pushinteger(L, 0); /* initialize as an empty list */ + lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */ + } + else { /* already initialized */ + lua_assert(lua_isinteger(L, -1)); + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ + } + lua_pop(L, 1); /* remove element from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ + } + else /* no free elements */ + ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); + lua_assert(lua_isinteger(L, -1)); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int n; /* number of pre-read characters */ + FILE *f; /* file being read */ + char buff[BUFSIZ]; /* area for reading file */ +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; /* not used */ + if (lf->n > 0) { /* are there pre-read characters to be read? */ + *size = lf->n; /* return them (chars already in buffer) */ + lf->n = 0; /* no more pre-read characters */ + } + else { /* read a block from file */ + /* 'fread' can return > 0 *and* set the EOF flag. If next call to + 'getF' called 'fread', it might still wait for user input. + The next check avoids this problem. */ + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ + } + return lf->buff; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + int err = errno; + const char *filename = lua_tostring(L, fnameindex) + 1; + if (err != 0) + lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err)); + else + lua_pushfstring(L, "cannot %s %s", what, filename); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +/* +** Skip an optional BOM at the start of a stream. If there is an +** incomplete BOM (the first character is correct but the rest is +** not), returns the first character anyway to force an error +** (as no chunk can start with 0xEF). +*/ +static int skipBOM (FILE *f) { + int c = getc(f); /* read first character */ + if (c == 0xEF && getc(f) == 0xBB && getc(f) == 0xBF) /* correct BOM? */ + return getc(f); /* ignore BOM and return next char */ + else /* no (valid) BOM */ + return c; /* return first character */ +} + + +/* +** reads the first character of file 'f' and skips an optional BOM mark +** in its beginning plus its first line if it starts with '#'. Returns +** true if it skipped the first line. In any case, '*cp' has the +** first "valid" character of the file (after the optional BOM and +** a first-line comment). +*/ +static int skipcomment (FILE *f, int *cp) { + int c = *cp = skipBOM(f); + if (c == '#') { /* first line is a comment (Unix exec. file)? */ + do { /* skip first line */ + c = getc(f); + } while (c != EOF && c != '\n'); + *cp = getc(f); /* next character after comment, if present */ + return 1; /* there was a comment */ + } + else return 0; /* no comment */ +} + + +LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, + const char *mode) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + errno = 0; + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + lf.n = 0; + if (skipcomment(lf.f, &c)) /* read initial portion */ + lf.buff[lf.n++] = '\n'; /* add newline to correct line numbers */ + if (c == LUA_SIGNATURE[0]) { /* binary file? */ + lf.n = 0; /* remove possible newline */ + if (filename) { /* "real" file? */ + errno = 0; + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + skipcomment(lf.f, &c); /* re-read initial portion */ + } + } + if (c != EOF) + lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ + errno = 0; + status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; /* not used */ + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, + const char *name, const char *mode) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name, mode); +} + + +LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + +/* }====================================================== */ + + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return LUA_TNIL; + else { + int tt; + lua_pushstring(L, event); + tt = lua_rawget(L, -2); + if (tt == LUA_TNIL) /* is metafield nil? */ + lua_pop(L, 2); /* remove metatable and metafield */ + else + lua_remove(L, -2); /* remove only metatable */ + return tt; /* return metafield type */ + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = lua_absindex(L, obj); + if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { + lua_Integer l; + int isnum; + lua_len(L, idx); + l = lua_tointegerx(L, -1, &isnum); + if (l_unlikely(!isnum)) + luaL_error(L, "object length is not an integer"); + lua_pop(L, 1); /* remove object */ + return l; +} + + +LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + idx = lua_absindex(L,idx); + if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ + if (!lua_isstring(L, -1)) + luaL_error(L, "'__tostring' must return a string"); + } + else { + switch (lua_type(L, idx)) { + case LUA_TNUMBER: { + if (lua_isinteger(L, idx)) + lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx)); + else + lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx)); + break; + } + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: { + int tt = luaL_getmetafield(L, idx, "__name"); /* try name */ + const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : + luaL_typename(L, idx); + lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx)); + if (tt != LUA_TNIL) + lua_remove(L, -2); /* remove '__name' */ + break; + } + } + } + return lua_tolstring(L, -1, len); +} + + +/* +** set functions from list 'l' into table at top - 'nup'; each +** function gets the 'nup' elements at the top as upvalues. +** Returns with only the table at the stack. +*/ +LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + if (l->func == NULL) /* placeholder? */ + lua_pushboolean(L, 0); + else { + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + } + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + +/* +** ensure that stack[idx][fname] has a table and push that table +** into the stack +*/ +LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { + if (lua_getfield(L, idx, fname) == LUA_TTABLE) + return 1; /* table already there */ + else { + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ + } +} + + +/* +** Stripped-down 'require': After checking "loaded" table, calls 'openf' +** to open a module, registers the result in 'package.loaded' table and, +** if 'glb' is true, also registers the result in the global table. +** Leaves resulting module on the top. +*/ +LUALIB_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, -1, modname); /* LOADED[modname] */ + if (!lua_toboolean(L, -1)) { /* package not already loaded? */ + lua_pop(L, 1); /* remove field */ + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* call 'openf' to open module */ + lua_pushvalue(L, -1); /* make copy of module (call result) */ + lua_setfield(L, -3, modname); /* LOADED[modname] = module */ + } + lua_remove(L, -2); /* remove LOADED table */ + if (glb) { + lua_pushvalue(L, -1); /* copy of module */ + lua_setglobal(L, modname); /* _G[modname] = module */ + } +} + + +LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, + const char *p, const char *r) { + const char *wild; + size_t l = strlen(p); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(b, s, wild - s); /* push prefix */ + luaL_addstring(b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after 'p' */ + } + luaL_addstring(b, s); /* push last suffix */ +} + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, + const char *p, const char *r) { + luaL_Buffer b; + luaL_buffinit(L, &b); + luaL_addgsub(&b, s, p, r); + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; (void)osize; /* not used */ + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +/* +** Standard panic funcion just prints an error message. The test +** with 'lua_type' avoids possible memory errors in 'lua_tostring'. +*/ +static int panic (lua_State *L) { + const char *msg = (lua_type(L, -1) == LUA_TSTRING) + ? lua_tostring(L, -1) + : "error object is not a string"; + lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", + msg); + return 0; /* return to Lua to abort */ +} + + +/* +** Warning functions: +** warnfoff: warning system is off +** warnfon: ready to start a new message +** warnfcont: previous message is to be continued +*/ +static void warnfoff (void *ud, const char *message, int tocont); +static void warnfon (void *ud, const char *message, int tocont); +static void warnfcont (void *ud, const char *message, int tocont); + + +/* +** Check whether message is a control message. If so, execute the +** control or ignore it if unknown. +*/ +static int checkcontrol (lua_State *L, const char *message, int tocont) { + if (tocont || *(message++) != '@') /* not a control message? */ + return 0; + else { + if (strcmp(message, "off") == 0) + lua_setwarnf(L, warnfoff, L); /* turn warnings off */ + else if (strcmp(message, "on") == 0) + lua_setwarnf(L, warnfon, L); /* turn warnings on */ + return 1; /* it was a control message */ + } +} + + +static void warnfoff (void *ud, const char *message, int tocont) { + checkcontrol((lua_State *)ud, message, tocont); +} + + +/* +** Writes the message and handle 'tocont', finishing the message +** if needed and setting the next warn function. +*/ +static void warnfcont (void *ud, const char *message, int tocont) { + lua_State *L = (lua_State *)ud; + lua_writestringerror("%s", message); /* write message */ + if (tocont) /* not the last part? */ + lua_setwarnf(L, warnfcont, L); /* to be continued */ + else { /* last part */ + lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ + lua_setwarnf(L, warnfon, L); /* next call is a new message */ + } +} + + +static void warnfon (void *ud, const char *message, int tocont) { + if (checkcontrol((lua_State *)ud, message, tocont)) /* control message? */ + return; /* nothing else to be done */ + lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ + warnfcont(ud, message, tocont); /* finish processing */ +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (l_likely(L)) { + lua_atpanic(L, &panic); + lua_setwarnf(L, warnfoff, L); /* default is warnings off */ + } + return L; +} + + +LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { + lua_Number v = lua_version(L); + if (sz != LUAL_NUMSIZES) /* check numeric types */ + luaL_error(L, "core and library have incompatible numeric types"); + else if (v != ver) + luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", + (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)v); +} + diff --git a/arm9/source/lua/lauxlib.h b/arm9/source/lua/lauxlib.h new file mode 100644 index 000000000..5b977e2a3 --- /dev/null +++ b/arm9/source/lua/lauxlib.h @@ -0,0 +1,301 @@ +/* +** $Id: lauxlib.h $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "luaconf.h" +#include "lua.h" + + +/* global table */ +#define LUA_GNAME "_G" + + +typedef struct luaL_Buffer luaL_Buffer; + + +/* extra error code for 'luaL_loadfilex' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +/* key, in the registry, for table of loaded modules */ +#define LUA_LOADED_TABLE "_LOADED" + + +/* key, in the registry, for table of preloaded loaders */ +#define LUA_PRELOAD_TABLE "_PRELOAD" + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + +#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) + +LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); +#define luaL_checkversion(L) \ + luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) + +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); +LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); +LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int arg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); +LUALIB_API int (luaL_execresult) (lua_State *L, int stat); + + +/* predefined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, + const char *mode); + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + +LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + +LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); + +LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s, + const char *p, const char *r); +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, + const char *p, const char *r); + +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); + +LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); + +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, + const char *msg, int level); + +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) \ + (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + +#define luaL_argcheck(L, cond,arg,extramsg) \ + ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg)))) + +#define luaL_argexpected(L,cond,arg,tname) \ + ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname)))) + +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + +/* +** Perform arithmetic operations on lua_Integer values with wrap-around +** semantics, as the Lua core does. +*/ +#define luaL_intop(op,v1,v2) \ + ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) + + +/* push the value used to represent failure/error */ +#define luaL_pushfail(L) lua_pushnil(L) + + +/* +** Internal assertions for in-house debugging +*/ +#if !defined(lua_assert) + +#if defined LUAI_ASSERT + #include + #define lua_assert(c) assert(c) +#else + #define lua_assert(c) ((void)0) +#endif + +#endif + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +struct luaL_Buffer { + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + union { + LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ + char b[LUAL_BUFFERSIZE]; /* initial buffer */ + } init; +}; + + +#define luaL_bufflen(bf) ((bf)->n) +#define luaL_buffaddr(bf) ((bf)->b) + + +#define luaL_addchar(B,c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) + +#define luaL_addsize(B,s) ((B)->n += (s)) + +#define luaL_buffsub(B,s) ((B)->n -= (s)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); + +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) + +/* }====================================================== */ + + + +/* +** {====================================================== +** File handles for IO library +** ======================================================= +*/ + +/* +** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +** initial structure 'luaL_Stream' (it may contain other fields +** after that initial structure). +*/ + +#define LUA_FILEHANDLE "FILE*" + + +typedef struct luaL_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ +} luaL_Stream; + +/* }====================================================== */ + +/* +** {================================================================== +** "Abstraction Layer" for basic report of messages and errors +** =================================================================== +*/ + +/* print a string */ +#if !defined(lua_writestring) +#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#endif + +/* print a newline and flush the output */ +#if !defined(lua_writeline) +#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) +#endif + +/* print an error message */ +#if !defined(lua_writestringerror) +#define lua_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) +#endif + +/* }================================================================== */ + + +/* +** {============================================================ +** Compatibility with deprecated conversions +** ============================================================= +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) +#define luaL_optunsigned(L,a,d) \ + ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) + +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) + +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#endif +/* }============================================================ */ + + + +#endif + + diff --git a/arm9/source/lua/lbaselib.c b/arm9/source/lua/lbaselib.c new file mode 100644 index 000000000..1d60c9ded --- /dev/null +++ b/arm9/source/lua/lbaselib.c @@ -0,0 +1,549 @@ +/* +** $Id: lbaselib.c $ +** Basic library +** See Copyright Notice in lua.h +*/ + +#define lbaselib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + for (i = 1; i <= n; i++) { /* for each argument */ + size_t l; + const char *s = luaL_tolstring(L, i, &l); /* convert it to string */ + if (i > 1) /* not the first element? */ + lua_writestring("\t", 1); /* add a tab before it */ + lua_writestring(s, l); /* print it */ + lua_pop(L, 1); /* pop result */ + } + lua_writeline(); + return 0; +} + + +/* +** Creates a warning with all given arguments. +** Check first for errors; otherwise an error may interrupt +** the composition of a warning, leaving it unfinished. +*/ +static int luaB_warn (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + luaL_checkstring(L, 1); /* at least one argument */ + for (i = 2; i <= n; i++) + luaL_checkstring(L, i); /* make sure all arguments are strings */ + for (i = 1; i < n; i++) /* compose warning */ + lua_warning(L, lua_tostring(L, i), 1); + lua_warning(L, lua_tostring(L, n), 0); /* close warning */ + return 0; +} + + +#define SPACECHARS " \f\n\r\t\v" + +static const char *b_str2int (const char *s, int base, lua_Integer *pn) { + lua_Unsigned n = 0; + int neg = 0; + s += strspn(s, SPACECHARS); /* skip initial spaces */ + if (*s == '-') { s++; neg = 1; } /* handle sign */ + else if (*s == '+') s++; + if (!isalnum((unsigned char)*s)) /* no digit? */ + return NULL; + do { + int digit = (isdigit((unsigned char)*s)) ? *s - '0' + : (toupper((unsigned char)*s) - 'A') + 10; + if (digit >= base) return NULL; /* invalid numeral */ + n = n * base + digit; + s++; + } while (isalnum((unsigned char)*s)); + s += strspn(s, SPACECHARS); /* skip trailing spaces */ + *pn = (lua_Integer)((neg) ? (0u - n) : n); + return s; +} + + +static int luaB_tonumber (lua_State *L) { + if (lua_isnoneornil(L, 2)) { /* standard conversion? */ + if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ + lua_settop(L, 1); /* yes; return it */ + return 1; + } + else { + size_t l; + const char *s = lua_tolstring(L, 1, &l); + if (s != NULL && lua_stringtonumber(L, s) == l + 1) + return 1; /* successful conversion to number */ + /* else not a number */ + luaL_checkany(L, 1); /* (but there must be some parameter) */ + } + } + else { + size_t l; + const char *s; + lua_Integer n = 0; /* to avoid warnings */ + lua_Integer base = luaL_checkinteger(L, 2); + luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */ + s = lua_tolstring(L, 1, &l); + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + if (b_str2int(s, (int)base, &n) == s + l) { + lua_pushinteger(L, n); + return 1; + } /* else not a number */ + } /* else not a number */ + luaL_pushfail(L); /* not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = (int)luaL_optinteger(L, 2, 1); + lua_settop(L, 1); + if (lua_type(L, 1) == LUA_TSTRING && level > 0) { + luaL_where(L, level); /* add extra information */ + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); + if (l_unlikely(luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)) + return luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawlen (lua_State *L) { + int t = lua_type(L, 1); + luaL_argexpected(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, + "table or string"); + lua_pushinteger(L, lua_rawlen(L, 1)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int pushmode (lua_State *L, int oldmode) { + if (oldmode == -1) + luaL_pushfail(L); /* invalid call to 'lua_gc' */ + else + lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" + : "generational"); + return 1; +} + + +/* +** check whether call to 'lua_gc' was valid (not inside a finalizer) +*/ +#define checkvalres(res) { if (res == -1) break; } + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", + "isrunning", "generational", "incremental", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; + int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; + switch (o) { + case LUA_GCCOUNT: { + int k = lua_gc(L, o); + int b = lua_gc(L, LUA_GCCOUNTB); + checkvalres(k); + lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + int step = (int)luaL_optinteger(L, 2, 0); + int res = lua_gc(L, o, step); + checkvalres(res); + lua_pushboolean(L, res); + return 1; + } + case LUA_GCSETPAUSE: + case LUA_GCSETSTEPMUL: { + int p = (int)luaL_optinteger(L, 2, 0); + int previous = lua_gc(L, o, p); + checkvalres(previous); + lua_pushinteger(L, previous); + return 1; + } + case LUA_GCISRUNNING: { + int res = lua_gc(L, o); + checkvalres(res); + lua_pushboolean(L, res); + return 1; + } + case LUA_GCGEN: { + int minormul = (int)luaL_optinteger(L, 2, 0); + int majormul = (int)luaL_optinteger(L, 3, 0); + return pushmode(L, lua_gc(L, o, minormul, majormul)); + } + case LUA_GCINC: { + int pause = (int)luaL_optinteger(L, 2, 0); + int stepmul = (int)luaL_optinteger(L, 3, 0); + int stepsize = (int)luaL_optinteger(L, 4, 0); + return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize)); + } + default: { + int res = lua_gc(L, o); + checkvalres(res); + lua_pushinteger(L, res); + return 1; + } + } + luaL_pushfail(L); /* invalid call (inside a finalizer) */ + return 1; +} + + +static int luaB_type (lua_State *L) { + int t = lua_type(L, 1); + luaL_argcheck(L, t != LUA_TNONE, 1, "value expected"); + lua_pushstring(L, lua_typename(L, t)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int pairscont (lua_State *L, int status, lua_KContext k) { + (void)L; (void)status; (void)k; /* unused */ + return 3; +} + +static int luaB_pairs (lua_State *L) { + luaL_checkany(L, 1); + if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */ + lua_pushcfunction(L, luaB_next); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + } + else { + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_callk(L, 1, 3, 0, pairscont); /* get 3 values from metamethod */ + } + return 3; +} + + +/* +** Traversal function for 'ipairs' +*/ +static int ipairsaux (lua_State *L) { + lua_Integer i = luaL_checkinteger(L, 2); + i = luaL_intop(+, i, 1); + lua_pushinteger(L, i); + return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; +} + + +/* +** 'ipairs' function. Returns 'ipairsaux', given "table", 0. +** (The given "table" may not be a table.) +*/ +static int luaB_ipairs (lua_State *L) { + luaL_checkany(L, 1); + lua_pushcfunction(L, ipairsaux); /* iteration function */ + lua_pushvalue(L, 1); /* state */ + lua_pushinteger(L, 0); /* initial value */ + return 3; +} + + +static int load_aux (lua_State *L, int status, int envidx) { + if (l_likely(status == LUA_OK)) { + if (envidx != 0) { /* 'env' parameter? */ + lua_pushvalue(L, envidx); /* environment for loaded function */ + if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ + lua_pop(L, 1); /* remove 'env' if not used by previous call */ + } + return 1; + } + else { /* error (message is on top of the stack) */ + luaL_pushfail(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return fail plus error message */ + } +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + const char *mode = luaL_optstring(L, 2, NULL); + int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ + int status = luaL_loadfilex(L, fname, mode); + return load_aux(L, status, env); +} + + +/* +** {====================================================== +** Generic Read function +** ======================================================= +*/ + + +/* +** reserved slot, above all arguments, to hold a copy of the returned +** string to avoid it being collected while parsed. 'load' has four +** optional arguments (chunk, source name, mode, and environment). +*/ +#define RESERVEDSLOT 5 + + +/* +** Reader for generic 'load' function: 'lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)(ud); /* not used */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* pop result */ + *size = 0; + return NULL; + } + else if (l_unlikely(!lua_isstring(L, -1))) + luaL_error(L, "reader function must return a string"); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tolstring(L, RESERVEDSLOT, size); +} + + +static int luaB_load (lua_State *L) { + int status; + size_t l; + const char *s = lua_tolstring(L, 1, &l); + const char *mode = luaL_optstring(L, 3, "bt"); + int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ + if (s != NULL) { /* loading a string? */ + const char *chunkname = luaL_optstring(L, 2, s); + status = luaL_loadbufferx(L, s, l, chunkname, mode); + } + else { /* loading from a reader function */ + const char *chunkname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, NULL, chunkname, mode); + } + return load_aux(L, status, env); +} + +/* }====================================================== */ + + +static int dofilecont (lua_State *L, int d1, lua_KContext d2) { + (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */ + return lua_gettop(L) - 1; +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + lua_settop(L, 1); + if (l_unlikely(luaL_loadfile(L, fname) != LUA_OK)) + return lua_error(L); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); + return dofilecont(L, 0, 0); +} + + +static int luaB_assert (lua_State *L) { + if (l_likely(lua_toboolean(L, 1))) /* condition is true? */ + return lua_gettop(L); /* return all arguments */ + else { /* error */ + luaL_checkany(L, 1); /* there must be a condition */ + lua_remove(L, 1); /* remove it */ + lua_pushliteral(L, "assertion failed!"); /* default message */ + lua_settop(L, 1); /* leave only message (default if no other one) */ + return luaB_error(L); /* call 'error' */ + } +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + lua_Integer i = luaL_checkinteger(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - (int)i; + } +} + + +/* +** Continuation function for 'pcall' and 'xpcall'. Both functions +** already pushed a 'true' before doing the call, so in case of success +** 'finishpcall' only has to return everything in the stack minus +** 'extra' values (where 'extra' is exactly the number of items to be +** ignored). +*/ +static int finishpcall (lua_State *L, int status, lua_KContext extra) { + if (l_unlikely(status != LUA_OK && status != LUA_YIELD)) { /* error? */ + lua_pushboolean(L, 0); /* first result (false) */ + lua_pushvalue(L, -2); /* error message */ + return 2; /* return false, msg */ + } + else + return lua_gettop(L) - (int)extra; /* return all results */ +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + lua_pushboolean(L, 1); /* first result if no errors */ + lua_insert(L, 1); /* put it in place */ + status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall); + return finishpcall(L, status, 0); +} + + +/* +** Do a protected call with error handling. After 'lua_rotate', the +** stack will have ; so, the function passes +** 2 to 'finishpcall' to skip the 2 first values when returning results. +*/ +static int luaB_xpcall (lua_State *L) { + int status; + int n = lua_gettop(L); + luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */ + lua_pushboolean(L, 1); /* first result */ + lua_pushvalue(L, 1); /* function */ + lua_rotate(L, 3, 2); /* move them below function's arguments */ + status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall); + return finishpcall(L, status, 2); +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + luaL_tolstring(L, 1, NULL); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"getmetatable", luaB_getmetatable}, + {"ipairs", luaB_ipairs}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, + {"next", luaB_next}, + {"pairs", luaB_pairs}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"warn", luaB_warn}, + {"rawequal", luaB_rawequal}, + {"rawlen", luaB_rawlen}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"xpcall", luaB_xpcall}, + /* placeholders */ + {LUA_GNAME, NULL}, + {"_VERSION", NULL}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_base (lua_State *L) { + /* open lib into global table */ + lua_pushglobaltable(L); + luaL_setfuncs(L, base_funcs, 0); + /* set global _G */ + lua_pushvalue(L, -1); + lua_setfield(L, -2, LUA_GNAME); + /* set global _VERSION */ + lua_pushliteral(L, LUA_VERSION); + lua_setfield(L, -2, "_VERSION"); + return 1; +} + diff --git a/arm9/source/lua/lcode.c b/arm9/source/lua/lcode.c new file mode 100644 index 000000000..87616140e --- /dev/null +++ b/arm9/source/lua/lcode.c @@ -0,0 +1,1874 @@ +/* +** $Id: lcode.c $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#define lcode_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* Maximum number of registers in a Lua function (must fit in 8 bits) */ +#define MAXREGS 255 + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int codesJ (FuncState *fs, OpCode o, int sj, int k); + + + +/* semantic error */ +l_noret luaK_semerror (LexState *ls, const char *msg) { + ls->t.token = 0; /* remove "near " from final message */ + luaX_syntaxerror(ls, msg); +} + + +/* +** If expression is a numeric constant, fills 'v' with its value +** and returns 1. Otherwise, returns 0. +*/ +static int tonumeral (const expdesc *e, TValue *v) { + if (hasjumps(e)) + return 0; /* not a numeral */ + switch (e->k) { + case VKINT: + if (v) setivalue(v, e->u.ival); + return 1; + case VKFLT: + if (v) setfltvalue(v, e->u.nval); + return 1; + default: return 0; + } +} + + +/* +** Get the constant value from a constant expression +*/ +static TValue *const2val (FuncState *fs, const expdesc *e) { + lua_assert(e->k == VCONST); + return &fs->ls->dyd->actvar.arr[e->u.info].k; +} + + +/* +** If expression is a constant, fills 'v' with its value +** and returns 1. Otherwise, returns 0. +*/ +int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) { + if (hasjumps(e)) + return 0; /* not a constant */ + switch (e->k) { + case VFALSE: + setbfvalue(v); + return 1; + case VTRUE: + setbtvalue(v); + return 1; + case VNIL: + setnilvalue(v); + return 1; + case VKSTR: { + setsvalue(fs->ls->L, v, e->u.strval); + return 1; + } + case VCONST: { + setobj(fs->ls->L, v, const2val(fs, e)); + return 1; + } + default: return tonumeral(e, v); + } +} + + +/* +** Return the previous instruction of the current code. If there +** may be a jump target between the current instruction and the +** previous one, return an invalid instruction (to avoid wrong +** optimizations). +*/ +static Instruction *previousinstruction (FuncState *fs) { + static const Instruction invalidinstruction = ~(Instruction)0; + if (fs->pc > fs->lasttarget) + return &fs->f->code[fs->pc - 1]; /* previous instruction */ + else + return cast(Instruction*, &invalidinstruction); +} + + +/* +** Create a OP_LOADNIL instruction, but try to optimize: if the previous +** instruction is also OP_LOADNIL and ranges are compatible, adjust +** range of previous instruction instead of emitting a new one. (For +** instance, 'local a; local b' will generate a single opcode.) +*/ +void luaK_nil (FuncState *fs, int from, int n) { + int l = from + n - 1; /* last register to set nil */ + Instruction *previous = previousinstruction(fs); + if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */ + int pfrom = GETARG_A(*previous); /* get previous range */ + int pl = pfrom + GETARG_B(*previous); + if ((pfrom <= from && from <= pl + 1) || + (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ + if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ + if (pl > l) l = pl; /* l = max(l, pl) */ + SETARG_A(*previous, from); + SETARG_B(*previous, l - from); + return; + } /* else go through */ + } + luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ +} + + +/* +** Gets the destination address of a jump instruction. Used to traverse +** a list of jumps. +*/ +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sJ(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +/* +** Fix jump instruction at position 'pc' to jump to 'dest'. +** (Jump addresses are relative in Lua) +*/ +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + lua_assert(dest != NO_JUMP); + if (!(-OFFSET_sJ <= offset && offset <= MAXARG_sJ - OFFSET_sJ)) + luaX_syntaxerror(fs->ls, "control structure too long"); + lua_assert(GET_OPCODE(*jmp) == OP_JMP); + SETARG_sJ(*jmp, offset); +} + + +/* +** Concatenate jump-list 'l2' into jump-list 'l1' +*/ +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; /* nothing to concatenate? */ + else if (*l1 == NO_JUMP) /* no original list? */ + *l1 = l2; /* 'l1' points to 'l2' */ + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); /* last element links to 'l2' */ + } +} + + +/* +** Create a jump instruction and return its position, so its destination +** can be fixed later (with 'fixjump'). +*/ +int luaK_jump (FuncState *fs) { + return codesJ(fs, OP_JMP, NO_JUMP, 0); +} + + +/* +** Code a 'return' instruction +*/ +void luaK_ret (FuncState *fs, int first, int nret) { + OpCode op; + switch (nret) { + case 0: op = OP_RETURN0; break; + case 1: op = OP_RETURN1; break; + default: op = OP_RETURN; break; + } + luaK_codeABC(fs, op, first, nret + 1, 0); +} + + +/* +** Code a "conditional jump", that is, a test or comparison opcode +** followed by a jump. Return jump position. +*/ +static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { + luaK_codeABCk(fs, op, A, B, C, k); + return luaK_jump(fs); +} + + +/* +** returns current 'pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +/* +** Returns the position of the instruction "controlling" a given +** jump (that is, its condition), or the jump itself if it is +** unconditional. +*/ +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** Patch destination register for a TESTSET instruction. +** If instruction in position 'node' is not a TESTSET, return 0 ("fails"). +** Otherwise, if 'reg' is not 'NO_REG', set it as the destination +** register. Otherwise, change instruction to a simple 'TEST' (produces +** no register value) +*/ +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else { + /* no register to put value or register already has the value; + change instruction to simple test */ + *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i)); + } + return 1; +} + + +/* +** Traverse a list of tests ensuring no one produces a value +*/ +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +/* +** Traverse a list of tests, patching their destination address and +** registers: tests producing values jump to 'vtarget' (and put their +** values in 'reg'), other tests jump to 'dtarget'. +*/ +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +/* +** Path all jumps in 'list' to jump to 'target'. +** (The assert means that we cannot fix a jump to a forward address +** because we only know addresses once code is generated.) +*/ +void luaK_patchlist (FuncState *fs, int list, int target) { + lua_assert(target <= fs->pc); + patchlistaux(fs, list, target, NO_REG, target); +} + + +void luaK_patchtohere (FuncState *fs, int list) { + int hr = luaK_getlabel(fs); /* mark "here" as a jump target */ + luaK_patchlist(fs, list, hr); +} + + +/* limit for difference between lines in relative line info. */ +#define LIMLINEDIFF 0x80 + + +/* +** Save line info for a new instruction. If difference from last line +** does not fit in a byte, of after that many instructions, save a new +** absolute line info; (in that case, the special value 'ABSLINEINFO' +** in 'lineinfo' signals the existence of this absolute information.) +** Otherwise, store the difference from last line in 'lineinfo'. +*/ +static void savelineinfo (FuncState *fs, Proto *f, int line) { + int linedif = line - fs->previousline; + int pc = fs->pc - 1; /* last instruction coded */ + if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ >= MAXIWTHABS) { + luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, + f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); + f->abslineinfo[fs->nabslineinfo].pc = pc; + f->abslineinfo[fs->nabslineinfo++].line = line; + linedif = ABSLINEINFO; /* signal that there is absolute information */ + fs->iwthabs = 1; /* restart counter */ + } + luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, + MAX_INT, "opcodes"); + f->lineinfo[pc] = linedif; + fs->previousline = line; /* last line saved */ +} + + +/* +** Remove line information from the last instruction. +** If line information for that instruction is absolute, set 'iwthabs' +** above its max to force the new (replacing) instruction to have +** absolute line info, too. +*/ +static void removelastlineinfo (FuncState *fs) { + Proto *f = fs->f; + int pc = fs->pc - 1; /* last instruction coded */ + if (f->lineinfo[pc] != ABSLINEINFO) { /* relative line info? */ + fs->previousline -= f->lineinfo[pc]; /* correct last line saved */ + fs->iwthabs--; /* undo previous increment */ + } + else { /* absolute line information */ + lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == pc); + fs->nabslineinfo--; /* remove it */ + fs->iwthabs = MAXIWTHABS + 1; /* force next line info to be absolute */ + } +} + + +/* +** Remove the last instruction created, correcting line information +** accordingly. +*/ +static void removelastinstruction (FuncState *fs) { + removelastlineinfo(fs); + fs->pc--; +} + + +/* +** Emit instruction 'i', checking for array sizes and saving also its +** line information. Return 'i' position. +*/ +int luaK_code (FuncState *fs, Instruction i) { + Proto *f = fs->f; + /* put new instruction in code array */ + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "opcodes"); + f->code[fs->pc++] = i; + savelineinfo(fs, f, fs->ls->lastline); + return fs->pc - 1; /* index of new instruction */ +} + + +/* +** Format and emit an 'iABC' instruction. (Assertions check consistency +** of parameters versus opcode.) +*/ +int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { + lua_assert(getOpMode(o) == iABC); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && + c <= MAXARG_C && (k & ~1) == 0); + return luaK_code(fs, CREATE_ABCk(o, a, b, c, k)); +} + + +/* +** Format and emit an 'iABx' instruction. +*/ +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx); + lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, bc)); +} + + +/* +** Format and emit an 'iAsBx' instruction. +*/ +static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) { + unsigned int b = bc + OFFSET_sBx; + lua_assert(getOpMode(o) == iAsBx); + lua_assert(a <= MAXARG_A && b <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, b)); +} + + +/* +** Format and emit an 'isJ' instruction. +*/ +static int codesJ (FuncState *fs, OpCode o, int sj, int k) { + unsigned int j = sj + OFFSET_sJ; + lua_assert(getOpMode(o) == isJ); + lua_assert(j <= MAXARG_sJ && (k & ~1) == 0); + return luaK_code(fs, CREATE_sJ(o, j, k)); +} + + +/* +** Emit an "extra argument" instruction (format 'iAx') +*/ +static int codeextraarg (FuncState *fs, int a) { + lua_assert(a <= MAXARG_Ax); + return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); +} + + +/* +** Emit a "load constant" instruction, using either 'OP_LOADK' +** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' +** instruction with "extra argument". +*/ +static int luaK_codek (FuncState *fs, int reg, int k) { + if (k <= MAXARG_Bx) + return luaK_codeABx(fs, OP_LOADK, reg, k); + else { + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); + codeextraarg(fs, k); + return p; + } +} + + +/* +** Check register-stack level, keeping track of its maximum size +** in field 'maxstacksize' +*/ +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXREGS) + luaX_syntaxerror(fs->ls, + "function or expression needs too many registers"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +/* +** Reserve 'n' registers in register stack +*/ +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +/* +** Free register 'reg', if it is neither a constant index nor +** a local variable. +) +*/ +static void freereg (FuncState *fs, int reg) { + if (reg >= luaY_nvarstack(fs)) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +/* +** Free two registers in proper order +*/ +static void freeregs (FuncState *fs, int r1, int r2) { + if (r1 > r2) { + freereg(fs, r1); + freereg(fs, r2); + } + else { + freereg(fs, r2); + freereg(fs, r1); + } +} + + +/* +** Free register used by expression 'e' (if any) +*/ +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.info); +} + + +/* +** Free registers used by expressions 'e1' and 'e2' (if any) in proper +** order. +*/ +static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { + int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; + int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; + freeregs(fs, r1, r2); +} + + +/* +** Add constant 'v' to prototype's list of constants (field 'k'). +** Use scanner's table to cache position of constants in constant list +** and try to reuse constants. Because some values should not be used +** as keys (nil cannot be a key, integer keys can collapse with float +** keys), the caller must provide a useful 'key' for indexing the cache. +** Note that all functions share the same table, so entering or exiting +** a function can make some indices wrong. +*/ +static int addk (FuncState *fs, TValue *key, TValue *v) { + TValue val; + lua_State *L = fs->ls->L; + Proto *f = fs->f; + const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */ + int k, oldsize; + if (ttisinteger(idx)) { /* is there an index there? */ + k = cast_int(ivalue(idx)); + /* correct value? (warning: must distinguish floats from integers!) */ + if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && + luaV_rawequalobj(&f->k[k], v)) + return k; /* reuse index */ + } + /* constant not found; create a new entry */ + oldsize = f->sizek; + k = fs->nk; + /* numerical value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setivalue(&val, k); + luaH_finishset(L, fs->ls->h, key, idx, &val); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[k], v); + fs->nk++; + luaC_barrier(L, f, v); + return k; +} + + +/* +** Add a string to list of constants and return its index. +*/ +static int stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->ls->L, &o, s); + return addk(fs, &o, &o); /* use string itself as key */ +} + + +/* +** Add an integer to list of constants and return its index. +*/ +static int luaK_intK (FuncState *fs, lua_Integer n) { + TValue o; + setivalue(&o, n); + return addk(fs, &o, &o); /* use integer itself as key */ +} + +/* +** Add a float to list of constants and return its index. Floats +** with integral values need a different key, to avoid collision +** with actual integers. To that, we add to the number its smaller +** power-of-two fraction that is still significant in its scale. +** For doubles, that would be 1/2^52. +** (This method is not bulletproof: there may be another float +** with that value, and for floats larger than 2^53 the result is +** still an integer. At worst, this only wastes an entry with +** a duplicate.) +*/ +static int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + lua_Integer ik; + setfltvalue(&o, r); + if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */ + return addk(fs, &o, &o); /* use number itself as key */ + else { /* must build an alternative key */ + const int nbm = l_floatatt(MANT_DIG); + const lua_Number q = l_mathop(ldexp)(l_mathop(1.0), -nbm + 1); + const lua_Number k = (ik == 0) ? q : r + r*q; /* new key */ + TValue kv; + setfltvalue(&kv, k); + /* result is not an integral value, unless value is too large */ + lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) || + l_mathop(fabs)(r) >= l_mathop(1e6)); + return addk(fs, &kv, &o); + } +} + + +/* +** Add a false to list of constants and return its index. +*/ +static int boolF (FuncState *fs) { + TValue o; + setbfvalue(&o); + return addk(fs, &o, &o); /* use boolean itself as key */ +} + + +/* +** Add a true to list of constants and return its index. +*/ +static int boolT (FuncState *fs) { + TValue o; + setbtvalue(&o); + return addk(fs, &o, &o); /* use boolean itself as key */ +} + + +/* +** Add nil to list of constants and return its index. +*/ +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->ls->L, &k, fs->ls->h); + return addk(fs, &k, &v); +} + + +/* +** Check whether 'i' can be stored in an 'sC' operand. Equivalent to +** (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) but without risk of +** overflows in the hidden addition inside 'int2sC'. +*/ +static int fitsC (lua_Integer i) { + return (l_castS2U(i) + OFFSET_sC <= cast_uint(MAXARG_C)); +} + + +/* +** Check whether 'i' can be stored in an 'sBx' operand. +*/ +static int fitsBx (lua_Integer i) { + return (-OFFSET_sBx <= i && i <= MAXARG_Bx - OFFSET_sBx); +} + + +void luaK_int (FuncState *fs, int reg, lua_Integer i) { + if (fitsBx(i)) + codeAsBx(fs, OP_LOADI, reg, cast_int(i)); + else + luaK_codek(fs, reg, luaK_intK(fs, i)); +} + + +static void luaK_float (FuncState *fs, int reg, lua_Number f) { + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) + codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); + else + luaK_codek(fs, reg, luaK_numberK(fs, f)); +} + + +/* +** Convert a constant in 'v' into an expression description 'e' +*/ +static void const2exp (TValue *v, expdesc *e) { + switch (ttypetag(v)) { + case LUA_VNUMINT: + e->k = VKINT; e->u.ival = ivalue(v); + break; + case LUA_VNUMFLT: + e->k = VKFLT; e->u.nval = fltvalue(v); + break; + case LUA_VFALSE: + e->k = VFALSE; + break; + case LUA_VTRUE: + e->k = VTRUE; + break; + case LUA_VNIL: + e->k = VNIL; + break; + case LUA_VSHRSTR: case LUA_VLNGSTR: + e->k = VKSTR; e->u.strval = tsvalue(v); + break; + default: lua_assert(0); + } +} + + +/* +** Fix an expression to return the number of results 'nresults'. +** 'e' must be a multi-ret expression (function call or vararg). +*/ +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + Instruction *pc = &getinstruction(fs, e); + if (e->k == VCALL) /* expression is an open function call? */ + SETARG_C(*pc, nresults + 1); + else { + lua_assert(e->k == VVARARG); + SETARG_C(*pc, nresults + 1); + SETARG_A(*pc, fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +/* +** Convert a VKSTR to a VK +*/ +static void str2K (FuncState *fs, expdesc *e) { + lua_assert(e->k == VKSTR); + e->u.info = stringK(fs, e->u.strval); + e->k = VK; +} + + +/* +** Fix an expression to return one result. +** If expression is not a multi-ret expression (function call or +** vararg), it already returns one result, so nothing needs to be done. +** Function calls become VNONRELOC expressions (as its result comes +** fixed in the base register of the call), while vararg expressions +** become VRELOC (as OP_VARARG puts its results where it wants). +** (Calls are created returning one result, so that does not need +** to be fixed.) +*/ +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + /* already returns 1 value */ + lua_assert(GETARG_C(getinstruction(fs, e)) == 2); + e->k = VNONRELOC; /* result has fixed position */ + e->u.info = GETARG_A(getinstruction(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_C(getinstruction(fs, e), 2); + e->k = VRELOC; /* can relocate its simple result */ + } +} + + +/* +** Ensure that expression 'e' is not a variable (nor a ). +** (Expression still may have jump lists.) +*/ +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VCONST: { + const2exp(const2val(fs, e), e); + break; + } + case VLOCAL: { /* already in a register */ + int temp = e->u.var.ridx; + e->u.info = temp; /* (can't do a direct assignment; values overlap) */ + e->k = VNONRELOC; /* becomes a non-relocatable value */ + break; + } + case VUPVAL: { /* move value to some (pending) register */ + e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); + e->k = VRELOC; + break; + } + case VINDEXUP: { + e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VINDEXI: { + freereg(fs, e->u.ind.t); + e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VINDEXSTR: { + freereg(fs, e->u.ind.t); + e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VINDEXED: { + freeregs(fs, e->u.ind.t, e->u.ind.idx); + e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VVARARG: case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +/* +** Ensure expression value is in register 'reg', making 'e' a +** non-relocatable expression. +** (Expression still may have jump lists.) +*/ +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: { + luaK_codeABC(fs, OP_LOADFALSE, reg, 0, 0); + break; + } + case VTRUE: { + luaK_codeABC(fs, OP_LOADTRUE, reg, 0, 0); + break; + } + case VKSTR: { + str2K(fs, e); + } /* FALLTHROUGH */ + case VK: { + luaK_codek(fs, reg, e->u.info); + break; + } + case VKFLT: { + luaK_float(fs, reg, e->u.nval); + break; + } + case VKINT: { + luaK_int(fs, reg, e->u.ival); + break; + } + case VRELOC: { + Instruction *pc = &getinstruction(fs, e); + SETARG_A(*pc, reg); /* instruction will put result in 'reg' */ + break; + } + case VNONRELOC: { + if (reg != e->u.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); + break; + } + default: { + lua_assert(e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.info = reg; + e->k = VNONRELOC; +} + + +/* +** Ensure expression value is in a register, making 'e' a +** non-relocatable expression. +** (Expression still may have jump lists.) +*/ +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { /* no fixed register yet? */ + luaK_reserveregs(fs, 1); /* get a register */ + discharge2reg(fs, e, fs->freereg-1); /* put value there */ + } +} + + +static int code_loadbool (FuncState *fs, int A, OpCode op) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, op, A, 0, 0); +} + + +/* +** check whether list has any jump that do not produce a value +** or produce an inverted value +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +/* +** Ensures final expression result (which includes results from its +** jump lists) is in register 'reg'. +** If expression has jumps, need to patch these jumps either to +** its final position or to "load" instructions (for those tests +** that do not produce values). +*/ +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) /* expression itself is a test? */ + luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_loadbool(fs, reg, OP_LFALSESKIP); /* skip next inst. */ + p_t = code_loadbool(fs, reg, OP_LOADTRUE); + /* jump around these booleans if 'e' is not a test */ + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.info = reg; + e->k = VNONRELOC; +} + + +/* +** Ensures final expression result is in next available register. +*/ +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +/* +** Ensures final expression result is in some (any) register +** and return that register. +*/ +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { /* expression already has a register? */ + if (!hasjumps(e)) /* no jumps? */ + return e->u.info; /* result is already in a register */ + if (e->u.info >= luaY_nvarstack(fs)) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.info); /* put final result in it */ + return e->u.info; + } + /* else expression has jumps and cannot change its register + to hold the jump values, because it is a local variable. + Go through to the default case. */ + } + luaK_exp2nextreg(fs, e); /* default: use next available register */ + return e->u.info; +} + + +/* +** Ensures final expression result is either in a register +** or in an upvalue. +*/ +void luaK_exp2anyregup (FuncState *fs, expdesc *e) { + if (e->k != VUPVAL || hasjumps(e)) + luaK_exp2anyreg(fs, e); +} + + +/* +** Ensures final expression result is either in a register +** or it is a constant. +*/ +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +/* +** Try to make 'e' a K expression with an index in the range of R/K +** indices. Return true iff succeeded. +*/ +static int luaK_exp2K (FuncState *fs, expdesc *e) { + if (!hasjumps(e)) { + int info; + switch (e->k) { /* move constants to 'k' */ + case VTRUE: info = boolT(fs); break; + case VFALSE: info = boolF(fs); break; + case VNIL: info = nilK(fs); break; + case VKINT: info = luaK_intK(fs, e->u.ival); break; + case VKFLT: info = luaK_numberK(fs, e->u.nval); break; + case VKSTR: info = stringK(fs, e->u.strval); break; + case VK: info = e->u.info; break; + default: return 0; /* not a constant */ + } + if (info <= MAXINDEXRK) { /* does constant fit in 'argC'? */ + e->k = VK; /* make expression a 'K' expression */ + e->u.info = info; + return 1; + } + } + /* else, expression doesn't fit; leave it unchanged */ + return 0; +} + + +/* +** Ensures final expression result is in a valid R/K index +** (that is, it is either in a register or in 'k' with an index +** in the range of R/K indices). +** Returns 1 iff expression is K. +*/ +static int exp2RK (FuncState *fs, expdesc *e) { + if (luaK_exp2K(fs, e)) + return 1; + else { /* not a constant in the right range: put it in a register */ + luaK_exp2anyreg(fs, e); + return 0; + } +} + + +static void codeABRK (FuncState *fs, OpCode o, int a, int b, + expdesc *ec) { + int k = exp2RK(fs, ec); + luaK_codeABCk(fs, o, a, b, ec->u.info, k); +} + + +/* +** Generate code to store result of expression 'ex' into variable 'var'. +*/ +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.var.ridx); /* compute 'ex' into proper place */ + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); + break; + } + case VINDEXUP: { + codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex); + break; + } + case VINDEXI: { + codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex); + break; + } + case VINDEXSTR: { + codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex); + break; + } + case VINDEXED: { + codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex); + break; + } + default: lua_assert(0); /* invalid var kind to store */ + } + freeexp(fs, ex); +} + + +/* +** Emit SELF instruction (convert expression 'e' into 'e:key(e,'). +*/ +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int ereg; + luaK_exp2anyreg(fs, e); + ereg = e->u.info; /* register where 'e' was placed */ + freeexp(fs, e); + e->u.info = fs->freereg; /* base register for op_self */ + e->k = VNONRELOC; /* self expression has a fixed register */ + luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ + codeABRK(fs, OP_SELF, e->u.info, ereg, key); + freeexp(fs, key); +} + + +/* +** Negate condition 'e' (where 'e' is a comparison). +*/ +static void negatecondition (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_k(*pc, (GETARG_k(*pc) ^ 1)); +} + + +/* +** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond' +** is true, code will jump if 'e' is true.) Return jump position. +** Optimize when 'e' is 'not' something, inverting the condition +** and removing the 'not'. +*/ +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOC) { + Instruction ie = getinstruction(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + removelastinstruction(fs); /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond); +} + + +/* +** Emit code to go through if 'e' is true, jump otherwise. +*/ +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of new jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { /* condition? */ + negatecondition(fs, e); /* jump when it is false */ + pc = e->u.info; /* save jump position */ + break; + } + case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 0); /* jump when false */ + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert new jump in false list */ + luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */ + e->t = NO_JUMP; +} + + +/* +** Emit code to go through if 'e' is false, jump otherwise. +*/ +void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of new jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { + pc = e->u.info; /* already jump if true */ + break; + } + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 1); /* jump if true */ + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */ + luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */ + e->f = NO_JUMP; +} + + +/* +** Code 'not e', doing constant folding. +*/ +static void codenot (FuncState *fs, expdesc *e) { + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; /* true == not nil == not false */ + break; + } + case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { + e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ + break; + } + case VJMP: { + negatecondition(fs, e); + break; + } + case VRELOC: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); + e->k = VRELOC; + break; + } + default: lua_assert(0); /* cannot happen */ + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); /* values are useless when negated */ + removevalues(fs, e->t); +} + + +/* +** Check whether expression 'e' is a short literal string +*/ +static int isKstr (FuncState *fs, expdesc *e) { + return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B && + ttisshrstring(&fs->f->k[e->u.info])); +} + +/* +** Check whether expression 'e' is a literal integer. +*/ +static int isKint (expdesc *e) { + return (e->k == VKINT && !hasjumps(e)); +} + + +/* +** Check whether expression 'e' is a literal integer in +** proper range to fit in register C +*/ +static int isCint (expdesc *e) { + return isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); +} + + +/* +** Check whether expression 'e' is a literal integer in +** proper range to fit in register sC +*/ +static int isSCint (expdesc *e) { + return isKint(e) && fitsC(e->u.ival); +} + + +/* +** Check whether expression 'e' is a literal integer or float in +** proper range to fit in a register (sB or sC). +*/ +static int isSCnumber (expdesc *e, int *pi, int *isfloat) { + lua_Integer i; + if (e->k == VKINT) + i = e->u.ival; + else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq)) + *isfloat = 1; + else + return 0; /* not a number */ + if (!hasjumps(e) && fitsC(i)) { + *pi = int2sC(cast_int(i)); + return 1; + } + else + return 0; +} + + +/* +** Create expression 't[k]'. 't' must have its final result already in a +** register or upvalue. Upvalues can only be indexed by literal strings. +** Keys can be literal strings in the constant table or arbitrary +** values in registers. +*/ +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + if (k->k == VKSTR) + str2K(fs, k); + lua_assert(!hasjumps(t) && + (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); + if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ + luaK_exp2anyreg(fs, t); /* put it in a register */ + if (t->k == VUPVAL) { + int temp = t->u.info; /* upvalue index */ + lua_assert(isKstr(fs, k)); + t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */ + t->u.ind.idx = k->u.info; /* literal short string */ + t->k = VINDEXUP; + } + else { + /* register index of the table */ + t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info; + if (isKstr(fs, k)) { + t->u.ind.idx = k->u.info; /* literal short string */ + t->k = VINDEXSTR; + } + else if (isCint(k)) { + t->u.ind.idx = cast_int(k->u.ival); /* int. constant in proper range */ + t->k = VINDEXI; + } + else { + t->u.ind.idx = luaK_exp2anyreg(fs, k); /* register */ + t->k = VINDEXED; + } + } +} + + +/* +** Return false if folding can raise an error. +** Bitwise operations need operands convertible to integers; division +** operations cannot have 0 as divisor. +*/ +static int validop (int op, TValue *v1, TValue *v2) { + switch (op) { + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ + lua_Integer i; + return (luaV_tointegerns(v1, &i, LUA_FLOORN2I) && + luaV_tointegerns(v2, &i, LUA_FLOORN2I)); + } + case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ + return (nvalue(v2) != 0); + default: return 1; /* everything else is valid */ + } +} + + +/* +** Try to "constant-fold" an operation; return 1 iff successful. +** (In this case, 'e1' has the final result.) +*/ +static int constfolding (FuncState *fs, int op, expdesc *e1, + const expdesc *e2) { + TValue v1, v2, res; + if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) + return 0; /* non-numeric operands or not safe to fold */ + luaO_rawarith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ + if (ttisinteger(&res)) { + e1->k = VKINT; + e1->u.ival = ivalue(&res); + } + else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */ + lua_Number n = fltvalue(&res); + if (luai_numisnan(n) || n == 0) + return 0; + e1->k = VKFLT; + e1->u.nval = n; + } + return 1; +} + + +/* +** Convert a BinOpr to an OpCode (ORDER OPR - ORDER OP) +*/ +l_sinline OpCode binopr2op (BinOpr opr, BinOpr baser, OpCode base) { + lua_assert(baser <= opr && + ((baser == OPR_ADD && opr <= OPR_SHR) || + (baser == OPR_LT && opr <= OPR_LE))); + return cast(OpCode, (cast_int(opr) - cast_int(baser)) + cast_int(base)); +} + + +/* +** Convert a UnOpr to an OpCode (ORDER OPR - ORDER OP) +*/ +l_sinline OpCode unopr2op (UnOpr opr) { + return cast(OpCode, (cast_int(opr) - cast_int(OPR_MINUS)) + + cast_int(OP_UNM)); +} + + +/* +** Convert a BinOpr to a tag method (ORDER OPR - ORDER TM) +*/ +l_sinline TMS binopr2TM (BinOpr opr) { + lua_assert(OPR_ADD <= opr && opr <= OPR_SHR); + return cast(TMS, (cast_int(opr) - cast_int(OPR_ADD)) + cast_int(TM_ADD)); +} + + +/* +** Emit code for unary expressions that "produce values" +** (everything but 'not'). +** Expression to produce final result will be encoded in 'e'. +*/ +static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { + int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */ + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */ + e->k = VRELOC; /* all those operations are relocatable */ + luaK_fixline(fs, line); +} + + +/* +** Emit code for binary expressions that "produce values" +** (everything but logical operators 'and'/'or' and comparison +** operators). +** Expression to produce final result will be encoded in 'e1'. +*/ +static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, + OpCode op, int v2, int flip, int line, + OpCode mmop, TMS event) { + int v1 = luaK_exp2anyreg(fs, e1); + int pc = luaK_codeABCk(fs, op, 0, v1, v2, 0); + freeexps(fs, e1, e2); + e1->u.info = pc; + e1->k = VRELOC; /* all those operations are relocatable */ + luaK_fixline(fs, line); + luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */ + luaK_fixline(fs, line); +} + + +/* +** Emit code for binary expressions that "produce values" over +** two registers. +*/ +static void codebinexpval (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int line) { + OpCode op = binopr2op(opr, OPR_ADD, OP_ADD); + int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */ + /* 'e1' must be already in a register or it is a constant */ + lua_assert((VNIL <= e1->k && e1->k <= VKSTR) || + e1->k == VNONRELOC || e1->k == VRELOC); + lua_assert(OP_ADD <= op && op <= OP_SHR); + finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, binopr2TM(opr)); +} + + +/* +** Code binary operators with immediate operands. +*/ +static void codebini (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int flip, int line, + TMS event) { + int v2 = int2sC(cast_int(e2->u.ival)); /* immediate operand */ + lua_assert(e2->k == VKINT); + finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event); +} + + +/* +** Code binary operators with K operand. +*/ +static void codebinK (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int flip, int line) { + TMS event = binopr2TM(opr); + int v2 = e2->u.info; /* K index */ + OpCode op = binopr2op(opr, OPR_ADD, OP_ADDK); + finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); +} + + +/* Try to code a binary operator negating its second operand. +** For the metamethod, 2nd operand must keep its original value. +*/ +static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, + OpCode op, int line, TMS event) { + if (!isKint(e2)) + return 0; /* not an integer constant */ + else { + lua_Integer i2 = e2->u.ival; + if (!(fitsC(i2) && fitsC(-i2))) + return 0; /* not in the proper range */ + else { /* operating a small integer constant */ + int v2 = cast_int(i2); + finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event); + /* correct metamethod argument */ + SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2)); + return 1; /* successfully coded */ + } + } +} + + +static void swapexps (expdesc *e1, expdesc *e2) { + expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ +} + + +/* +** Code binary operators with no constant operand. +*/ +static void codebinNoK (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int flip, int line) { + if (flip) + swapexps(e1, e2); /* back to original order */ + codebinexpval(fs, opr, e1, e2, line); /* use standard operators */ +} + + +/* +** Code arithmetic operators ('+', '-', ...). If second operand is a +** constant in the proper range, use variant opcodes with K operands. +*/ +static void codearith (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int flip, int line) { + if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) /* K operand? */ + codebinK(fs, opr, e1, e2, flip, line); + else /* 'e2' is neither an immediate nor a K operand */ + codebinNoK(fs, opr, e1, e2, flip, line); +} + + +/* +** Code commutative operators ('+', '*'). If first operand is a +** numeric constant, change order of operands to try to use an +** immediate or K operator. +*/ +static void codecommutative (FuncState *fs, BinOpr op, + expdesc *e1, expdesc *e2, int line) { + int flip = 0; + if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ + swapexps(e1, e2); /* change order */ + flip = 1; + } + if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */ + codebini(fs, OP_ADDI, e1, e2, flip, line, TM_ADD); + else + codearith(fs, op, e1, e2, flip, line); +} + + +/* +** Code bitwise operations; they are all commutative, so the function +** tries to put an integer constant as the 2nd operand (a K operand). +*/ +static void codebitwise (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int line) { + int flip = 0; + if (e1->k == VKINT) { + swapexps(e1, e2); /* 'e2' will be the constant operand */ + flip = 1; + } + if (e2->k == VKINT && luaK_exp2K(fs, e2)) /* K operand? */ + codebinK(fs, opr, e1, e2, flip, line); + else /* no constants */ + codebinNoK(fs, opr, e1, e2, flip, line); +} + + +/* +** Emit code for order comparisons. When using an immediate operand, +** 'isfloat' tells whether the original value was a float. +*/ +static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { + int r1, r2; + int im; + int isfloat = 0; + OpCode op; + if (isSCnumber(e2, &im, &isfloat)) { + /* use immediate operand */ + r1 = luaK_exp2anyreg(fs, e1); + r2 = im; + op = binopr2op(opr, OPR_LT, OP_LTI); + } + else if (isSCnumber(e1, &im, &isfloat)) { + /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ + r1 = luaK_exp2anyreg(fs, e2); + r2 = im; + op = binopr2op(opr, OPR_LT, OP_GTI); + } + else { /* regular case, compare two registers */ + r1 = luaK_exp2anyreg(fs, e1); + r2 = luaK_exp2anyreg(fs, e2); + op = binopr2op(opr, OPR_LT, OP_LT); + } + freeexps(fs, e1, e2); + e1->u.info = condjump(fs, op, r1, r2, isfloat, 1); + e1->k = VJMP; +} + + +/* +** Emit code for equality comparisons ('==', '~='). +** 'e1' was already put as RK by 'luaK_infix'. +*/ +static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { + int r1, r2; + int im; + int isfloat = 0; /* not needed here, but kept for symmetry */ + OpCode op; + if (e1->k != VNONRELOC) { + lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); + swapexps(e1, e2); + } + r1 = luaK_exp2anyreg(fs, e1); /* 1st expression must be in register */ + if (isSCnumber(e2, &im, &isfloat)) { + op = OP_EQI; + r2 = im; /* immediate operand */ + } + else if (exp2RK(fs, e2)) { /* 2nd expression is constant? */ + op = OP_EQK; + r2 = e2->u.info; /* constant index */ + } + else { + op = OP_EQ; /* will compare two registers */ + r2 = luaK_exp2anyreg(fs, e2); + } + freeexps(fs, e1, e2); + e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ)); + e1->k = VJMP; +} + + +/* +** Apply prefix operation 'op' to expression 'e'. +*/ +void luaK_prefix (FuncState *fs, UnOpr opr, expdesc *e, int line) { + static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; + luaK_dischargevars(fs, e); + switch (opr) { + case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ + if (constfolding(fs, opr + LUA_OPUNM, e, &ef)) + break; + /* else */ /* FALLTHROUGH */ + case OPR_LEN: + codeunexpval(fs, unopr2op(opr), e, line); + break; + case OPR_NOT: codenot(fs, e); break; + default: lua_assert(0); + } +} + + +/* +** Process 1st operand 'v' of binary operation 'op' before reading +** 2nd operand. +*/ +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + luaK_dischargevars(fs, v); + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */ + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */ + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the stack */ + break; + } + case OPR_ADD: case OPR_SUB: + case OPR_MUL: case OPR_DIV: case OPR_IDIV: + case OPR_MOD: case OPR_POW: + case OPR_BAND: case OPR_BOR: case OPR_BXOR: + case OPR_SHL: case OPR_SHR: { + if (!tonumeral(v, NULL)) + luaK_exp2anyreg(fs, v); + /* else keep numeral, which may be folded or used as an immediate + operand */ + break; + } + case OPR_EQ: case OPR_NE: { + if (!tonumeral(v, NULL)) + exp2RK(fs, v); + /* else keep numeral, which may be an immediate operand */ + break; + } + case OPR_LT: case OPR_LE: + case OPR_GT: case OPR_GE: { + int dummy, dummy2; + if (!isSCnumber(v, &dummy, &dummy2)) + luaK_exp2anyreg(fs, v); + /* else keep numeral, which may be an immediate operand */ + break; + } + default: lua_assert(0); + } +} + +/* +** Create code for '(e1 .. e2)'. +** For '(e1 .. e2.1 .. e2.2)' (which is '(e1 .. (e2.1 .. e2.2))', +** because concatenation is right associative), merge both CONCATs. +*/ +static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int line) { + Instruction *ie2 = previousinstruction(fs); + if (GET_OPCODE(*ie2) == OP_CONCAT) { /* is 'e2' a concatenation? */ + int n = GETARG_B(*ie2); /* # of elements concatenated in 'e2' */ + lua_assert(e1->u.info + 1 == GETARG_A(*ie2)); + freeexp(fs, e2); + SETARG_A(*ie2, e1->u.info); /* correct first element ('e1') */ + SETARG_B(*ie2, n + 1); /* will concatenate one more element */ + } + else { /* 'e2' is not a concatenation */ + luaK_codeABC(fs, OP_CONCAT, e1->u.info, 2, 0); /* new concat opcode */ + freeexp(fs, e2); + luaK_fixline(fs, line); + } +} + + +/* +** Finalize code for binary operation, after reading 2nd operand. +*/ +void luaK_posfix (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int line) { + luaK_dischargevars(fs, e2); + if (foldbinop(opr) && constfolding(fs, opr + LUA_OPADD, e1, e2)) + return; /* done by folding */ + switch (opr) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list closed by 'luaK_infix' */ + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list closed by 'luaK_infix' */ + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { /* e1 .. e2 */ + luaK_exp2nextreg(fs, e2); + codeconcat(fs, e1, e2, line); + break; + } + case OPR_ADD: case OPR_MUL: { + codecommutative(fs, opr, e1, e2, line); + break; + } + case OPR_SUB: { + if (finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB)) + break; /* coded as (r1 + -I) */ + /* ELSE */ + } /* FALLTHROUGH */ + case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { + codearith(fs, opr, e1, e2, 0, line); + break; + } + case OPR_BAND: case OPR_BOR: case OPR_BXOR: { + codebitwise(fs, opr, e1, e2, line); + break; + } + case OPR_SHL: { + if (isSCint(e1)) { + swapexps(e1, e2); + codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); /* I << r2 */ + } + else if (finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL)) { + /* coded as (r1 >> -I) */; + } + else /* regular case (two registers) */ + codebinexpval(fs, opr, e1, e2, line); + break; + } + case OPR_SHR: { + if (isSCint(e2)) + codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */ + else /* regular case (two registers) */ + codebinexpval(fs, opr, e1, e2, line); + break; + } + case OPR_EQ: case OPR_NE: { + codeeq(fs, opr, e1, e2); + break; + } + case OPR_GT: case OPR_GE: { + /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */ + swapexps(e1, e2); + opr = cast(BinOpr, (opr - OPR_GT) + OPR_LT); + } /* FALLTHROUGH */ + case OPR_LT: case OPR_LE: { + codeorder(fs, opr, e1, e2); + break; + } + default: lua_assert(0); + } +} + + +/* +** Change line information associated with current position, by removing +** previous info and adding it again with new line. +*/ +void luaK_fixline (FuncState *fs, int line) { + removelastlineinfo(fs); + savelineinfo(fs, fs->f, line); +} + + +void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { + Instruction *inst = &fs->f->code[pc]; + int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0; /* hash size */ + int extra = asize / (MAXARG_C + 1); /* higher bits of array size */ + int rc = asize % (MAXARG_C + 1); /* lower bits of array size */ + int k = (extra > 0); /* true iff needs extra argument */ + *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); + *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); +} + + +/* +** Emit a SETLIST instruction. +** 'base' is register that keeps table; +** 'nelems' is #table plus those to be stored now; +** 'tostore' is number of values (in registers 'base + 1',...) to add to +** table (or LUA_MULTRET to add up to stack top). +*/ +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); + if (tostore == LUA_MULTRET) + tostore = 0; + if (nelems <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems); + else { + int extra = nelems / (MAXARG_C + 1); + nelems %= (MAXARG_C + 1); + luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1); + codeextraarg(fs, extra); + } + fs->freereg = base + 1; /* free registers with list values */ +} + + +/* +** return the final target of a jump (skipping jumps to jumps) +*/ +static int finaltarget (Instruction *code, int i) { + int count; + for (count = 0; count < 100; count++) { /* avoid infinite loops */ + Instruction pc = code[i]; + if (GET_OPCODE(pc) != OP_JMP) + break; + else + i += GETARG_sJ(pc) + 1; + } + return i; +} + + +/* +** Do a final pass over the code of a function, doing small peephole +** optimizations and adjustments. +*/ +void luaK_finish (FuncState *fs) { + int i; + Proto *p = fs->f; + for (i = 0; i < fs->pc; i++) { + Instruction *pc = &p->code[i]; + lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc)); + switch (GET_OPCODE(*pc)) { + case OP_RETURN0: case OP_RETURN1: { + if (!(fs->needclose || p->is_vararg)) + break; /* no extra work */ + /* else use OP_RETURN to do the extra work */ + SET_OPCODE(*pc, OP_RETURN); + } /* FALLTHROUGH */ + case OP_RETURN: case OP_TAILCALL: { + if (fs->needclose) + SETARG_k(*pc, 1); /* signal that it needs to close */ + if (p->is_vararg) + SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */ + break; + } + case OP_JMP: { + int target = finaltarget(p->code, i); + fixjump(fs, i, target); + break; + } + default: break; + } + } +} diff --git a/arm9/source/lua/lcode.h b/arm9/source/lua/lcode.h new file mode 100644 index 000000000..0b971fc43 --- /dev/null +++ b/arm9/source/lua/lcode.h @@ -0,0 +1,101 @@ +/* +** $Id: lcode.h $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums (ORDER OP) +*/ +typedef enum BinOpr { + /* arithmetic operators */ + OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, + OPR_DIV, OPR_IDIV, + /* bitwise operators */ + OPR_BAND, OPR_BOR, OPR_BXOR, + OPR_SHL, OPR_SHR, + /* string operator */ + OPR_CONCAT, + /* comparison operators */ + OPR_EQ, OPR_LT, OPR_LE, + OPR_NE, OPR_GT, OPR_GE, + /* logical operators */ + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +/* true if operation is foldable (that is, it is arithmetic or bitwise) */ +#define foldbinop(op) ((op) <= OPR_SHR) + + +#define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) + + +typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +/* get (pointer to) instruction of given 'expdesc' */ +#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) + + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) + +LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, + int B, int C, int k); +LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); +LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, + int ra, int asize, int hsize); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); +LUAI_FUNC void luaK_finish (FuncState *fs); +LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); + + +#endif diff --git a/arm9/source/lua/lcorolib.c b/arm9/source/lua/lcorolib.c new file mode 100644 index 000000000..c64adf08a --- /dev/null +++ b/arm9/source/lua/lcorolib.c @@ -0,0 +1,210 @@ +/* +** $Id: lcorolib.c $ +** Coroutine Library +** See Copyright Notice in lua.h +*/ + +#define lcorolib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static lua_State *getco (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argexpected(L, co, 1, "thread"); + return co; +} + + +/* +** Resumes a coroutine. Returns the number of results for non-error +** cases or -1 for errors. +*/ +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status, nres; + if (l_unlikely(!lua_checkstack(co, narg))) { + lua_pushliteral(L, "too many arguments to resume"); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + status = lua_resume(co, L, narg, &nres); + if (l_likely(status == LUA_OK || status == LUA_YIELD)) { + if (l_unlikely(!lua_checkstack(L, nres + 1))) { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); + return -1; /* error flag */ + } + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = getco(L); + int r; + r = auxresume(L, co, lua_gettop(L) - 1); + if (l_unlikely(r < 0)) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + 'resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (l_unlikely(r < 0)) { /* error? */ + int stat = lua_status(co); + if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ + stat = lua_closethread(co, L); /* close its tbc variables */ + lua_assert(stat != LUA_OK); + lua_xmove(co, L, 1); /* move error message to the caller */ + } + if (stat != LUA_ERRMEM && /* not a memory error and ... */ + lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ + luaL_where(L, 1); /* add extra info, if available */ + lua_insert(L, -2); + lua_concat(L, 2); + } + return lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL; + luaL_checktype(L, 1, LUA_TFUNCTION); + NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +#define COS_RUN 0 +#define COS_DEAD 1 +#define COS_YIELD 2 +#define COS_NORM 3 + + +static const char *const statname[] = + {"running", "dead", "suspended", "normal"}; + + +static int auxstatus (lua_State *L, lua_State *co) { + if (L == co) return COS_RUN; + else { + switch (lua_status(co)) { + case LUA_YIELD: + return COS_YIELD; + case LUA_OK: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar)) /* does it have frames? */ + return COS_NORM; /* it is running */ + else if (lua_gettop(co) == 0) + return COS_DEAD; + else + return COS_YIELD; /* initial state */ + } + default: /* some error occurred */ + return COS_DEAD; + } + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = getco(L); + lua_pushstring(L, statname[auxstatus(L, co)]); + return 1; +} + + +static int luaB_yieldable (lua_State *L) { + lua_State *co = lua_isnone(L, 1) ? L : getco(L); + lua_pushboolean(L, lua_isyieldable(co)); + return 1; +} + + +static int luaB_corunning (lua_State *L) { + int ismain = lua_pushthread(L); + lua_pushboolean(L, ismain); + return 2; +} + + +static int luaB_close (lua_State *L) { + lua_State *co = getco(L); + int status = auxstatus(L, co); + switch (status) { + case COS_DEAD: case COS_YIELD: { + status = lua_closethread(co, L); + if (status == LUA_OK) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushboolean(L, 0); + lua_xmove(co, L, 1); /* move error message */ + return 2; + } + } + default: /* normal or running coroutine */ + return luaL_error(L, "cannot close a %s coroutine", statname[status]); + } +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {"isyieldable", luaB_yieldable}, + {"close", luaB_close}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_coroutine (lua_State *L) { + luaL_newlib(L, co_funcs); + return 1; +} + diff --git a/arm9/source/lua/lctype.c b/arm9/source/lua/lctype.c new file mode 100644 index 000000000..954228094 --- /dev/null +++ b/arm9/source/lua/lctype.c @@ -0,0 +1,64 @@ +/* +** $Id: lctype.c $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#define lctype_c +#define LUA_CORE + +#include "lprefix.h" + + +#include "lctype.h" + +#if !LUA_USE_CTYPE /* { */ + +#include + + +#if defined (LUA_UCID) /* accept UniCode IDentifiers? */ +/* consider all non-ascii codepoints to be alphabetic */ +#define NONA 0x01 +#else +#define NONA 0x00 /* default */ +#endif + + +LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { + 0x00, /* EOZ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ + 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif /* } */ diff --git a/arm9/source/lua/lctype.h b/arm9/source/lua/lctype.h new file mode 100644 index 000000000..864e19018 --- /dev/null +++ b/arm9/source/lua/lctype.h @@ -0,0 +1,101 @@ +/* +** $Id: lctype.h $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lctype_h +#define lctype_h + +#include "lua.h" + + +/* +** WARNING: the functions defined here do not necessarily correspond +** to the similar functions in the standard C ctype.h. They are +** optimized for the specific needs of Lua. +*/ + +#if !defined(LUA_USE_CTYPE) + +#if 'A' == 65 && '0' == 48 +/* ASCII case: can use its own tables; faster and fixed */ +#define LUA_USE_CTYPE 0 +#else +/* must use standard C ctype */ +#define LUA_USE_CTYPE 1 +#endif + +#endif + + +#if !LUA_USE_CTYPE /* { */ + +#include + +#include "llimits.h" + + +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 + + +#define MASK(B) (1 << (B)) + + +/* +** add 1 to char to allow index -1 (EOZ) +*/ +#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) + +/* +** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' +*/ +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) + + +/* +** In ASCII, this 'ltolower' is correct for alphabetic characters and +** for '.'. That is enough for Lua needs. ('check_exp' ensures that +** the character either is an upper-case letter or is unchanged by +** the transformation, which holds for lower-case letters and '.'.) +*/ +#define ltolower(c) \ + check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ + (c) | ('A' ^ 'a')) + + +/* one entry for each character and for -1 (EOZ) */ +LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) + + +#else /* }{ */ + +/* +** use standard C ctypes +*/ + +#include + + +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) + +#define ltolower(c) (tolower(c)) + +#endif /* } */ + +#endif + diff --git a/arm9/source/lua/ldblib.c b/arm9/source/lua/ldblib.c new file mode 100644 index 000000000..6dcbaa982 --- /dev/null +++ b/arm9/source/lua/ldblib.c @@ -0,0 +1,483 @@ +/* +** $Id: ldblib.c $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + +#define ldblib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** The hook table at registry[HOOKKEY] maps threads to their current +** hook function. +*/ +static const char *const HOOKKEY = "_HOOKKEY"; + + +/* +** If L1 != L, L1 can be in any state, and therefore there are no +** guarantees about its stack space; any push in L1 must be +** checked. +*/ +static void checkstack (lua_State *L, lua_State *L1, int n) { + if (l_unlikely(L != L1 && !lua_checkstack(L1, n))) + luaL_error(L, "stack overflow"); +} + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; /* return 1st argument */ +} + + +static int db_getuservalue (lua_State *L) { + int n = (int)luaL_optinteger(L, 2, 1); + if (lua_type(L, 1) != LUA_TUSERDATA) + luaL_pushfail(L); + else if (lua_getiuservalue(L, 1, n) != LUA_TNONE) { + lua_pushboolean(L, 1); + return 2; + } + return 1; +} + + +static int db_setuservalue (lua_State *L) { + int n = (int)luaL_optinteger(L, 3, 1); + luaL_checktype(L, 1, LUA_TUSERDATA); + luaL_checkany(L, 2); + lua_settop(L, 2); + if (!lua_setiuservalue(L, 1, n)) + luaL_pushfail(L); + return 1; +} + + +/* +** Auxiliary function used by several library functions: check for +** an optional thread as function's first argument and set 'arg' with +** 1 if this argument is present (so that functions can skip it to +** access their other arguments) +*/ +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; /* function will operate over current thread */ + } +} + + +/* +** Variations of 'lua_settable', used by 'db_getinfo' to put results +** from 'lua_getinfo' into result table. Key is always a string; +** value can be a string, an int, or a boolean. +*/ +static void settabss (lua_State *L, const char *k, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, k); +} + +static void settabsi (lua_State *L, const char *k, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, k); +} + +static void settabsb (lua_State *L, const char *k, int v) { + lua_pushboolean(L, v); + lua_setfield(L, -2, k); +} + + +/* +** In function 'db_getinfo', the call to 'lua_getinfo' may push +** results on the stack; later it creates the result table to put +** these objects. Function 'treatstackoption' puts the result from +** 'lua_getinfo' on top of the result table so that it can call +** 'lua_setfield'. +*/ +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) + lua_rotate(L, -2, 1); /* exchange object and table */ + else + lua_xmove(L1, L, 1); /* move object to the "main" stack */ + lua_setfield(L, -2, fname); /* put object into table */ +} + + +/* +** Calls 'lua_getinfo' and collects all results in a new table. +** L1 needs stack space for an optional input (function) plus +** two optional outputs (function and line table) from function +** 'lua_getinfo'. +*/ +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSrtu"); + checkstack(L, L1, 3); + luaL_argcheck(L, options[0] != '>', arg + 2, "invalid option '>'"); + if (lua_isfunction(L, arg + 1)) { /* info about a function? */ + options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ + lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ + lua_xmove(L, L1, 1); + } + else { /* stack level */ + if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { + luaL_pushfail(L); /* level out of range */ + return 1; + } + } + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_newtable(L); /* table to collect results */ + if (strchr(options, 'S')) { + lua_pushlstring(L, ar.source, ar.srclen); + lua_setfield(L, -2, "source"); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) { + settabsi(L, "nups", ar.nups); + settabsi(L, "nparams", ar.nparams); + settabsb(L, "isvararg", ar.isvararg); + } + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'r')) { + settabsi(L, "ftransfer", ar.ftransfer); + settabsi(L, "ntransfer", ar.ntransfer); + } + if (strchr(options, 't')) + settabsb(L, "istailcall", ar.istailcall); + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ + if (lua_isfunction(L, arg + 1)) { /* function argument? */ + lua_pushvalue(L, arg + 1); /* push function */ + lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ + return 1; /* return only name (there is no value) */ + } + else { /* stack-level argument */ + lua_Debug ar; + const char *name; + int level = (int)luaL_checkinteger(L, arg + 1); + if (l_unlikely(!lua_getstack(L1, level, &ar))) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + checkstack(L, L1, 1); + name = lua_getlocal(L1, &ar, nvar); + if (name) { + lua_xmove(L1, L, 1); /* move local value */ + lua_pushstring(L, name); /* push name */ + lua_rotate(L, -2, 1); /* re-order */ + return 2; + } + else { + luaL_pushfail(L); /* no name (nor value) */ + return 1; + } + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + const char *name; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + int level = (int)luaL_checkinteger(L, arg + 1); + int nvar = (int)luaL_checkinteger(L, arg + 2); + if (l_unlikely(!lua_getstack(L1, level, &ar))) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + checkstack(L, L1, 1); + lua_xmove(L, L1, 1); + name = lua_setlocal(L1, &ar, nvar); + if (name == NULL) + lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ + lua_pushstring(L, name); + return 1; +} + + +/* +** get (if 'get' is true) or set an upvalue from a closure +*/ +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = (int)luaL_checkinteger(L, 2); /* upvalue index */ + luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); /* no-op if get is false */ + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + +/* +** Check whether a given upvalue from a given closure exists and +** returns its index +*/ +static void *checkupval (lua_State *L, int argf, int argnup, int *pnup) { + void *id; + int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ + luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ + id = lua_upvalueid(L, argf, nup); + if (pnup) { + luaL_argcheck(L, id != NULL, argnup, "invalid upvalue index"); + *pnup = nup; + } + return id; +} + + +static int db_upvalueid (lua_State *L) { + void *id = checkupval(L, 1, 2, NULL); + if (id != NULL) + lua_pushlightuserdata(L, id); + else + luaL_pushfail(L); + return 1; +} + + +static int db_upvaluejoin (lua_State *L) { + int n1, n2; + checkupval(L, 1, 2, &n1); + checkupval(L, 3, 4, &n2); + luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); + luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); + lua_upvaluejoin(L, 1, n1, 3, n2); + return 0; +} + + +/* +** Call hook function registered at hook table for the current +** thread (if there is one) +*/ +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail call"}; + lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY); + lua_pushthread(L); + if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ + lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); /* push current line */ + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); /* call hook function */ + } +} + + +/* +** Convert a string mask (for 'sethook') into a bit mask +*/ +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +/* +** Convert a bit mask (for 'gethook') into a string mask +*/ +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { /* no hook? */ + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = (int)luaL_optinteger(L, arg + 3, 0); + func = hookf; mask = makemask(smask, count); + } + if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) { + /* table just created; initialize it */ + lua_pushliteral(L, "k"); + lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); /* metatable(hooktable) = hooktable */ + } + checkstack(L, L1, 1); + lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ + lua_pushvalue(L, arg + 1); /* value (hook function) */ + lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ + lua_sethook(L1, func, mask, count); + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook == NULL) { /* no hook? */ + luaL_pushfail(L); + return 1; + } + else if (hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { /* hook table must exist */ + lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY); + checkstack(L, L1, 1); + lua_pushthread(L1); lua_xmove(L1, L, 1); + lua_rawget(L, -2); /* 1st result = hooktable[L1] */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ + lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */ + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + lua_writestringerror("%s", "lua_debug> "); + if (fgets(buffer, sizeof(buffer), stdin) == NULL || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) + lua_writestringerror("%s\n", luaL_tolstring(L, -1, NULL)); + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +static int db_traceback (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + const char *msg = lua_tostring(L, arg + 1); + if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ + lua_pushvalue(L, arg + 1); /* return it untouched */ + else { + int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0); + luaL_traceback(L, L1, msg, level); + } + return 1; +} + + +static int db_setcstacklimit (lua_State *L) { + int limit = (int)luaL_checkinteger(L, 1); + int res = lua_setcstacklimit(L, limit); + lua_pushinteger(L, res); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getuservalue", db_getuservalue}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"upvaluejoin", db_upvaluejoin}, + {"upvalueid", db_upvalueid}, + {"setuservalue", db_setuservalue}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_traceback}, + {"setcstacklimit", db_setcstacklimit}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_debug (lua_State *L) { + luaL_newlib(L, dblib); + return 1; +} + diff --git a/arm9/source/lua/ldebug.c b/arm9/source/lua/ldebug.c new file mode 100644 index 000000000..591b3528a --- /dev/null +++ b/arm9/source/lua/ldebug.c @@ -0,0 +1,962 @@ +/* +** $Id: ldebug.c $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + +#define ldebug_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +#define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL) + + +static const char *funcnamefromcall (lua_State *L, CallInfo *ci, + const char **name); + + +static int currentpc (CallInfo *ci) { + lua_assert(isLua(ci)); + return pcRel(ci->u.l.savedpc, ci_func(ci)->p); +} + + +/* +** Get a "base line" to find the line corresponding to an instruction. +** Base lines are regularly placed at MAXIWTHABS intervals, so usually +** an integer division gets the right place. When the source file has +** large sequences of empty/comment lines, it may need extra entries, +** so the original estimate needs a correction. +** If the original estimate is -1, the initial 'if' ensures that the +** 'while' will run at least once. +** The assertion that the estimate is a lower bound for the correct base +** is valid as long as the debug info has been generated with the same +** value for MAXIWTHABS or smaller. (Previous releases use a little +** smaller value.) +*/ +static int getbaseline (const Proto *f, int pc, int *basepc) { + if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) { + *basepc = -1; /* start from the beginning */ + return f->linedefined; + } + else { + int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */ + /* estimate must be a lower bound of the correct base */ + lua_assert(i < 0 || + (i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc)); + while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc) + i++; /* low estimate; adjust it */ + *basepc = f->abslineinfo[i].pc; + return f->abslineinfo[i].line; + } +} + + +/* +** Get the line corresponding to instruction 'pc' in function 'f'; +** first gets a base line and from there does the increments until +** the desired instruction. +*/ +int luaG_getfuncline (const Proto *f, int pc) { + if (f->lineinfo == NULL) /* no debug information? */ + return -1; + else { + int basepc; + int baseline = getbaseline(f, pc, &basepc); + while (basepc++ < pc) { /* walk until given instruction */ + lua_assert(f->lineinfo[basepc] != ABSLINEINFO); + baseline += f->lineinfo[basepc]; /* correct line */ + } + return baseline; + } +} + + +static int getcurrentline (CallInfo *ci) { + return luaG_getfuncline(ci_func(ci)->p, currentpc(ci)); +} + + +/* +** Set 'trap' for all active Lua frames. +** This function can be called during a signal, under "reasonable" +** assumptions. A new 'ci' is completely linked in the list before it +** becomes part of the "active" list, and we assume that pointers are +** atomic; see comment in next function. +** (A compiler doing interprocedural optimizations could, theoretically, +** reorder memory writes in such a way that the list could be +** temporarily broken while inserting a new element. We simply assume it +** has no good reasons to do that.) +*/ +static void settraps (CallInfo *ci) { + for (; ci != NULL; ci = ci->previous) + if (isLua(ci)) + ci->u.l.trap = 1; +} + + +/* +** This function can be called during a signal, under "reasonable" +** assumptions. +** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount') +** are for debug only, and it is no problem if they get arbitrary +** values (causes at most one wrong hook call). 'hookmask' is an atomic +** value. We assume that pointers are atomic too (e.g., gcc ensures that +** for all platforms where it runs). Moreover, 'hook' is always checked +** before being called (see 'luaD_hook'). +*/ +LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + if (mask) + settraps(L->ci); /* to trace inside 'luaV_execute' */ +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + if (level < 0) return 0; /* invalid (negative) level */ + lua_lock(L); + for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) + level--; + if (level == 0 && ci != &L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = ci; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static const char *upvalname (const Proto *p, int uv) { + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); + if (s == NULL) return "?"; + else return getstr(s); +} + + +static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + if (clLvalue(s2v(ci->func.p))->p->is_vararg) { + int nextra = ci->u.l.nextraargs; + if (n >= -nextra) { /* 'n' is negative */ + *pos = ci->func.p - nextra - (n + 1); + return "(vararg)"; /* generic name for any vararg */ + } + } + return NULL; /* no such vararg */ +} + + +const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) { + StkId base = ci->func.p + 1; + const char *name = NULL; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ + return findvararg(ci, n, pos); + else + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } + if (name == NULL) { /* no 'standard' name? */ + StkId limit = (ci == L->ci) ? L->top.p : ci->next->func.p; + if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */ + /* generic name for any valid slot */ + name = isLua(ci) ? "(temporary)" : "(C temporary)"; + } + else + return NULL; /* no name */ + } + if (pos) + *pos = base + (n - 1); + return name; +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + lua_lock(L); + if (ar == NULL) { /* information about non-active function? */ + if (!isLfunction(s2v(L->top.p - 1))) /* not a Lua function? */ + name = NULL; + else /* consider live variables at function start (parameters) */ + name = luaF_getlocalname(clLvalue(s2v(L->top.p - 1))->p, n, 0); + } + else { /* active function; get information through 'ar' */ + StkId pos = NULL; /* to avoid warnings */ + name = luaG_findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobjs2s(L, L->top.p, pos); + api_incr_top(L); + } + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + StkId pos = NULL; /* to avoid warnings */ + const char *name; + lua_lock(L); + name = luaG_findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobjs2s(L, pos, L->top.p - 1); + L->top.p--; /* pop value */ + } + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (!LuaClosure(cl)) { + ar->source = "=[C]"; + ar->srclen = LL("=[C]"); + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + const Proto *p = cl->l.p; + if (p->source) { + ar->source = getstr(p->source); + ar->srclen = tsslen(p->source); + } + else { + ar->source = "=?"; + ar->srclen = LL("=?"); + } + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, ar->srclen); +} + + +static int nextline (const Proto *p, int currentline, int pc) { + if (p->lineinfo[pc] != ABSLINEINFO) + return currentline + p->lineinfo[pc]; + else + return luaG_getfuncline(p, pc); +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (!LuaClosure(f)) { + setnilvalue(s2v(L->top.p)); + api_incr_top(L); + } + else { + const Proto *p = f->l.p; + int currentline = p->linedefined; + Table *t = luaH_new(L); /* new table to store active lines */ + sethvalue2s(L, L->top.p, t); /* push it on stack */ + api_incr_top(L); + if (p->lineinfo != NULL) { /* proto with debug information? */ + int i; + TValue v; + setbtvalue(&v); /* boolean 'true' to be the value of all indices */ + if (!p->is_vararg) /* regular function? */ + i = 0; /* consider all instructions */ + else { /* vararg function */ + lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP); + currentline = nextline(p, currentline, 0); + i = 1; /* skip first instruction (OP_VARARGPREP) */ + } + for (; i < p->sizelineinfo; i++) { /* for each instruction */ + currentline = nextline(p, currentline, i); /* get its line */ + luaH_setint(L, t, currentline, &v); /* table[line] = true */ + } + } + } +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + /* calling function is a known function? */ + if (ci != NULL && !(ci->callstatus & CIST_TAIL)) + return funcnamefromcall(L, ci->previous, name); + else return NULL; /* no way to find a name */ +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci && isLua(ci)) ? getcurrentline(ci) : -1; + break; + } + case 'u': { + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; + if (!LuaClosure(f)) { + ar->isvararg = 1; + ar->nparams = 0; + } + else { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 't': { + ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; + break; + } + case 'n': { + ar->namewhat = getfuncname(L, ci, &ar->name); + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'r': { + if (ci == NULL || !(ci->callstatus & CIST_TRAN)) + ar->ftransfer = ar->ntransfer = 0; + else { + ar->ftransfer = ci->u2.transferinfo.ftransfer; + ar->ntransfer = ci->u2.transferinfo.ntransfer; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *cl; + CallInfo *ci; + TValue *func; + lua_lock(L); + if (*what == '>') { + ci = NULL; + func = s2v(L->top.p - 1); + api_check(L, ttisfunction(func), "function expected"); + what++; /* skip the '>' */ + L->top.p--; /* pop function */ + } + else { + ci = ar->i_ci; + func = s2v(ci->func.p); + lua_assert(ttisfunction(func)); + } + cl = ttisclosure(func) ? clvalue(func) : NULL; + status = auxgetinfo(L, what, ar, cl, ci); + if (strchr(what, 'f')) { + setobj2s(L, L->top.p, func); + api_incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, cl); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution +** ======================================================= +*/ + + +static int filterpc (int pc, int jmptarget) { + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ + else return pc; /* current position sets that register */ +} + + +/* +** Try to find last instruction before 'lastpc' that modified register 'reg'. +*/ +static int findsetreg (const Proto *p, int lastpc, int reg) { + int pc; + int setreg = -1; /* keep last instruction that changed 'reg' */ + int jmptarget = 0; /* any code before this address is conditional */ + if (testMMMode(GET_OPCODE(p->code[lastpc]))) + lastpc--; /* previous instruction was not actually executed */ + for (pc = 0; pc < lastpc; pc++) { + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int change; /* true if current instruction changed 'reg' */ + switch (op) { + case OP_LOADNIL: { /* set registers from 'a' to 'a+b' */ + int b = GETARG_B(i); + change = (a <= reg && reg <= a + b); + break; + } + case OP_TFORCALL: { /* affect all regs above its base */ + change = (reg >= a + 2); + break; + } + case OP_CALL: + case OP_TAILCALL: { /* affect all registers above base */ + change = (reg >= a); + break; + } + case OP_JMP: { /* doesn't change registers, but changes 'jmptarget' */ + int b = GETARG_sJ(i); + int dest = pc + 1 + b; + /* jump does not skip 'lastpc' and is larger than current one? */ + if (dest <= lastpc && dest > jmptarget) + jmptarget = dest; /* update 'jmptarget' */ + change = 0; + break; + } + default: /* any instruction that sets A */ + change = (testAMode(op) && reg == a); + break; + } + if (change) + setreg = filterpc(pc, jmptarget); + } + return setreg; +} + + +/* +** Find a "name" for the constant 'c'. +*/ +static const char *kname (const Proto *p, int index, const char **name) { + TValue *kvalue = &p->k[index]; + if (ttisstring(kvalue)) { + *name = getstr(tsvalue(kvalue)); + return "constant"; + } + else { + *name = "?"; + return NULL; + } +} + + +static const char *basicgetobjname (const Proto *p, int *ppc, int reg, + const char **name) { + int pc = *ppc; + *name = luaF_getlocalname(p, reg + 1, pc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ + *ppc = pc = findsetreg(p, pc, reg); + if (pc != -1) { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_MOVE: { + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) + return basicgetobjname(p, ppc, b, name); /* get name for 'b' */ + break; + } + case OP_GETUPVAL: { + *name = upvalname(p, GETARG_B(i)); + return "upvalue"; + } + case OP_LOADK: return kname(p, GETARG_Bx(i), name); + case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); + default: break; + } + } + return NULL; /* could not find reasonable name */ +} + + +/* +** Find a "name" for the register 'c'. +*/ +static void rname (const Proto *p, int pc, int c, const char **name) { + const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */ + if (!(what && *what == 'c')) /* did not find a constant name? */ + *name = "?"; +} + + +/* +** Find a "name" for a 'C' value in an RK instruction. +*/ +static void rkname (const Proto *p, int pc, Instruction i, const char **name) { + int c = GETARG_C(i); /* key index */ + if (GETARG_k(i)) /* is 'c' a constant? */ + kname(p, c, name); + else /* 'c' is a register */ + rname(p, pc, c, name); +} + + +/* +** Check whether table being indexed by instruction 'i' is the +** environment '_ENV' +*/ +static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { + int t = GETARG_B(i); /* table index */ + const char *name; /* name of indexed variable */ + if (isup) /* is 't' an upvalue? */ + name = upvalname(p, t); + else /* 't' is a register */ + basicgetobjname(p, &pc, t, &name); + return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; +} + + +/* +** Extend 'basicgetobjname' to handle table accesses +*/ +static const char *getobjname (const Proto *p, int lastpc, int reg, + const char **name) { + const char *kind = basicgetobjname(p, &lastpc, reg, name); + if (kind != NULL) + return kind; + else if (lastpc != -1) { /* could find instruction? */ + Instruction i = p->code[lastpc]; + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_GETTABUP: { + int k = GETARG_C(i); /* key index */ + kname(p, k, name); + return isEnv(p, lastpc, i, 1); + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + rname(p, lastpc, k, name); + return isEnv(p, lastpc, i, 0); + } + case OP_GETI: { + *name = "integer index"; + return "field"; + } + case OP_GETFIELD: { + int k = GETARG_C(i); /* key index */ + kname(p, k, name); + return isEnv(p, lastpc, i, 0); + } + case OP_SELF: { + rkname(p, lastpc, i, name); + return "method"; + } + default: break; /* go through to return NULL */ + } + } + return NULL; /* could not find reasonable name */ +} + + +/* +** Try to find a name for a function based on the code that called it. +** (Only works when function was called by a Lua function.) +** Returns what the name is (e.g., "for iterator", "method", +** "metamethod") and sets '*name' to point to the name. +*/ +static const char *funcnamefromcode (lua_State *L, const Proto *p, + int pc, const char **name) { + TMS tm = (TMS)0; /* (initial value avoids warnings) */ + Instruction i = p->code[pc]; /* calling instruction */ + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + return getobjname(p, pc, GETARG_A(i), name); /* get function name */ + case OP_TFORCALL: { /* for iterator */ + *name = "for iterator"; + return "for iterator"; + } + /* other instructions can do calls through metamethods */ + case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: + case OP_GETI: case OP_GETFIELD: + tm = TM_INDEX; + break; + case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD: + tm = TM_NEWINDEX; + break; + case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { + tm = cast(TMS, GETARG_C(i)); + break; + } + case OP_UNM: tm = TM_UNM; break; + case OP_BNOT: tm = TM_BNOT; break; + case OP_LEN: tm = TM_LEN; break; + case OP_CONCAT: tm = TM_CONCAT; break; + case OP_EQ: tm = TM_EQ; break; + /* no cases for OP_EQI and OP_EQK, as they don't call metamethods */ + case OP_LT: case OP_LTI: case OP_GTI: tm = TM_LT; break; + case OP_LE: case OP_LEI: case OP_GEI: tm = TM_LE; break; + case OP_CLOSE: case OP_RETURN: tm = TM_CLOSE; break; + default: + return NULL; /* cannot find a reasonable name */ + } + *name = getshrstr(G(L)->tmname[tm]) + 2; + return "metamethod"; +} + + +/* +** Try to find a name for a function based on how it was called. +*/ +static const char *funcnamefromcall (lua_State *L, CallInfo *ci, + const char **name) { + if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ + *name = "?"; + return "hook"; + } + else if (ci->callstatus & CIST_FIN) { /* was it called as a finalizer? */ + *name = "__gc"; + return "metamethod"; /* report it as such */ + } + else if (isLua(ci)) + return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name); + else + return NULL; +} + +/* }====================================================== */ + + + +/* +** Check whether pointer 'o' points to some value in the stack frame of +** the current function and, if so, returns its index. Because 'o' may +** not point to a value in this stack, we cannot compare it with the +** region boundaries (undefined behavior in ISO C). +*/ +static int instack (CallInfo *ci, const TValue *o) { + int pos; + StkId base = ci->func.p + 1; + for (pos = 0; base + pos < ci->top.p; pos++) { + if (o == s2v(base + pos)) + return pos; + } + return -1; /* not found */ +} + + +/* +** Checks whether value 'o' came from an upvalue. (That can only happen +** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on +** upvalues.) +*/ +static const char *getupvalname (CallInfo *ci, const TValue *o, + const char **name) { + LClosure *c = ci_func(ci); + int i; + for (i = 0; i < c->nupvalues; i++) { + if (c->upvals[i]->v.p == o) { + *name = upvalname(c->p, i); + return "upvalue"; + } + } + return NULL; +} + + +static const char *formatvarinfo (lua_State *L, const char *kind, + const char *name) { + if (kind == NULL) + return ""; /* no information */ + else + return luaO_pushfstring(L, " (%s '%s')", kind, name); +} + +/* +** Build a string with a "description" for the value 'o', such as +** "variable 'x'" or "upvalue 'y'". +*/ +static const char *varinfo (lua_State *L, const TValue *o) { + CallInfo *ci = L->ci; + const char *name = NULL; /* to avoid warnings */ + const char *kind = NULL; + if (isLua(ci)) { + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ + if (!kind) { /* not an upvalue? */ + int reg = instack(ci, o); /* try a register */ + if (reg >= 0) /* is 'o' a register? */ + kind = getobjname(ci_func(ci)->p, currentpc(ci), reg, &name); + } + } + return formatvarinfo(L, kind, name); +} + + +/* +** Raise a type error +*/ +static l_noret typeerror (lua_State *L, const TValue *o, const char *op, + const char *extra) { + const char *t = luaT_objtypename(L, o); + luaG_runerror(L, "attempt to %s a %s value%s", op, t, extra); +} + + +/* +** Raise a type error with "standard" information about the faulty +** object 'o' (using 'varinfo'). +*/ +l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + typeerror(L, o, op, varinfo(L, o)); +} + + +/* +** Raise an error for calling a non-callable object. Try to find a name +** for the object based on how it was called ('funcnamefromcall'); if it +** cannot get a name there, try 'varinfo'. +*/ +l_noret luaG_callerror (lua_State *L, const TValue *o) { + CallInfo *ci = L->ci; + const char *name = NULL; /* to avoid warnings */ + const char *kind = funcnamefromcall(L, ci, &name); + const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o); + typeerror(L, o, "call", extra); +} + + +l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) { + luaG_runerror(L, "bad 'for' %s (number expected, got %s)", + what, luaT_objtypename(L, o)); +} + + +l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { + if (ttisstring(p1) || cvt2str(p1)) p1 = p2; + luaG_typeerror(L, p1, "concatenate"); +} + + +l_noret luaG_opinterror (lua_State *L, const TValue *p1, + const TValue *p2, const char *msg) { + if (!ttisnumber(p1)) /* first operand is wrong? */ + p2 = p1; /* now second is wrong */ + luaG_typeerror(L, p2, msg); +} + + +/* +** Error when both values are convertible to numbers, but not to integers +*/ +l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { + lua_Integer temp; + if (!luaV_tointegerns(p1, &temp, LUA_FLOORN2I)) + p2 = p1; + luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); +} + + +l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_objtypename(L, p1); + const char *t2 = luaT_objtypename(L, p2); + if (strcmp(t1, t2) == 0) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); +} + + +/* add src:line information to 'msg' */ +const char *luaG_addinfo (lua_State *L, const char *msg, TString *src, + int line) { + char buff[LUA_IDSIZE]; + if (src) + luaO_chunkid(buff, getstr(src), tsslen(src)); + else { /* no source available; use "?" instead */ + buff[0] = '?'; buff[1] = '\0'; + } + return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); +} + + +l_noret luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + lua_assert(ttisfunction(s2v(errfunc))); + setobjs2s(L, L->top.p, L->top.p - 1); /* move argument */ + setobjs2s(L, L->top.p - 1, errfunc); /* push function */ + L->top.p++; /* assume EXTRA_STACK */ + luaD_callnoyield(L, L->top.p - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { + CallInfo *ci = L->ci; + const char *msg; + va_list argp; + luaC_checkGC(L); /* error message uses memory */ + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); /* format message */ + va_end(argp); + if (isLua(ci)) { /* if Lua function, add source:line information */ + luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci)); + setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */ + L->top.p--; + } + luaG_errormsg(L); +} + + +/* +** Check whether new instruction 'newpc' is in a different line from +** previous instruction 'oldpc'. More often than not, 'newpc' is only +** one or a few instructions after 'oldpc' (it must be after, see +** caller), so try to avoid calling 'luaG_getfuncline'. If they are +** too far apart, there is a good chance of a ABSLINEINFO in the way, +** so it goes directly to 'luaG_getfuncline'. +*/ +static int changedline (const Proto *p, int oldpc, int newpc) { + if (p->lineinfo == NULL) /* no debug information? */ + return 0; + if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */ + int delta = 0; /* line difference */ + int pc = oldpc; + for (;;) { + int lineinfo = p->lineinfo[++pc]; + if (lineinfo == ABSLINEINFO) + break; /* cannot compute delta; fall through */ + delta += lineinfo; + if (pc == newpc) + return (delta != 0); /* delta computed successfully */ + } + } + /* either instructions are too far apart or there is an absolute line + info in the way; compute line difference explicitly */ + return (luaG_getfuncline(p, oldpc) != luaG_getfuncline(p, newpc)); +} + + +/* +** Traces Lua calls. If code is running the first instruction of a function, +** and function is not vararg, and it is not coming from an yield, +** calls 'luaD_hookcall'. (Vararg functions will call 'luaD_hookcall' +** after adjusting its variable arguments; otherwise, they could call +** a line/count hook before the call hook. Functions coming from +** an yield already called 'luaD_hookcall' before yielding.) +*/ +int luaG_tracecall (lua_State *L) { + CallInfo *ci = L->ci; + Proto *p = ci_func(ci)->p; + ci->u.l.trap = 1; /* ensure hooks will be checked */ + if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */ + if (p->is_vararg) + return 0; /* hooks will start at VARARGPREP instruction */ + else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yieded? */ + luaD_hookcall(L, ci); /* check 'call' hook */ + } + return 1; /* keep 'trap' on */ +} + + +/* +** Traces the execution of a Lua function. Called before the execution +** of each opcode, when debug is on. 'L->oldpc' stores the last +** instruction traced, to detect line changes. When entering a new +** function, 'npci' will be zero and will test as a new line whatever +** the value of 'oldpc'. Some exceptional conditions may return to +** a function without setting 'oldpc'. In that case, 'oldpc' may be +** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc' +** at most causes an extra call to a line hook.) +** This function is not "Protected" when called, so it should correct +** 'L->top.p' before calling anything that can run the GC. +*/ +int luaG_traceexec (lua_State *L, const Instruction *pc) { + CallInfo *ci = L->ci; + lu_byte mask = L->hookmask; + const Proto *p = ci_func(ci)->p; + int counthook; + if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) { /* no hooks? */ + ci->u.l.trap = 0; /* don't need to stop again */ + return 0; /* turn off 'trap' */ + } + pc++; /* reference is always next instruction */ + ci->u.l.savedpc = pc; /* save 'pc' */ + counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0); + if (counthook) + resethookcount(L); /* reset count */ + else if (!(mask & LUA_MASKLINE)) + return 1; /* no line hook and count != 0; nothing to be done now */ + if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */ + ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ + return 1; /* do not call hook again (VM yielded, so it did not move) */ + } + if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */ + L->top.p = ci->top.p; /* correct top */ + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */ + if (mask & LUA_MASKLINE) { + /* 'L->oldpc' may be invalid; use zero in this case */ + int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; + int npci = pcRel(pc, p); + if (npci <= oldpc || /* call hook when jump back (loop), */ + changedline(p, oldpc, npci)) { /* or when enter new line */ + int newline = luaG_getfuncline(p, npci); + luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */ + } + L->oldpc = npci; /* 'pc' of last call to line hook */ + } + if (L->status == LUA_YIELD) { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ + ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ + luaD_throw(L, LUA_YIELD); + } + return 1; /* keep 'trap' on */ +} + diff --git a/arm9/source/lua/ldebug.h b/arm9/source/lua/ldebug.h new file mode 100644 index 000000000..2bfce3cb5 --- /dev/null +++ b/arm9/source/lua/ldebug.h @@ -0,0 +1,64 @@ +/* +** $Id: ldebug.h $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) + + +/* Active Lua function (given call info) */ +#define ci_func(ci) (clLvalue(s2v((ci)->func.p))) + + +#define resethookcount(L) (L->hookcount = L->basehookcount) + +/* +** mark for entries in 'lineinfo' array that has absolute information in +** 'abslineinfo' array +*/ +#define ABSLINEINFO (-0x80) + + +/* +** MAXimum number of successive Instructions WiTHout ABSolute line +** information. (A power of two allows fast divisions.) +*/ +#if !defined(MAXIWTHABS) +#define MAXIWTHABS 128 +#endif + + +LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); +LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, + StkId *pos); +LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); +LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, + const char *what); +LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, + const TValue *p2, + const char *msg); +LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, + TString *src, int line); +LUAI_FUNC l_noret luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); +LUAI_FUNC int luaG_tracecall (lua_State *L); + + +#endif diff --git a/arm9/source/lua/ldo.c b/arm9/source/lua/ldo.c new file mode 100644 index 000000000..ea0529507 --- /dev/null +++ b/arm9/source/lua/ldo.c @@ -0,0 +1,1028 @@ +/* +** $Id: ldo.c $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#define ldo_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + +#define errorstatus(s) ((s) > LUA_YIELD) + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + +/* +** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By +** default, Lua handles errors with exceptions when compiling as +** C++ code, with _longjmp/_setjmp when asked to use them, and with +** longjmp/setjmp otherwise. +*/ +#if !defined(LUAI_THROW) /* { */ + +#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */ + +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) \ + try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_POSIX) /* }{ */ + +/* in POSIX, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else /* }{ */ + +/* ISO C handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif /* } */ + +#endif /* } */ + + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { /* memory error? */ + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_OK: { /* special case only for closing upvalues */ + setnilvalue(s2v(oldtop)); /* no error message */ + break; + } + default: { + lua_assert(errorstatus(errcode)); /* real error */ + setobjs2s(L, oldtop, L->top.p - 1); /* error message on current top */ + break; + } + } + L->top.p = oldtop + 1; +} + + +l_noret luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { /* thread has an error handler? */ + L->errorJmp->status = errcode; /* set status */ + LUAI_THROW(L, L->errorJmp); /* jump to it */ + } + else { /* thread has no error handler */ + global_State *g = G(L); + errcode = luaE_resetthread(L, errcode); /* close all upvalues */ + if (g->mainthread->errorJmp) { /* main thread has a handler? */ + setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */ + luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ + } + else { /* no handler at all; abort */ + if (g->panic) { /* panic function? */ + lua_unlock(L); + g->panic(L); /* call panic function (last chance to jump out) */ + } + abort(); + } + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + l_uint32 oldnCcalls = L->nCcalls; + struct lua_longjmp lj; + lj.status = LUA_OK; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + L->nCcalls = oldnCcalls; + return lj.status; +} + +/* }====================================================== */ + + +/* +** {================================================================== +** Stack reallocation +** =================================================================== +*/ + + +/* +** Change all pointers to the stack into offsets. +*/ +static void relstack (lua_State *L) { + CallInfo *ci; + UpVal *up; + L->top.offset = savestack(L, L->top.p); + L->tbclist.offset = savestack(L, L->tbclist.p); + for (up = L->openupval; up != NULL; up = up->u.open.next) + up->v.offset = savestack(L, uplevel(up)); + for (ci = L->ci; ci != NULL; ci = ci->previous) { + ci->top.offset = savestack(L, ci->top.p); + ci->func.offset = savestack(L, ci->func.p); + } +} + + +/* +** Change back all offsets into pointers. +*/ +static void correctstack (lua_State *L) { + CallInfo *ci; + UpVal *up; + L->top.p = restorestack(L, L->top.offset); + L->tbclist.p = restorestack(L, L->tbclist.offset); + for (up = L->openupval; up != NULL; up = up->u.open.next) + up->v.p = s2v(restorestack(L, up->v.offset)); + for (ci = L->ci; ci != NULL; ci = ci->previous) { + ci->top.p = restorestack(L, ci->top.offset); + ci->func.p = restorestack(L, ci->func.offset); + if (isLua(ci)) + ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */ + } +} + + +/* some space for error handling */ +#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) + +/* +** Reallocate the stack to a new size, correcting all pointers into it. +** In ISO C, any pointer use after the pointer has been deallocated is +** undefined behavior. So, before the reallocation, all pointers are +** changed to offsets, and after the reallocation they are changed back +** to pointers. As during the reallocation the pointers are invalid, the +** reallocation cannot run emergency collections. +** +** In case of allocation error, raise an error or return false according +** to 'raiseerror'. +*/ +int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { + int oldsize = stacksize(L); + int i; + StkId newstack; + int oldgcstop = G(L)->gcstopem; + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + relstack(L); /* change pointers to offsets */ + G(L)->gcstopem = 1; /* stop emergency collection */ + newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK, + newsize + EXTRA_STACK, StackValue); + G(L)->gcstopem = oldgcstop; /* restore emergency collection */ + if (l_unlikely(newstack == NULL)) { /* reallocation failed? */ + correctstack(L); /* change offsets back to pointers */ + if (raiseerror) + luaM_error(L); + else return 0; /* do not raise an error */ + } + L->stack.p = newstack; + correctstack(L); /* change offsets back to pointers */ + L->stack_last.p = L->stack.p + newsize; + for (i = oldsize + EXTRA_STACK; i < newsize + EXTRA_STACK; i++) + setnilvalue(s2v(newstack + i)); /* erase new segment */ + return 1; +} + + +/* +** Try to grow the stack by at least 'n' elements. When 'raiseerror' +** is true, raises any error; otherwise, return 0 in case of errors. +*/ +int luaD_growstack (lua_State *L, int n, int raiseerror) { + int size = stacksize(L); + if (l_unlikely(size > LUAI_MAXSTACK)) { + /* if stack is larger than maximum, thread is already using the + extra space reserved for errors, that is, thread is handling + a stack error; cannot grow further than that. */ + lua_assert(stacksize(L) == ERRORSTACKSIZE); + if (raiseerror) + luaD_throw(L, LUA_ERRERR); /* error inside message handler */ + return 0; /* if not 'raiseerror', just signal it */ + } + else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */ + int newsize = 2 * size; /* tentative new size */ + int needed = cast_int(L->top.p - L->stack.p) + n; + if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ + newsize = LUAI_MAXSTACK; + if (newsize < needed) /* but must respect what was asked for */ + newsize = needed; + if (l_likely(newsize <= LUAI_MAXSTACK)) + return luaD_reallocstack(L, newsize, raiseerror); + } + /* else stack overflow */ + /* add extra size to be able to handle the error message */ + luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror); + if (raiseerror) + luaG_runerror(L, "stack overflow"); + return 0; +} + + +/* +** Compute how much of the stack is being used, by computing the +** maximum top of all call frames in the stack and the current top. +*/ +static int stackinuse (lua_State *L) { + CallInfo *ci; + int res; + StkId lim = L->top.p; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + if (lim < ci->top.p) lim = ci->top.p; + } + lua_assert(lim <= L->stack_last.p + EXTRA_STACK); + res = cast_int(lim - L->stack.p) + 1; /* part of stack in use */ + if (res < LUA_MINSTACK) + res = LUA_MINSTACK; /* ensure a minimum size */ + return res; +} + + +/* +** If stack size is more than 3 times the current use, reduce that size +** to twice the current use. (So, the final stack size is at most 2/3 the +** previous size, and half of its entries are empty.) +** As a particular case, if stack was handling a stack overflow and now +** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than +** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack +** will be reduced to a "regular" size. +*/ +void luaD_shrinkstack (lua_State *L) { + int inuse = stackinuse(L); + int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3; + /* if thread is currently not handling a stack overflow and its + size is larger than maximum "reasonable" size, shrink it */ + if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) { + int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2; + luaD_reallocstack(L, nsize, 0); /* ok if that fails */ + } + else /* don't change stack */ + condmovestack(L,{},{}); /* (change only for debugging) */ + luaE_shrinkCI(L); /* shrink CI list */ +} + + +void luaD_inctop (lua_State *L) { + luaD_checkstack(L, 1); + L->top.p++; +} + +/* }================================================================== */ + + +/* +** Call a hook for the given event. Make sure there is a hook to be +** called. (Both 'L->hook' and 'L->hookmask', which trigger this +** function, can be changed asynchronously by signals.) +*/ +void luaD_hook (lua_State *L, int event, int line, + int ftransfer, int ntransfer) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { /* make sure there is a hook */ + int mask = CIST_HOOKED; + CallInfo *ci = L->ci; + ptrdiff_t top = savestack(L, L->top.p); /* preserve original 'top' */ + ptrdiff_t ci_top = savestack(L, ci->top.p); /* idem for 'ci->top' */ + lua_Debug ar; + ar.event = event; + ar.currentline = line; + ar.i_ci = ci; + if (ntransfer != 0) { + mask |= CIST_TRAN; /* 'ci' has transfer information */ + ci->u2.transferinfo.ftransfer = ftransfer; + ci->u2.transferinfo.ntransfer = ntransfer; + } + if (isLua(ci) && L->top.p < ci->top.p) + L->top.p = ci->top.p; /* protect entire activation register */ + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + if (ci->top.p < L->top.p + LUA_MINSTACK) + ci->top.p = L->top.p + LUA_MINSTACK; + L->allowhook = 0; /* cannot call hooks inside a hook */ + ci->callstatus |= mask; + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + ci->top.p = restorestack(L, ci_top); + L->top.p = restorestack(L, top); + ci->callstatus &= ~mask; + } +} + + +/* +** Executes a call hook for Lua functions. This function is called +** whenever 'hookmask' is not zero, so it checks whether call hooks are +** active. +*/ +void luaD_hookcall (lua_State *L, CallInfo *ci) { + L->oldpc = 0; /* set 'oldpc' for new function */ + if (L->hookmask & LUA_MASKCALL) { /* is call hook on? */ + int event = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL + : LUA_HOOKCALL; + Proto *p = ci_func(ci)->p; + ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_hook(L, event, -1, 1, p->numparams); + ci->u.l.savedpc--; /* correct 'pc' */ + } +} + + +/* +** Executes a return hook for Lua and C functions and sets/corrects +** 'oldpc'. (Note that this correction is needed by the line hook, so it +** is done even when return hooks are off.) +*/ +static void rethook (lua_State *L, CallInfo *ci, int nres) { + if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ + StkId firstres = L->top.p - nres; /* index of first result */ + int delta = 0; /* correction for vararg functions */ + int ftransfer; + if (isLua(ci)) { + Proto *p = ci_func(ci)->p; + if (p->is_vararg) + delta = ci->u.l.nextraargs + p->numparams + 1; + } + ci->func.p += delta; /* if vararg, back to virtual 'func' */ + ftransfer = cast(unsigned short, firstres - ci->func.p); + luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ + ci->func.p -= delta; + } + if (isLua(ci = ci->previous)) + L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */ +} + + +/* +** Check whether 'func' has a '__call' metafield. If so, put it in the +** stack, below original 'func', so that 'luaD_precall' can call it. Raise +** an error if there is no '__call' metafield. +*/ +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm; + StkId p; + checkstackGCp(L, 1, func); /* space for metamethod */ + tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */ + if (l_unlikely(ttisnil(tm))) + luaG_callerror(L, s2v(func)); /* nothing to call */ + for (p = L->top.p; p > func; p--) /* open space for metamethod */ + setobjs2s(L, p, p-1); + L->top.p++; /* stack space pre-allocated by the caller */ + setobj2s(L, func, tm); /* metamethod is the new function to be called */ + return func; +} + + +/* +** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. +** Handle most typical cases (zero results for commands, one result for +** expressions, multiple results for tail calls/single parameters) +** separated. +*/ +l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) { + StkId firstresult; + int i; + switch (wanted) { /* handle typical cases separately */ + case 0: /* no values needed */ + L->top.p = res; + return; + case 1: /* one value needed */ + if (nres == 0) /* no results? */ + setnilvalue(s2v(res)); /* adjust with nil */ + else /* at least one result */ + setobjs2s(L, res, L->top.p - nres); /* move it to proper place */ + L->top.p = res + 1; + return; + case LUA_MULTRET: + wanted = nres; /* we want all results */ + break; + default: /* two/more results and/or to-be-closed variables */ + if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ + L->ci->callstatus |= CIST_CLSRET; /* in case of yields */ + L->ci->u2.nres = nres; + res = luaF_close(L, res, CLOSEKTOP, 1); + L->ci->callstatus &= ~CIST_CLSRET; + if (L->hookmask) { /* if needed, call hook after '__close's */ + ptrdiff_t savedres = savestack(L, res); + rethook(L, L->ci, nres); + res = restorestack(L, savedres); /* hook can move stack */ + } + wanted = decodeNresults(wanted); + if (wanted == LUA_MULTRET) + wanted = nres; /* we want all results */ + } + break; + } + /* generic case */ + firstresult = L->top.p - nres; /* index of first result */ + if (nres > wanted) /* extra results? */ + nres = wanted; /* don't need them */ + for (i = 0; i < nres; i++) /* move all results to correct place */ + setobjs2s(L, res + i, firstresult + i); + for (; i < wanted; i++) /* complete wanted number of results */ + setnilvalue(s2v(res + i)); + L->top.p = res + wanted; /* top points after the last result */ +} + + +/* +** Finishes a function call: calls hook if necessary, moves current +** number of results to proper place, and returns to previous call +** info. If function has to close variables, hook must be called after +** that. +*/ +void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { + int wanted = ci->nresults; + if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted))) + rethook(L, ci, nres); + /* move results to proper place */ + moveresults(L, ci->func.p, nres, wanted); + /* function cannot be in any of these cases when returning */ + lua_assert(!(ci->callstatus & + (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET))); + L->ci = ci->previous; /* back to caller (after closing variables) */ +} + + + +#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) + + +l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, + int mask, StkId top) { + CallInfo *ci = L->ci = next_ci(L); /* new frame */ + ci->func.p = func; + ci->nresults = nret; + ci->callstatus = mask; + ci->top.p = top; + return ci; +} + + +/* +** precall for C functions +*/ +l_sinline int precallC (lua_State *L, StkId func, int nresults, + lua_CFunction f) { + int n; /* number of returns */ + CallInfo *ci; + checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ + L->ci = ci = prepCallInfo(L, func, nresults, CIST_C, + L->top.p + LUA_MINSTACK); + lua_assert(ci->top.p <= L->stack_last.p); + if (l_unlikely(L->hookmask & LUA_MASKCALL)) { + int narg = cast_int(L->top.p - func) - 1; + luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); + } + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, ci, n); + return n; +} + + +/* +** Prepare a function for a tail call, building its call info on top +** of the current call info. 'narg1' is the number of arguments plus 1 +** (so that it includes the function itself). Return the number of +** results, if it was a C function, or -1 for a Lua function. +*/ +int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, + int narg1, int delta) { + retry: + switch (ttypetag(s2v(func))) { + case LUA_VCCL: /* C closure */ + return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f); + case LUA_VLCF: /* light C function */ + return precallC(L, func, LUA_MULTRET, fvalue(s2v(func))); + case LUA_VLCL: { /* Lua function */ + Proto *p = clLvalue(s2v(func))->p; + int fsize = p->maxstacksize; /* frame size */ + int nfixparams = p->numparams; + int i; + checkstackGCp(L, fsize - delta, func); + ci->func.p -= delta; /* restore 'func' (if vararg) */ + for (i = 0; i < narg1; i++) /* move down function and arguments */ + setobjs2s(L, ci->func.p + i, func + i); + func = ci->func.p; /* moved-down function */ + for (; narg1 <= nfixparams; narg1++) + setnilvalue(s2v(func + narg1)); /* complete missing arguments */ + ci->top.p = func + 1 + fsize; /* top for new function */ + lua_assert(ci->top.p <= L->stack_last.p); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus |= CIST_TAIL; + L->top.p = func + narg1; /* set top */ + return -1; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* try to get '__call' metamethod */ + /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ + narg1++; + goto retry; /* try again */ + } + } +} + + +/* +** Prepares the call to a function (C or Lua). For C functions, also do +** the call. The function to be called is at '*func'. The arguments +** are on the stack, right after the function. Returns the CallInfo +** to be executed, if it was a Lua function. Otherwise (a C function) +** returns NULL, with all the results on the stack, starting at the +** original function position. +*/ +CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { + retry: + switch (ttypetag(s2v(func))) { + case LUA_VCCL: /* C closure */ + precallC(L, func, nresults, clCvalue(s2v(func))->f); + return NULL; + case LUA_VLCF: /* light C function */ + precallC(L, func, nresults, fvalue(s2v(func))); + return NULL; + case LUA_VLCL: { /* Lua function */ + CallInfo *ci; + Proto *p = clLvalue(s2v(func))->p; + int narg = cast_int(L->top.p - func) - 1; /* number of real arguments */ + int nfixparams = p->numparams; + int fsize = p->maxstacksize; /* frame size */ + checkstackGCp(L, fsize, func); + L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize); + ci->u.l.savedpc = p->code; /* starting point */ + for (; narg < nfixparams; narg++) + setnilvalue(s2v(L->top.p++)); /* complete missing arguments */ + lua_assert(ci->top.p <= L->stack_last.p); + return ci; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* try to get '__call' metamethod */ + /* return luaD_precall(L, func, nresults); */ + goto retry; /* try again with metamethod */ + } + } +} + + +/* +** Call a function (C or Lua) through C. 'inc' can be 1 (increment +** number of recursive invocations in the C stack) or nyci (the same +** plus increment number of non-yieldable calls). +** This function can be called with some use of EXTRA_STACK, so it should +** check the stack before doing anything else. 'luaD_precall' already +** does that. +*/ +l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) { + CallInfo *ci; + L->nCcalls += inc; + if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) { + checkstackp(L, 0, func); /* free any use of EXTRA_STACK */ + luaE_checkcstack(L); + } + if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ + ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ + luaV_execute(L, ci); /* call it */ + } + L->nCcalls -= inc; +} + + +/* +** External interface for 'ccall' +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + ccall(L, func, nResults, 1); +} + + +/* +** Similar to 'luaD_call', but does not allow yields during the call. +*/ +void luaD_callnoyield (lua_State *L, StkId func, int nResults) { + ccall(L, func, nResults, nyci); +} + + +/* +** Finish the job of 'lua_pcallk' after it was interrupted by an yield. +** (The caller, 'finishCcall', does the final call to 'adjustresults'.) +** The main job is to complete the 'luaD_pcall' called by 'lua_pcallk'. +** If a '__close' method yields here, eventually control will be back +** to 'finishCcall' (when that '__close' method finally returns) and +** 'finishpcallk' will run again and close any still pending '__close' +** methods. Similarly, if a '__close' method errs, 'precover' calls +** 'unroll' which calls ''finishCcall' and we are back here again, to +** close any pending '__close' methods. +** Note that, up to the call to 'luaF_close', the corresponding +** 'CallInfo' is not modified, so that this repeated run works like the +** first one (except that it has at least one less '__close' to do). In +** particular, field CIST_RECST preserves the error status across these +** multiple runs, changing only if there is a new error. +*/ +static int finishpcallk (lua_State *L, CallInfo *ci) { + int status = getcistrecst(ci); /* get original status */ + if (l_likely(status == LUA_OK)) /* no error? */ + status = LUA_YIELD; /* was interrupted by an yield */ + else { /* error */ + StkId func = restorestack(L, ci->u2.funcidx); + L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */ + func = luaF_close(L, func, status, 1); /* can yield or raise an error */ + luaD_seterrorobj(L, status, func); + luaD_shrinkstack(L); /* restore stack size in case of overflow */ + setcistrecst(ci, LUA_OK); /* clear original status */ + } + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + /* if it is here, there were errors or yields; unlike 'lua_pcallk', + do not change status */ + return status; +} + + +/* +** Completes the execution of a C function interrupted by an yield. +** The interruption must have happened while the function was either +** closing its tbc variables in 'moveresults' or executing +** 'lua_callk'/'lua_pcallk'. In the first case, it just redoes +** 'luaD_poscall'. In the second case, the call to 'finishpcallk' +** finishes the interrupted execution of 'lua_pcallk'. After that, it +** calls the continuation of the interrupted function and finally it +** completes the job of the 'luaD_call' that called the function. In +** the call to 'adjustresults', we do not know the number of results +** of the function called by 'lua_callk'/'lua_pcallk', so we are +** conservative and use LUA_MULTRET (always adjust). +*/ +static void finishCcall (lua_State *L, CallInfo *ci) { + int n; /* actual number of results from C function */ + if (ci->callstatus & CIST_CLSRET) { /* was returning? */ + lua_assert(hastocloseCfunc(ci->nresults)); + n = ci->u2.nres; /* just redo 'luaD_poscall' */ + /* don't need to reset CIST_CLSRET, as it will be set again anyway */ + } + else { + int status = LUA_YIELD; /* default if there were no errors */ + /* must have a continuation and must be able to call it */ + lua_assert(ci->u.c.k != NULL && yieldable(L)); + if (ci->callstatus & CIST_YPCALL) /* was inside a 'lua_pcallk'? */ + status = finishpcallk(L, ci); /* finish it */ + adjustresults(L, LUA_MULTRET); /* finish 'lua_callk' */ + lua_unlock(L); + n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + } + luaD_poscall(L, ci, n); /* finish 'luaD_call' */ +} + + +/* +** Executes "full continuation" (everything in the stack) of a +** previously interrupted coroutine until the stack is empty (or another +** interruption long-jumps out of the loop). +*/ +static void unroll (lua_State *L, void *ud) { + CallInfo *ci; + UNUSED(ud); + while ((ci = L->ci) != &L->base_ci) { /* something in the stack */ + if (!isLua(ci)) /* C function? */ + finishCcall(L, ci); /* complete its execution */ + else { /* Lua function */ + luaV_finishOp(L); /* finish interrupted instruction */ + luaV_execute(L, ci); /* execute down to higher C 'boundary' */ + } + } +} + + +/* +** Try to find a suspended protected call (a "recover point") for the +** given thread. +*/ +static CallInfo *findpcall (lua_State *L) { + CallInfo *ci; + for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ + if (ci->callstatus & CIST_YPCALL) + return ci; + } + return NULL; /* no pending pcall */ +} + + +/* +** Signal an error in the call to 'lua_resume', not in the execution +** of the coroutine itself. (Such errors should not be handled by any +** coroutine error handler and should not kill the coroutine.) +*/ +static int resume_error (lua_State *L, const char *msg, int narg) { + L->top.p -= narg; /* remove args from the stack */ + setsvalue2s(L, L->top.p, luaS_new(L, msg)); /* push error message */ + api_incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +/* +** Do the work for 'lua_resume' in protected mode. Most of the work +** depends on the status of the coroutine: initial state, suspended +** inside a hook, or regularly suspended (optionally with a continuation +** function), plus erroneous cases: non-suspended coroutine or dead +** coroutine. +*/ +static void resume (lua_State *L, void *ud) { + int n = *(cast(int*, ud)); /* number of arguments */ + StkId firstArg = L->top.p - n; /* first argument */ + CallInfo *ci = L->ci; + if (L->status == LUA_OK) /* starting a coroutine? */ + ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */ + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = LUA_OK; /* mark that it is running (again) */ + if (isLua(ci)) { /* yielded inside a hook? */ + /* undo increment made by 'luaG_traceexec': instruction was not + executed yet */ + lua_assert(ci->callstatus & CIST_HOOKYIELD); + ci->u.l.savedpc--; + L->top.p = firstArg; /* discard arguments */ + luaV_execute(L, ci); /* just continue running Lua code */ + } + else { /* 'common' yield */ + if (ci->u.c.k != NULL) { /* does it have a continuation function? */ + lua_unlock(L); + n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + } + luaD_poscall(L, ci, n); /* finish 'luaD_call' */ + } + unroll(L, NULL); /* run continuation */ + } +} + + +/* +** Unrolls a coroutine in protected mode while there are recoverable +** errors, that is, errors inside a protected call. (Any error +** interrupts 'unroll', and this loop protects it again so it can +** continue.) Stops with a normal end (status == LUA_OK), an yield +** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't +** find a recover point). +*/ +static int precover (lua_State *L, int status) { + CallInfo *ci; + while (errorstatus(status) && (ci = findpcall(L)) != NULL) { + L->ci = ci; /* go down to recovery functions */ + setcistrecst(ci, status); /* status to finish 'pcall' */ + status = luaD_rawrunprotected(L, unroll, NULL); + } + return status; +} + + +LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, + int *nresults) { + int status; + lua_lock(L); + if (L->status == LUA_OK) { /* may be starting a coroutine */ + if (L->ci != &L->base_ci) /* not in base level? */ + return resume_error(L, "cannot resume non-suspended coroutine", nargs); + else if (L->top.p - (L->ci->func.p + 1) == nargs) /* no function? */ + return resume_error(L, "cannot resume dead coroutine", nargs); + } + else if (L->status != LUA_YIELD) /* ended with errors? */ + return resume_error(L, "cannot resume dead coroutine", nargs); + L->nCcalls = (from) ? getCcalls(from) : 0; + if (getCcalls(L) >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow", nargs); + L->nCcalls++; + luai_userstateresume(L, nargs); + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); + status = luaD_rawrunprotected(L, resume, &nargs); + /* continue running after recoverable errors */ + status = precover(L, status); + if (l_likely(!errorstatus(status))) + lua_assert(status == L->status); /* normal end or yield */ + else { /* unrecoverable error */ + L->status = cast_byte(status); /* mark thread as 'dead' */ + luaD_seterrorobj(L, status, L->top.p); /* push error message */ + L->ci->top.p = L->top.p; + } + *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield + : cast_int(L->top.p - (L->ci->func.p + 1)); + lua_unlock(L); + return status; +} + + +LUA_API int lua_isyieldable (lua_State *L) { + return yieldable(L); +} + + +LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, + lua_KFunction k) { + CallInfo *ci; + luai_userstateyield(L, nresults); + lua_lock(L); + ci = L->ci; + api_checknelems(L, nresults); + if (l_unlikely(!yieldable(L))) { + if (L != G(L)->mainthread) + luaG_runerror(L, "attempt to yield across a C-call boundary"); + else + luaG_runerror(L, "attempt to yield from outside a coroutine"); + } + L->status = LUA_YIELD; + ci->u2.nyield = nresults; /* save number of results */ + if (isLua(ci)) { /* inside a hook? */ + lua_assert(!isLuacode(ci)); + api_check(L, nresults == 0, "hooks cannot yield values"); + api_check(L, k == NULL, "hooks cannot continue after yielding"); + } + else { + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ + ci->u.c.ctx = ctx; /* save context */ + luaD_throw(L, LUA_YIELD); + } + lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ + lua_unlock(L); + return 0; /* return to 'luaD_hook' */ +} + + +/* +** Auxiliary structure to call 'luaF_close' in protected mode. +*/ +struct CloseP { + StkId level; + int status; +}; + + +/* +** Auxiliary function to call 'luaF_close' in protected mode. +*/ +static void closepaux (lua_State *L, void *ud) { + struct CloseP *pcl = cast(struct CloseP *, ud); + luaF_close(L, pcl->level, pcl->status, 0); +} + + +/* +** Calls 'luaF_close' in protected mode. Return the original status +** or, in case of errors, the new status. +*/ +int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) { + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + for (;;) { /* keep closing upvalues until no more errors */ + struct CloseP pcl; + pcl.level = restorestack(L, level); pcl.status = status; + status = luaD_rawrunprotected(L, &closepaux, &pcl); + if (l_likely(status == LUA_OK)) /* no more errors? */ + return pcl.status; + else { /* an error occurred; restore saved state and repeat */ + L->ci = old_ci; + L->allowhook = old_allowhooks; + } + } +} + + +/* +** Call the C function 'func' in protected mode, restoring basic +** thread information ('allowhook', etc.) and in particular +** its stack level in case of errors. +*/ +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (l_unlikely(status != LUA_OK)) { /* an error occurred? */ + L->ci = old_ci; + L->allowhook = old_allowhooks; + status = luaD_closeprotected(L, old_top, status); + luaD_seterrorobj(L, status, restorestack(L, old_top)); + luaD_shrinkstack(L); /* restore stack size in case of overflow */ + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to 'f_parser' */ + ZIO *z; + Mbuffer buff; /* dynamic structure used by the scanner */ + Dyndata dyd; /* dynamic structures used by the parser */ + const char *mode; + const char *name; +}; + + +static void checkmode (lua_State *L, const char *mode, const char *x) { + if (mode && strchr(mode, x[0]) == NULL) { + luaO_pushfstring(L, + "attempt to load a %s chunk (mode is '%s')", x, mode); + luaD_throw(L, LUA_ERRSYNTAX); + } +} + + +static void f_parser (lua_State *L, void *ud) { + LClosure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = zgetc(p->z); /* read first character */ + if (c == LUA_SIGNATURE[0]) { + checkmode(L, p->mode, "binary"); + cl = luaU_undump(L, p->z, p->name); + } + else { + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); + } + lua_assert(cl->nupvalues == cl->p->sizeupvalues); + luaF_initupvals(L, cl); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode) { + struct SParser p; + int status; + incnny(L); /* cannot yield during parsing */ + p.z = z; p.name = name; p.mode = mode; + p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; + p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; + p.dyd.label.arr = NULL; p.dyd.label.size = 0; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top.p), L->errfunc); + luaZ_freebuffer(L, &p.buff); + luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); + luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); + luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); + decnny(L); + return status; +} + + diff --git a/arm9/source/lua/ldo.h b/arm9/source/lua/ldo.h new file mode 100644 index 000000000..f30022494 --- /dev/null +++ b/arm9/source/lua/ldo.h @@ -0,0 +1,87 @@ +/* +** $Id: ldo.h $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "llimits.h" +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +/* +** Macro to check stack size and grow stack if needed. Parameters +** 'pre'/'pos' allow the macro to preserve a pointer into the +** stack across reallocations, doing the work only when needed. +** It also allows the running of one GC step when the stack is +** reallocated. +** 'condmovestack' is used in heavy tests to force a stack reallocation +** at every check. +*/ +#define luaD_checkstackaux(L,n,pre,pos) \ + if (l_unlikely(L->stack_last.p - L->top.p <= (n))) \ + { pre; luaD_growstack(L, n, 1); pos; } \ + else { condmovestack(L,pre,pos); } + +/* In general, 'pre'/'pos' are empty (nothing to save) */ +#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) + + + +#define savestack(L,pt) (cast_charp(pt) - cast_charp(L->stack.p)) +#define restorestack(L,n) castp(StkId, cast_charp(L->stack.p) + (n)) + + +/* macro to check stack size, preserving 'p' */ +#define checkstackp(L,n,p) \ + luaD_checkstackaux(L, n, \ + ptrdiff_t t__ = savestack(L, p), /* save 'p' */ \ + p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ + + +/* macro to check stack size and GC, preserving 'p' */ +#define checkstackGCp(L,n,p) \ + luaD_checkstackaux(L, n, \ + ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ + luaC_checkGC(L), /* stack grow uses memory */ \ + p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ + + +/* macro to check stack size and GC */ +#define checkstackGC(L,fsize) \ + luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) + + +/* type of protected functions, to be ran by 'runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, + int fTransfer, int nTransfer); +LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); +LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, + int narg1, int delta); +LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); +LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); +LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); +LUAI_FUNC void luaD_shrinkstack (lua_State *L); +LUAI_FUNC void luaD_inctop (lua_State *L); + +LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +#endif + diff --git a/arm9/source/lua/ldump.c b/arm9/source/lua/ldump.c new file mode 100644 index 000000000..f231691b7 --- /dev/null +++ b/arm9/source/lua/ldump.c @@ -0,0 +1,230 @@ +/* +** $Id: ldump.c $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#define ldump_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + + +typedef struct { + lua_State *L; + lua_Writer writer; + void *data; + int strip; + int status; +} DumpState; + + +/* +** All high-level dumps go through dumpVector; you can change it to +** change the endianness of the result +*/ +#define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) + +#define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) + + +static void dumpBlock (DumpState *D, const void *b, size_t size) { + if (D->status == 0 && size > 0) { + lua_unlock(D->L); + D->status = (*D->writer)(D->L, b, size, D->data); + lua_lock(D->L); + } +} + + +#define dumpVar(D,x) dumpVector(D,&x,1) + + +static void dumpByte (DumpState *D, int y) { + lu_byte x = (lu_byte)y; + dumpVar(D, x); +} + + +/* +** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6" +** rounds up the division.) +*/ +#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7) + +static void dumpSize (DumpState *D, size_t x) { + lu_byte buff[DIBS]; + int n = 0; + do { + buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ + x >>= 7; + } while (x != 0); + buff[DIBS - 1] |= 0x80; /* mark last byte */ + dumpVector(D, buff + DIBS - n, n); +} + + +static void dumpInt (DumpState *D, int x) { + dumpSize(D, x); +} + + +static void dumpNumber (DumpState *D, lua_Number x) { + dumpVar(D, x); +} + + +static void dumpInteger (DumpState *D, lua_Integer x) { + dumpVar(D, x); +} + + +static void dumpString (DumpState *D, const TString *s) { + if (s == NULL) + dumpSize(D, 0); + else { + size_t size = tsslen(s); + const char *str = getstr(s); + dumpSize(D, size + 1); + dumpVector(D, str, size); + } +} + + +static void dumpCode (DumpState *D, const Proto *f) { + dumpInt(D, f->sizecode); + dumpVector(D, f->code, f->sizecode); +} + + +static void dumpFunction(DumpState *D, const Proto *f, TString *psource); + +static void dumpConstants (DumpState *D, const Proto *f) { + int i; + int n = f->sizek; + dumpInt(D, n); + for (i = 0; i < n; i++) { + const TValue *o = &f->k[i]; + int tt = ttypetag(o); + dumpByte(D, tt); + switch (tt) { + case LUA_VNUMFLT: + dumpNumber(D, fltvalue(o)); + break; + case LUA_VNUMINT: + dumpInteger(D, ivalue(o)); + break; + case LUA_VSHRSTR: + case LUA_VLNGSTR: + dumpString(D, tsvalue(o)); + break; + default: + lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); + } + } +} + + +static void dumpProtos (DumpState *D, const Proto *f) { + int i; + int n = f->sizep; + dumpInt(D, n); + for (i = 0; i < n; i++) + dumpFunction(D, f->p[i], f->source); +} + + +static void dumpUpvalues (DumpState *D, const Proto *f) { + int i, n = f->sizeupvalues; + dumpInt(D, n); + for (i = 0; i < n; i++) { + dumpByte(D, f->upvalues[i].instack); + dumpByte(D, f->upvalues[i].idx); + dumpByte(D, f->upvalues[i].kind); + } +} + + +static void dumpDebug (DumpState *D, const Proto *f) { + int i, n; + n = (D->strip) ? 0 : f->sizelineinfo; + dumpInt(D, n); + dumpVector(D, f->lineinfo, n); + n = (D->strip) ? 0 : f->sizeabslineinfo; + dumpInt(D, n); + for (i = 0; i < n; i++) { + dumpInt(D, f->abslineinfo[i].pc); + dumpInt(D, f->abslineinfo[i].line); + } + n = (D->strip) ? 0 : f->sizelocvars; + dumpInt(D, n); + for (i = 0; i < n; i++) { + dumpString(D, f->locvars[i].varname); + dumpInt(D, f->locvars[i].startpc); + dumpInt(D, f->locvars[i].endpc); + } + n = (D->strip) ? 0 : f->sizeupvalues; + dumpInt(D, n); + for (i = 0; i < n; i++) + dumpString(D, f->upvalues[i].name); +} + + +static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { + if (D->strip || f->source == psource) + dumpString(D, NULL); /* no debug info or same source as its parent */ + else + dumpString(D, f->source); + dumpInt(D, f->linedefined); + dumpInt(D, f->lastlinedefined); + dumpByte(D, f->numparams); + dumpByte(D, f->is_vararg); + dumpByte(D, f->maxstacksize); + dumpCode(D, f); + dumpConstants(D, f); + dumpUpvalues(D, f); + dumpProtos(D, f); + dumpDebug(D, f); +} + + +static void dumpHeader (DumpState *D) { + dumpLiteral(D, LUA_SIGNATURE); + dumpByte(D, LUAC_VERSION); + dumpByte(D, LUAC_FORMAT); + dumpLiteral(D, LUAC_DATA); + dumpByte(D, sizeof(Instruction)); + dumpByte(D, sizeof(lua_Integer)); + dumpByte(D, sizeof(lua_Number)); + dumpInteger(D, LUAC_INT); + dumpNumber(D, LUAC_NUM); +} + + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, + int strip) { + DumpState D; + D.L = L; + D.writer = w; + D.data = data; + D.strip = strip; + D.status = 0; + dumpHeader(&D); + dumpByte(&D, f->sizeupvalues); + dumpFunction(&D, f, NULL); + return D.status; +} + diff --git a/arm9/source/lua/lfunc.c b/arm9/source/lua/lfunc.c new file mode 100644 index 000000000..0945f241d --- /dev/null +++ b/arm9/source/lua/lfunc.c @@ -0,0 +1,294 @@ +/* +** $Id: lfunc.c $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#define lfunc_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +CClosure *luaF_newCclosure (lua_State *L, int nupvals) { + GCObject *o = luaC_newobj(L, LUA_VCCL, sizeCclosure(nupvals)); + CClosure *c = gco2ccl(o); + c->nupvalues = cast_byte(nupvals); + return c; +} + + +LClosure *luaF_newLclosure (lua_State *L, int nupvals) { + GCObject *o = luaC_newobj(L, LUA_VLCL, sizeLclosure(nupvals)); + LClosure *c = gco2lcl(o); + c->p = NULL; + c->nupvalues = cast_byte(nupvals); + while (nupvals--) c->upvals[nupvals] = NULL; + return c; +} + + +/* +** fill a closure with new closed upvalues +*/ +void luaF_initupvals (lua_State *L, LClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) { + GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); + UpVal *uv = gco2upv(o); + uv->v.p = &uv->u.value; /* make it closed */ + setnilvalue(uv->v.p); + cl->upvals[i] = uv; + luaC_objbarrier(L, cl, uv); + } +} + + +/* +** Create a new upvalue at the given level, and link it to the list of +** open upvalues of 'L' after entry 'prev'. +**/ +static UpVal *newupval (lua_State *L, StkId level, UpVal **prev) { + GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); + UpVal *uv = gco2upv(o); + UpVal *next = *prev; + uv->v.p = s2v(level); /* current value lives in the stack */ + uv->u.open.next = next; /* link it to list of open upvalues */ + uv->u.open.previous = prev; + if (next) + next->u.open.previous = &uv->u.open.next; + *prev = uv; + if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ + L->twups = G(L)->twups; /* link it to the list */ + G(L)->twups = L; + } + return uv; +} + + +/* +** Find and reuse, or create if it does not exist, an upvalue +** at the given level. +*/ +UpVal *luaF_findupval (lua_State *L, StkId level) { + UpVal **pp = &L->openupval; + UpVal *p; + lua_assert(isintwups(L) || L->openupval == NULL); + while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ + lua_assert(!isdead(G(L), p)); + if (uplevel(p) == level) /* corresponding upvalue? */ + return p; /* return it */ + pp = &p->u.open.next; + } + /* not found: create a new upvalue after 'pp' */ + return newupval(L, level, pp); +} + + +/* +** Call closing method for object 'obj' with error message 'err'. The +** boolean 'yy' controls whether the call is yieldable. +** (This function assumes EXTRA_STACK.) +*/ +static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) { + StkId top = L->top.p; + const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); + setobj2s(L, top, tm); /* will call metamethod... */ + setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */ + setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */ + L->top.p = top + 3; /* add function and arguments */ + if (yy) + luaD_call(L, top, 0); + else + luaD_callnoyield(L, top, 0); +} + + +/* +** Check whether object at given level has a close metamethod and raise +** an error if not. +*/ +static void checkclosemth (lua_State *L, StkId level) { + const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE); + if (ttisnil(tm)) { /* no metamethod? */ + int idx = cast_int(level - L->ci->func.p); /* variable index */ + const char *vname = luaG_findlocal(L, L->ci, idx, NULL); + if (vname == NULL) vname = "?"; + luaG_runerror(L, "variable '%s' got a non-closable value", vname); + } +} + + +/* +** Prepare and call a closing method. +** If status is CLOSEKTOP, the call to the closing method will be pushed +** at the top of the stack. Otherwise, values can be pushed right after +** the 'level' of the upvalue being closed, as everything after that +** won't be used again. +*/ +static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) { + TValue *uv = s2v(level); /* value being closed */ + TValue *errobj; + if (status == CLOSEKTOP) + errobj = &G(L)->nilvalue; /* error object is nil */ + else { /* 'luaD_seterrorobj' will set top to level + 2 */ + errobj = s2v(level + 1); /* error object goes after 'uv' */ + luaD_seterrorobj(L, status, level + 1); /* set error object */ + } + callclosemethod(L, uv, errobj, yy); +} + + +/* +** Maximum value for deltas in 'tbclist', dependent on the type +** of delta. (This macro assumes that an 'L' is in scope where it +** is used.) +*/ +#define MAXDELTA \ + ((256ul << ((sizeof(L->stack.p->tbclist.delta) - 1) * 8)) - 1) + + +/* +** Insert a variable in the list of to-be-closed variables. +*/ +void luaF_newtbcupval (lua_State *L, StkId level) { + lua_assert(level > L->tbclist.p); + if (l_isfalse(s2v(level))) + return; /* false doesn't need to be closed */ + checkclosemth(L, level); /* value must have a close method */ + while (cast_uint(level - L->tbclist.p) > MAXDELTA) { + L->tbclist.p += MAXDELTA; /* create a dummy node at maximum delta */ + L->tbclist.p->tbclist.delta = 0; + } + level->tbclist.delta = cast(unsigned short, level - L->tbclist.p); + L->tbclist.p = level; +} + + +void luaF_unlinkupval (UpVal *uv) { + lua_assert(upisopen(uv)); + *uv->u.open.previous = uv->u.open.next; + if (uv->u.open.next) + uv->u.open.next->u.open.previous = uv->u.open.previous; +} + + +/* +** Close all upvalues up to the given stack level. +*/ +void luaF_closeupval (lua_State *L, StkId level) { + UpVal *uv; + StkId upl; /* stack index pointed by 'uv' */ + while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) { + TValue *slot = &uv->u.value; /* new position for value */ + lua_assert(uplevel(uv) < L->top.p); + luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */ + setobj(L, slot, uv->v.p); /* move value to upvalue slot */ + uv->v.p = slot; /* now current value lives here */ + if (!iswhite(uv)) { /* neither white nor dead? */ + nw2black(uv); /* closed upvalues cannot be gray */ + luaC_barrier(L, uv, slot); + } + } +} + + +/* +** Remove first element from the tbclist plus its dummy nodes. +*/ +static void poptbclist (lua_State *L) { + StkId tbc = L->tbclist.p; + lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */ + tbc -= tbc->tbclist.delta; + while (tbc > L->stack.p && tbc->tbclist.delta == 0) + tbc -= MAXDELTA; /* remove dummy nodes */ + L->tbclist.p = tbc; +} + + +/* +** Close all upvalues and to-be-closed variables up to the given stack +** level. Return restored 'level'. +*/ +StkId luaF_close (lua_State *L, StkId level, int status, int yy) { + ptrdiff_t levelrel = savestack(L, level); + luaF_closeupval(L, level); /* first, close the upvalues */ + while (L->tbclist.p >= level) { /* traverse tbc's down to that level */ + StkId tbc = L->tbclist.p; /* get variable index */ + poptbclist(L); /* remove it from list */ + prepcallclosemth(L, tbc, status, yy); /* close variable */ + level = restorestack(L, levelrel); + } + return level; +} + + +Proto *luaF_newproto (lua_State *L) { + GCObject *o = luaC_newobj(L, LUA_VPROTO, sizeof(Proto)); + Proto *f = gco2p(o); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->lineinfo = NULL; + f->sizelineinfo = 0; + f->abslineinfo = NULL; + f->sizeabslineinfo = 0; + f->upvalues = NULL; + f->sizeupvalues = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->locvars = NULL; + f->sizelocvars = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->abslineinfo, f->sizeabslineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); + luaM_free(L, f); +} + + +/* +** Look for n-th local variable at line 'line' in function 'func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/arm9/source/lua/lfunc.h b/arm9/source/lua/lfunc.h new file mode 100644 index 000000000..3be265efb --- /dev/null +++ b/arm9/source/lua/lfunc.h @@ -0,0 +1,64 @@ +/* +** $Id: lfunc.h $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ + cast_int(sizeof(TValue)) * (n)) + +#define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ + cast_int(sizeof(TValue *)) * (n)) + + +/* test whether thread is in 'twups' list */ +#define isintwups(L) (L->twups != L) + + +/* +** maximum number of upvalues in a closure (both C and Lua). (Value +** must fit in a VM register.) +*/ +#define MAXUPVAL 255 + + +#define upisopen(up) ((up)->v.p != &(up)->u.value) + + +#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p)) + + +/* +** maximum number of misses before giving up the cache of closures +** in prototypes +*/ +#define MAXMISS 10 + + + +/* special status to close upvalues preserving the top of the stack */ +#define CLOSEKTOP (-1) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); +LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); +LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); +LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy); +LUAI_FUNC void luaF_unlinkupval (UpVal *uv); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/arm9/source/lua/lgc.c b/arm9/source/lua/lgc.c new file mode 100644 index 000000000..f1652714a --- /dev/null +++ b/arm9/source/lua/lgc.c @@ -0,0 +1,1743 @@ +/* +** $Id: lgc.c $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#define lgc_c +#define LUA_CORE + +#include "lprefix.h" + +#include +#include + + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +/* +** Maximum number of elements to sweep in each single step. +** (Large enough to dissipate fixed overheads but small enough +** to allow small steps for the collector.) +*/ +#define GCSWEEPMAX 100 + +/* +** Maximum number of finalizers to call in each single step. +*/ +#define GCFINMAX 10 + + +/* +** Cost of calling one finalizer. +*/ +#define GCFINALIZECOST 50 + + +/* +** The equivalent, in bytes, of one unit of "work" (visiting a slot, +** sweeping an object, etc.) +*/ +#define WORK2MEM sizeof(TValue) + + +/* +** macro to adjust 'pause': 'pause' is actually used like +** 'pause / PAUSEADJ' (value chosen by tests) +*/ +#define PAUSEADJ 100 + + +/* mask with all color bits */ +#define maskcolors (bitmask(BLACKBIT) | WHITEBITS) + +/* mask with all GC bits */ +#define maskgcbits (maskcolors | AGEBITS) + + +/* macro to erase all color bits then set only the current white bit */ +#define makewhite(g,x) \ + (x->marked = cast_byte((x->marked & ~maskcolors) | luaC_white(g))) + +/* make an object gray (neither white nor black) */ +#define set2gray(x) resetbits(x->marked, maskcolors) + + +/* make an object black (coming from any color) */ +#define set2black(x) \ + (x->marked = cast_byte((x->marked & ~WHITEBITS) | bitmask(BLACKBIT))) + + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define keyiswhite(n) (keyiscollectable(n) && iswhite(gckey(n))) + + +/* +** Protected access to objects in values +*/ +#define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) + + +#define markvalue(g,o) { checkliveness(g->mainthread,o); \ + if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } + +#define markkey(g, n) { if keyiswhite(n) reallymarkobject(g,gckey(n)); } + +#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } + +/* +** mark an object that can be NULL (either because it is really optional, +** or it was stripped as debug info, or inside an uncompleted structure) +*/ +#define markobjectN(g,t) { if (t) markobject(g,t); } + +static void reallymarkobject (global_State *g, GCObject *o); +static lu_mem atomic (lua_State *L); +static void entersweep (lua_State *L); + + +/* +** {====================================================== +** Generic functions +** ======================================================= +*/ + + +/* +** one after last element in a hash array +*/ +#define gnodelast(h) gnode(h, cast_sizet(sizenode(h))) + + +static GCObject **getgclist (GCObject *o) { + switch (o->tt) { + case LUA_VTABLE: return &gco2t(o)->gclist; + case LUA_VLCL: return &gco2lcl(o)->gclist; + case LUA_VCCL: return &gco2ccl(o)->gclist; + case LUA_VTHREAD: return &gco2th(o)->gclist; + case LUA_VPROTO: return &gco2p(o)->gclist; + case LUA_VUSERDATA: { + Udata *u = gco2u(o); + lua_assert(u->nuvalue > 0); + return &u->gclist; + } + default: lua_assert(0); return 0; + } +} + + +/* +** Link a collectable object 'o' with a known type into the list 'p'. +** (Must be a macro to access the 'gclist' field in different types.) +*/ +#define linkgclist(o,p) linkgclist_(obj2gco(o), &(o)->gclist, &(p)) + +static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) { + lua_assert(!isgray(o)); /* cannot be in a gray list */ + *pnext = *list; + *list = o; + set2gray(o); /* now it is */ +} + + +/* +** Link a generic collectable object 'o' into the list 'p'. +*/ +#define linkobjgclist(o,p) linkgclist_(obj2gco(o), getgclist(o), &(p)) + + + +/* +** Clear keys for empty entries in tables. If entry is empty, mark its +** entry as dead. This allows the collection of the key, but keeps its +** entry in the table: its removal could break a chain and could break +** a table traversal. Other places never manipulate dead keys, because +** its associated empty value is enough to signal that the entry is +** logically empty. +*/ +static void clearkey (Node *n) { + lua_assert(isempty(gval(n))); + if (keyiscollectable(n)) + setdeadkey(n); /* unused key; remove it */ +} + + +/* +** tells whether a key or value can be cleared from a weak +** table. Non-collectable objects are never removed from weak +** tables. Strings behave as 'values', so are never removed too. for +** other objects: if really collected, cannot keep them; for objects +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (global_State *g, const GCObject *o) { + if (o == NULL) return 0; /* non-collectable value */ + else if (novariant(o->tt) == LUA_TSTRING) { + markobject(g, o); /* strings are 'values', so are never weak */ + return 0; + } + else return iswhite(o); +} + + +/* +** Barrier that moves collector forward, that is, marks the white object +** 'v' being pointed by the black object 'o'. In the generational +** mode, 'v' must also become old, if 'o' is old; however, it cannot +** be changed directly to OLD, because it may still point to non-old +** objects. So, it is marked as OLD0. In the next cycle it will become +** OLD1, and in the next it will finally become OLD (regular old). By +** then, any object it points to will also be old. If called in the +** incremental sweep phase, it clears the black object to white (sweep +** it) to avoid other barrier calls for this same object. (That cannot +** be done is generational mode, as its sweep does not distinguish +** whites from deads.) +*/ +void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + if (keepinvariant(g)) { /* must keep invariant? */ + reallymarkobject(g, v); /* restore invariant */ + if (isold(o)) { + lua_assert(!isold(v)); /* white object could not be old */ + setage(v, G_OLD0); /* restore generational invariant */ + } + } + else { /* sweep phase */ + lua_assert(issweepphase(g)); + if (g->gckind == KGC_INC) /* incremental mode? */ + makewhite(g, o); /* mark 'o' as white to avoid other barriers */ + } +} + + +/* +** barrier that moves collector backward, that is, mark the black object +** pointing to a white object as gray again. +*/ +void luaC_barrierback_ (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1)); + if (getage(o) == G_TOUCHED2) /* already in gray list? */ + set2gray(o); /* make it gray to become touched1 */ + else /* link it in 'grayagain' and paint it gray */ + linkobjgclist(o, g->grayagain); + if (isold(o)) /* generational mode? */ + setage(o, G_TOUCHED1); /* touched in current cycle */ +} + + +void luaC_fix (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ + set2gray(o); /* they will be gray forever */ + setage(o, G_OLD); /* and old forever */ + g->allgc = o->next; /* remove object from 'allgc' list */ + o->next = g->fixedgc; /* link it to 'fixedgc' list */ + g->fixedgc = o; +} + + +/* +** create a new collectable object (with given type, size, and offset) +** and link it to 'allgc' list. +*/ +GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, size_t offset) { + global_State *g = G(L); + char *p = cast_charp(luaM_newobject(L, novariant(tt), sz)); + GCObject *o = castp(GCObject *, p + offset); + o->marked = luaC_white(g); + o->tt = tt; + o->next = g->allgc; + g->allgc = o; + return o; +} + + +GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { + return luaC_newobjdt(L, tt, sz, 0); +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Mark functions +** ======================================================= +*/ + + +/* +** Mark an object. Userdata with no user values, strings, and closed +** upvalues are visited and turned black here. Open upvalues are +** already indirectly linked through their respective threads in the +** 'twups' list, so they don't go to the gray list; nevertheless, they +** are kept gray to avoid barriers, as their values will be revisited +** by the thread or by 'remarkupvals'. Other objects are added to the +** gray list to be visited (and turned black) later. Both userdata and +** upvalues can call this function recursively, but this recursion goes +** for at most two levels: An upvalue cannot refer to another upvalue +** (only closures can), and a userdata's metatable must be a table. +*/ +static void reallymarkobject (global_State *g, GCObject *o) { + switch (o->tt) { + case LUA_VSHRSTR: + case LUA_VLNGSTR: { + set2black(o); /* nothing to visit */ + break; + } + case LUA_VUPVAL: { + UpVal *uv = gco2upv(o); + if (upisopen(uv)) + set2gray(uv); /* open upvalues are kept gray */ + else + set2black(uv); /* closed upvalues are visited here */ + markvalue(g, uv->v.p); /* mark its content */ + break; + } + case LUA_VUSERDATA: { + Udata *u = gco2u(o); + if (u->nuvalue == 0) { /* no user values? */ + markobjectN(g, u->metatable); /* mark its metatable */ + set2black(u); /* nothing else to mark */ + break; + } + /* else... */ + } /* FALLTHROUGH */ + case LUA_VLCL: case LUA_VCCL: case LUA_VTABLE: + case LUA_VTHREAD: case LUA_VPROTO: { + linkobjgclist(o, g->gray); /* to be visited later */ + break; + } + default: lua_assert(0); break; + } +} + + +/* +** mark metamethods for basic types +*/ +static void markmt (global_State *g) { + int i; + for (i=0; i < LUA_NUMTAGS; i++) + markobjectN(g, g->mt[i]); +} + + +/* +** mark all objects in list of being-finalized +*/ +static lu_mem markbeingfnz (global_State *g) { + GCObject *o; + lu_mem count = 0; + for (o = g->tobefnz; o != NULL; o = o->next) { + count++; + markobject(g, o); + } + return count; +} + + +/* +** For each non-marked thread, simulates a barrier between each open +** upvalue and its value. (If the thread is collected, the value will be +** assigned to the upvalue, but then it can be too late for the barrier +** to act. The "barrier" does not need to check colors: A non-marked +** thread must be young; upvalues cannot be older than their threads; so +** any visited upvalue must be young too.) Also removes the thread from +** the list, as it was already visited. Removes also threads with no +** upvalues, as they have nothing to be checked. (If the thread gets an +** upvalue later, it will be linked in the list again.) +*/ +static int remarkupvals (global_State *g) { + lua_State *thread; + lua_State **p = &g->twups; + int work = 0; /* estimate of how much work was done here */ + while ((thread = *p) != NULL) { + work++; + if (!iswhite(thread) && thread->openupval != NULL) + p = &thread->twups; /* keep marked thread with upvalues in the list */ + else { /* thread is not marked or without upvalues */ + UpVal *uv; + lua_assert(!isold(thread) || thread->openupval == NULL); + *p = thread->twups; /* remove thread from the list */ + thread->twups = thread; /* mark that it is out of list */ + for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { + lua_assert(getage(uv) <= getage(thread)); + work++; + if (!iswhite(uv)) { /* upvalue already visited? */ + lua_assert(upisopen(uv) && isgray(uv)); + markvalue(g, uv->v.p); /* mark its value */ + } + } + } + } + return work; +} + + +static void cleargraylists (global_State *g) { + g->gray = g->grayagain = NULL; + g->weak = g->allweak = g->ephemeron = NULL; +} + + +/* +** mark root set and reset all gray lists, to start a new collection +*/ +static void restartcollection (global_State *g) { + cleargraylists(g); + markobject(g, g->mainthread); + markvalue(g, &g->l_registry); + markmt(g); + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Traverse functions +** ======================================================= +*/ + + +/* +** Check whether object 'o' should be kept in the 'grayagain' list for +** post-processing by 'correctgraylist'. (It could put all old objects +** in the list and leave all the work to 'correctgraylist', but it is +** more efficient to avoid adding elements that will be removed.) Only +** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go +** back to a gray list, but then it must become OLD. (That is what +** 'correctgraylist' does when it finds a TOUCHED2 object.) +*/ +static void genlink (global_State *g, GCObject *o) { + lua_assert(isblack(o)); + if (getage(o) == G_TOUCHED1) { /* touched in this cycle? */ + linkobjgclist(o, g->grayagain); /* link it back in 'grayagain' */ + } /* everything else do not need to be linked back */ + else if (getage(o) == G_TOUCHED2) + changeage(o, G_TOUCHED2, G_OLD); /* advance age */ +} + + +/* +** Traverse a table with weak values and link it to proper list. During +** propagate phase, keep it in 'grayagain' list, to be revisited in the +** atomic phase. In the atomic phase, if table has any white value, +** put it in 'weak' list, to be cleared. +*/ +static void traverseweakvalue (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + /* if there is array part, assume it may have white values (it is not + worth traversing it now just to check) */ + int hasclears = (h->alimit > 0); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + if (isempty(gval(n))) /* entry is empty? */ + clearkey(n); /* clear its key */ + else { + lua_assert(!keyisnil(n)); + markkey(g, n); + if (!hasclears && iscleared(g, gcvalueN(gval(n)))) /* a white value? */ + hasclears = 1; /* table will have to be cleared */ + } + } + if (g->gcstate == GCSatomic && hasclears) + linkgclist(h, g->weak); /* has to be cleared later */ + else + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ +} + + +/* +** Traverse an ephemeron table and link it to proper list. Returns true +** iff any object was marked during this traversal (which implies that +** convergence has to continue). During propagation phase, keep table +** in 'grayagain' list, to be visited again in the atomic phase. In +** the atomic phase, if table has any white->white entry, it has to +** be revisited during ephemeron convergence (as that key may turn +** black). Otherwise, if it has any white key, table has to be cleared +** (in the atomic phase). In generational mode, some tables +** must be kept in some gray list for post-processing; this is done +** by 'genlink'. +*/ +static int traverseephemeron (global_State *g, Table *h, int inv) { + int marked = 0; /* true if an object is marked in this traversal */ + int hasclears = 0; /* true if table has white keys */ + int hasww = 0; /* true if table has entry "white-key -> white-value" */ + unsigned int i; + unsigned int asize = luaH_realasize(h); + unsigned int nsize = sizenode(h); + /* traverse array part */ + for (i = 0; i < asize; i++) { + if (valiswhite(&h->array[i])) { + marked = 1; + reallymarkobject(g, gcvalue(&h->array[i])); + } + } + /* traverse hash part; if 'inv', traverse descending + (see 'convergeephemerons') */ + for (i = 0; i < nsize; i++) { + Node *n = inv ? gnode(h, nsize - 1 - i) : gnode(h, i); + if (isempty(gval(n))) /* entry is empty? */ + clearkey(n); /* clear its key */ + else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */ + hasclears = 1; /* table must be cleared */ + if (valiswhite(gval(n))) /* value not marked yet? */ + hasww = 1; /* white-white entry */ + } + else if (valiswhite(gval(n))) { /* value not marked yet? */ + marked = 1; + reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ + } + } + /* link table into proper list */ + if (g->gcstate == GCSpropagate) + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ + else if (hasww) /* table has white->white entries? */ + linkgclist(h, g->ephemeron); /* have to propagate again */ + else if (hasclears) /* table has white keys? */ + linkgclist(h, g->allweak); /* may have to clean white keys */ + else + genlink(g, obj2gco(h)); /* check whether collector still needs to see it */ + return marked; +} + + +static void traversestrongtable (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + unsigned int i; + unsigned int asize = luaH_realasize(h); + for (i = 0; i < asize; i++) /* traverse array part */ + markvalue(g, &h->array[i]); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + if (isempty(gval(n))) /* entry is empty? */ + clearkey(n); /* clear its key */ + else { + lua_assert(!keyisnil(n)); + markkey(g, n); + markvalue(g, gval(n)); + } + } + genlink(g, obj2gco(h)); +} + + +static lu_mem traversetable (global_State *g, Table *h) { + const char *weakkey, *weakvalue; + const TValue *mode = gfasttm(g, h->metatable, TM_MODE); + TString *smode; + markobjectN(g, h->metatable); + if (mode && ttisshrstring(mode) && /* is there a weak mode? */ + (cast_void(smode = tsvalue(mode)), + cast_void(weakkey = strchr(getshrstr(smode), 'k')), + cast_void(weakvalue = strchr(getshrstr(smode), 'v')), + (weakkey || weakvalue))) { /* is really weak? */ + if (!weakkey) /* strong keys? */ + traverseweakvalue(g, h); + else if (!weakvalue) /* strong values? */ + traverseephemeron(g, h, 0); + else /* all weak */ + linkgclist(h, g->allweak); /* nothing to traverse now */ + } + else /* not weak */ + traversestrongtable(g, h); + return 1 + h->alimit + 2 * allocsizenode(h); +} + + +static int traverseudata (global_State *g, Udata *u) { + int i; + markobjectN(g, u->metatable); /* mark its metatable */ + for (i = 0; i < u->nuvalue; i++) + markvalue(g, &u->uv[i].uv); + genlink(g, obj2gco(u)); + return 1 + u->nuvalue; +} + + +/* +** Traverse a prototype. (While a prototype is being build, its +** arrays can be larger than needed; the extra slots are filled with +** NULL, so the use of 'markobjectN') +*/ +static int traverseproto (global_State *g, Proto *f) { + int i; + markobjectN(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobjectN(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobjectN(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobjectN(g, f->locvars[i].varname); + return 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; +} + + +static int traverseCclosure (global_State *g, CClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return 1 + cl->nupvalues; +} + +/* +** Traverse a Lua closure, marking its prototype and its upvalues. +** (Both can be NULL while closure is being created.) +*/ +static int traverseLclosure (global_State *g, LClosure *cl) { + int i; + markobjectN(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */ + UpVal *uv = cl->upvals[i]; + markobjectN(g, uv); /* mark upvalue */ + } + return 1 + cl->nupvalues; +} + + +/* +** Traverse a thread, marking the elements in the stack up to its top +** and cleaning the rest of the stack in the final traversal. That +** ensures that the entire stack have valid (non-dead) objects. +** Threads have no barriers. In gen. mode, old threads must be visited +** at every cycle, because they might point to young objects. In inc. +** mode, the thread can still be modified before the end of the cycle, +** and therefore it must be visited again in the atomic phase. To ensure +** these visits, threads must return to a gray list if they are not new +** (which can only happen in generational mode) or if the traverse is in +** the propagate phase (which can only happen in incremental mode). +*/ +static int traversethread (global_State *g, lua_State *th) { + UpVal *uv; + StkId o = th->stack.p; + if (isold(th) || g->gcstate == GCSpropagate) + linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ + if (o == NULL) + return 1; /* stack not completely built yet */ + lua_assert(g->gcstate == GCSatomic || + th->openupval == NULL || isintwups(th)); + for (; o < th->top.p; o++) /* mark live elements in the stack */ + markvalue(g, s2v(o)); + for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) + markobject(g, uv); /* open upvalues cannot be collected */ + if (g->gcstate == GCSatomic) { /* final traversal? */ + if (!g->gcemergency) + luaD_shrinkstack(th); /* do not change stack in emergency cycle */ + for (o = th->top.p; o < th->stack_last.p + EXTRA_STACK; o++) + setnilvalue(s2v(o)); /* clear dead stack slice */ + /* 'remarkupvals' may have removed thread from 'twups' list */ + if (!isintwups(th) && th->openupval != NULL) { + th->twups = g->twups; /* link it back to the list */ + g->twups = th; + } + } + return 1 + stacksize(th); +} + + +/* +** traverse one gray object, turning it to black. +*/ +static lu_mem propagatemark (global_State *g) { + GCObject *o = g->gray; + nw2black(o); + g->gray = *getgclist(o); /* remove from 'gray' list */ + switch (o->tt) { + case LUA_VTABLE: return traversetable(g, gco2t(o)); + case LUA_VUSERDATA: return traverseudata(g, gco2u(o)); + case LUA_VLCL: return traverseLclosure(g, gco2lcl(o)); + case LUA_VCCL: return traverseCclosure(g, gco2ccl(o)); + case LUA_VPROTO: return traverseproto(g, gco2p(o)); + case LUA_VTHREAD: return traversethread(g, gco2th(o)); + default: lua_assert(0); return 0; + } +} + + +static lu_mem propagateall (global_State *g) { + lu_mem tot = 0; + while (g->gray) + tot += propagatemark(g); + return tot; +} + + +/* +** Traverse all ephemeron tables propagating marks from keys to values. +** Repeat until it converges, that is, nothing new is marked. 'dir' +** inverts the direction of the traversals, trying to speed up +** convergence on chains in the same table. +** +*/ +static void convergeephemerons (global_State *g) { + int changed; + int dir = 0; + do { + GCObject *w; + GCObject *next = g->ephemeron; /* get ephemeron list */ + g->ephemeron = NULL; /* tables may return to this list when traversed */ + changed = 0; + while ((w = next) != NULL) { /* for each ephemeron table */ + Table *h = gco2t(w); + next = h->gclist; /* list is rebuilt during loop */ + nw2black(h); /* out of the list (for now) */ + if (traverseephemeron(g, h, dir)) { /* marked some value? */ + propagateall(g); /* propagate changes */ + changed = 1; /* will have to revisit all ephemeron tables */ + } + } + dir = !dir; /* invert direction next time */ + } while (changed); /* repeat until no more changes */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Sweep Functions +** ======================================================= +*/ + + +/* +** clear entries with unmarked keys from all weaktables in list 'l' +*/ +static void clearbykeys (global_State *g, GCObject *l) { + for (; l; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *limit = gnodelast(h); + Node *n; + for (n = gnode(h, 0); n < limit; n++) { + if (iscleared(g, gckeyN(n))) /* unmarked key? */ + setempty(gval(n)); /* remove entry */ + if (isempty(gval(n))) /* is entry empty? */ + clearkey(n); /* clear its key */ + } + } +} + + +/* +** clear entries with unmarked values from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + unsigned int i; + unsigned int asize = luaH_realasize(h); + for (i = 0; i < asize; i++) { + TValue *o = &h->array[i]; + if (iscleared(g, gcvalueN(o))) /* value was collected? */ + setempty(o); /* remove entry */ + } + for (n = gnode(h, 0); n < limit; n++) { + if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ + setempty(gval(n)); /* remove entry */ + if (isempty(gval(n))) /* is entry empty? */ + clearkey(n); /* clear its key */ + } + } +} + + +static void freeupval (lua_State *L, UpVal *uv) { + if (upisopen(uv)) + luaF_unlinkupval(uv); + luaM_free(L, uv); +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->tt) { + case LUA_VPROTO: + luaF_freeproto(L, gco2p(o)); + break; + case LUA_VUPVAL: + freeupval(L, gco2upv(o)); + break; + case LUA_VLCL: { + LClosure *cl = gco2lcl(o); + luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); + break; + } + case LUA_VCCL: { + CClosure *cl = gco2ccl(o); + luaM_freemem(L, cl, sizeCclosure(cl->nupvalues)); + break; + } + case LUA_VTABLE: + luaH_free(L, gco2t(o)); + break; + case LUA_VTHREAD: + luaE_freethread(L, gco2th(o)); + break; + case LUA_VUSERDATA: { + Udata *u = gco2u(o); + luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); + break; + } + case LUA_VSHRSTR: { + TString *ts = gco2ts(o); + luaS_remove(L, ts); /* remove it from hash table */ + luaM_freemem(L, ts, sizelstring(ts->shrlen)); + break; + } + case LUA_VLNGSTR: { + TString *ts = gco2ts(o); + luaM_freemem(L, ts, sizelstring(ts->u.lnglen)); + break; + } + default: lua_assert(0); + } +} + + +/* +** sweep at most 'countin' elements from a list of GCObjects erasing dead +** objects, where a dead object is one marked with the old (non current) +** white; change all non-dead objects back to white, preparing for next +** collection cycle. Return where to continue the traversal or NULL if +** list is finished. ('*countout' gets the number of elements traversed.) +*/ +static GCObject **sweeplist (lua_State *L, GCObject **p, int countin, + int *countout) { + global_State *g = G(L); + int ow = otherwhite(g); + int i; + int white = luaC_white(g); /* current white */ + for (i = 0; *p != NULL && i < countin; i++) { + GCObject *curr = *p; + int marked = curr->marked; + if (isdeadm(ow, marked)) { /* is 'curr' dead? */ + *p = curr->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { /* change mark to 'white' */ + curr->marked = cast_byte((marked & ~maskgcbits) | white); + p = &curr->next; /* go to next element */ + } + } + if (countout) + *countout = i; /* number of elements traversed */ + return (*p == NULL) ? NULL : p; +} + + +/* +** sweep a list until a live object (or end of list) +*/ +static GCObject **sweeptolive (lua_State *L, GCObject **p) { + GCObject **old = p; + do { + p = sweeplist(L, p, 1, NULL); + } while (p == old); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Finalization +** ======================================================= +*/ + +/* +** If possible, shrink string table. +*/ +static void checkSizes (lua_State *L, global_State *g) { + if (!g->gcemergency) { + if (g->strt.nuse < g->strt.size / 4) { /* string table too big? */ + l_mem olddebt = g->GCdebt; + luaS_resize(L, g->strt.size / 2); + g->GCestimate += g->GCdebt - olddebt; /* correct estimate */ + } + } +} + + +/* +** Get the next udata to be finalized from the 'tobefnz' list, and +** link it back into the 'allgc' list. +*/ +static GCObject *udata2finalize (global_State *g) { + GCObject *o = g->tobefnz; /* get first element */ + lua_assert(tofinalize(o)); + g->tobefnz = o->next; /* remove it from 'tobefnz' list */ + o->next = g->allgc; /* return it to 'allgc' list */ + g->allgc = o; + resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ + if (issweepphase(g)) + makewhite(g, o); /* "sweep" object */ + else if (getage(o) == G_OLD1) + g->firstold1 = o; /* it is the first OLD1 object in the list */ + return o; +} + + +static void dothecall (lua_State *L, void *ud) { + UNUSED(ud); + luaD_callnoyield(L, L->top.p - 2, 0); +} + + +static void GCTM (lua_State *L) { + global_State *g = G(L); + const TValue *tm; + TValue v; + lua_assert(!g->gcemergency); + setgcovalue(L, &v, udata2finalize(g)); + tm = luaT_gettmbyobj(L, &v, TM_GC); + if (!notm(tm)) { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; + int oldgcstp = g->gcstp; + g->gcstp |= GCSTPGC; /* avoid GC steps */ + L->allowhook = 0; /* stop debug hooks during GC metamethod */ + setobj2s(L, L->top.p++, tm); /* push finalizer... */ + setobj2s(L, L->top.p++, &v); /* ... and its argument */ + L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top.p - 2), 0); + L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ + L->allowhook = oldah; /* restore hooks */ + g->gcstp = oldgcstp; /* restore state */ + if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ + luaE_warnerror(L, "__gc"); + L->top.p--; /* pops error object */ + } + } +} + + +/* +** Call a few finalizers +*/ +static int runafewfinalizers (lua_State *L, int n) { + global_State *g = G(L); + int i; + for (i = 0; i < n && g->tobefnz; i++) + GCTM(L); /* call one finalizer */ + return i; +} + + +/* +** call all pending finalizers +*/ +static void callallpendingfinalizers (lua_State *L) { + global_State *g = G(L); + while (g->tobefnz) + GCTM(L); +} + + +/* +** find last 'next' field in list 'p' list (to add elements in its end) +*/ +static GCObject **findlast (GCObject **p) { + while (*p != NULL) + p = &(*p)->next; + return p; +} + + +/* +** Move all unreachable objects (or 'all' objects) that need +** finalization from list 'finobj' to list 'tobefnz' (to be finalized). +** (Note that objects after 'finobjold1' cannot be white, so they +** don't need to be traversed. In incremental mode, 'finobjold1' is NULL, +** so the whole list is traversed.) +*/ +static void separatetobefnz (global_State *g, int all) { + GCObject *curr; + GCObject **p = &g->finobj; + GCObject **lastnext = findlast(&g->tobefnz); + while ((curr = *p) != g->finobjold1) { /* traverse all finalizable objects */ + lua_assert(tofinalize(curr)); + if (!(iswhite(curr) || all)) /* not being collected? */ + p = &curr->next; /* don't bother with it */ + else { + if (curr == g->finobjsur) /* removing 'finobjsur'? */ + g->finobjsur = curr->next; /* correct it */ + *p = curr->next; /* remove 'curr' from 'finobj' list */ + curr->next = *lastnext; /* link at the end of 'tobefnz' list */ + *lastnext = curr; + lastnext = &curr->next; + } + } +} + + +/* +** If pointer 'p' points to 'o', move it to the next element. +*/ +static void checkpointer (GCObject **p, GCObject *o) { + if (o == *p) + *p = o->next; +} + + +/* +** Correct pointers to objects inside 'allgc' list when +** object 'o' is being removed from the list. +*/ +static void correctpointers (global_State *g, GCObject *o) { + checkpointer(&g->survival, o); + checkpointer(&g->old1, o); + checkpointer(&g->reallyold, o); + checkpointer(&g->firstold1, o); +} + + +/* +** if object 'o' has a finalizer, remove it from 'allgc' list (must +** search the list to find it) and link it in 'finobj' list. +*/ +void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { + global_State *g = G(L); + if (tofinalize(o) || /* obj. is already marked... */ + gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */ + (g->gcstp & GCSTPCLS)) /* or closing state? */ + return; /* nothing to be done */ + else { /* move 'o' to 'finobj' list */ + GCObject **p; + if (issweepphase(g)) { + makewhite(g, o); /* "sweep" object 'o' */ + if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ + g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ + } + else + correctpointers(g, o); + /* search for pointer pointing to 'o' */ + for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } + *p = o->next; /* remove 'o' from 'allgc' list */ + o->next = g->finobj; /* link it in 'finobj' list */ + g->finobj = o; + l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generational Collector +** ======================================================= +*/ + + +/* +** Set the "time" to wait before starting a new GC cycle; cycle will +** start when memory use hits the threshold of ('estimate' * pause / +** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero, +** because Lua cannot even start with less than PAUSEADJ bytes). +*/ +static void setpause (global_State *g) { + l_mem threshold, debt; + int pause = getgcparam(g->gcpause); + l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ + lua_assert(estimate > 0); + threshold = (pause < MAX_LMEM / estimate) /* overflow? */ + ? estimate * pause /* no overflow */ + : MAX_LMEM; /* overflow; truncate to maximum */ + debt = gettotalbytes(g) - threshold; + if (debt > 0) debt = 0; + luaE_setdebt(g, debt); +} + + +/* +** Sweep a list of objects to enter generational mode. Deletes dead +** objects and turns the non dead to old. All non-dead threads---which +** are now old---must be in a gray list. Everything else is not in a +** gray list. Open upvalues are also kept gray. +*/ +static void sweep2old (lua_State *L, GCObject **p) { + GCObject *curr; + global_State *g = G(L); + while ((curr = *p) != NULL) { + if (iswhite(curr)) { /* is 'curr' dead? */ + lua_assert(isdead(g, curr)); + *p = curr->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { /* all surviving objects become old */ + setage(curr, G_OLD); + if (curr->tt == LUA_VTHREAD) { /* threads must be watched */ + lua_State *th = gco2th(curr); + linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ + } + else if (curr->tt == LUA_VUPVAL && upisopen(gco2upv(curr))) + set2gray(curr); /* open upvalues are always gray */ + else /* everything else is black */ + nw2black(curr); + p = &curr->next; /* go to next element */ + } + } +} + + +/* +** Sweep for generational mode. Delete dead objects. (Because the +** collection is not incremental, there are no "new white" objects +** during the sweep. So, any white object must be dead.) For +** non-dead objects, advance their ages and clear the color of +** new objects. (Old objects keep their colors.) +** The ages of G_TOUCHED1 and G_TOUCHED2 objects cannot be advanced +** here, because these old-generation objects are usually not swept +** here. They will all be advanced in 'correctgraylist'. That function +** will also remove objects turned white here from any gray list. +*/ +static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, + GCObject *limit, GCObject **pfirstold1) { + static const lu_byte nextage[] = { + G_SURVIVAL, /* from G_NEW */ + G_OLD1, /* from G_SURVIVAL */ + G_OLD1, /* from G_OLD0 */ + G_OLD, /* from G_OLD1 */ + G_OLD, /* from G_OLD (do not change) */ + G_TOUCHED1, /* from G_TOUCHED1 (do not change) */ + G_TOUCHED2 /* from G_TOUCHED2 (do not change) */ + }; + int white = luaC_white(g); + GCObject *curr; + while ((curr = *p) != limit) { + if (iswhite(curr)) { /* is 'curr' dead? */ + lua_assert(!isold(curr) && isdead(g, curr)); + *p = curr->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { /* correct mark and age */ + if (getage(curr) == G_NEW) { /* new objects go back to white */ + int marked = curr->marked & ~maskgcbits; /* erase GC bits */ + curr->marked = cast_byte(marked | G_SURVIVAL | white); + } + else { /* all other objects will be old, and so keep their color */ + setage(curr, nextage[getage(curr)]); + if (getage(curr) == G_OLD1 && *pfirstold1 == NULL) + *pfirstold1 = curr; /* first OLD1 object in the list */ + } + p = &curr->next; /* go to next element */ + } + } + return p; +} + + +/* +** Traverse a list making all its elements white and clearing their +** age. In incremental mode, all objects are 'new' all the time, +** except for fixed strings (which are always old). +*/ +static void whitelist (global_State *g, GCObject *p) { + int white = luaC_white(g); + for (; p != NULL; p = p->next) + p->marked = cast_byte((p->marked & ~maskgcbits) | white); +} + + +/* +** Correct a list of gray objects. Return pointer to where rest of the +** list should be linked. +** Because this correction is done after sweeping, young objects might +** be turned white and still be in the list. They are only removed. +** 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list; +** Non-white threads also remain on the list; 'TOUCHED2' objects become +** regular old; they and anything else are removed from the list. +*/ +static GCObject **correctgraylist (GCObject **p) { + GCObject *curr; + while ((curr = *p) != NULL) { + GCObject **next = getgclist(curr); + if (iswhite(curr)) + goto remove; /* remove all white objects */ + else if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ + lua_assert(isgray(curr)); + nw2black(curr); /* make it black, for next barrier */ + changeage(curr, G_TOUCHED1, G_TOUCHED2); + goto remain; /* keep it in the list and go to next element */ + } + else if (curr->tt == LUA_VTHREAD) { + lua_assert(isgray(curr)); + goto remain; /* keep non-white threads on the list */ + } + else { /* everything else is removed */ + lua_assert(isold(curr)); /* young objects should be white here */ + if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */ + changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ + nw2black(curr); /* make object black (to be removed) */ + goto remove; + } + remove: *p = *next; continue; + remain: p = next; continue; + } + return p; +} + + +/* +** Correct all gray lists, coalescing them into 'grayagain'. +*/ +static void correctgraylists (global_State *g) { + GCObject **list = correctgraylist(&g->grayagain); + *list = g->weak; g->weak = NULL; + list = correctgraylist(list); + *list = g->allweak; g->allweak = NULL; + list = correctgraylist(list); + *list = g->ephemeron; g->ephemeron = NULL; + correctgraylist(list); +} + + +/* +** Mark black 'OLD1' objects when starting a new young collection. +** Gray objects are already in some gray list, and so will be visited +** in the atomic step. +*/ +static void markold (global_State *g, GCObject *from, GCObject *to) { + GCObject *p; + for (p = from; p != to; p = p->next) { + if (getage(p) == G_OLD1) { + lua_assert(!iswhite(p)); + changeage(p, G_OLD1, G_OLD); /* now they are old */ + if (isblack(p)) + reallymarkobject(g, p); + } + } +} + + +/* +** Finish a young-generation collection. +*/ +static void finishgencycle (lua_State *L, global_State *g) { + correctgraylists(g); + checkSizes(L, g); + g->gcstate = GCSpropagate; /* skip restart */ + if (!g->gcemergency) + callallpendingfinalizers(L); +} + + +/* +** Does a young collection. First, mark 'OLD1' objects. Then does the +** atomic step. Then, sweep all lists and advance pointers. Finally, +** finish the collection. +*/ +static void youngcollection (lua_State *L, global_State *g) { + GCObject **psurvival; /* to point to first non-dead survival object */ + GCObject *dummy; /* dummy out parameter to 'sweepgen' */ + lua_assert(g->gcstate == GCSpropagate); + if (g->firstold1) { /* are there regular OLD1 objects? */ + markold(g, g->firstold1, g->reallyold); /* mark them */ + g->firstold1 = NULL; /* no more OLD1 objects (for now) */ + } + markold(g, g->finobj, g->finobjrold); + markold(g, g->tobefnz, NULL); + atomic(L); + + /* sweep nursery and get a pointer to its last live element */ + g->gcstate = GCSswpallgc; + psurvival = sweepgen(L, g, &g->allgc, g->survival, &g->firstold1); + /* sweep 'survival' */ + sweepgen(L, g, psurvival, g->old1, &g->firstold1); + g->reallyold = g->old1; + g->old1 = *psurvival; /* 'survival' survivals are old now */ + g->survival = g->allgc; /* all news are survivals */ + + /* repeat for 'finobj' lists */ + dummy = NULL; /* no 'firstold1' optimization for 'finobj' lists */ + psurvival = sweepgen(L, g, &g->finobj, g->finobjsur, &dummy); + /* sweep 'survival' */ + sweepgen(L, g, psurvival, g->finobjold1, &dummy); + g->finobjrold = g->finobjold1; + g->finobjold1 = *psurvival; /* 'survival' survivals are old now */ + g->finobjsur = g->finobj; /* all news are survivals */ + + sweepgen(L, g, &g->tobefnz, NULL, &dummy); + finishgencycle(L, g); +} + + +/* +** Clears all gray lists, sweeps objects, and prepare sublists to enter +** generational mode. The sweeps remove dead objects and turn all +** surviving objects to old. Threads go back to 'grayagain'; everything +** else is turned black (not in any gray list). +*/ +static void atomic2gen (lua_State *L, global_State *g) { + cleargraylists(g); + /* sweep all elements making them old */ + g->gcstate = GCSswpallgc; + sweep2old(L, &g->allgc); + /* everything alive now is old */ + g->reallyold = g->old1 = g->survival = g->allgc; + g->firstold1 = NULL; /* there are no OLD1 objects anywhere */ + + /* repeat for 'finobj' lists */ + sweep2old(L, &g->finobj); + g->finobjrold = g->finobjold1 = g->finobjsur = g->finobj; + + sweep2old(L, &g->tobefnz); + + g->gckind = KGC_GEN; + g->lastatomic = 0; + g->GCestimate = gettotalbytes(g); /* base for memory control */ + finishgencycle(L, g); +} + + +/* +** Set debt for the next minor collection, which will happen when +** memory grows 'genminormul'%. +*/ +static void setminordebt (global_State *g) { + luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul)); +} + + +/* +** Enter generational mode. Must go until the end of an atomic cycle +** to ensure that all objects are correctly marked and weak tables +** are cleared. Then, turn all objects into old and finishes the +** collection. +*/ +static lu_mem entergen (lua_State *L, global_State *g) { + lu_mem numobjs; + luaC_runtilstate(L, bitmask(GCSpause)); /* prepare to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ + numobjs = atomic(L); /* propagates all and then do the atomic stuff */ + atomic2gen(L, g); + setminordebt(g); /* set debt assuming next cycle will be minor */ + return numobjs; +} + + +/* +** Enter incremental mode. Turn all objects white, make all +** intermediate lists point to NULL (to avoid invalid pointers), +** and go to the pause state. +*/ +static void enterinc (global_State *g) { + whitelist(g, g->allgc); + g->reallyold = g->old1 = g->survival = NULL; + whitelist(g, g->finobj); + whitelist(g, g->tobefnz); + g->finobjrold = g->finobjold1 = g->finobjsur = NULL; + g->gcstate = GCSpause; + g->gckind = KGC_INC; + g->lastatomic = 0; +} + + +/* +** Change collector mode to 'newmode'. +*/ +void luaC_changemode (lua_State *L, int newmode) { + global_State *g = G(L); + if (newmode != g->gckind) { + if (newmode == KGC_GEN) /* entering generational mode? */ + entergen(L, g); + else + enterinc(g); /* entering incremental mode */ + } + g->lastatomic = 0; +} + + +/* +** Does a full collection in generational mode. +*/ +static lu_mem fullgen (lua_State *L, global_State *g) { + enterinc(g); + return entergen(L, g); +} + + +/* +** Does a major collection after last collection was a "bad collection". +** +** When the program is building a big structure, it allocates lots of +** memory but generates very little garbage. In those scenarios, +** the generational mode just wastes time doing small collections, and +** major collections are frequently what we call a "bad collection", a +** collection that frees too few objects. To avoid the cost of switching +** between generational mode and the incremental mode needed for full +** (major) collections, the collector tries to stay in incremental mode +** after a bad collection, and to switch back to generational mode only +** after a "good" collection (one that traverses less than 9/8 objects +** of the previous one). +** The collector must choose whether to stay in incremental mode or to +** switch back to generational mode before sweeping. At this point, it +** does not know the real memory in use, so it cannot use memory to +** decide whether to return to generational mode. Instead, it uses the +** number of objects traversed (returned by 'atomic') as a proxy. The +** field 'g->lastatomic' keeps this count from the last collection. +** ('g->lastatomic != 0' also means that the last collection was bad.) +*/ +static void stepgenfull (lua_State *L, global_State *g) { + lu_mem newatomic; /* count of traversed objects */ + lu_mem lastatomic = g->lastatomic; /* count from last collection */ + if (g->gckind == KGC_GEN) /* still in generational mode? */ + enterinc(g); /* enter incremental mode */ + luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ + newatomic = atomic(L); /* mark everybody */ + if (newatomic < lastatomic + (lastatomic >> 3)) { /* good collection? */ + atomic2gen(L, g); /* return to generational mode */ + setminordebt(g); + } + else { /* another bad collection; stay in incremental mode */ + g->GCestimate = gettotalbytes(g); /* first estimate */ + entersweep(L); + luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ + setpause(g); + g->lastatomic = newatomic; + } +} + + +/* +** Does a generational "step". +** Usually, this means doing a minor collection and setting the debt to +** make another collection when memory grows 'genminormul'% larger. +** +** However, there are exceptions. If memory grows 'genmajormul'% +** larger than it was at the end of the last major collection (kept +** in 'g->GCestimate'), the function does a major collection. At the +** end, it checks whether the major collection was able to free a +** decent amount of memory (at least half the growth in memory since +** previous major collection). If so, the collector keeps its state, +** and the next collection will probably be minor again. Otherwise, +** we have what we call a "bad collection". In that case, set the field +** 'g->lastatomic' to signal that fact, so that the next collection will +** go to 'stepgenfull'. +** +** 'GCdebt <= 0' means an explicit call to GC step with "size" zero; +** in that case, do a minor collection. +*/ +static void genstep (lua_State *L, global_State *g) { + if (g->lastatomic != 0) /* last collection was a bad one? */ + stepgenfull(L, g); /* do a full step */ + else { + lu_mem majorbase = g->GCestimate; /* memory after last major collection */ + lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); + if (g->GCdebt > 0 && gettotalbytes(g) > majorbase + majorinc) { + lu_mem numobjs = fullgen(L, g); /* do a major collection */ + if (gettotalbytes(g) < majorbase + (majorinc / 2)) { + /* collected at least half of memory growth since last major + collection; keep doing minor collections. */ + lua_assert(g->lastatomic == 0); + } + else { /* bad collection */ + g->lastatomic = numobjs; /* signal that last collection was bad */ + setpause(g); /* do a long wait for next (major) collection */ + } + } + else { /* regular case; do a minor collection */ + youngcollection(L, g); + setminordebt(g); + g->GCestimate = majorbase; /* preserve base value */ + } + } + lua_assert(isdecGCmodegen(g)); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** GC control +** ======================================================= +*/ + + +/* +** Enter first sweep phase. +** The call to 'sweeptolive' makes the pointer point to an object +** inside the list (instead of to the header), so that the real sweep do +** not need to skip objects created between "now" and the start of the +** real sweep. +*/ +static void entersweep (lua_State *L) { + global_State *g = G(L); + g->gcstate = GCSswpallgc; + lua_assert(g->sweepgc == NULL); + g->sweepgc = sweeptolive(L, &g->allgc); +} + + +/* +** Delete all objects in list 'p' until (but not including) object +** 'limit'. +*/ +static void deletelist (lua_State *L, GCObject *p, GCObject *limit) { + while (p != limit) { + GCObject *next = p->next; + freeobj(L, p); + p = next; + } +} + + +/* +** Call all finalizers of the objects in the given Lua state, and +** then free all objects, except for the main thread. +*/ +void luaC_freeallobjects (lua_State *L) { + global_State *g = G(L); + g->gcstp = GCSTPCLS; /* no extra finalizers after here */ + luaC_changemode(L, KGC_INC); + separatetobefnz(g, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); + callallpendingfinalizers(L); + deletelist(L, g->allgc, obj2gco(g->mainthread)); + lua_assert(g->finobj == NULL); /* no new finalizers */ + deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ + lua_assert(g->strt.nuse == 0); +} + + +static lu_mem atomic (lua_State *L) { + global_State *g = G(L); + lu_mem work = 0; + GCObject *origweak, *origall; + GCObject *grayagain = g->grayagain; /* save original list */ + g->grayagain = NULL; + lua_assert(g->ephemeron == NULL && g->weak == NULL); + lua_assert(!iswhite(g->mainthread)); + g->gcstate = GCSatomic; + markobject(g, L); /* mark running thread */ + /* registry and global metatables may be changed by API */ + markvalue(g, &g->l_registry); + markmt(g); /* mark global metatables */ + work += propagateall(g); /* empties 'gray' list */ + /* remark occasional upvalues of (maybe) dead threads */ + work += remarkupvals(g); + work += propagateall(g); /* propagate changes */ + g->gray = grayagain; + work += propagateall(g); /* traverse 'grayagain' list */ + convergeephemerons(g); + /* at this point, all strongly accessible objects are marked. */ + /* Clear values from weak tables, before checking finalizers */ + clearbyvalues(g, g->weak, NULL); + clearbyvalues(g, g->allweak, NULL); + origweak = g->weak; origall = g->allweak; + separatetobefnz(g, 0); /* separate objects to be finalized */ + work += markbeingfnz(g); /* mark objects that will be finalized */ + work += propagateall(g); /* remark, to propagate 'resurrection' */ + convergeephemerons(g); + /* at this point, all resurrected objects are marked. */ + /* remove dead objects from weak tables */ + clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ + clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */ + /* clear values from resurrected weak tables */ + clearbyvalues(g, g->weak, origweak); + clearbyvalues(g, g->allweak, origall); + luaS_clearcache(g); + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ + lua_assert(g->gray == NULL); + return work; /* estimate of slots marked by 'atomic' */ +} + + +static int sweepstep (lua_State *L, global_State *g, + int nextstate, GCObject **nextlist) { + if (g->sweepgc) { + l_mem olddebt = g->GCdebt; + int count; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX, &count); + g->GCestimate += g->GCdebt - olddebt; /* update estimate */ + return count; + } + else { /* enter next state */ + g->gcstate = nextstate; + g->sweepgc = nextlist; + return 0; /* no work done */ + } +} + + +static lu_mem singlestep (lua_State *L) { + global_State *g = G(L); + lu_mem work; + lua_assert(!g->gcstopem); /* collector is not reentrant */ + g->gcstopem = 1; /* no emergency collections while collecting */ + switch (g->gcstate) { + case GCSpause: { + restartcollection(g); + g->gcstate = GCSpropagate; + work = 1; + break; + } + case GCSpropagate: { + if (g->gray == NULL) { /* no more gray objects? */ + g->gcstate = GCSenteratomic; /* finish propagate phase */ + work = 0; + } + else + work = propagatemark(g); /* traverse one gray object */ + break; + } + case GCSenteratomic: { + work = atomic(L); /* work is what was traversed by 'atomic' */ + entersweep(L); + g->GCestimate = gettotalbytes(g); /* first estimate */ + break; + } + case GCSswpallgc: { /* sweep "regular" objects */ + work = sweepstep(L, g, GCSswpfinobj, &g->finobj); + break; + } + case GCSswpfinobj: { /* sweep objects with finalizers */ + work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz); + break; + } + case GCSswptobefnz: { /* sweep objects to be finalized */ + work = sweepstep(L, g, GCSswpend, NULL); + break; + } + case GCSswpend: { /* finish sweeps */ + checkSizes(L, g); + g->gcstate = GCScallfin; + work = 0; + break; + } + case GCScallfin: { /* call remaining finalizers */ + if (g->tobefnz && !g->gcemergency) { + g->gcstopem = 0; /* ok collections during finalizers */ + work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; + } + else { /* emergency mode or no more finalizers */ + g->gcstate = GCSpause; /* finish collection */ + work = 0; + } + break; + } + default: lua_assert(0); return 0; + } + g->gcstopem = 0; + return work; +} + + +/* +** advances the garbage collector until it reaches a state allowed +** by 'statemask' +*/ +void luaC_runtilstate (lua_State *L, int statesmask) { + global_State *g = G(L); + while (!testbit(statesmask, g->gcstate)) + singlestep(L); +} + + + +/* +** Performs a basic incremental step. The debt and step size are +** converted from bytes to "units of work"; then the function loops +** running single steps until adding that many units of work or +** finishing a cycle (pause state). Finally, it sets the debt that +** controls when next step will be performed. +*/ +static void incstep (lua_State *L, global_State *g) { + int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */ + l_mem debt = (g->GCdebt / WORK2MEM) * stepmul; + l_mem stepsize = (g->gcstepsize <= log2maxs(l_mem)) + ? ((cast(l_mem, 1) << g->gcstepsize) / WORK2MEM) * stepmul + : MAX_LMEM; /* overflow; keep maximum value */ + do { /* repeat until pause or enough "credit" (negative debt) */ + lu_mem work = singlestep(L); /* perform one single step */ + debt -= work; + } while (debt > -stepsize && g->gcstate != GCSpause); + if (g->gcstate == GCSpause) + setpause(g); /* pause until next cycle */ + else { + debt = (debt / stepmul) * WORK2MEM; /* convert 'work units' to bytes */ + luaE_setdebt(g, debt); + } +} + +/* +** Performs a basic GC step if collector is running. (If collector is +** not running, set a reasonable debt to avoid it being called at +** every single check.) +*/ +void luaC_step (lua_State *L) { + global_State *g = G(L); + if (!gcrunning(g)) /* not running? */ + luaE_setdebt(g, -2000); + else { + if(isdecGCmodegen(g)) + genstep(L, g); + else + incstep(L, g); + } +} + + +/* +** Perform a full collection in incremental mode. +** Before running the collection, check 'keepinvariant'; if it is true, +** there may be some objects marked as black, so the collector has +** to sweep all objects to turn them back to white (as white has not +** changed, nothing will be collected). +*/ +static void fullinc (lua_State *L, global_State *g) { + if (keepinvariant(g)) /* black objects? */ + entersweep(L); /* sweep everything to turn them back to white */ + /* finish any pending sweep phase to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpause)); + luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ + g->gcstate = GCSenteratomic; /* go straight to atomic phase */ + luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ + /* estimate must be correct after a full GC cycle */ + lua_assert(g->GCestimate == gettotalbytes(g)); + luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ + setpause(g); +} + + +/* +** Performs a full GC cycle; if 'isemergency', set a flag to avoid +** some operations which could change the interpreter state in some +** unexpected ways (running finalizers and shrinking some structures). +*/ +void luaC_fullgc (lua_State *L, int isemergency) { + global_State *g = G(L); + lua_assert(!g->gcemergency); + g->gcemergency = isemergency; /* set flag */ + if (g->gckind == KGC_INC) + fullinc(L, g); + else + fullgen(L, g); + g->gcemergency = 0; +} + +/* }====================================================== */ + + diff --git a/arm9/source/lua/lgc.h b/arm9/source/lua/lgc.h new file mode 100644 index 000000000..538f6edcc --- /dev/null +++ b/arm9/source/lua/lgc.h @@ -0,0 +1,202 @@ +/* +** $Id: lgc.h $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" +#include "lstate.h" + +/* +** Collectable objects may have one of three colors: white, which means +** the object is not marked; gray, which means the object is marked, but +** its references may be not marked; and black, which means that the +** object and all its references are marked. The main invariant of the +** garbage collector, while marking objects, is that a black object can +** never point to a white one. Moreover, any gray object must be in a +** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it +** can be visited again before finishing the collection cycle. (Open +** upvalues are an exception to this rule.) These lists have no meaning +** when the invariant is not being enforced (e.g., sweep phase). +*/ + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpropagate 0 +#define GCSenteratomic 1 +#define GCSatomic 2 +#define GCSswpallgc 3 +#define GCSswpfinobj 4 +#define GCSswptobefnz 5 +#define GCSswpend 6 +#define GCScallfin 7 +#define GCSpause 8 + + +#define issweepphase(g) \ + (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) + + +/* +** macro to tell when main invariant (white objects cannot point to black +** ones) must be kept. During a collection, the sweep +** phase may break the invariant, as objects turned white may point to +** still-black objects. The invariant is restored when sweep ends and +** all objects are white again. +*/ + +#define keepinvariant(g) ((g)->gcstate <= GCSatomic) + + +/* +** some useful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast_byte(~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) + + +/* +** Layout for bit use in 'marked' field. First three bits are +** used for object "age" in generational mode. Last bit is used +** by tests. +*/ +#define WHITE0BIT 3 /* object is white (type 0) */ +#define WHITE1BIT 4 /* object is white (type 1) */ +#define BLACKBIT 5 /* object is black */ +#define FINALIZEDBIT 6 /* object has been marked for finalization */ + +#define TESTBIT 7 + + + +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) testbits((x)->marked, WHITEBITS) +#define isblack(x) testbit((x)->marked, BLACKBIT) +#define isgray(x) /* neither white nor black */ \ + (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) + +#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) + +#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) +#define isdeadm(ow,m) ((m) & (ow)) +#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) + +#define changewhite(x) ((x)->marked ^= WHITEBITS) +#define nw2black(x) \ + check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT)) + +#define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) + + +/* object age in generational mode */ +#define G_NEW 0 /* created in current cycle */ +#define G_SURVIVAL 1 /* created in previous cycle */ +#define G_OLD0 2 /* marked old by frw. barrier in this cycle */ +#define G_OLD1 3 /* first full cycle as old */ +#define G_OLD 4 /* really old object (not to be visited) */ +#define G_TOUCHED1 5 /* old object touched this cycle */ +#define G_TOUCHED2 6 /* old object touched in previous cycle */ + +#define AGEBITS 7 /* all age bits (111) */ + +#define getage(o) ((o)->marked & AGEBITS) +#define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) +#define isold(o) (getage(o) > G_SURVIVAL) + +#define changeage(o,f,t) \ + check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) + + +/* Default Values for GC parameters */ +#define LUAI_GENMAJORMUL 100 +#define LUAI_GENMINORMUL 20 + +/* wait memory to double before starting new cycle */ +#define LUAI_GCPAUSE 200 + +/* +** some gc parameters are stored divided by 4 to allow a maximum value +** up to 1023 in a 'lu_byte'. +*/ +#define getgcparam(p) ((p) * 4) +#define setgcparam(p,v) ((p) = (v) / 4) + +#define LUAI_GCMUL 100 + +/* how much to allocate before next GC step (log2) */ +#define LUAI_GCSTEPSIZE 13 /* 8 KB */ + + +/* +** Check whether the declared GC mode is generational. While in +** generational mode, the collector can go temporarily to incremental +** mode to improve performance. This is signaled by 'g->lastatomic != 0'. +*/ +#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) + + +/* +** Control when GC is running: +*/ +#define GCSTPUSR 1 /* bit true when GC stopped by user */ +#define GCSTPGC 2 /* bit true when GC stopped by itself */ +#define GCSTPCLS 4 /* bit true when closing Lua state */ +#define gcrunning(g) ((g)->gcstp == 0) + + +/* +** Does one step of collection when debt becomes positive. 'pre'/'pos' +** allows some adjustments to be done only when needed. macro +** 'condchangemem' is used only for heavy tests (forcing a full +** GC cycle on every opportunity) +*/ +#define luaC_condGC(L,pre,pos) \ + { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ + condchangemem(L,pre,pos); } + +/* more often than not, 'pre'/'pos' are empty */ +#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) + + +#define luaC_objbarrier(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? \ + luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) + +#define luaC_barrier(L,p,v) ( \ + iscollectable(v) ? luaC_objbarrier(L,p,gcvalue(v)) : cast_void(0)) + +#define luaC_objbarrierback(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? luaC_barrierback_(L,p) : cast_void(0)) + +#define luaC_barrierback(L,p,v) ( \ + iscollectable(v) ? luaC_objbarrierback(L, p, gcvalue(v)) : cast_void(0)) + +LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_freeallobjects (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); +LUAI_FUNC GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, + size_t offset); +LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); + + +#endif diff --git a/arm9/source/lua/linit.c b/arm9/source/lua/linit.c new file mode 100644 index 000000000..69808f84f --- /dev/null +++ b/arm9/source/lua/linit.c @@ -0,0 +1,65 @@ +/* +** $Id: linit.c $ +** Initialization of libraries for lua.c and other clients +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +/* +** If you embed Lua in your program and need to open the standard +** libraries, call luaL_openlibs in your program. If you need a +** different set of libraries, copy this file to your project and edit +** it to suit your needs. +** +** You can also *preload* libraries, so that a later 'require' can +** open the library, which is already linked to the application. +** For that, do the following code: +** +** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); +** lua_pushcfunction(L, luaopen_modname); +** lua_setfield(L, -2, modname); +** lua_pop(L, 1); // remove PRELOAD table +*/ + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +/* +** these libs are loaded by lua.c and are readily available to any Lua +** program +*/ +static const luaL_Reg loadedlibs[] = { + {LUA_GNAME, luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_UTF8LIBNAME, luaopen_utf8}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib; + /* "require" functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } +} + diff --git a/arm9/source/lua/ljumptab.h b/arm9/source/lua/ljumptab.h new file mode 100644 index 000000000..8306f250c --- /dev/null +++ b/arm9/source/lua/ljumptab.h @@ -0,0 +1,112 @@ +/* +** $Id: ljumptab.h $ +** Jump Table for the Lua interpreter +** See Copyright Notice in lua.h +*/ + + +#undef vmdispatch +#undef vmcase +#undef vmbreak + +#define vmdispatch(x) goto *disptab[x]; + +#define vmcase(l) L_##l: + +#define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); + + +static const void *const disptab[NUM_OPCODES] = { + +#if 0 +** you can update the following list with this command: +** +** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h +** +#endif + +&&L_OP_MOVE, +&&L_OP_LOADI, +&&L_OP_LOADF, +&&L_OP_LOADK, +&&L_OP_LOADKX, +&&L_OP_LOADFALSE, +&&L_OP_LFALSESKIP, +&&L_OP_LOADTRUE, +&&L_OP_LOADNIL, +&&L_OP_GETUPVAL, +&&L_OP_SETUPVAL, +&&L_OP_GETTABUP, +&&L_OP_GETTABLE, +&&L_OP_GETI, +&&L_OP_GETFIELD, +&&L_OP_SETTABUP, +&&L_OP_SETTABLE, +&&L_OP_SETI, +&&L_OP_SETFIELD, +&&L_OP_NEWTABLE, +&&L_OP_SELF, +&&L_OP_ADDI, +&&L_OP_ADDK, +&&L_OP_SUBK, +&&L_OP_MULK, +&&L_OP_MODK, +&&L_OP_POWK, +&&L_OP_DIVK, +&&L_OP_IDIVK, +&&L_OP_BANDK, +&&L_OP_BORK, +&&L_OP_BXORK, +&&L_OP_SHRI, +&&L_OP_SHLI, +&&L_OP_ADD, +&&L_OP_SUB, +&&L_OP_MUL, +&&L_OP_MOD, +&&L_OP_POW, +&&L_OP_DIV, +&&L_OP_IDIV, +&&L_OP_BAND, +&&L_OP_BOR, +&&L_OP_BXOR, +&&L_OP_SHL, +&&L_OP_SHR, +&&L_OP_MMBIN, +&&L_OP_MMBINI, +&&L_OP_MMBINK, +&&L_OP_UNM, +&&L_OP_BNOT, +&&L_OP_NOT, +&&L_OP_LEN, +&&L_OP_CONCAT, +&&L_OP_CLOSE, +&&L_OP_TBC, +&&L_OP_JMP, +&&L_OP_EQ, +&&L_OP_LT, +&&L_OP_LE, +&&L_OP_EQK, +&&L_OP_EQI, +&&L_OP_LTI, +&&L_OP_LEI, +&&L_OP_GTI, +&&L_OP_GEI, +&&L_OP_TEST, +&&L_OP_TESTSET, +&&L_OP_CALL, +&&L_OP_TAILCALL, +&&L_OP_RETURN, +&&L_OP_RETURN0, +&&L_OP_RETURN1, +&&L_OP_FORLOOP, +&&L_OP_FORPREP, +&&L_OP_TFORPREP, +&&L_OP_TFORCALL, +&&L_OP_TFORLOOP, +&&L_OP_SETLIST, +&&L_OP_CLOSURE, +&&L_OP_VARARG, +&&L_OP_VARARGPREP, +&&L_OP_EXTRAARG + +}; diff --git a/arm9/source/lua/llex.c b/arm9/source/lua/llex.c new file mode 100644 index 000000000..5fc39a5cd --- /dev/null +++ b/arm9/source/lua/llex.c @@ -0,0 +1,581 @@ +/* +** $Id: llex.c $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#define llex_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +static const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "//", "..", "...", "==", ">=", "<=", "~=", + "<<", ">>", "::", "", + "", "", "", "" +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static l_noret lexerror (LexState *ls, const char *msg, int token); + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { + size_t newsize; + if (luaZ_sizebuffer(b) >= MAX_SIZE/2) + lexerror(ls, "lexical element too long", 0); + newsize = luaZ_sizebuffer(b) * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[luaZ_bufflen(b)++] = cast_char(c); +} + + +void luaX_init (lua_State *L) { + int i; + TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */ + luaC_fix(L, obj2gco(e)); /* never collect this name */ + for (i=0; iextra = cast_byte(i+1); /* reserved word */ + } +} + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { /* single-byte symbols? */ + if (lisprint(token)) + return luaO_pushfstring(ls->L, "'%c'", token); + else /* control character */ + return luaO_pushfstring(ls->L, "'<\\%d>'", token); + } + else { + const char *s = luaX_tokens[token - FIRST_RESERVED]; + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return luaO_pushfstring(ls->L, "'%s'", s); + else /* names, strings, and numerals */ + return s; + } +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: case TK_STRING: + case TK_FLT: case TK_INT: + save(ls, '\0'); + return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff)); + default: + return luaX_token2str(ls, token); + } +} + + +static l_noret lexerror (LexState *ls, const char *msg, int token) { + msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber); + if (token) + luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +l_noret luaX_syntaxerror (LexState *ls, const char *msg) { + lexerror(ls, msg, ls->t.token); +} + + +/* +** Creates a new string and anchors it in scanner's table so that it +** will not be collected until the end of the compilation; by that time +** it should be anchored somewhere. It also internalizes long strings, +** ensuring there is only one copy of each unique string. The table +** here is used as a set: the string enters as the key, while its value +** is irrelevant. We use the string itself as the value only because it +** is a TValue readily available. Later, the code generation can change +** this value. +*/ +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); /* create new string */ + const TValue *o = luaH_getstr(ls->h, ts); + if (!ttisnil(o)) /* string already present? */ + ts = keystrval(nodefromval(o)); /* get saved copy */ + else { /* not in use yet */ + TValue *stv = s2v(L->top.p++); /* reserve stack space for string */ + setsvalue(L, stv, ts); /* temporarily anchor the string */ + luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */ + /* table is not a metatable, so it does not need to invalidate cache */ + luaC_checkGC(L); + L->top.p--; /* remove string from stack */ + } + return ts; +} + + +/* +** increment line number and skips newline sequence (any of +** \n, \r, \n\r, or \r\n) +*/ +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip '\n' or '\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip '\n\r' or '\r\n' */ + if (++ls->linenumber >= MAX_INT) + lexerror(ls, "chunk has too many lines", 0); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, + int firstchar) { + ls->t.token = 0; + ls->L = L; + ls->current = firstchar; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */ + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + +static int check_next1 (LexState *ls, int c) { + if (ls->current == c) { + next(ls); + return 1; + } + else return 0; +} + + +/* +** Check whether current char is in set 'set' (with two chars) and +** saves it +*/ +static int check_next2 (LexState *ls, const char *set) { + lua_assert(set[2] == '\0'); + if (ls->current == set[0] || ls->current == set[1]) { + save_and_next(ls); + return 1; + } + else return 0; +} + + +/* LUA_NUMBER */ +/* +** This function is quite liberal in what it accepts, as 'luaO_str2num' +** will reject ill-formed numerals. Roughly, it accepts the following +** pattern: +** +** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))* +** +** The only tricky part is to accept [+-] only after a valid exponent +** mark, to avoid reading '3-4' or '0xe+1' as a single number. +** +** The caller might have already read an initial dot. +*/ +static int read_numeral (LexState *ls, SemInfo *seminfo) { + TValue obj; + const char *expo = "Ee"; + int first = ls->current; + lua_assert(lisdigit(ls->current)); + save_and_next(ls); + if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */ + expo = "Pp"; + for (;;) { + if (check_next2(ls, expo)) /* exponent mark? */ + check_next2(ls, "-+"); /* optional exponent sign */ + else if (lisxdigit(ls->current) || ls->current == '.') /* '%x|%.' */ + save_and_next(ls); + else break; + } + if (lislalpha(ls->current)) /* is numeral touching a letter? */ + save_and_next(ls); /* force an error */ + save(ls, '\0'); + if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */ + lexerror(ls, "malformed number", TK_FLT); + if (ttisinteger(&obj)) { + seminfo->i = ivalue(&obj); + return TK_INT; + } + else { + lua_assert(ttisfloat(&obj)); + seminfo->r = fltvalue(&obj); + return TK_FLT; + } +} + + +/* +** read a sequence '[=*[' or ']=*]', leaving the last bracket. If +** sequence is well formed, return its number of '='s + 2; otherwise, +** return 1 if it is a single bracket (no '='s and no 2nd bracket); +** otherwise (an unfinished '[==...') return 0. +*/ +static size_t skip_sep (LexState *ls) { + size_t count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count + 2 + : (count == 0) ? 1 + : 0; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { + int line = ls->linenumber; /* initial line (for error message) */ + save_and_next(ls); /* skip 2nd '[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: { /* error */ + const char *what = (seminfo ? "string" : "comment"); + const char *msg = luaO_pushfstring(ls->L, + "unfinished long %s (starting at line %d)", what, line); + lexerror(ls, msg, TK_EOS); + break; /* to avoid warnings */ + } + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd ']' */ + goto endloop; + } + break; + } + case '\n': case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, + luaZ_bufflen(ls->buff) - 2 * sep); +} + + +static void esccheck (LexState *ls, int c, const char *msg) { + if (!c) { + if (ls->current != EOZ) + save_and_next(ls); /* add current to buffer for error message */ + lexerror(ls, msg, TK_STRING); + } +} + + +static int gethexa (LexState *ls) { + save_and_next(ls); + esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected"); + return luaO_hexavalue(ls->current); +} + + +static int readhexaesc (LexState *ls) { + int r = gethexa(ls); + r = (r << 4) + gethexa(ls); + luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */ + return r; +} + + +static unsigned long readutf8esc (LexState *ls) { + unsigned long r; + int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ + save_and_next(ls); /* skip 'u' */ + esccheck(ls, ls->current == '{', "missing '{'"); + r = gethexa(ls); /* must have at least one digit */ + while (cast_void(save_and_next(ls)), lisxdigit(ls->current)) { + i++; + esccheck(ls, r <= (0x7FFFFFFFu >> 4), "UTF-8 value too large"); + r = (r << 4) + luaO_hexavalue(ls->current); + } + esccheck(ls, ls->current == '}', "missing '}'"); + next(ls); /* skip '}' */ + luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */ + return r; +} + + +static void utf8esc (LexState *ls) { + char buff[UTF8BUFFSZ]; + int n = luaO_utf8esc(buff, readutf8esc(ls)); + for (; n > 0; n--) /* add 'buff' to string */ + save(ls, buff[UTF8BUFFSZ - n]); +} + + +static int readdecesc (LexState *ls) { + int i; + int r = 0; /* result accumulator */ + for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ + r = 10*r + ls->current - '0'; + save_and_next(ls); + } + esccheck(ls, r <= UCHAR_MAX, "decimal escape too large"); + luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */ + return r; +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); /* keep delimiter (for error messages) */ + while (ls->current != del) { + switch (ls->current) { + case EOZ: + lexerror(ls, "unfinished string", TK_EOS); + break; /* to avoid warnings */ + case '\n': + case '\r': + lexerror(ls, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': { /* escape sequences */ + int c; /* final character to be saved */ + save_and_next(ls); /* keep '\\' for error messages */ + switch (ls->current) { + case 'a': c = '\a'; goto read_save; + case 'b': c = '\b'; goto read_save; + case 'f': c = '\f'; goto read_save; + case 'n': c = '\n'; goto read_save; + case 'r': c = '\r'; goto read_save; + case 't': c = '\t'; goto read_save; + case 'v': c = '\v'; goto read_save; + case 'x': c = readhexaesc(ls); goto read_save; + case 'u': utf8esc(ls); goto no_save; + case '\n': case '\r': + inclinenumber(ls); c = '\n'; goto only_save; + case '\\': case '\"': case '\'': + c = ls->current; goto read_save; + case EOZ: goto no_save; /* will raise an error next loop */ + case 'z': { /* zap following span of spaces */ + luaZ_buffremove(ls->buff, 1); /* remove '\\' */ + next(ls); /* skip the 'z' */ + while (lisspace(ls->current)) { + if (currIsNewline(ls)) inclinenumber(ls); + else next(ls); + } + goto no_save; + } + default: { + esccheck(ls, lisdigit(ls->current), "invalid escape sequence"); + c = readdecesc(ls); /* digital escape '\ddd' */ + goto only_save; + } + } + read_save: + next(ls); + /* go through */ + only_save: + luaZ_buffremove(ls->buff, 1); /* remove '\\' */ + save(ls, c); + /* go through */ + no_save: break; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': case '\r': { /* line breaks */ + inclinenumber(ls); + break; + } + case ' ': case '\f': case '\t': case '\v': { /* spaces */ + next(ls); + break; + } + case '-': { /* '-' or '--' (comment) */ + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { /* long comment? */ + size_t sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ + if (sep >= 2) { + read_long_string(ls, NULL, sep); /* skip long comment */ + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ + break; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); /* skip until end of line (or end of file) */ + break; + } + case '[': { /* long string or simply '[' */ + size_t sep = skip_sep(ls); + if (sep >= 2) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == 0) /* '[=...' missing second bracket? */ + lexerror(ls, "invalid long string delimiter", TK_STRING); + return '['; + } + case '=': { + next(ls); + if (check_next1(ls, '=')) return TK_EQ; /* '==' */ + else return '='; + } + case '<': { + next(ls); + if (check_next1(ls, '=')) return TK_LE; /* '<=' */ + else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */ + else return '<'; + } + case '>': { + next(ls); + if (check_next1(ls, '=')) return TK_GE; /* '>=' */ + else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */ + else return '>'; + } + case '/': { + next(ls); + if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ + else return '/'; + } + case '~': { + next(ls); + if (check_next1(ls, '=')) return TK_NE; /* '~=' */ + else return '~'; + } + case ':': { + next(ls); + if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */ + else return ':'; + } + case '"': case '\'': { /* short literal strings */ + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { /* '.', '..', '...', or number */ + save_and_next(ls); + if (check_next1(ls, '.')) { + if (check_next1(ls, '.')) + return TK_DOTS; /* '...' */ + else return TK_CONCAT; /* '..' */ + } + else if (!lisdigit(ls->current)) return '.'; + else return read_numeral(ls, seminfo); + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + return read_numeral(ls, seminfo); + } + case EOZ: { + return TK_EOS; + } + default: { + if (lislalpha(ls->current)) { /* identifier or reserved word? */ + TString *ts; + do { + save_and_next(ls); + } while (lislalnum(ls->current)); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + seminfo->ts = ts; + if (isreserved(ts)) /* reserved word? */ + return ts->extra - 1 + FIRST_RESERVED; + else { + return TK_NAME; + } + } + else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */ + int c = ls->current; + next(ls); + return c; + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +int luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); + return ls->lookahead.token; +} + diff --git a/arm9/source/lua/llex.h b/arm9/source/lua/llex.h new file mode 100644 index 000000000..389d2f863 --- /dev/null +++ b/arm9/source/lua/llex.h @@ -0,0 +1,91 @@ +/* +** $Id: llex.h $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include + +#include "lobject.h" +#include "lzio.h" + + +/* +** Single-char tokens (terminal symbols) are represented by their own +** numeric code. Other tokens start at the following value. +*/ +#define FIRST_RESERVED (UCHAR_MAX + 1) + + +#if !defined(LUA_ENV) +#define LUA_ENV "_ENV" +#endif + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, + TK_SHL, TK_SHR, + TK_DBCOLON, TK_EOS, + TK_FLT, TK_INT, TK_NAME, TK_STRING +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) + + +typedef union { + lua_Number r; + lua_Integer i; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +/* state of the lexer plus state of the parser when shared by all + functions */ +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token 'consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* current function (parser) */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + Table *h; /* to avoid collection/reuse strings */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ + TString *source; /* current source name */ + TString *envn; /* environment variable name */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source, int firstchar); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC int luaX_lookahead (LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/arm9/source/lua/llimits.h b/arm9/source/lua/llimits.h new file mode 100644 index 000000000..cd44ddf2c --- /dev/null +++ b/arm9/source/lua/llimits.h @@ -0,0 +1,381 @@ +/* +** $Id: llimits.h $ +** Limits, basic types, and some other 'installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +/* +** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count +** the total memory used by Lua (in bytes). Usually, 'size_t' and +** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. +*/ +#if defined(LUAI_MEM) /* { external definitions? */ +typedef LUAI_UMEM lu_mem; +typedef LUAI_MEM l_mem; +#elif LUAI_IS32INT /* }{ */ +typedef size_t lu_mem; +typedef ptrdiff_t l_mem; +#else /* 16-bit ints */ /* }{ */ +typedef unsigned long lu_mem; +typedef long l_mem; +#endif /* } */ + + +/* chars used as small naturals (so that 'char' is reserved for characters) */ +typedef unsigned char lu_byte; +typedef signed char ls_byte; + + +/* maximum value for size_t */ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +/* maximum size visible for Lua (must be representable in a lua_Integer) */ +#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ + : (size_t)(LUA_MAXINTEGER)) + + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) + +#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) + + +#define MAX_INT INT_MAX /* maximum value of an int */ + + +/* +** floor of the log2 of the maximum signed value for integral type 't'. +** (That is, maximum 'n' such that '2^n' fits in the given signed type.) +*/ +#define log2maxs(t) (sizeof(t) * 8 - 2) + + +/* +** test whether an unsigned value is a power of 2 (or zero) +*/ +#define ispow2(x) (((x) & ((x) - 1)) == 0) + + +/* number of chars of a literal string without the ending \0 */ +#define LL(x) (sizeof(x)/sizeof(char) - 1) + + +/* +** conversion of pointer to unsigned integer: this is for hashing only; +** there is no problem if the integer cannot hold the whole pointer +** value. (In strict ISO C this may cause undefined behavior, but no +** actual machine seems to bother.) +*/ +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(UINTPTR_MAX) /* even in C99 this type is optional */ +#define L_P2I uintptr_t +#else /* no 'intptr'? */ +#define L_P2I uintmax_t /* use the largest available integer */ +#endif +#else /* C89 option */ +#define L_P2I size_t +#endif + +#define point2uint(p) ((unsigned int)((L_P2I)(p) & UINT_MAX)) + + + +/* types of 'usual argument conversions' for lua_Number and lua_Integer */ +typedef LUAI_UACNUMBER l_uacNumber; +typedef LUAI_UACINT l_uacInt; + + +/* +** Internal assertions for in-house debugging +*/ +#if defined LUAI_ASSERT +#undef NDEBUG +#include +#define lua_assert(c) assert(c) +#endif + +#if defined(lua_assert) +#define check_exp(c,e) (lua_assert(c), (e)) +/* to avoid problems with conditions too long */ +#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) +#else +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define lua_longassert(c) ((void)0) +#endif + +/* +** assertion for checking API calls +*/ +#if !defined(luai_apicheck) +#define luai_apicheck(l,e) ((void)l, lua_assert(e)) +#endif + +#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) + + +/* macro to avoid warnings about unused variables */ +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif + + +/* type casts (a macro highlights casts in the code) */ +#define cast(t, exp) ((t)(exp)) +#define castp(t, exp) ((t)(void *)(exp)) + +#define cast_void(i) cast(void, (i)) +#define cast_voidp(i) cast(void *, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) +#define cast_uint(i) cast(unsigned int, (i)) +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) +#define cast_char(i) cast(char, (i)) +#define cast_charp(i) castp(char *, (i)) +#define cast_sizet(i) cast(size_t, (i)) + + +/* cast a signed lua_Integer to lua_Unsigned */ +#if !defined(l_castS2U) +#define l_castS2U(i) ((lua_Unsigned)(i)) +#endif + +/* +** cast a lua_Unsigned to a signed lua_Integer; this cast is +** not strict ISO C, but two-complement architectures should +** work fine. +*/ +#if !defined(l_castU2S) +#define l_castU2S(i) ((lua_Integer)(i)) +#endif + + +/* +** non-return type +*/ +#if !defined(l_noret) + +#if defined(__GNUC__) +#define l_noret void __attribute__((noreturn)) +#elif defined(_MSC_VER) && _MSC_VER >= 1200 +#define l_noret void __declspec(noreturn) +#else +#define l_noret void +#endif + +#endif + + +/* +** Inline functions +*/ +#if !defined(LUA_USE_C89) +#define l_inline inline +#elif defined(__GNUC__) +#define l_inline __inline__ +#else +#define l_inline /* empty */ +#endif + +#define l_sinline static l_inline + + +/* +** type for virtual-machine instructions; +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +#if LUAI_IS32INT +typedef unsigned int l_uint32; +#else +typedef unsigned long l_uint32; +#endif + +typedef l_uint32 Instruction; + + + +/* +** Maximum length for short strings, that is, strings that are +** internalized. (Cannot be smaller than reserved words or tags for +** metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#if !defined(LUAI_MAXSHORTLEN) +#define LUAI_MAXSHORTLEN 40 +#endif + + +/* +** Initial size for the string table (must be power of 2). +** The Lua core alone registers ~50 strings (reserved words + +** metaevent keys + a few others). Libraries would typically add +** a few dozens more. +*/ +#if !defined(MINSTRTABSIZE) +#define MINSTRTABSIZE 128 +#endif + + +/* +** Size of cache for strings in the API. 'N' is the number of +** sets (better be a prime) and "M" is the size of each set (M == 1 +** makes a direct cache.) +*/ +#if !defined(STRCACHE_N) +#define STRCACHE_N 53 +#define STRCACHE_M 2 +#endif + + +/* minimum size for string buffer */ +#if !defined(LUA_MINBUFFER) +#define LUA_MINBUFFER 32 +#endif + + +/* +** Maximum depth for nested C calls, syntactical nested non-terminals, +** and other features implemented through recursion in C. (Value must +** fit in a 16-bit unsigned integer. It must also be compatible with +** the size of the C stack.) +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 200 +#endif + + +/* +** macros that are executed whenever program enters the Lua core +** ('lua_lock') and leaves the core ('lua_unlock') +*/ +#if !defined(lua_lock) +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +/* +** macro executed during Lua functions at points where the +** function can yield. +*/ +#if !defined(luai_threadyield) +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** these macros allow user-specific actions when a thread is +** created/deleted/resumed/yielded. +*/ +#if !defined(luai_userstateopen) +#define luai_userstateopen(L) ((void)L) +#endif + +#if !defined(luai_userstateclose) +#define luai_userstateclose(L) ((void)L) +#endif + +#if !defined(luai_userstatethread) +#define luai_userstatethread(L,L1) ((void)L) +#endif + +#if !defined(luai_userstatefree) +#define luai_userstatefree(L,L1) ((void)L) +#endif + +#if !defined(luai_userstateresume) +#define luai_userstateresume(L,n) ((void)L) +#endif + +#if !defined(luai_userstateyield) +#define luai_userstateyield(L,n) ((void)L) +#endif + + + +/* +** The luai_num* macros define the primitive operations over numbers. +*/ + +/* floor division (defined as 'floor(a/b)') */ +#if !defined(luai_numidiv) +#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) +#endif + +/* float division */ +#if !defined(luai_numdiv) +#define luai_numdiv(L,a,b) ((a)/(b)) +#endif + +/* +** modulo: defined as 'a - floor(a/b)*b'; the direct computation +** using this definition has several problems with rounding errors, +** so it is better to use 'fmod'. 'fmod' gives the result of +** 'a - trunc(a/b)*b', and therefore must be corrected when +** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a +** non-integer negative result: non-integer result is equivalent to +** a non-zero remainder 'm'; negative result is equivalent to 'a' and +** 'b' with different signs, or 'm' and 'b' with different signs +** (as the result 'm' of 'fmod' has the same sign of 'a'). +*/ +#if !defined(luai_nummod) +#define luai_nummod(L,a,b,m) \ + { (void)L; (m) = l_mathop(fmod)(a,b); \ + if (((m) > 0) ? (b) < 0 : ((m) < 0 && (b) > 0)) (m) += (b); } +#endif + +/* exponentiation */ +#if !defined(luai_numpow) +#define luai_numpow(L,a,b) \ + ((void)L, (b == 2) ? (a)*(a) : l_mathop(pow)(a,b)) +#endif + +/* the others are quite standard operations */ +#if !defined(luai_numadd) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numgt(a,b) ((a)>(b)) +#define luai_numge(a,b) ((a)>=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + + + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if !defined(HARDSTACKTESTS) +#define condmovestack(L,pre,pos) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L,pre,pos) \ + { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } +#endif + +#if !defined(HARDMEMTESTS) +#define condchangemem(L,pre,pos) ((void)0) +#else +#define condchangemem(L,pre,pos) \ + { if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } } +#endif + +#endif diff --git a/arm9/source/lua/lmathlib.c b/arm9/source/lua/lmathlib.c new file mode 100644 index 000000000..438106348 --- /dev/null +++ b/arm9/source/lua/lmathlib.c @@ -0,0 +1,781 @@ +/* +** $Id: lmathlib.c $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + +#define lmathlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (l_mathop(3.141592653589793238462643383279502884)) + + +static int math_abs (lua_State *L) { + if (lua_isinteger(L, 1)) { + lua_Integer n = lua_tointeger(L, 1); + if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); + lua_pushinteger(L, n); + } + else + lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_Number y = luaL_checknumber(L, 1); + lua_Number x = luaL_optnumber(L, 2, 1); + lua_pushnumber(L, l_mathop(atan2)(y, x)); + return 1; +} + + +static int math_toint (lua_State *L) { + int valid; + lua_Integer n = lua_tointegerx(L, 1, &valid); + if (l_likely(valid)) + lua_pushinteger(L, n); + else { + luaL_checkany(L, 1); + luaL_pushfail(L); /* value is not convertible to integer */ + } + return 1; +} + + +static void pushnumint (lua_State *L, lua_Number d) { + lua_Integer n; + if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ + lua_pushinteger(L, n); /* result is integer */ + else + lua_pushnumber(L, d); /* result is float */ +} + + +static int math_floor (lua_State *L) { + if (lua_isinteger(L, 1)) + lua_settop(L, 1); /* integer is its own floor */ + else { + lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); + pushnumint(L, d); + } + return 1; +} + + +static int math_ceil (lua_State *L) { + if (lua_isinteger(L, 1)) + lua_settop(L, 1); /* integer is its own ceil */ + else { + lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); + pushnumint(L, d); + } + return 1; +} + + +static int math_fmod (lua_State *L) { + if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { + lua_Integer d = lua_tointeger(L, 2); + if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ + luaL_argcheck(L, d != 0, 2, "zero"); + lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ + } + else + lua_pushinteger(L, lua_tointeger(L, 1) % d); + } + else + lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); + return 1; +} + + +/* +** next function does not use 'modf', avoiding problems with 'double*' +** (which is not compatible with 'float*') when lua_Number is not +** 'double'. +*/ +static int math_modf (lua_State *L) { + if (lua_isinteger(L ,1)) { + lua_settop(L, 1); /* number is its own integer part */ + lua_pushnumber(L, 0); /* no fractional part */ + } + else { + lua_Number n = luaL_checknumber(L, 1); + /* integer part (rounds toward zero) */ + lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); + pushnumint(L, ip); + /* fractional part (test needed for inf/-inf) */ + lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); + } + return 2; +} + + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); + return 1; +} + + +static int math_ult (lua_State *L) { + lua_Integer a = luaL_checkinteger(L, 1); + lua_Integer b = luaL_checkinteger(L, 2); + lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); + return 1; +} + +static int math_log (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number res; + if (lua_isnoneornil(L, 2)) + res = l_mathop(log)(x); + else { + lua_Number base = luaL_checknumber(L, 2); +#if !defined(LUA_USE_C89) + if (base == l_mathop(2.0)) + res = l_mathop(log2)(x); + else +#endif + if (base == l_mathop(10.0)) + res = l_mathop(log10)(x); + else + res = l_mathop(log)(x)/l_mathop(log)(base); + } + lua_pushnumber(L, res); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); + return 1; +} + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int imin = 1; /* index of current minimum value */ + int i; + luaL_argcheck(L, n >= 1, 1, "value expected"); + for (i = 2; i <= n; i++) { + if (lua_compare(L, i, imin, LUA_OPLT)) + imin = i; + } + lua_pushvalue(L, imin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int imax = 1; /* index of current maximum value */ + int i; + luaL_argcheck(L, n >= 1, 1, "value expected"); + for (i = 2; i <= n; i++) { + if (lua_compare(L, imax, i, LUA_OPLT)) + imax = i; + } + lua_pushvalue(L, imax); + return 1; +} + + +static int math_type (lua_State *L) { + if (lua_type(L, 1) == LUA_TNUMBER) + lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float"); + else { + luaL_checkany(L, 1); + luaL_pushfail(L); + } + return 1; +} + + + +/* +** {================================================================== +** Pseudo-Random Number Generator based on 'xoshiro256**'. +** =================================================================== +*/ + +/* +** This code uses lots of shifts. ANSI C does not allow shifts greater +** than or equal to the width of the type being shifted, so some shifts +** are written in convoluted ways to match that restriction. For +** preprocessor tests, it assumes a width of 32 bits, so the maximum +** shift there is 31 bits. +*/ + + +/* number of binary digits in the mantissa of a float */ +#define FIGS l_floatatt(MANT_DIG) + +#if FIGS > 64 +/* there are only 64 random bits; use them all */ +#undef FIGS +#define FIGS 64 +#endif + + +/* +** LUA_RAND32 forces the use of 32-bit integers in the implementation +** of the PRN generator (mainly for testing). +*/ +#if !defined(LUA_RAND32) && !defined(Rand64) + +/* try to find an integer type with at least 64 bits */ + +#if ((ULONG_MAX >> 31) >> 31) >= 3 + +/* 'long' has at least 64 bits */ +#define Rand64 unsigned long +#define SRand64 long + +#elif !defined(LUA_USE_C89) && defined(LLONG_MAX) + +/* there is a 'long long' type (which must have at least 64 bits) */ +#define Rand64 unsigned long long +#define SRand64 long long + +#elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3 + +/* 'lua_Unsigned' has at least 64 bits */ +#define Rand64 lua_Unsigned +#define SRand64 lua_Integer + +#endif + +#endif + + +#if defined(Rand64) /* { */ + +/* +** Standard implementation, using 64-bit integers. +** If 'Rand64' has more than 64 bits, the extra bits do not interfere +** with the 64 initial bits, except in a right shift. Moreover, the +** final result has to discard the extra bits. +*/ + +/* avoid using extra bits when needed */ +#define trim64(x) ((x) & 0xffffffffffffffffu) + + +/* rotate left 'x' by 'n' bits */ +static Rand64 rotl (Rand64 x, int n) { + return (x << n) | (trim64(x) >> (64 - n)); +} + +static Rand64 nextrand (Rand64 *state) { + Rand64 state0 = state[0]; + Rand64 state1 = state[1]; + Rand64 state2 = state[2] ^ state0; + Rand64 state3 = state[3] ^ state1; + Rand64 res = rotl(state1 * 5, 7) * 9; + state[0] = state0 ^ state3; + state[1] = state1 ^ state2; + state[2] = state2 ^ (state1 << 17); + state[3] = rotl(state3, 45); + return res; +} + + +/* +** Convert bits from a random integer into a float in the +** interval [0,1), getting the higher FIG bits from the +** random unsigned integer and converting that to a float. +** Some old Microsoft compilers cannot cast an unsigned long +** to a floating-point number, so we use a signed long as an +** intermediary. When lua_Number is float or double, the shift ensures +** that 'sx' is non negative; in that case, a good compiler will remove +** the correction. +*/ + +/* must throw out the extra (64 - FIGS) bits */ +#define shift64_FIG (64 - FIGS) + +/* 2^(-FIGS) == 2^-1 / 2^(FIGS-1) */ +#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) + +static lua_Number I2d (Rand64 x) { + SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG); + lua_Number res = (lua_Number)(sx) * scaleFIG; + if (sx < 0) + res += l_mathop(1.0); /* correct the two's complement if negative */ + lua_assert(0 <= res && res < 1); + return res; +} + +/* convert a 'Rand64' to a 'lua_Unsigned' */ +#define I2UInt(x) ((lua_Unsigned)trim64(x)) + +/* convert a 'lua_Unsigned' to a 'Rand64' */ +#define Int2I(x) ((Rand64)(x)) + + +#else /* no 'Rand64' }{ */ + +/* get an integer with at least 32 bits */ +#if LUAI_IS32INT +typedef unsigned int lu_int32; +#else +typedef unsigned long lu_int32; +#endif + + +/* +** Use two 32-bit integers to represent a 64-bit quantity. +*/ +typedef struct Rand64 { + lu_int32 h; /* higher half */ + lu_int32 l; /* lower half */ +} Rand64; + + +/* +** If 'lu_int32' has more than 32 bits, the extra bits do not interfere +** with the 32 initial bits, except in a right shift and comparisons. +** Moreover, the final result has to discard the extra bits. +*/ + +/* avoid using extra bits when needed */ +#define trim32(x) ((x) & 0xffffffffu) + + +/* +** basic operations on 'Rand64' values +*/ + +/* build a new Rand64 value */ +static Rand64 packI (lu_int32 h, lu_int32 l) { + Rand64 result; + result.h = h; + result.l = l; + return result; +} + +/* return i << n */ +static Rand64 Ishl (Rand64 i, int n) { + lua_assert(n > 0 && n < 32); + return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n); +} + +/* i1 ^= i2 */ +static void Ixor (Rand64 *i1, Rand64 i2) { + i1->h ^= i2.h; + i1->l ^= i2.l; +} + +/* return i1 + i2 */ +static Rand64 Iadd (Rand64 i1, Rand64 i2) { + Rand64 result = packI(i1.h + i2.h, i1.l + i2.l); + if (trim32(result.l) < trim32(i1.l)) /* carry? */ + result.h++; + return result; +} + +/* return i * 5 */ +static Rand64 times5 (Rand64 i) { + return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */ +} + +/* return i * 9 */ +static Rand64 times9 (Rand64 i) { + return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */ +} + +/* return 'i' rotated left 'n' bits */ +static Rand64 rotl (Rand64 i, int n) { + lua_assert(n > 0 && n < 32); + return packI((i.h << n) | (trim32(i.l) >> (32 - n)), + (trim32(i.h) >> (32 - n)) | (i.l << n)); +} + +/* for offsets larger than 32, rotate right by 64 - offset */ +static Rand64 rotl1 (Rand64 i, int n) { + lua_assert(n > 32 && n < 64); + n = 64 - n; + return packI((trim32(i.h) >> n) | (i.l << (32 - n)), + (i.h << (32 - n)) | (trim32(i.l) >> n)); +} + +/* +** implementation of 'xoshiro256**' algorithm on 'Rand64' values +*/ +static Rand64 nextrand (Rand64 *state) { + Rand64 res = times9(rotl(times5(state[1]), 7)); + Rand64 t = Ishl(state[1], 17); + Ixor(&state[2], state[0]); + Ixor(&state[3], state[1]); + Ixor(&state[1], state[2]); + Ixor(&state[0], state[3]); + Ixor(&state[2], t); + state[3] = rotl1(state[3], 45); + return res; +} + + +/* +** Converts a 'Rand64' into a float. +*/ + +/* an unsigned 1 with proper type */ +#define UONE ((lu_int32)1) + + +#if FIGS <= 32 + +/* 2^(-FIGS) */ +#define scaleFIG (l_mathop(0.5) / (UONE << (FIGS - 1))) + +/* +** get up to 32 bits from higher half, shifting right to +** throw out the extra bits. +*/ +static lua_Number I2d (Rand64 x) { + lua_Number h = (lua_Number)(trim32(x.h) >> (32 - FIGS)); + return h * scaleFIG; +} + +#else /* 32 < FIGS <= 64 */ + +/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ +#define scaleFIG \ + (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33))) + +/* +** use FIGS - 32 bits from lower half, throwing out the other +** (32 - (FIGS - 32)) = (64 - FIGS) bits +*/ +#define shiftLOW (64 - FIGS) + +/* +** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32) +*/ +#define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * l_mathop(2.0)) + + +static lua_Number I2d (Rand64 x) { + lua_Number h = (lua_Number)trim32(x.h) * shiftHI; + lua_Number l = (lua_Number)(trim32(x.l) >> shiftLOW); + return (h + l) * scaleFIG; +} + +#endif + + +/* convert a 'Rand64' to a 'lua_Unsigned' */ +static lua_Unsigned I2UInt (Rand64 x) { + return (((lua_Unsigned)trim32(x.h) << 31) << 1) | (lua_Unsigned)trim32(x.l); +} + +/* convert a 'lua_Unsigned' to a 'Rand64' */ +static Rand64 Int2I (lua_Unsigned n) { + return packI((lu_int32)((n >> 31) >> 1), (lu_int32)n); +} + +#endif /* } */ + + +/* +** A state uses four 'Rand64' values. +*/ +typedef struct { + Rand64 s[4]; +} RanState; + + +/* +** Project the random integer 'ran' into the interval [0, n]. +** Because 'ran' has 2^B possible values, the projection can only be +** uniform when the size of the interval is a power of 2 (exact +** division). Otherwise, to get a uniform projection into [0, n], we +** first compute 'lim', the smallest Mersenne number not smaller than +** 'n'. We then project 'ran' into the interval [0, lim]. If the result +** is inside [0, n], we are done. Otherwise, we try with another 'ran', +** until we have a result inside the interval. +*/ +static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, + RanState *state) { + if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */ + return ran & n; /* no bias */ + else { + lua_Unsigned lim = n; + /* compute the smallest (2^b - 1) not smaller than 'n' */ + lim |= (lim >> 1); + lim |= (lim >> 2); + lim |= (lim >> 4); + lim |= (lim >> 8); + lim |= (lim >> 16); +#if (LUA_MAXUNSIGNED >> 31) >= 3 + lim |= (lim >> 32); /* integer type has more than 32 bits */ +#endif + lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ + && lim >= n /* not smaller than 'n', */ + && (lim >> 1) < n); /* and it is the smallest one */ + while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ + ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ + return ran; + } +} + + +static int math_random (lua_State *L) { + lua_Integer low, up; + lua_Unsigned p; + RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); + Rand64 rv = nextrand(state->s); /* next pseudo-random value */ + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, I2d(rv)); /* float between 0 and 1 */ + return 1; + } + case 1: { /* only upper limit */ + low = 1; + up = luaL_checkinteger(L, 1); + if (up == 0) { /* single 0 as argument? */ + lua_pushinteger(L, I2UInt(rv)); /* full random integer */ + return 1; + } + break; + } + case 2: { /* lower and upper limits */ + low = luaL_checkinteger(L, 1); + up = luaL_checkinteger(L, 2); + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + /* random integer in the interval [low, up] */ + luaL_argcheck(L, low <= up, 1, "interval is empty"); + /* project random integer into the interval [0, up - low] */ + p = project(I2UInt(rv), (lua_Unsigned)up - (lua_Unsigned)low, state); + lua_pushinteger(L, p + (lua_Unsigned)low); + return 1; +} + + +static void setseed (lua_State *L, Rand64 *state, + lua_Unsigned n1, lua_Unsigned n2) { + int i; + state[0] = Int2I(n1); + state[1] = Int2I(0xff); /* avoid a zero state */ + state[2] = Int2I(n2); + state[3] = Int2I(0); + for (i = 0; i < 16; i++) + nextrand(state); /* discard initial values to "spread" seed */ + lua_pushinteger(L, n1); + lua_pushinteger(L, n2); +} + + +/* +** Set a "random" seed. To get some randomness, use the current time +** and the address of 'L' (in case the machine does address space layout +** randomization). +*/ +static void randseed (lua_State *L, RanState *state) { + lua_Unsigned seed1 = (lua_Unsigned)time(NULL); + lua_Unsigned seed2 = (lua_Unsigned)(size_t)L; + setseed(L, state->s, seed1, seed2); +} + + +static int math_randomseed (lua_State *L) { + RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); + if (lua_isnone(L, 1)) { + randseed(L, state); + } + else { + lua_Integer n1 = luaL_checkinteger(L, 1); + lua_Integer n2 = luaL_optinteger(L, 2, 0); + setseed(L, state->s, n1, n2); + } + return 2; /* return seeds */ +} + + +static const luaL_Reg randfuncs[] = { + {"random", math_random}, + {"randomseed", math_randomseed}, + {NULL, NULL} +}; + + +/* +** Register the random functions and initialize their state. +*/ +static void setrandfunc (lua_State *L) { + RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); + randseed(L, state); /* initialize with a "random" seed */ + lua_pop(L, 2); /* remove pushed seeds */ + luaL_setfuncs(L, randfuncs, 1); +} + +/* }================================================================== */ + + +/* +** {================================================================== +** Deprecated functions (for compatibility only) +** =================================================================== +*/ +#if defined(LUA_COMPAT_MATHLIB) + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number y = luaL_checknumber(L, 2); + lua_pushnumber(L, l_mathop(pow)(x, y)); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + int ep = (int)luaL_checkinteger(L, 2); + lua_pushnumber(L, l_mathop(ldexp)(x, ep)); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); + return 1; +} + +#endif +/* }================================================================== */ + + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"tointeger", math_toint}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"ult", math_ult}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"rad", math_rad}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tan", math_tan}, + {"type", math_type}, +#if defined(LUA_COMPAT_MATHLIB) + {"atan2", math_atan}, + {"cosh", math_cosh}, + {"sinh", math_sinh}, + {"tanh", math_tanh}, + {"pow", math_pow}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, +#endif + /* placeholders */ + {"random", NULL}, + {"randomseed", NULL}, + {"pi", NULL}, + {"huge", NULL}, + {"maxinteger", NULL}, + {"mininteger", NULL}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUAMOD_API int luaopen_math (lua_State *L) { + luaL_newlib(L, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, (lua_Number)HUGE_VAL); + lua_setfield(L, -2, "huge"); + lua_pushinteger(L, LUA_MAXINTEGER); + lua_setfield(L, -2, "maxinteger"); + lua_pushinteger(L, LUA_MININTEGER); + lua_setfield(L, -2, "mininteger"); + setrandfunc(L); + return 1; +} + diff --git a/arm9/source/lua/lmem.c b/arm9/source/lua/lmem.c new file mode 100644 index 000000000..9800a86fc --- /dev/null +++ b/arm9/source/lua/lmem.c @@ -0,0 +1,215 @@ +/* +** $Id: lmem.c $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#define lmem_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** ('osize' is the old size, 'nsize' is the new size) +** +** - frealloc(ud, p, x, 0) frees the block 'p' and returns NULL. +** Particularly, frealloc(ud, NULL, 0, 0) does nothing, +** which is equivalent to free(NULL) in ISO C. +** +** - frealloc(ud, NULL, x, s) creates a new block of size 's' +** (no matter 'x'). Returns NULL if it cannot create the new block. +** +** - otherwise, frealloc(ud, b, x, y) reallocates the block 'b' from +** size 'x' to size 'y'. Returns NULL if it cannot reallocate the +** block to the new size. +*/ + + +/* +** Macro to call the allocation function. +*/ +#define callfrealloc(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) + + +/* +** When an allocation fails, it will try again after an emergency +** collection, except when it cannot run a collection. The GC should +** not be called while the state is not fully built, as the collector +** is not yet fully initialized. Also, it should not be called when +** 'gcstopem' is true, because then the interpreter is in the middle of +** a collection step. +*/ +#define cantryagain(g) (completestate(g) && !g->gcstopem) + + + + +#if defined(EMERGENCYGCTESTS) +/* +** First allocation will fail except when freeing a block (frees never +** fail) and when it cannot try again; this fail will trigger 'tryagain' +** and a full GC cycle at every allocation. +*/ +static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { + if (ns > 0 && cantryagain(g)) + return NULL; /* fail */ + else /* normal allocation */ + return callfrealloc(g, block, os, ns); +} +#else +#define firsttry(g,block,os,ns) callfrealloc(g, block, os, ns) +#endif + + + + + +/* +** {================================================================== +** Functions to allocate/deallocate arrays for the Parser +** =================================================================== +*/ + +/* +** Minimum size for arrays during parsing, to avoid overhead of +** reallocating to size 1, then 2, and then 4. All these arrays +** will be reallocated to exact sizes or erased when parsing ends. +*/ +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, + int size_elems, int limit, const char *what) { + void *newblock; + int size = *psize; + if (nelems + 1 <= size) /* does one extra element still fit? */ + return block; /* nothing to be done */ + if (size >= limit / 2) { /* cannot double it? */ + if (l_unlikely(size >= limit)) /* cannot grow even a little? */ + luaG_runerror(L, "too many %s (limit is %d)", what, limit); + size = limit; /* still have at least one free place */ + } + else { + size *= 2; + if (size < MINSIZEARRAY) + size = MINSIZEARRAY; /* minimum size */ + } + lua_assert(nelems + 1 <= size && size <= limit); + /* 'limit' ensures that multiplication will not overflow */ + newblock = luaM_saferealloc_(L, block, cast_sizet(*psize) * size_elems, + cast_sizet(size) * size_elems); + *psize = size; /* update only when everything else is OK */ + return newblock; +} + + +/* +** In prototypes, the size of the array is also its number of +** elements (to save memory). So, if it cannot shrink an array +** to its number of elements, the only option is to raise an +** error. +*/ +void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, + int final_n, int size_elem) { + void *newblock; + size_t oldsize = cast_sizet((*size) * size_elem); + size_t newsize = cast_sizet(final_n * size_elem); + lua_assert(newsize <= oldsize); + newblock = luaM_saferealloc_(L, block, oldsize, newsize); + *size = final_n; + return newblock; +} + +/* }================================================================== */ + + +l_noret luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); +} + + +/* +** Free memory +*/ +void luaM_free_ (lua_State *L, void *block, size_t osize) { + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + callfrealloc(g, block, osize, 0); + g->GCdebt -= osize; +} + + +/* +** In case of allocation fail, this function will do an emergency +** collection to free some memory and then try the allocation again. +*/ +static void *tryagain (lua_State *L, void *block, + size_t osize, size_t nsize) { + global_State *g = G(L); + if (cantryagain(g)) { + luaC_fullgc(L, 1); /* try to free some memory... */ + return callfrealloc(g, block, osize, nsize); /* try again */ + } + else return NULL; /* cannot run an emergency collection */ +} + + +/* +** Generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + void *newblock; + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + newblock = firsttry(g, block, osize, nsize); + if (l_unlikely(newblock == NULL && nsize > 0)) { + newblock = tryagain(L, block, osize, nsize); + if (newblock == NULL) /* still no memory? */ + return NULL; /* do not update 'GCdebt' */ + } + lua_assert((nsize == 0) == (newblock == NULL)); + g->GCdebt = (g->GCdebt + nsize) - osize; + return newblock; +} + + +void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, + size_t nsize) { + void *newblock = luaM_realloc_(L, block, osize, nsize); + if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ + luaM_error(L); + return newblock; +} + + +void *luaM_malloc_ (lua_State *L, size_t size, int tag) { + if (size == 0) + return NULL; /* that's all */ + else { + global_State *g = G(L); + void *newblock = firsttry(g, NULL, tag, size); + if (l_unlikely(newblock == NULL)) { + newblock = tryagain(L, NULL, tag, size); + if (newblock == NULL) + luaM_error(L); + } + g->GCdebt += size; + return newblock; + } +} diff --git a/arm9/source/lua/lmem.h b/arm9/source/lua/lmem.h new file mode 100644 index 000000000..8c75a44be --- /dev/null +++ b/arm9/source/lua/lmem.h @@ -0,0 +1,93 @@ +/* +** $Id: lmem.h $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + + +#define luaM_error(L) luaD_throw(L, LUA_ERRMEM) + + +/* +** This macro tests whether it is safe to multiply 'n' by the size of +** type 't' without overflows. Because 'e' is always constant, it avoids +** the runtime division MAX_SIZET/(e). +** (The macro is somewhat complex to avoid warnings: The 'sizeof' +** comparison avoids a runtime comparison when overflow cannot occur. +** The compiler should be able to optimize the real test by itself, but +** when it does it, it may give a warning about "comparison is always +** false due to limited range of data type"; the +1 tricks the compiler, +** avoiding this warning but also this optimization.) +*/ +#define luaM_testsize(n,e) \ + (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) + +#define luaM_checksize(L,n,e) \ + (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) + + +/* +** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that +** the result is not larger than 'n' and cannot overflow a 'size_t' +** when multiplied by the size of type 't'. (Assumes that 'n' is an +** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) +*/ +#define luaM_limitN(n,t) \ + ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ + cast_uint((MAX_SIZET/sizeof(t)))) + + +/* +** Arrays of chars do not need any test +*/ +#define luaM_reallocvchar(L,b,on,n) \ + cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) + +#define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) +#define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) +#define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) + +#define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) +#define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) +#define luaM_newvectorchecked(L,n,t) \ + (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) + +#define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ + luaM_limitN(limit,t),e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ + cast_sizet(n) * sizeof(t)))) + +#define luaM_shrinkvector(L,v,size,fs,t) \ + ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) + +LUAI_FUNC l_noret luaM_toobig (lua_State *L); + +/* not to be called directly */ +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, + int *size, int size_elem, int limit, + const char *what); +LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, + int final_n, int size_elem); +LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); + +#endif + diff --git a/arm9/source/lua/loadlib.c b/arm9/source/lua/loadlib.c new file mode 100644 index 000000000..6d289fceb --- /dev/null +++ b/arm9/source/lua/loadlib.c @@ -0,0 +1,758 @@ +/* +** $Id: loadlib.c $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Windows, and a stub for other +** systems. +*/ + +#define loadlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** LUA_CSUBSEP is the character that replaces dots in submodule names +** when searching for a C loader. +** LUA_LSUBSEP is the character that replaces dots in submodule names +** when searching for a Lua loader. +*/ +#if !defined(LUA_CSUBSEP) +#define LUA_CSUBSEP LUA_DIRSEP +#endif + +#if !defined(LUA_LSUBSEP) +#define LUA_LSUBSEP LUA_DIRSEP +#endif + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +/* +** key for table in the registry that keeps handles +** for all loaded C libraries +*/ +static const char *const CLIBS = "_CLIBS"; + +#define LIB_FAIL "open" + + +#define setprogdir(L) ((void)0) + + +/* +** Special type equivalent to '(void*)' for functions in gcc +** (to suppress warnings when converting function pointers) +*/ +typedef void (*voidf)(void); + + +/* +** system-dependent functions +*/ + +/* +** unload library 'lib' +*/ +static void lsys_unloadlib (void *lib); + +/* +** load C library in file 'path'. If 'seeglb', load with all names in +** the library global. +** Returns the library; in case of error, returns NULL plus an +** error string in the stack. +*/ +static void *lsys_load (lua_State *L, const char *path, int seeglb); + +/* +** Try to find a function named 'sym' in library 'lib'. +** Returns the function; in case of error, returns NULL plus an +** error string in the stack. +*/ +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym); + + + + +#if defined(LUA_USE_DLOPEN) /* { */ +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +/* +** Macro to convert pointer-to-void* to pointer-to-function. This cast +** is undefined according to ISO C, but POSIX assumes that it works. +** (The '__extension__' in gnu compilers is only to avoid warnings.) +*/ +#if defined(__GNUC__) +#define cast_func(p) (__extension__ (lua_CFunction)(p)) +#else +#define cast_func(p) ((lua_CFunction)(p)) +#endif + + +static void lsys_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); + if (l_unlikely(lib == NULL)) + lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = cast_func(dlsym(lib, sym)); + if (l_unlikely(f == NULL)) + lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) /* }{ */ +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +/* +** optional flags for LoadLibraryEx +*/ +#if !defined(LUA_LLE_FLAGS) +#define LUA_LLE_FLAGS 0 +#endif + + +#undef setprogdir + + +/* +** Replace in the path (on the top of the stack) any occurrence +** of LUA_EXEC_DIR with the executable's path. +*/ +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */ + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; /* cut name on the last '\\' to get the path */ + luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void lsys_unloadlib (void *lib) { + FreeLibrary((HMODULE)lib); +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); + (void)(seeglb); /* not used: symbols are 'global' by default */ + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)(voidf)GetProcAddress((HMODULE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + +#else /* }{ */ +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void lsys_unloadlib (void *lib) { + (void)(lib); /* not used */ +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + (void)(path); (void)(seeglb); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + (void)(lib); (void)(sym); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif /* } */ + + +/* +** {================================================================== +** Set Paths +** =================================================================== +*/ + +/* +** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment +** variables that Lua check to set its paths. +*/ +#if !defined(LUA_PATH_VAR) +#define LUA_PATH_VAR "LUA_PATH" +#endif + +#if !defined(LUA_CPATH_VAR) +#define LUA_CPATH_VAR "LUA_CPATH" +#endif + + + +/* +** return registry.LUA_NOENV as a boolean +*/ +static int noenv (lua_State *L) { + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; +} + + +/* +** Set a path +*/ +static void setpath (lua_State *L, const char *fieldname, + const char *envname, + const char *dft) { + const char *dftmark; + const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX); + const char *path = getenv(nver); /* try versioned name */ + if (path == NULL) /* no versioned environment variable? */ + path = getenv(envname); /* try unversioned name */ + if (path == NULL || noenv(L)) /* no environment variable? */ + lua_pushstring(L, dft); /* use default */ + else if ((dftmark = strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL) + lua_pushstring(L, path); /* nothing to change */ + else { /* path contains a ";;": insert default path in its place */ + size_t len = strlen(path); + luaL_Buffer b; + luaL_buffinit(L, &b); + if (path < dftmark) { /* is there a prefix before ';;'? */ + luaL_addlstring(&b, path, dftmark - path); /* add it */ + luaL_addchar(&b, *LUA_PATH_SEP); + } + luaL_addstring(&b, dft); /* add default */ + if (dftmark < path + len - 2) { /* is there a suffix after ';;'? */ + luaL_addchar(&b, *LUA_PATH_SEP); + luaL_addlstring(&b, dftmark + 2, (path + len - 2) - dftmark); + } + luaL_pushresult(&b); + } + setprogdir(L); + lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ + lua_pop(L, 1); /* pop versioned variable name ('nver') */ +} + +/* }================================================================== */ + + +/* +** return registry.CLIBS[path] +*/ +static void *checkclib (lua_State *L, const char *path) { + void *plib; + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_getfield(L, -1, path); + plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ + return plib; +} + + +/* +** registry.CLIBS[path] = plib -- for queries +** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries +*/ +static void addtoclib (lua_State *L, const char *path, void *plib) { + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ +} + + +/* +** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib +** handles in list CLIBS +*/ +static int gctm (lua_State *L) { + lua_Integer n = luaL_len(L, 1); + for (; n >= 1; n--) { /* for each handle, in reverse order */ + lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ + lsys_unloadlib(lua_touserdata(L, -1)); + lua_pop(L, 1); /* pop handle */ + } + return 0; +} + + + +/* error codes for 'lookforfunc' */ +#define ERRLIB 1 +#define ERRFUNC 2 + +/* +** Look for a C function named 'sym' in a dynamically loaded library +** 'path'. +** First, check whether the library is already loaded; if not, try +** to load it. +** Then, if 'sym' is '*', return true (as library has been loaded). +** Otherwise, look for symbol 'sym' in the library and push a +** C function with that symbol. +** Return 0 and 'true' or a function in the stack; in case of +** errors, return an error code and an error message in the stack. +*/ +static int lookforfunc (lua_State *L, const char *path, const char *sym) { + void *reg = checkclib(L, path); /* check loaded C libraries */ + if (reg == NULL) { /* must load library? */ + reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */ + if (reg == NULL) return ERRLIB; /* unable to load library */ + addtoclib(L, path, reg); + } + if (*sym == '*') { /* loading only library (no function)? */ + lua_pushboolean(L, 1); /* return 'true' */ + return 0; /* no errors */ + } + else { + lua_CFunction f = lsys_sym(L, reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); /* else create new function */ + return 0; /* no errors */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = lookforfunc(L, path, init); + if (l_likely(stat == 0)) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + luaL_pushfail(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return fail, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +/* +** Get the next name in '*path' = 'name1;name2;name3;...', changing +** the ending ';' to '\0' to create a zero-terminated string. Return +** NULL when list ends. +*/ +static const char *getnextfilename (char **path, char *end) { + char *sep; + char *name = *path; + if (name == end) + return NULL; /* no more names */ + else if (*name == '\0') { /* from previous iteration? */ + *name = *LUA_PATH_SEP; /* restore separator */ + name++; /* skip it */ + } + sep = strchr(name, *LUA_PATH_SEP); /* find next separator */ + if (sep == NULL) /* separator not found? */ + sep = end; /* name goes until the end */ + *sep = '\0'; /* finish file name */ + *path = sep; /* will start next search from here */ + return name; +} + + +/* +** Given a path such as ";blabla.so;blublu.so", pushes the string +** +** no file 'blabla.so' +** no file 'blublu.so' +*/ +static void pusherrornotfound (lua_State *L, const char *path) { + luaL_Buffer b; + luaL_buffinit(L, &b); + luaL_addstring(&b, "no file '"); + luaL_addgsub(&b, path, LUA_PATH_SEP, "'\n\tno file '"); + luaL_addstring(&b, "'"); + luaL_pushresult(&b); +} + + +static const char *searchpath (lua_State *L, const char *name, + const char *path, + const char *sep, + const char *dirsep) { + luaL_Buffer buff; + char *pathname; /* path with name inserted */ + char *endpathname; /* its end */ + const char *filename; + /* separator is non-empty and appears in 'name'? */ + if (*sep != '\0' && strchr(name, *sep) != NULL) + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ + luaL_buffinit(L, &buff); + /* add path to the buffer, replacing marks ('?') with the file name */ + luaL_addgsub(&buff, path, LUA_PATH_MARK, name); + luaL_addchar(&buff, '\0'); + pathname = luaL_buffaddr(&buff); /* writable list of file names */ + endpathname = pathname + luaL_bufflen(&buff) - 1; + while ((filename = getnextfilename(&pathname, endpathname)) != NULL) { + if (readable(filename)) /* does file exist and is readable? */ + return lua_pushstring(L, filename); /* save and return name */ + } + luaL_pushresult(&buff); /* push path to create error message */ + pusherrornotfound(L, lua_tostring(L, -1)); /* create error message */ + return NULL; /* not found */ +} + + +static int ll_searchpath (lua_State *L) { + const char *f = searchpath(L, luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, "."), + luaL_optstring(L, 4, LUA_DIRSEP)); + if (f != NULL) return 1; + else { /* error message is on top of the stack */ + luaL_pushfail(L); + lua_insert(L, -2); + return 2; /* return fail + error message */ + } +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname, + const char *dirsep) { + const char *path; + lua_getfield(L, lua_upvalueindex(1), pname); + path = lua_tostring(L, -1); + if (l_unlikely(path == NULL)) + luaL_error(L, "'package.%s' must be a string", pname); + return searchpath(L, name, path, ".", dirsep); +} + + +static int checkload (lua_State *L, int stat, const char *filename) { + if (l_likely(stat)) { /* module loaded successfully? */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; /* return open function and file name */ + } + else + return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int searcher_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path", LUA_LSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); +} + + +/* +** Try to find a load function for module 'modname' at file 'filename'. +** First, change '.' to '_' in 'modname'; then, if 'modname' has +** the form X-Y (that is, it has an "ignore mark"), build a function +** name "luaopen_X" and look for it. (For compatibility, if that +** fails, it also tries "luaopen_Y".) If there is no ignore mark, +** look for a function named "luaopen_modname". +*/ +static int loadfunc (lua_State *L, const char *filename, const char *modname) { + const char *openfunc; + const char *mark; + modname = luaL_gsub(L, modname, ".", LUA_OFSEP); + mark = strchr(modname, *LUA_IGMARK); + if (mark) { + int stat; + openfunc = lua_pushlstring(L, modname, mark - modname); + openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc); + stat = lookforfunc(L, filename, openfunc); + if (stat != ERRFUNC) return stat; + modname = mark + 1; /* else go ahead and try old-style name */ + } + openfunc = lua_pushfstring(L, LUA_POF"%s", modname); + return lookforfunc(L, filename, openfunc); +} + + +static int searcher_C (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (loadfunc(L, filename, name) == 0), filename); +} + + +static int searcher_Croot (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* root not found */ + if ((stat = loadfunc(L, filename, name)) != 0) { + if (stat != ERRFUNC) + return checkload(L, 0, filename); /* real error */ + else { /* open function not found */ + lua_pushfstring(L, "no module '%s' in file '%s'", name, filename); + return 1; + } + } + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; +} + + +static int searcher_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + if (lua_getfield(L, -1, name) == LUA_TNIL) { /* not found? */ + lua_pushfstring(L, "no field package.preload['%s']", name); + return 1; + } + else { + lua_pushliteral(L, ":preload:"); + return 2; + } +} + + +static void findloader (lua_State *L, const char *name) { + int i; + luaL_Buffer msg; /* to build error message */ + /* push 'package.searchers' to index 3 in the stack */ + if (l_unlikely(lua_getfield(L, lua_upvalueindex(1), "searchers") + != LUA_TTABLE)) + luaL_error(L, "'package.searchers' must be a table"); + luaL_buffinit(L, &msg); + /* iterate over available searchers to find a loader */ + for (i = 1; ; i++) { + luaL_addstring(&msg, "\n\t"); /* error-message prefix */ + if (l_unlikely(lua_rawgeti(L, 3, i) == LUA_TNIL)) { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_buffsub(&msg, 2); /* remove prefix */ + luaL_pushresult(&msg); /* create error message */ + luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); + } + lua_pushstring(L, name); + lua_call(L, 1, 2); /* call it */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ + return; /* module loader found */ + else if (lua_isstring(L, -2)) { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(&msg); /* concatenate error message */ + } + else { /* no error message */ + lua_pop(L, 2); /* remove both returns */ + luaL_buffsub(&msg, 2); /* remove prefix */ + } + } +} + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); /* LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, 2, name); /* LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded */ + /* else must load package */ + lua_pop(L, 1); /* remove 'getfield' result */ + findloader(L, name); + lua_rotate(L, -2, 1); /* function <-> loader data */ + lua_pushvalue(L, 1); /* name is 1st argument to module loader */ + lua_pushvalue(L, -3); /* loader data is 2nd argument */ + /* stack: ...; loader data; loader function; mod. name; loader data */ + lua_call(L, 2, 1); /* run loader to load module */ + /* stack: ...; loader data; result from loader */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* LOADED[name] = returned value */ + else + lua_pop(L, 1); /* pop nil */ + if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_copy(L, -1, -2); /* replace loader result */ + lua_setfield(L, 2, name); /* LOADED[name] = true */ + } + lua_rotate(L, -2, 1); /* loader data <-> module result */ + return 2; /* return module result and loader data */ +} + +/* }====================================================== */ + + + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"searchpath", ll_searchpath}, + /* placeholders */ + {"preload", NULL}, + {"cpath", NULL}, + {"path", NULL}, + {"searchers", NULL}, + {"loaded", NULL}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { + {"require", ll_require}, + {NULL, NULL} +}; + + +static void createsearcherstable (lua_State *L) { + static const lua_CFunction searchers[] = { + searcher_preload, + searcher_Lua, + searcher_C, + searcher_Croot, + NULL + }; + int i; + /* create 'searchers' table */ + lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); + /* fill it with predefined searchers */ + for (i=0; searchers[i] != NULL; i++) { + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); + lua_rawseti(L, -2, i+1); + } + lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ +} + + +/* +** create table CLIBS to keep track of loaded C libraries, +** setting a finalizer to close all libraries when closing state. +*/ +static void createclibstable (lua_State *L) { + luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */ + lua_createtable(L, 0, 1); /* create metatable for CLIBS */ + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ + lua_setmetatable(L, -2); +} + + +LUAMOD_API int luaopen_package (lua_State *L) { + createclibstable(L); + luaL_newlib(L, pk_funcs); /* create 'package' table */ + createsearcherstable(L); + /* set paths */ + setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT); + setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT); + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" + LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); + lua_setfield(L, -2, "config"); + /* set field 'loaded' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_setfield(L, -2, "loaded"); + /* set field 'preload' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + lua_setfield(L, -2, "preload"); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ + return 1; /* return 'package' table */ +} + diff --git a/arm9/source/lua/lobject.c b/arm9/source/lua/lobject.c new file mode 100644 index 000000000..9cfa5227e --- /dev/null +++ b/arm9/source/lua/lobject.c @@ -0,0 +1,602 @@ +/* +** $Id: lobject.c $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#define lobject_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + +/* +** Computes ceil(log2(x)) +*/ +int luaO_ceillog2 (unsigned int x) { + static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = 0; + x--; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; +} + + +static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, + lua_Integer v2) { + switch (op) { + case LUA_OPADD: return intop(+, v1, v2); + case LUA_OPSUB:return intop(-, v1, v2); + case LUA_OPMUL:return intop(*, v1, v2); + case LUA_OPMOD: return luaV_mod(L, v1, v2); + case LUA_OPIDIV: return luaV_idiv(L, v1, v2); + case LUA_OPBAND: return intop(&, v1, v2); + case LUA_OPBOR: return intop(|, v1, v2); + case LUA_OPBXOR: return intop(^, v1, v2); + case LUA_OPSHL: return luaV_shiftl(v1, v2); + case LUA_OPSHR: return luaV_shiftr(v1, v2); + case LUA_OPUNM: return intop(-, 0, v1); + case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1); + default: lua_assert(0); return 0; + } +} + + +static lua_Number numarith (lua_State *L, int op, lua_Number v1, + lua_Number v2) { + switch (op) { + case LUA_OPADD: return luai_numadd(L, v1, v2); + case LUA_OPSUB: return luai_numsub(L, v1, v2); + case LUA_OPMUL: return luai_nummul(L, v1, v2); + case LUA_OPDIV: return luai_numdiv(L, v1, v2); + case LUA_OPPOW: return luai_numpow(L, v1, v2); + case LUA_OPIDIV: return luai_numidiv(L, v1, v2); + case LUA_OPUNM: return luai_numunm(L, v1); + case LUA_OPMOD: return luaV_modf(L, v1, v2); + default: lua_assert(0); return 0; + } +} + + +int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2, + TValue *res) { + switch (op) { + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: + case LUA_OPBNOT: { /* operate only on integers */ + lua_Integer i1; lua_Integer i2; + if (tointegerns(p1, &i1) && tointegerns(p2, &i2)) { + setivalue(res, intarith(L, op, i1, i2)); + return 1; + } + else return 0; /* fail */ + } + case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ + lua_Number n1; lua_Number n2; + if (tonumberns(p1, n1) && tonumberns(p2, n2)) { + setfltvalue(res, numarith(L, op, n1, n2)); + return 1; + } + else return 0; /* fail */ + } + default: { /* other operations */ + lua_Number n1; lua_Number n2; + if (ttisinteger(p1) && ttisinteger(p2)) { + setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); + return 1; + } + else if (tonumberns(p1, n1) && tonumberns(p2, n2)) { + setfltvalue(res, numarith(L, op, n1, n2)); + return 1; + } + else return 0; /* fail */ + } + } +} + + +void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, + StkId res) { + if (!luaO_rawarith(L, op, p1, p2, s2v(res))) { + /* could not perform raw operation; try metamethod */ + luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD)); + } +} + + +int luaO_hexavalue (int c) { + if (lisdigit(c)) return c - '0'; + else return (ltolower(c) - 'a') + 10; +} + + +static int isneg (const char **s) { + if (**s == '-') { (*s)++; return 1; } + else if (**s == '+') (*s)++; + return 0; +} + + + +/* +** {================================================================== +** Lua's implementation for 'lua_strx2number' +** =================================================================== +*/ + +#if !defined(lua_strx2number) + +/* maximum number of significant digits to read (to avoid overflows + even with single floats) */ +#define MAXSIGDIG 30 + +/* +** convert a hexadecimal numeric string to a number, following +** C99 specification for 'strtod' +*/ +static lua_Number lua_strx2number (const char *s, char **endptr) { + int dot = lua_getlocaledecpoint(); + lua_Number r = l_mathop(0.0); /* result (accumulator) */ + int sigdig = 0; /* number of significant digits */ + int nosigdig = 0; /* number of non-significant digits */ + int e = 0; /* exponent correction */ + int neg; /* 1 if number is negative */ + int hasdot = 0; /* true after seen a dot */ + *endptr = cast_charp(s); /* nothing is valid yet */ + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); /* check sign */ + if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ + return l_mathop(0.0); /* invalid format (no '0x') */ + for (s += 2; ; s++) { /* skip '0x' and read numeral */ + if (*s == dot) { + if (hasdot) break; /* second dot? stop loop */ + else hasdot = 1; + } + else if (lisxdigit(cast_uchar(*s))) { + if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ + nosigdig++; + else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ + r = (r * l_mathop(16.0)) + luaO_hexavalue(*s); + else e++; /* too many digits; ignore, but still count for exponent */ + if (hasdot) e--; /* decimal digit? correct exponent */ + } + else break; /* neither a dot nor a digit */ + } + if (nosigdig + sigdig == 0) /* no digits? */ + return l_mathop(0.0); /* invalid format */ + *endptr = cast_charp(s); /* valid up to here */ + e *= 4; /* each digit multiplies/divides value by 2^4 */ + if (*s == 'p' || *s == 'P') { /* exponent part? */ + int exp1 = 0; /* exponent value */ + int neg1; /* exponent sign */ + s++; /* skip 'p' */ + neg1 = isneg(&s); /* sign */ + if (!lisdigit(cast_uchar(*s))) + return l_mathop(0.0); /* invalid; must have at least one digit */ + while (lisdigit(cast_uchar(*s))) /* read exponent */ + exp1 = exp1 * 10 + *(s++) - '0'; + if (neg1) exp1 = -exp1; + e += exp1; + *endptr = cast_charp(s); /* valid up to here */ + } + if (neg) r = -r; + return l_mathop(ldexp)(r, e); +} + +#endif +/* }====================================================== */ + + +/* maximum length of a numeral to be converted to a number */ +#if !defined (L_MAXLENNUM) +#define L_MAXLENNUM 200 +#endif + +/* +** Convert string 's' to a Lua number (put in 'result'). Return NULL on +** fail or the address of the ending '\0' on success. ('mode' == 'x') +** means a hexadecimal numeral. +*/ +static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { + char *endptr; + *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */ + : lua_str2number(s, &endptr); + if (endptr == s) return NULL; /* nothing recognized? */ + while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */ + return (*endptr == '\0') ? endptr : NULL; /* OK iff no trailing chars */ +} + + +/* +** Convert string 's' to a Lua number (put in 'result') handling the +** current locale. +** This function accepts both the current locale or a dot as the radix +** mark. If the conversion fails, it may mean number has a dot but +** locale accepts something else. In that case, the code copies 's' +** to a buffer (because 's' is read-only), changes the dot to the +** current locale radix mark, and tries to convert again. +** The variable 'mode' checks for special characters in the string: +** - 'n' means 'inf' or 'nan' (which should be rejected) +** - 'x' means a hexadecimal numeral +** - '.' just optimizes the search for the common case (no special chars) +*/ +static const char *l_str2d (const char *s, lua_Number *result) { + const char *endptr; + const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */ + int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; + if (mode == 'n') /* reject 'inf' and 'nan' */ + return NULL; + endptr = l_str2dloc(s, result, mode); /* try to convert */ + if (endptr == NULL) { /* failed? may be a different locale */ + char buff[L_MAXLENNUM + 1]; + const char *pdot = strchr(s, '.'); + if (pdot == NULL || strlen(s) > L_MAXLENNUM) + return NULL; /* string too long or no dot; fail */ + strcpy(buff, s); /* copy string to buffer */ + buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ + endptr = l_str2dloc(buff, result, mode); /* try again */ + if (endptr != NULL) + endptr = s + (endptr - buff); /* make relative to 's' */ + } + return endptr; +} + + +#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10) +#define MAXLASTD cast_int(LUA_MAXINTEGER % 10) + +static const char *l_str2int (const char *s, lua_Integer *result) { + lua_Unsigned a = 0; + int empty = 1; + int neg; + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); + if (s[0] == '0' && + (s[1] == 'x' || s[1] == 'X')) { /* hex? */ + s += 2; /* skip '0x' */ + for (; lisxdigit(cast_uchar(*s)); s++) { + a = a * 16 + luaO_hexavalue(*s); + empty = 0; + } + } + else { /* decimal */ + for (; lisdigit(cast_uchar(*s)); s++) { + int d = *s - '0'; + if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ + return NULL; /* do not accept it (as integer) */ + a = a * 10 + d; + empty = 0; + } + } + while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ + if (empty || *s != '\0') return NULL; /* something wrong in the numeral */ + else { + *result = l_castU2S((neg) ? 0u - a : a); + return s; + } +} + + +size_t luaO_str2num (const char *s, TValue *o) { + lua_Integer i; lua_Number n; + const char *e; + if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */ + setivalue(o, i); + } + else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */ + setfltvalue(o, n); + } + else + return 0; /* conversion failed */ + return (e - s) + 1; /* success; return string size */ +} + + +int luaO_utf8esc (char *buff, unsigned long x) { + int n = 1; /* number of bytes put in buffer (backwards) */ + lua_assert(x <= 0x7FFFFFFFu); + if (x < 0x80) /* ascii? */ + buff[UTF8BUFFSZ - 1] = cast_char(x); + else { /* need continuation bytes */ + unsigned int mfb = 0x3f; /* maximum that fits in first byte */ + do { /* add continuation bytes */ + buff[UTF8BUFFSZ - (n++)] = cast_char(0x80 | (x & 0x3f)); + x >>= 6; /* remove added bits */ + mfb >>= 1; /* now there is one less bit available in first byte */ + } while (x > mfb); /* still needs continuation byte? */ + buff[UTF8BUFFSZ - n] = cast_char((~mfb << 1) | x); /* add first byte */ + } + return n; +} + + +/* +** Maximum length of the conversion of a number to a string. Must be +** enough to accommodate both LUA_INTEGER_FMT and LUA_NUMBER_FMT. +** (For a long long int, this is 19 digits plus a sign and a final '\0', +** adding to 21. For a long double, it can go to a sign, 33 digits, +** the dot, an exponent letter, an exponent sign, 5 exponent digits, +** and a final '\0', adding to 43.) +*/ +#define MAXNUMBER2STR 44 + + +/* +** Convert a number object to a string, adding it to a buffer +*/ +static int tostringbuff (TValue *obj, char *buff) { + int len; + lua_assert(ttisnumber(obj)); + if (ttisinteger(obj)) + len = lua_integer2str(buff, MAXNUMBER2STR, ivalue(obj)); + else { + len = lua_number2str(buff, MAXNUMBER2STR, fltvalue(obj)); + if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ + buff[len++] = lua_getlocaledecpoint(); + buff[len++] = '0'; /* adds '.0' to result */ + } + } + return len; +} + + +/* +** Convert a number object to a Lua string, replacing the value at 'obj' +*/ +void luaO_tostring (lua_State *L, TValue *obj) { + char buff[MAXNUMBER2STR]; + int len = tostringbuff(obj, buff); + setsvalue(L, obj, luaS_newlstr(L, buff, len)); +} + + + + +/* +** {================================================================== +** 'luaO_pushvfstring' +** =================================================================== +*/ + +/* +** Size for buffer space used by 'luaO_pushvfstring'. It should be +** (LUA_IDSIZE + MAXNUMBER2STR) + a minimal space for basic messages, +** so that 'luaG_addinfo' can work directly on the buffer. +*/ +#define BUFVFS (LUA_IDSIZE + MAXNUMBER2STR + 95) + +/* buffer used by 'luaO_pushvfstring' */ +typedef struct BuffFS { + lua_State *L; + int pushed; /* true if there is a part of the result on the stack */ + int blen; /* length of partial string in 'space' */ + char space[BUFVFS]; /* holds last part of the result */ +} BuffFS; + + +/* +** Push given string to the stack, as part of the result, and +** join it to previous partial result if there is one. +** It may call 'luaV_concat' while using one slot from EXTRA_STACK. +** This call cannot invoke metamethods, as both operands must be +** strings. It can, however, raise an error if the result is too +** long. In that case, 'luaV_concat' frees the extra slot before +** raising the error. +*/ +static void pushstr (BuffFS *buff, const char *str, size_t lstr) { + lua_State *L = buff->L; + setsvalue2s(L, L->top.p, luaS_newlstr(L, str, lstr)); + L->top.p++; /* may use one slot from EXTRA_STACK */ + if (!buff->pushed) /* no previous string on the stack? */ + buff->pushed = 1; /* now there is one */ + else /* join previous string with new one */ + luaV_concat(L, 2); +} + + +/* +** empty the buffer space into the stack +*/ +static void clearbuff (BuffFS *buff) { + pushstr(buff, buff->space, buff->blen); /* push buffer contents */ + buff->blen = 0; /* space now is empty */ +} + + +/* +** Get a space of size 'sz' in the buffer. If buffer has not enough +** space, empty it. 'sz' must fit in an empty buffer. +*/ +static char *getbuff (BuffFS *buff, int sz) { + lua_assert(buff->blen <= BUFVFS); lua_assert(sz <= BUFVFS); + if (sz > BUFVFS - buff->blen) /* not enough space? */ + clearbuff(buff); + return buff->space + buff->blen; +} + + +#define addsize(b,sz) ((b)->blen += (sz)) + + +/* +** Add 'str' to the buffer. If string is larger than the buffer space, +** push the string directly to the stack. +*/ +static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { + if (slen <= BUFVFS) { /* does string fit into buffer? */ + char *bf = getbuff(buff, cast_int(slen)); + memcpy(bf, str, slen); /* add string to buffer */ + addsize(buff, cast_int(slen)); + } + else { /* string larger than buffer */ + clearbuff(buff); /* string comes after buffer's content */ + pushstr(buff, str, slen); /* push string */ + } +} + + +/* +** Add a numeral to the buffer. +*/ +static void addnum2buff (BuffFS *buff, TValue *num) { + char *numbuff = getbuff(buff, MAXNUMBER2STR); + int len = tostringbuff(num, numbuff); /* format number into 'numbuff' */ + addsize(buff, len); +} + + +/* +** this function handles only '%d', '%c', '%f', '%p', '%s', and '%%' + conventional formats, plus Lua-specific '%I' and '%U' +*/ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + BuffFS buff; /* holds last part of the result */ + const char *e; /* points to next '%' */ + buff.pushed = buff.blen = 0; + buff.L = L; + while ((e = strchr(fmt, '%')) != NULL) { + addstr2buff(&buff, fmt, e - fmt); /* add 'fmt' up to '%' */ + switch (*(e + 1)) { /* conversion specifier */ + case 's': { /* zero-terminated string */ + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + addstr2buff(&buff, s, strlen(s)); + break; + } + case 'c': { /* an 'int' as a character */ + char c = cast_uchar(va_arg(argp, int)); + addstr2buff(&buff, &c, sizeof(char)); + break; + } + case 'd': { /* an 'int' */ + TValue num; + setivalue(&num, va_arg(argp, int)); + addnum2buff(&buff, &num); + break; + } + case 'I': { /* a 'lua_Integer' */ + TValue num; + setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt))); + addnum2buff(&buff, &num); + break; + } + case 'f': { /* a 'lua_Number' */ + TValue num; + setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber))); + addnum2buff(&buff, &num); + break; + } + case 'p': { /* a pointer */ + const int sz = 3 * sizeof(void*) + 8; /* enough space for '%p' */ + char *bf = getbuff(&buff, sz); + void *p = va_arg(argp, void *); + int len = lua_pointer2str(bf, sz, p); + addsize(&buff, len); + break; + } + case 'U': { /* a 'long' as a UTF-8 sequence */ + char bf[UTF8BUFFSZ]; + int len = luaO_utf8esc(bf, va_arg(argp, long)); + addstr2buff(&buff, bf + UTF8BUFFSZ - len, len); + break; + } + case '%': { + addstr2buff(&buff, "%", 1); + break; + } + default: { + luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'", + *(e + 1)); + } + } + fmt = e + 2; /* skip '%' and the specifier */ + } + addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ + clearbuff(&buff); /* empty buffer into the stack */ + lua_assert(buff.pushed == 1); + return getstr(tsvalue(s2v(L->top.p - 1))); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + +/* }================================================================== */ + + +#define RETS "..." +#define PRE "[string \"" +#define POS "\"]" + +#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) + +void luaO_chunkid (char *out, const char *source, size_t srclen) { + size_t bufflen = LUA_IDSIZE; /* free space in buffer */ + if (*source == '=') { /* 'literal' source */ + if (srclen <= bufflen) /* small enough? */ + memcpy(out, source + 1, srclen * sizeof(char)); + else { /* truncate it */ + addstr(out, source + 1, bufflen - 1); + *out = '\0'; + } + } + else if (*source == '@') { /* file name */ + if (srclen <= bufflen) /* small enough? */ + memcpy(out, source + 1, srclen * sizeof(char)); + else { /* add '...' before rest of name */ + addstr(out, RETS, LL(RETS)); + bufflen -= LL(RETS); + memcpy(out, source + 1 + srclen - bufflen, bufflen * sizeof(char)); + } + } + else { /* string; format as [string "source"] */ + const char *nl = strchr(source, '\n'); /* find first new line (if any) */ + addstr(out, PRE, LL(PRE)); /* add prefix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ + if (srclen < bufflen && nl == NULL) { /* small one-line source? */ + addstr(out, source, srclen); /* keep it */ + } + else { + if (nl != NULL) srclen = nl - source; /* stop at first newline */ + if (srclen > bufflen) srclen = bufflen; + addstr(out, source, srclen); + addstr(out, RETS, LL(RETS)); + } + memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); + } +} + diff --git a/arm9/source/lua/lobject.h b/arm9/source/lua/lobject.h new file mode 100644 index 000000000..980e42f8c --- /dev/null +++ b/arm9/source/lua/lobject.h @@ -0,0 +1,813 @@ +/* +** $Id: lobject.h $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* +** Extra types for collectable non-values +*/ +#define LUA_TUPVAL LUA_NUMTYPES /* upvalues */ +#define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */ +#define LUA_TDEADKEY (LUA_NUMTYPES+2) /* removed keys in tables */ + + + +/* +** number of all possible types (including LUA_TNONE but excluding DEADKEY) +*/ +#define LUA_TOTALTYPES (LUA_TPROTO + 2) + + +/* +** tags for Tagged Values have the following use of bits: +** bits 0-3: actual tag (a LUA_T* constant) +** bits 4-5: variant bits +** bit 6: whether value is collectable +*/ + +/* add variant bits to a type */ +#define makevariant(t,v) ((t) | ((v) << 4)) + + + +/* +** Union of all Lua values +*/ +typedef union Value { + struct GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + lua_CFunction f; /* light C functions */ + lua_Integer i; /* integer numbers */ + lua_Number n; /* float numbers */ + /* not used, but may avoid warnings for uninitialized value */ + lu_byte ub; +} Value; + + +/* +** Tagged Values. This is the basic representation of values in Lua: +** an actual value plus a tag with its type. +*/ + +#define TValuefields Value value_; lu_byte tt_ + +typedef struct TValue { + TValuefields; +} TValue; + + +#define val_(o) ((o)->value_) +#define valraw(o) (val_(o)) + + +/* raw type tag of a TValue */ +#define rawtt(o) ((o)->tt_) + +/* tag with no variants (bits 0-3) */ +#define novariant(t) ((t) & 0x0F) + +/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ +#define withvariant(t) ((t) & 0x3F) +#define ttypetag(o) withvariant(rawtt(o)) + +/* type of a TValue */ +#define ttype(o) (novariant(rawtt(o))) + + +/* Macros to test type */ +#define checktag(o,t) (rawtt(o) == (t)) +#define checktype(o,t) (ttype(o) == (t)) + + +/* Macros for internal tests */ + +/* collectable object has the same tag as the original value */ +#define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt) + +/* +** Any value being manipulated by the program either is non +** collectable, or the collectable object has the right tag +** and it is not dead. The option 'L == NULL' allows other +** macros using this one to be used where L is not available. +*/ +#define checkliveness(L,obj) \ + ((void)L, lua_longassert(!iscollectable(obj) || \ + (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))) + + +/* Macros to set values */ + +/* set a value's tag */ +#define settt_(o,t) ((o)->tt_=(t)) + + +/* main macro to copy values (from 'obj2' to 'obj1') */ +#define setobj(L,obj1,obj2) \ + { TValue *io1=(obj1); const TValue *io2=(obj2); \ + io1->value_ = io2->value_; settt_(io1, io2->tt_); \ + checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); } + +/* +** Different types of assignments, according to source and destination. +** (They are mostly equal now, but may be different in the future.) +*/ + +/* from stack to stack */ +#define setobjs2s(L,o1,o2) setobj(L,s2v(o1),s2v(o2)) +/* to stack (not from same stack) */ +#define setobj2s(L,o1,o2) setobj(L,s2v(o1),o2) +/* from table to same table */ +#define setobjt2t setobj +/* to new object */ +#define setobj2n setobj +/* to table */ +#define setobj2t setobj + + +/* +** Entries in a Lua stack. Field 'tbclist' forms a list of all +** to-be-closed variables active in this stack. Dummy entries are +** used when the distance between two tbc variables does not fit +** in an unsigned short. They are represented by delta==0, and +** their real delta is always the maximum value that fits in +** that field. +*/ +typedef union StackValue { + TValue val; + struct { + TValuefields; + unsigned short delta; + } tbclist; +} StackValue; + + +/* index to stack elements */ +typedef StackValue *StkId; + + +/* +** When reallocating the stack, change all pointers to the stack into +** proper offsets. +*/ +typedef union { + StkId p; /* actual pointer */ + ptrdiff_t offset; /* used while the stack is being reallocated */ +} StkIdRel; + + +/* convert a 'StackValue' to a 'TValue' */ +#define s2v(o) (&(o)->val) + + + +/* +** {================================================================== +** Nil +** =================================================================== +*/ + +/* Standard nil */ +#define LUA_VNIL makevariant(LUA_TNIL, 0) + +/* Empty slot (which might be different from a slot containing nil) */ +#define LUA_VEMPTY makevariant(LUA_TNIL, 1) + +/* Value returned for a key not found in a table (absent key) */ +#define LUA_VABSTKEY makevariant(LUA_TNIL, 2) + + +/* macro to test for (any kind of) nil */ +#define ttisnil(v) checktype((v), LUA_TNIL) + + +/* macro to test for a standard nil */ +#define ttisstrictnil(o) checktag((o), LUA_VNIL) + + +#define setnilvalue(obj) settt_(obj, LUA_VNIL) + + +#define isabstkey(v) checktag((v), LUA_VABSTKEY) + + +/* +** macro to detect non-standard nils (used only in assertions) +*/ +#define isnonstrictnil(v) (ttisnil(v) && !ttisstrictnil(v)) + + +/* +** By default, entries with any kind of nil are considered empty. +** (In any definition, values associated with absent keys must also +** be accepted as empty.) +*/ +#define isempty(v) ttisnil(v) + + +/* macro defining a value corresponding to an absent key */ +#define ABSTKEYCONSTANT {NULL}, LUA_VABSTKEY + + +/* mark an entry as empty */ +#define setempty(v) settt_(v, LUA_VEMPTY) + + + +/* }================================================================== */ + + +/* +** {================================================================== +** Booleans +** =================================================================== +*/ + + +#define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0) +#define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1) + +#define ttisboolean(o) checktype((o), LUA_TBOOLEAN) +#define ttisfalse(o) checktag((o), LUA_VFALSE) +#define ttistrue(o) checktag((o), LUA_VTRUE) + + +#define l_isfalse(o) (ttisfalse(o) || ttisnil(o)) + + +#define setbfvalue(obj) settt_(obj, LUA_VFALSE) +#define setbtvalue(obj) settt_(obj, LUA_VTRUE) + +/* }================================================================== */ + + +/* +** {================================================================== +** Threads +** =================================================================== +*/ + +#define LUA_VTHREAD makevariant(LUA_TTHREAD, 0) + +#define ttisthread(o) checktag((o), ctb(LUA_VTHREAD)) + +#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) + +#define setthvalue(L,obj,x) \ + { TValue *io = (obj); lua_State *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTHREAD)); \ + checkliveness(L,io); } + +#define setthvalue2s(L,o,t) setthvalue(L,s2v(o),t) + +/* }================================================================== */ + + +/* +** {================================================================== +** Collectable Objects +** =================================================================== +*/ + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader struct GCObject *next; lu_byte tt; lu_byte marked + + +/* Common type for all collectable objects */ +typedef struct GCObject { + CommonHeader; +} GCObject; + + +/* Bit mark for collectable types */ +#define BIT_ISCOLLECTABLE (1 << 6) + +#define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE) + +/* mark a tag as collectable */ +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) + +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) + +#define gcvalueraw(v) ((v).gc) + +#define setgcovalue(L,obj,x) \ + { TValue *io = (obj); GCObject *i_g=(x); \ + val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Numbers +** =================================================================== +*/ + +/* Variant tags for numbers */ +#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */ +#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */ + +#define ttisnumber(o) checktype((o), LUA_TNUMBER) +#define ttisfloat(o) checktag((o), LUA_VNUMFLT) +#define ttisinteger(o) checktag((o), LUA_VNUMINT) + +#define nvalue(o) check_exp(ttisnumber(o), \ + (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) +#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) +#define ivalue(o) check_exp(ttisinteger(o), val_(o).i) + +#define fltvalueraw(v) ((v).n) +#define ivalueraw(v) ((v).i) + +#define setfltvalue(obj,x) \ + { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_VNUMFLT); } + +#define chgfltvalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); } + +#define setivalue(obj,x) \ + { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_VNUMINT); } + +#define chgivalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Strings +** =================================================================== +*/ + +/* Variant tags for strings */ +#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */ +#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */ + +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_VSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_VLNGSTR)) + +#define tsvalueraw(v) (gco2ts((v).gc)) + +#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) + +#define setsvalue(L,obj,x) \ + { TValue *io = (obj); TString *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ + checkliveness(L,io); } + +/* set a string to the stack */ +#define setsvalue2s(L,o,s) setsvalue(L,s2v(o),s) + +/* set a string to a new object */ +#define setsvalue2n setsvalue + + +/* +** Header for a string value. +*/ +typedef struct TString { + CommonHeader; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ + lu_byte shrlen; /* length for short strings, 0xFF for long strings */ + unsigned int hash; + union { + size_t lnglen; /* length for long strings */ + struct TString *hnext; /* linked list for hash table */ + } u; + char contents[1]; +} TString; + + + +/* +** Get the actual string (array of bytes) from a 'TString'. (Generic +** version and specialized versions for long and short strings.) +*/ +#define getstr(ts) ((ts)->contents) +#define getlngstr(ts) check_exp((ts)->shrlen == 0xFF, (ts)->contents) +#define getshrstr(ts) check_exp((ts)->shrlen != 0xFF, (ts)->contents) + + +/* get string length from 'TString *s' */ +#define tsslen(s) \ + ((s)->shrlen != 0xFF ? (s)->shrlen : (s)->u.lnglen) + +/* }================================================================== */ + + +/* +** {================================================================== +** Userdata +** =================================================================== +*/ + + +/* +** Light userdata should be a variant of userdata, but for compatibility +** reasons they are also different types. +*/ +#define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0) + +#define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0) + +#define ttislightuserdata(o) checktag((o), LUA_VLIGHTUSERDATA) +#define ttisfulluserdata(o) checktag((o), ctb(LUA_VUSERDATA)) + +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) + +#define pvalueraw(v) ((v).p) + +#define setpvalue(obj,x) \ + { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_VLIGHTUSERDATA); } + +#define setuvalue(L,obj,x) \ + { TValue *io = (obj); Udata *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VUSERDATA)); \ + checkliveness(L,io); } + + +/* Ensures that addresses after this type are always fully aligned. */ +typedef union UValue { + TValue uv; + LUAI_MAXALIGN; /* ensures maximum alignment for udata bytes */ +} UValue; + + +/* +** Header for userdata with user values; +** memory area follows the end of this structure. +*/ +typedef struct Udata { + CommonHeader; + unsigned short nuvalue; /* number of user values */ + size_t len; /* number of bytes */ + struct Table *metatable; + GCObject *gclist; + UValue uv[1]; /* user values */ +} Udata; + + +/* +** Header for userdata with no user values. These userdata do not need +** to be gray during GC, and therefore do not need a 'gclist' field. +** To simplify, the code always use 'Udata' for both kinds of userdata, +** making sure it never accesses 'gclist' on userdata with no user values. +** This structure here is used only to compute the correct size for +** this representation. (The 'bindata' field in its end ensures correct +** alignment for binary data following this header.) +*/ +typedef struct Udata0 { + CommonHeader; + unsigned short nuvalue; /* number of user values */ + size_t len; /* number of bytes */ + struct Table *metatable; + union {LUAI_MAXALIGN;} bindata; +} Udata0; + + +/* compute the offset of the memory area of a userdata */ +#define udatamemoffset(nuv) \ + ((nuv) == 0 ? offsetof(Udata0, bindata) \ + : offsetof(Udata, uv) + (sizeof(UValue) * (nuv))) + +/* get the address of the memory block inside 'Udata' */ +#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) + +/* compute the size of a userdata */ +#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb)) + +/* }================================================================== */ + + +/* +** {================================================================== +** Prototypes +** =================================================================== +*/ + +#define LUA_VPROTO makevariant(LUA_TPROTO, 0) + + +/* +** Description of an upvalue for function prototypes +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack (register) */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ + lu_byte kind; /* kind of corresponding variable */ +} Upvaldesc; + + +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + +/* +** Associates the absolute line source for a given instruction ('pc'). +** The array 'lineinfo' gives, for each instruction, the difference in +** lines from the previous instruction. When that difference does not +** fit into a byte, Lua saves the absolute line for that instruction. +** (Lua also saves the absolute line periodically, to speed up the +** computation of a line number: we can use binary search in the +** absolute-line array, but we must traverse the 'lineinfo' array +** linearly to compute a line.) +*/ +typedef struct AbsLineInfo { + int pc; + int line; +} AbsLineInfo; + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + lu_byte numparams; /* number of fixed (named) parameters */ + lu_byte is_vararg; + lu_byte maxstacksize; /* number of registers needed by this function */ + int sizeupvalues; /* size of 'upvalues' */ + int sizek; /* size of 'k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of 'p' */ + int sizelocvars; + int sizeabslineinfo; /* size of 'abslineinfo' */ + int linedefined; /* debug information */ + int lastlinedefined; /* debug information */ + TValue *k; /* constants used by the function */ + Instruction *code; /* opcodes */ + struct Proto **p; /* functions defined inside the function */ + Upvaldesc *upvalues; /* upvalue information */ + ls_byte *lineinfo; /* information about source lines (debug information) */ + AbsLineInfo *abslineinfo; /* idem */ + LocVar *locvars; /* information about local variables (debug information) */ + TString *source; /* used for debug information */ + GCObject *gclist; +} Proto; + +/* }================================================================== */ + + +/* +** {================================================================== +** Functions +** =================================================================== +*/ + +#define LUA_VUPVAL makevariant(LUA_TUPVAL, 0) + + +/* Variant tags for functions */ +#define LUA_VLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */ +#define LUA_VLCF makevariant(LUA_TFUNCTION, 1) /* light C function */ +#define LUA_VCCL makevariant(LUA_TFUNCTION, 2) /* C closure */ + +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisLclosure(o) checktag((o), ctb(LUA_VLCL)) +#define ttislcf(o) checktag((o), LUA_VLCF) +#define ttisCclosure(o) checktag((o), ctb(LUA_VCCL)) +#define ttisclosure(o) (ttisLclosure(o) || ttisCclosure(o)) + + +#define isLfunction(o) ttisLclosure(o) + +#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) +#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) + +#define fvalueraw(v) ((v).f) + +#define setclLvalue(L,obj,x) \ + { TValue *io = (obj); LClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VLCL)); \ + checkliveness(L,io); } + +#define setclLvalue2s(L,o,cl) setclLvalue(L,s2v(o),cl) + +#define setfvalue(obj,x) \ + { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_VLCF); } + +#define setclCvalue(L,obj,x) \ + { TValue *io = (obj); CClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VCCL)); \ + checkliveness(L,io); } + + +/* +** Upvalues for Lua closures +*/ +typedef struct UpVal { + CommonHeader; + union { + TValue *p; /* points to stack or to its own value */ + ptrdiff_t offset; /* used while the stack is being reallocated */ + } v; + union { + struct { /* (when open) */ + struct UpVal *next; /* linked list */ + struct UpVal **previous; + } open; + TValue value; /* the value (when closed) */ + } u; +} UpVal; + + + +#define ClosureHeader \ + CommonHeader; lu_byte nupvalues; GCObject *gclist + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; /* list of upvalues */ +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; /* list of upvalues */ +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define getproto(o) (clLvalue(o)->p) + +/* }================================================================== */ + + +/* +** {================================================================== +** Tables +** =================================================================== +*/ + +#define LUA_VTABLE makevariant(LUA_TTABLE, 0) + +#define ttistable(o) checktag((o), ctb(LUA_VTABLE)) + +#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) + +#define sethvalue(L,obj,x) \ + { TValue *io = (obj); Table *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTABLE)); \ + checkliveness(L,io); } + +#define sethvalue2s(L,o,h) sethvalue(L,s2v(o),h) + + +/* +** Nodes for Hash tables: A pack of two TValue's (key-value pairs) +** plus a 'next' field to link colliding entries. The distribution +** of the key's fields ('key_tt' and 'key_val') not forming a proper +** 'TValue' allows for a smaller size for 'Node' both in 4-byte +** and 8-byte alignments. +*/ +typedef union Node { + struct NodeKey { + TValuefields; /* fields for value */ + lu_byte key_tt; /* key type */ + int next; /* for chaining */ + Value key_val; /* key value */ + } u; + TValue i_val; /* direct access to node's value as a proper 'TValue' */ +} Node; + + +/* copy a value into a key */ +#define setnodekey(L,node,obj) \ + { Node *n_=(node); const TValue *io_=(obj); \ + n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \ + checkliveness(L,io_); } + + +/* copy a value from a key */ +#define getnodekey(L,obj,node) \ + { TValue *io_=(obj); const Node *n_=(node); \ + io_->value_ = n_->u.key_val; io_->tt_ = n_->u.key_tt; \ + checkliveness(L,io_); } + + +/* +** About 'alimit': if 'isrealasize(t)' is true, then 'alimit' is the +** real size of 'array'. Otherwise, the real size of 'array' is the +** smallest power of two not smaller than 'alimit' (or zero iff 'alimit' +** is zero); 'alimit' is then used as a hint for #t. +*/ + +#define BITRAS (1 << 7) +#define isrealasize(t) (!((t)->flags & BITRAS)) +#define setrealasize(t) ((t)->flags &= cast_byte(~BITRAS)) +#define setnorealasize(t) ((t)->flags |= BITRAS) + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

u.key_tt) +#define keyval(node) ((node)->u.key_val) + +#define keyisnil(node) (keytt(node) == LUA_TNIL) +#define keyisinteger(node) (keytt(node) == LUA_VNUMINT) +#define keyival(node) (keyval(node).i) +#define keyisshrstr(node) (keytt(node) == ctb(LUA_VSHRSTR)) +#define keystrval(node) (gco2ts(keyval(node).gc)) + +#define setnilkey(node) (keytt(node) = LUA_TNIL) + +#define keyiscollectable(n) (keytt(n) & BIT_ISCOLLECTABLE) + +#define gckey(n) (keyval(n).gc) +#define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL) + + +/* +** Dead keys in tables have the tag DEADKEY but keep their original +** gcvalue. This distinguishes them from regular keys but allows them to +** be found when searched in a special way. ('next' needs that to find +** keys removed from a table during a traversal.) +*/ +#define setdeadkey(node) (keytt(node) = LUA_TDEADKEY) +#define keyisdead(node) (keytt(node) == LUA_TDEADKEY) + +/* }================================================================== */ + + + +/* +** 'module' operation for hashing (size is always a power of 2) +*/ +#define lmod(s,size) \ + (check_exp((size&(size-1))==0, (cast_int((s) & ((size)-1))))) + + +#define twoto(x) (1<<(x)) +#define sizenode(t) (twoto((t)->lsizenode)) + + +/* size of buffer for 'luaO_utf8esc' function */ +#define UTF8BUFFSZ 8 + +LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); +LUAI_FUNC int luaO_ceillog2 (unsigned int x); +LUAI_FUNC int luaO_rawarith (lua_State *L, int op, const TValue *p1, + const TValue *p2, TValue *res); +LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, + const TValue *p2, StkId res); +LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); +LUAI_FUNC int luaO_hexavalue (int c); +LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t srclen); + + +#endif + diff --git a/arm9/source/lua/lopcodes.c b/arm9/source/lua/lopcodes.c new file mode 100644 index 000000000..c67aa227c --- /dev/null +++ b/arm9/source/lua/lopcodes.c @@ -0,0 +1,104 @@ +/* +** $Id: lopcodes.c $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#define lopcodes_c +#define LUA_CORE + +#include "lprefix.h" + + +#include "lopcodes.h" + + +/* ORDER OP */ + +LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* MM OT IT T A mode opcode */ + opmode(0, 0, 0, 0, 1, iABC) /* OP_MOVE */ + ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADI */ + ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LFALSESKIP */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABUP */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETFIELD */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABUP */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BANDK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BORK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXORK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHRI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHLI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADD */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUB */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MUL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MOD */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POW */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIV */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIV */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BAND */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BOR */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXOR */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHR */ + ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBIN */ + ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINI*/ + ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINK*/ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_UNM */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BNOT */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NOT */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LEN */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_CONCAT */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TBC */ + ,opmode(0, 0, 0, 0, 0, isJ) /* OP_JMP */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQ */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LT */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LE */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQK */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LTI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LEI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GTI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GEI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_TEST */ + ,opmode(0, 0, 0, 1, 1, iABC) /* OP_TESTSET */ + ,opmode(0, 1, 1, 0, 1, iABC) /* OP_CALL */ + ,opmode(0, 1, 1, 0, 1, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, 1, 0, 0, iABC) /* OP_RETURN */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN0 */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN1 */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORLOOP */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORPREP */ + ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ + ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ + ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ + ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ +}; + diff --git a/arm9/source/lua/lopcodes.h b/arm9/source/lua/lopcodes.h new file mode 100644 index 000000000..46911cac1 --- /dev/null +++ b/arm9/source/lua/lopcodes.h @@ -0,0 +1,405 @@ +/* +** $Id: lopcodes.h $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned 32-bit integers. + All instructions have an opcode in the first 7 bits. + Instructions can have the following formats: + + 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 + 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +iABC C(8) | B(8) |k| A(8) | Op(7) | +iABx Bx(17) | A(8) | Op(7) | +iAsBx sBx (signed)(17) | A(8) | Op(7) | +iAx Ax(25) | Op(7) | +isJ sJ (signed)(25) | Op(7) | + + A signed argument is represented in excess K: the represented value is + the written unsigned value minus K, where K is half the maximum for the + corresponding unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 8 +#define SIZE_B 8 +#define SIZE_Bx (SIZE_C + SIZE_B + 1) +#define SIZE_A 8 +#define SIZE_Ax (SIZE_Bx + SIZE_A) +#define SIZE_sJ (SIZE_Bx + SIZE_A) + +#define SIZE_OP 7 + +#define POS_OP 0 + +#define POS_A (POS_OP + SIZE_OP) +#define POS_k (POS_A + SIZE_A) +#define POS_B (POS_k + 1) +#define POS_C (POS_B + SIZE_B) + +#define POS_Bx POS_k + +#define POS_Ax POS_A + +#define POS_sJ POS_A + + +/* +** limits for opcode arguments. +** we use (signed) 'int' to manipulate most arguments, +** so they must fit in ints. +*/ + +/* Check whether type 'int' has at least 'b' bits ('b' < 32) */ +#define L_INTHASBITS(b) ((UINT_MAX >> ((b) - 1)) >= 1) + + +#if L_INTHASBITS(SIZE_Bx) +#define MAXARG_Bx ((1<>1) /* 'sBx' is signed */ + + +#if L_INTHASBITS(SIZE_Ax) +#define MAXARG_Ax ((1<> 1) + + +#define MAXARG_A ((1<> 1) + +#define int2sC(i) ((i) + OFFSET_sC) +#define sC2int(i) ((i) - OFFSET_sC) + + +/* creates a mask with 'n' 1 bits at position 'p' */ +#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p)) + +/* creates a mask with 'n' 0 bits at position 'p' */ +#define MASK0(n,p) (~MASK1(n,p)) + +/* +** the following macros help to manipulate instructions +*/ + +#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>(pos)) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<> sC */ +OP_SHLI,/* A B sC R[A] := sC << R[B] */ + +OP_ADD,/* A B C R[A] := R[B] + R[C] */ +OP_SUB,/* A B C R[A] := R[B] - R[C] */ +OP_MUL,/* A B C R[A] := R[B] * R[C] */ +OP_MOD,/* A B C R[A] := R[B] % R[C] */ +OP_POW,/* A B C R[A] := R[B] ^ R[C] */ +OP_DIV,/* A B C R[A] := R[B] / R[C] */ +OP_IDIV,/* A B C R[A] := R[B] // R[C] */ + +OP_BAND,/* A B C R[A] := R[B] & R[C] */ +OP_BOR,/* A B C R[A] := R[B] | R[C] */ +OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */ +OP_SHL,/* A B C R[A] := R[B] << R[C] */ +OP_SHR,/* A B C R[A] := R[B] >> R[C] */ + +OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] (*) */ +OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */ +OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */ + +OP_UNM,/* A B R[A] := -R[B] */ +OP_BNOT,/* A B R[A] := ~R[B] */ +OP_NOT,/* A B R[A] := not R[B] */ +OP_LEN,/* A B R[A] := #R[B] (length operator) */ + +OP_CONCAT,/* A B R[A] := R[A].. ... ..R[A + B - 1] */ + +OP_CLOSE,/* A close all upvalues >= R[A] */ +OP_TBC,/* A mark variable A "to be closed" */ +OP_JMP,/* sJ pc += sJ */ +OP_EQ,/* A B k if ((R[A] == R[B]) ~= k) then pc++ */ +OP_LT,/* A B k if ((R[A] < R[B]) ~= k) then pc++ */ +OP_LE,/* A B k if ((R[A] <= R[B]) ~= k) then pc++ */ + +OP_EQK,/* A B k if ((R[A] == K[B]) ~= k) then pc++ */ +OP_EQI,/* A sB k if ((R[A] == sB) ~= k) then pc++ */ +OP_LTI,/* A sB k if ((R[A] < sB) ~= k) then pc++ */ +OP_LEI,/* A sB k if ((R[A] <= sB) ~= k) then pc++ */ +OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */ +OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */ + +OP_TEST,/* A k if (not R[A] == k) then pc++ */ +OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] (*) */ + +OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */ +OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */ + +OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */ +OP_RETURN0,/* return */ +OP_RETURN1,/* A return R[A] */ + +OP_FORLOOP,/* A Bx update counters; if loop continues then pc-=Bx; */ +OP_FORPREP,/* A Bx ; + if not to run then pc+=Bx+1; */ + +OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */ +OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ +OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ + +OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ + +OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ + +OP_VARARG,/* A C R[A], R[A+1], ..., R[A+C-2] = vararg */ + +OP_VARARGPREP,/*A (adjust vararg parameters) */ + +OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ +} OpCode; + + +#define NUM_OPCODES ((int)(OP_EXTRAARG) + 1) + + + +/*=========================================================================== + Notes: + + (*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean + value, in a code equivalent to (not cond ? false : true). (It + produces false and skips the next instruction producing true.) + + (*) Opcodes OP_MMBIN and variants follow each arithmetic and + bitwise opcode. If the operation succeeds, it skips this next + opcode. Otherwise, this opcode calls the corresponding metamethod. + + (*) Opcode OP_TESTSET is used in short-circuit expressions that need + both to jump and to produce a value, such as (a = b or c). + + (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then + 'top' is set to last_result+1, so next open instruction (OP_CALL, + OP_RETURN*, OP_SETLIST) may use 'top'. + + (*) In OP_VARARG, if (C == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + + (*) In OP_RETURN, if (B == 0) then return up to 'top'. + + (*) In OP_LOADKX and OP_NEWTABLE, the next instruction is always + OP_EXTRAARG. + + (*) In OP_SETLIST, if (B == 0) then real B = 'top'; if k, then + real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the + bits of C). + + (*) In OP_NEWTABLE, B is log2 of the hash size (which is always a + power of 2) plus 1, or zero for size zero. If not k, the array size + is C. Otherwise, the array size is EXTRAARG _ C. + + (*) For comparisons, k specifies what condition the test should accept + (true or false). + + (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped + (the constant is the first operand). + + (*) All 'skips' (pc++) assume that next instruction is a jump. + + (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the + function builds upvalues, which may need to be closed. C > 0 means + the function is vararg, so that its 'func' must be corrected before + returning; in this case, (C - 1) is its number of fixed parameters. + + (*) In comparisons with an immediate operand, C signals whether the + original operand was a float. (It must be corrected in case of + metamethods.) + +===========================================================================*/ + + +/* +** masks for instruction properties. The format is: +** bits 0-2: op mode +** bit 3: instruction set register A +** bit 4: operator is a test (next instruction must be a jump) +** bit 5: instruction uses 'L->top' set by previous instruction (when B == 0) +** bit 6: instruction sets 'L->top' for next instruction (when C == 0) +** bit 7: instruction is an MM instruction (call a metamethod) +*/ + +LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];) + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 7)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 3)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 4)) +#define testITMode(m) (luaP_opmodes[m] & (1 << 5)) +#define testOTMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testMMMode(m) (luaP_opmodes[m] & (1 << 7)) + +/* "out top" (set top for next instruction) */ +#define isOT(i) \ + ((testOTMode(GET_OPCODE(i)) && GETARG_C(i) == 0) || \ + GET_OPCODE(i) == OP_TAILCALL) + +/* "in top" (uses top from previous instruction) */ +#define isIT(i) (testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0) + +#define opmode(mm,ot,it,t,a,m) \ + (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m)) + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + +#endif diff --git a/arm9/source/lua/lopnames.h b/arm9/source/lua/lopnames.h new file mode 100644 index 000000000..965cec9bf --- /dev/null +++ b/arm9/source/lua/lopnames.h @@ -0,0 +1,103 @@ +/* +** $Id: lopnames.h $ +** Opcode names +** See Copyright Notice in lua.h +*/ + +#if !defined(lopnames_h) +#define lopnames_h + +#include + + +/* ORDER OP */ + +static const char *const opnames[] = { + "MOVE", + "LOADI", + "LOADF", + "LOADK", + "LOADKX", + "LOADFALSE", + "LFALSESKIP", + "LOADTRUE", + "LOADNIL", + "GETUPVAL", + "SETUPVAL", + "GETTABUP", + "GETTABLE", + "GETI", + "GETFIELD", + "SETTABUP", + "SETTABLE", + "SETI", + "SETFIELD", + "NEWTABLE", + "SELF", + "ADDI", + "ADDK", + "SUBK", + "MULK", + "MODK", + "POWK", + "DIVK", + "IDIVK", + "BANDK", + "BORK", + "BXORK", + "SHRI", + "SHLI", + "ADD", + "SUB", + "MUL", + "MOD", + "POW", + "DIV", + "IDIV", + "BAND", + "BOR", + "BXOR", + "SHL", + "SHR", + "MMBIN", + "MMBINI", + "MMBINK", + "UNM", + "BNOT", + "NOT", + "LEN", + "CONCAT", + "CLOSE", + "TBC", + "JMP", + "EQ", + "LT", + "LE", + "EQK", + "EQI", + "LTI", + "LEI", + "GTI", + "GEI", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "RETURN0", + "RETURN1", + "FORLOOP", + "FORPREP", + "TFORPREP", + "TFORCALL", + "TFORLOOP", + "SETLIST", + "CLOSURE", + "VARARG", + "VARARGPREP", + "EXTRAARG", + NULL +}; + +#endif + diff --git a/arm9/source/lua/lparser.c b/arm9/source/lua/lparser.c new file mode 100644 index 000000000..2b888c7cf --- /dev/null +++ b/arm9/source/lua/lparser.c @@ -0,0 +1,1967 @@ +/* +** $Id: lparser.c $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#define lparser_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +/* maximum number of local variables per function (must be smaller + than 250, due to the bytecode format) */ +#define MAXVARS 200 + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + + +/* because all strings are unified by the scanner, the parser + can use pointer equality for string equality */ +#define eqstr(a,b) ((a) == (b)) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int firstlabel; /* index of first label in this block */ + int firstgoto; /* index of first pending goto in this block */ + lu_byte nactvar; /* # active locals outside the block */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isloop; /* true if 'block' is a loop */ + lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void statement (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static l_noret error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); +} + + +static l_noret errorlimit (FuncState *fs, int limit, const char *what) { + lua_State *L = fs->ls->L; + const char *msg; + int line = fs->f->linedefined; + const char *where = (line == 0) + ? "main function" + : luaO_pushfstring(L, "function at line %d", line); + msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", + what, limit, where); + luaX_syntaxerror(fs->ls, msg); +} + + +static void checklimit (FuncState *fs, int v, int l, const char *what) { + if (v > l) errorlimit(fs, l, what); +} + + +/* +** Test whether next token is 'c'; if so, skip it. +*/ +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +/* +** Check that next token is 'c'. +*/ +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + + +/* +** Check that next token is 'c' and skip it. +*/ +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + +/* +** Check that next token is 'what' and skip it. In case of error, +** raise an error that the expected 'what' should match a 'who' +** in line 'where' (if that is not the current line). +*/ +static void check_match (LexState *ls, int what, int who, int where) { + if (l_unlikely(!testnext(ls, what))) { + if (where == ls->linenumber) /* all in the same line? */ + error_expected(ls, what); /* do not need a complex message */ + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + "%s expected (to close %s at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.info = i; +} + + +static void codestring (expdesc *e, TString *s) { + e->f = e->t = NO_JUMP; + e->k = VKSTR; + e->u.strval = s; +} + + +static void codename (LexState *ls, expdesc *e) { + codestring(e, str_checkname(ls)); +} + + +/* +** Register a new local variable in the active 'Proto' (for debug +** information). +*/ +static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) { + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars, + LocVar, SHRT_MAX, "local variables"); + while (oldsize < f->sizelocvars) + f->locvars[oldsize++].varname = NULL; + f->locvars[fs->ndebugvars].varname = varname; + f->locvars[fs->ndebugvars].startpc = fs->pc; + luaC_objbarrier(ls->L, f, varname); + return fs->ndebugvars++; +} + + +/* +** Create a new local variable with the given 'name'. Return its index +** in the function. +*/ +static int new_localvar (LexState *ls, TString *name) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Dyndata *dyd = ls->dyd; + Vardesc *var; + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + MAXVARS, "local variables"); + luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, + dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); + var = &dyd->actvar.arr[dyd->actvar.n++]; + var->vd.kind = VDKREG; /* default */ + var->vd.name = name; + return dyd->actvar.n - 1 - fs->firstlocal; +} + +#define new_localvarliteral(ls,v) \ + new_localvar(ls, \ + luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); + + + +/* +** Return the "variable description" (Vardesc) of a given variable. +** (Unless noted otherwise, all variables are referred to by their +** compiler indices.) +*/ +static Vardesc *getlocalvardesc (FuncState *fs, int vidx) { + return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx]; +} + + +/* +** Convert 'nvar', a compiler index level, to its corresponding +** register. For that, search for the highest variable below that level +** that is in a register and uses its register index ('ridx') plus one. +*/ +static int reglevel (FuncState *fs, int nvar) { + while (nvar-- > 0) { + Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ + if (vd->vd.kind != RDKCTC) /* is in a register? */ + return vd->vd.ridx + 1; + } + return 0; /* no variables in registers */ +} + + +/* +** Return the number of variables in the register stack for the given +** function. +*/ +int luaY_nvarstack (FuncState *fs) { + return reglevel(fs, fs->nactvar); +} + + +/* +** Get the debug-information entry for current variable 'vidx'. +*/ +static LocVar *localdebuginfo (FuncState *fs, int vidx) { + Vardesc *vd = getlocalvardesc(fs, vidx); + if (vd->vd.kind == RDKCTC) + return NULL; /* no debug info. for constants */ + else { + int idx = vd->vd.pidx; + lua_assert(idx < fs->ndebugvars); + return &fs->f->locvars[idx]; + } +} + + +/* +** Create an expression representing variable 'vidx' +*/ +static void init_var (FuncState *fs, expdesc *e, int vidx) { + e->f = e->t = NO_JUMP; + e->k = VLOCAL; + e->u.var.vidx = vidx; + e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx; +} + + +/* +** Raises an error if variable described by 'e' is read only +*/ +static void check_readonly (LexState *ls, expdesc *e) { + FuncState *fs = ls->fs; + TString *varname = NULL; /* to be set if variable is const */ + switch (e->k) { + case VCONST: { + varname = ls->dyd->actvar.arr[e->u.info].vd.name; + break; + } + case VLOCAL: { + Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx); + if (vardesc->vd.kind != VDKREG) /* not a regular variable? */ + varname = vardesc->vd.name; + break; + } + case VUPVAL: { + Upvaldesc *up = &fs->f->upvalues[e->u.info]; + if (up->kind != VDKREG) + varname = up->name; + break; + } + default: + return; /* other cases cannot be read-only */ + } + if (varname) { + const char *msg = luaO_pushfstring(ls->L, + "attempt to assign to const variable '%s'", getstr(varname)); + luaK_semerror(ls, msg); /* error */ + } +} + + +/* +** Start the scope for the last 'nvars' created variables. +*/ +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + int reglevel = luaY_nvarstack(fs); + int i; + for (i = 0; i < nvars; i++) { + int vidx = fs->nactvar++; + Vardesc *var = getlocalvardesc(fs, vidx); + var->vd.ridx = reglevel++; + var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); + } +} + + +/* +** Close the scope for all variables up to level 'tolevel'. +** (debug info.) +*/ +static void removevars (FuncState *fs, int tolevel) { + fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); + while (fs->nactvar > tolevel) { + LocVar *var = localdebuginfo(fs, --fs->nactvar); + if (var) /* does it have debug information? */ + var->endpc = fs->pc; + } +} + + +/* +** Search the upvalues of the function 'fs' for one +** with the given 'name'. +*/ +static int searchupvalue (FuncState *fs, TString *name) { + int i; + Upvaldesc *up = fs->f->upvalues; + for (i = 0; i < fs->nups; i++) { + if (eqstr(up[i].name, name)) return i; + } + return -1; /* not found */ +} + + +static Upvaldesc *allocupvalue (FuncState *fs) { + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, MAXUPVAL, "upvalues"); + while (oldsize < f->sizeupvalues) + f->upvalues[oldsize++].name = NULL; + return &f->upvalues[fs->nups++]; +} + + +static int newupvalue (FuncState *fs, TString *name, expdesc *v) { + Upvaldesc *up = allocupvalue(fs); + FuncState *prev = fs->prev; + if (v->k == VLOCAL) { + up->instack = 1; + up->idx = v->u.var.ridx; + up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind; + lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name)); + } + else { + up->instack = 0; + up->idx = cast_byte(v->u.info); + up->kind = prev->f->upvalues[v->u.info].kind; + lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name)); + } + up->name = name; + luaC_objbarrier(fs->ls->L, fs->f, name); + return fs->nups - 1; +} + + +/* +** Look for an active local variable with the name 'n' in the +** function 'fs'. If found, initialize 'var' with it and return +** its expression kind; otherwise return -1. +*/ +static int searchvar (FuncState *fs, TString *n, expdesc *var) { + int i; + for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { + Vardesc *vd = getlocalvardesc(fs, i); + if (eqstr(n, vd->vd.name)) { /* found? */ + if (vd->vd.kind == RDKCTC) /* compile-time constant? */ + init_exp(var, VCONST, fs->firstlocal + i); + else /* real variable */ + init_var(fs, var, i); + return var->k; + } + } + return -1; /* not found */ +} + + +/* +** Mark block where variable at given level was defined +** (to emit close instructions later). +*/ +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl->nactvar > level) + bl = bl->previous; + bl->upval = 1; + fs->needclose = 1; +} + + +/* +** Mark that current block has a to-be-closed variable. +*/ +static void marktobeclosed (FuncState *fs) { + BlockCnt *bl = fs->bl; + bl->upval = 1; + bl->insidetbc = 1; + fs->needclose = 1; +} + + +/* +** Find a variable with the given name 'n'. If it is an upvalue, add +** this upvalue into all intermediate functions. If it is a global, set +** 'var' as 'void' as a flag. +*/ +static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) /* no more levels? */ + init_exp(var, VVOID, 0); /* default is global */ + else { + int v = searchvar(fs, n, var); /* look up locals at current level */ + if (v >= 0) { /* found? */ + if (v == VLOCAL && !base) + markupval(fs, var->u.var.vidx); /* local will be used as an upval */ + } + else { /* not found as local at current level; try upvalues */ + int idx = searchupvalue(fs, n); /* try existing upvalues */ + if (idx < 0) { /* not found? */ + singlevaraux(fs->prev, n, var, 0); /* try upper levels */ + if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ + idx = newupvalue(fs, n, var); /* will be a new upvalue */ + else /* it is a global or a constant */ + return; /* don't need to do anything at this level */ + } + init_exp(var, VUPVAL, idx); /* new or old upvalue */ + } + } +} + + +/* +** Find a variable with the given name 'n', handling global variables +** too. +*/ +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + singlevaraux(fs, varname, var, 1); + if (var->k == VVOID) { /* global name? */ + expdesc key; + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + lua_assert(var->k != VVOID); /* this one must exist */ + luaK_exp2anyregup(fs, var); /* but could be a constant */ + codestring(&key, varname); /* key is variable name */ + luaK_indexed(fs, var, &key); /* env[varname] */ + } +} + + +/* +** Adjust the number of results from an expression list 'e' with 'nexps' +** expressions to 'nvars' values. +*/ +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int needed = nvars - nexps; /* extra values needed */ + if (hasmultret(e->k)) { /* last expression has multiple returns? */ + int extra = needed + 1; /* discount last expression itself */ + if (extra < 0) + extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + } + else { + if (e->k != VVOID) /* at least one expression? */ + luaK_exp2nextreg(fs, e); /* close last expression */ + if (needed > 0) /* missing values? */ + luaK_nil(fs, fs->freereg, needed); /* complete with nils */ + } + if (needed > 0) + luaK_reserveregs(fs, needed); /* registers for extra values */ + else /* adding 'needed' is actually a subtraction */ + fs->freereg += needed; /* remove extra values */ +} + + +#define enterlevel(ls) luaE_incCstack(ls->L) + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +/* +** Generates an error that a goto jumps into the scope of some +** local variable. +*/ +static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { + const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name); + const char *msg = " at line %d jumps into the scope of local '%s'"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); + luaK_semerror(ls, msg); /* raise the error */ +} + + +/* +** Solves the goto at index 'g' to given 'label' and removes it +** from the list of pending gotos. +** If it jumps into the scope of some variable, raises an error. +*/ +static void solvegoto (LexState *ls, int g, Labeldesc *label) { + int i; + Labellist *gl = &ls->dyd->gt; /* list of gotos */ + Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */ + lua_assert(eqstr(gt->name, label->name)); + if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ + jumpscopeerror(ls, gt); + luaK_patchlist(ls->fs, gt->pc, label->pc); + for (i = g; i < gl->n - 1; i++) /* remove goto from pending list */ + gl->arr[i] = gl->arr[i + 1]; + gl->n--; +} + + +/* +** Search for an active label with the given name. +*/ +static Labeldesc *findlabel (LexState *ls, TString *name) { + int i; + Dyndata *dyd = ls->dyd; + /* check labels in current function for a match */ + for (i = ls->fs->firstlabel; i < dyd->label.n; i++) { + Labeldesc *lb = &dyd->label.arr[i]; + if (eqstr(lb->name, name)) /* correct label? */ + return lb; + } + return NULL; /* label not found */ +} + + +/* +** Adds a new label/goto in the corresponding list. +*/ +static int newlabelentry (LexState *ls, Labellist *l, TString *name, + int line, int pc) { + int n = l->n; + luaM_growvector(ls->L, l->arr, n, l->size, + Labeldesc, SHRT_MAX, "labels/gotos"); + l->arr[n].name = name; + l->arr[n].line = line; + l->arr[n].nactvar = ls->fs->nactvar; + l->arr[n].close = 0; + l->arr[n].pc = pc; + l->n = n + 1; + return n; +} + + +static int newgotoentry (LexState *ls, TString *name, int line, int pc) { + return newlabelentry(ls, &ls->dyd->gt, name, line, pc); +} + + +/* +** Solves forward jumps. Check whether new label 'lb' matches any +** pending gotos in current block and solves them. Return true +** if any of the gotos need to close upvalues. +*/ +static int solvegotos (LexState *ls, Labeldesc *lb) { + Labellist *gl = &ls->dyd->gt; + int i = ls->fs->bl->firstgoto; + int needsclose = 0; + while (i < gl->n) { + if (eqstr(gl->arr[i].name, lb->name)) { + needsclose |= gl->arr[i].close; + solvegoto(ls, i, lb); /* will remove 'i' from the list */ + } + else + i++; + } + return needsclose; +} + + +/* +** Create a new label with the given 'name' at the given 'line'. +** 'last' tells whether label is the last non-op statement in its +** block. Solves all pending gotos to this new label and adds +** a close instruction if necessary. +** Returns true iff it added a close instruction. +*/ +static int createlabel (LexState *ls, TString *name, int line, + int last) { + FuncState *fs = ls->fs; + Labellist *ll = &ls->dyd->label; + int l = newlabelentry(ls, ll, name, line, luaK_getlabel(fs)); + if (last) { /* label is last no-op statement in the block? */ + /* assume that locals are already out of scope */ + ll->arr[l].nactvar = fs->bl->nactvar; + } + if (solvegotos(ls, &ll->arr[l])) { /* need close? */ + luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0); + return 1; + } + return 0; +} + + +/* +** Adjust pending gotos to outer level of a block. +*/ +static void movegotosout (FuncState *fs, BlockCnt *bl) { + int i; + Labellist *gl = &fs->ls->dyd->gt; + /* correct pending gotos to current block */ + for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ + Labeldesc *gt = &gl->arr[i]; + /* leaving a variable scope? */ + if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar)) + gt->close |= bl->upval; /* jump may need a close */ + gt->nactvar = bl->nactvar; /* update goto level */ + } +} + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { + bl->isloop = isloop; + bl->nactvar = fs->nactvar; + bl->firstlabel = fs->ls->dyd->label.n; + bl->firstgoto = fs->ls->dyd->gt.n; + bl->upval = 0; + bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == luaY_nvarstack(fs)); +} + + +/* +** generates an error for an undefined 'goto'. +*/ +static l_noret undefgoto (LexState *ls, Labeldesc *gt) { + const char *msg; + if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) { + msg = "break outside loop at line %d"; + msg = luaO_pushfstring(ls->L, msg, gt->line); + } + else { + msg = "no visible label '%s' for at line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); + } + luaK_semerror(ls, msg); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + LexState *ls = fs->ls; + int hasclose = 0; + int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */ + removevars(fs, bl->nactvar); /* remove block locals */ + lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */ + if (bl->isloop) /* has to fix pending breaks? */ + hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); + if (!hasclose && bl->previous && bl->upval) /* still need a 'close'? */ + luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); + fs->freereg = stklevel; /* free registers */ + ls->dyd->label.n = bl->firstlabel; /* remove local labels */ + fs->bl = bl->previous; /* current block now is previous one */ + if (bl->previous) /* was it a nested block? */ + movegotosout(fs, bl); /* update pending gotos to enclosing block */ + else { + if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */ + undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ + } +} + + +/* +** adds a new prototype into list of prototypes +*/ +static Proto *addprototype (LexState *ls) { + Proto *clp; + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; /* prototype of current function */ + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) + f->p[oldsize++] = NULL; + } + f->p[fs->np++] = clp = luaF_newproto(L); + luaC_objbarrier(L, f, clp); + return clp; +} + + +/* +** codes instruction to create new closure in parent function. +** The OP_CLOSURE instruction uses the last available register, +** so that, if it invokes the GC, the GC knows which registers +** are in use at that time. + +*/ +static void codeclosure (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs->prev; + init_exp(v, VRELOC, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ +} + + +static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { + Proto *f = fs->f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + ls->fs = fs; + fs->pc = 0; + fs->previousline = f->linedefined; + fs->iwthabs = 0; + fs->lasttarget = 0; + fs->freereg = 0; + fs->nk = 0; + fs->nabslineinfo = 0; + fs->np = 0; + fs->nups = 0; + fs->ndebugvars = 0; + fs->nactvar = 0; + fs->needclose = 0; + fs->firstlocal = ls->dyd->actvar.n; + fs->firstlabel = ls->dyd->label.n; + fs->bl = NULL; + f->source = ls->source; + luaC_objbarrier(ls->L, f, f->source); + f->maxstacksize = 2; /* registers 0/1 are always valid */ + enterblock(fs, bl, 0); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ + leaveblock(fs); + lua_assert(fs->bl == NULL); + luaK_finish(fs); + luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); + luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); + luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo, + fs->nabslineinfo, AbsLineInfo); + luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue); + luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); + luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); + luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + ls->fs = fs->prev; + luaC_checkGC(L); +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +/* +** check whether current token is in the follow set of a block. +** 'until' closes syntactical blocks, but do not close scope, +** so it is handled in separate. +*/ +static int block_follow (LexState *ls, int withuntil) { + switch (ls->t.token) { + case TK_ELSE: case TK_ELSEIF: + case TK_END: case TK_EOS: + return 1; + case TK_UNTIL: return withuntil; + default: return 0; + } +} + + +static void statlist (LexState *ls) { + /* statlist -> { stat [';'] } */ + while (!block_follow(ls, 1)) { + if (ls->t.token == TK_RETURN) { + statement(ls); + return; /* 'return' must be last statement */ + } + statement(ls); + } +} + + +static void fieldsel (LexState *ls, expdesc *v) { + /* fieldsel -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyregup(fs, v); + luaX_next(ls); /* skip the dot or colon */ + codename(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +typedef struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of 'record' elements */ + int na; /* number of array elements already stored */ + int tostore; /* number of array elements pending to be stored */ +} ConsControl; + + +static void recfield (LexState *ls, ConsControl *cc) { + /* recfield -> (NAME | '['exp']') = exp */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc tab, key, val; + if (ls->t.token == TK_NAME) { + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + codename(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + tab = *cc->t; + luaK_indexed(fs, &tab, &key); + expr(ls, &val); + luaK_storevar(fs, &tab, &val); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ + cc->na += cc->tostore; + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); + } + cc->na += cc->tostore; +} + + +static void listfield (LexState *ls, ConsControl *cc) { + /* listfield -> exp */ + expr(ls, &cc->v); + cc->tostore++; +} + + +static void field (LexState *ls, ConsControl *cc) { + /* field -> listfield | recfield */ + switch(ls->t.token) { + case TK_NAME: { /* may be 'listfield' or 'recfield' */ + if (luaX_lookahead(ls) != '=') /* expression? */ + listfield(ls, cc); + else + recfield(ls, cc); + break; + } + case '[': { + recfield(ls, cc); + break; + } + default: { + listfield(ls, cc); + break; + } + } +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> '{' [ field { sep field } [sep] ] '}' + sep -> ',' | ';' */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + ConsControl cc; + luaK_code(fs, 0); /* space for extra arg. */ + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VNONRELOC, fs->freereg); /* table will be at stack top */ + luaK_reserveregs(fs, 1); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + field(ls, &cc); + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh); +} + +/* }====================================================================== */ + + +static void setvararg (FuncState *fs, int nparams) { + fs->f->is_vararg = 1; + luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0); +} + + +static void parlist (LexState *ls) { + /* parlist -> [ {NAME ','} (NAME | '...') ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + int isvararg = 0; + if (ls->t.token != ')') { /* is 'parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { + new_localvar(ls, str_checkname(ls)); + nparams++; + break; + } + case TK_DOTS: { + luaX_next(ls); + isvararg = 1; + break; + } + default: luaX_syntaxerror(ls, " or '...' expected"); + } + } while (!isvararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar); + if (isvararg) + setvararg(fs, f->numparams); /* declared vararg */ + luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int ismethod, int line) { + /* body -> '(' parlist ')' block END */ + FuncState new_fs; + BlockCnt bl; + new_fs.f = addprototype(ls); + new_fs.f->linedefined = line; + open_func(ls, &new_fs, &bl); + checknext(ls, '('); + if (ismethod) { + new_localvarliteral(ls, "self"); /* create 'self' parameter */ + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + statlist(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + codeclosure(ls, e); + close_func(ls); +} + + +static int explist (LexState *ls, expdesc *v) { + /* explist -> expr { ',' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> '(' [ explist ] ')' */ + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist(ls, &args); + if (hasmultret(args.k)) + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(&args, ls->t.seminfo.ts); + luaX_next(ls); /* must use 'seminfo' before 'next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call removes function and arguments and leaves + one result (unless changed later) */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + } + } +} + + +static void suffixedexp (LexState *ls, expdesc *v) { + /* suffixedexp -> + primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + primaryexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* fieldsel */ + fieldsel(ls, v); + break; + } + case '[': { /* '[' exp ']' */ + expdesc key; + luaK_exp2anyregup(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* ':' NAME funcargs */ + expdesc key; + luaX_next(ls); + codename(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | + constructor | FUNCTION body | suffixedexp */ + switch (ls->t.token) { + case TK_FLT: { + init_exp(v, VKFLT, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_INT: { + init_exp(v, VKINT, 0); + v->u.ival = ls->t.seminfo.i; + break; + } + case TK_STRING: { + codestring(v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use '...' outside a vararg function"); + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + suffixedexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '~': return OPR_BNOT; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case '/': return OPR_DIV; + case TK_IDIV: return OPR_IDIV; + case '&': return OPR_BAND; + case '|': return OPR_BOR; + case '~': return OPR_BXOR; + case TK_SHL: return OPR_SHL; + case TK_SHR: return OPR_SHR; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +/* +** Priority table for binary operators. +*/ +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {10, 10}, {10, 10}, /* '+' '-' */ + {11, 11}, {11, 11}, /* '*' '%' */ + {14, 13}, /* '^' (right associative) */ + {11, 11}, {11, 11}, /* '/' '//' */ + {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ + {7, 7}, {7, 7}, /* '<<' '>>' */ + {9, 8}, /* '..' (right associative) */ + {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ + {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ + {2, 2}, {1, 1} /* and, or */ +}; + +#define UNARY_PRIORITY 12 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where 'binop' is any binary operator with a priority higher than 'limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */ + int line = ls->linenumber; + luaX_next(ls); /* skip operator */ + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v, line); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than 'limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + int line = ls->linenumber; + luaX_next(ls); /* skip operator */ + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2, line); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static void block (LexState *ls) { + /* block -> statlist */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + statlist(ls); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to an upvalue/local variable, the +** upvalue/local variable is begin used in a previous assignment to a +** table. If so, save original upvalue/local value in a safe place and +** use this safe copy in the previous assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { /* check all previous assignments */ + if (vkisindexed(lh->v.k)) { /* assignment to table field? */ + if (lh->v.k == VINDEXUP) { /* is table an upvalue? */ + if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) { + conflict = 1; /* table is the upvalue being assigned now */ + lh->v.k = VINDEXSTR; + lh->v.u.ind.t = extra; /* assignment will use safe copy */ + } + } + else { /* table is a register */ + if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) { + conflict = 1; /* table is the local being assigned now */ + lh->v.u.ind.t = extra; /* assignment will use safe copy */ + } + /* is index the local being assigned? */ + if (lh->v.k == VINDEXED && v->k == VLOCAL && + lh->v.u.ind.idx == v->u.var.ridx) { + conflict = 1; + lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ + } + } + } + } + if (conflict) { + /* copy upvalue/local value to a temporary (in position 'extra') */ + if (v->k == VLOCAL) + luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0); + else + luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0); + luaK_reserveregs(fs, 1); + } +} + +/* +** Parse and compile a multiple assignment. The first "variable" +** (a 'suffixedexp') was already read by the caller. +** +** assignment -> suffixedexp restassign +** restassign -> ',' suffixedexp restassign | '=' explist +*/ +static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, vkisvar(lh->v.k), "syntax error"); + check_readonly(ls, &lh->v); + if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */ + struct LHS_assign nv; + nv.prev = lh; + suffixedexp(ls, &nv.v); + if (!vkisindexed(nv.v.k)) + check_conflict(ls, lh, &nv.v); + enterlevel(ls); /* control recursion depth */ + restassign(ls, &nv, nvars+1); + leavelevel(ls); + } + else { /* restassign -> '=' explist */ + int nexps; + checknext(ls, '='); + nexps = explist(ls, &e); + if (nexps != nvars) + adjust_assign(ls, nvars, nexps, &e); + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void gotostat (LexState *ls) { + FuncState *fs = ls->fs; + int line = ls->linenumber; + TString *name = str_checkname(ls); /* label's name */ + Labeldesc *lb = findlabel(ls, name); + if (lb == NULL) /* no label? */ + /* forward jump; will be resolved when the label is declared */ + newgotoentry(ls, name, line, luaK_jump(fs)); + else { /* found a label */ + /* backward jump; will be resolved here */ + int lblevel = reglevel(fs, lb->nactvar); /* label level */ + if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */ + luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0); + /* create jump and link it to the label */ + luaK_patchlist(fs, luaK_jump(fs), lb->pc); + } +} + + +/* +** Break statement. Semantically equivalent to "goto break". +*/ +static void breakstat (LexState *ls) { + int line = ls->linenumber; + luaX_next(ls); /* skip break */ + newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, luaK_jump(ls->fs)); +} + + +/* +** Check whether there is already a label with the given 'name'. +*/ +static void checkrepeated (LexState *ls, TString *name) { + Labeldesc *lb = findlabel(ls, name); + if (l_unlikely(lb != NULL)) { /* already defined? */ + const char *msg = "label '%s' already defined on line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line); + luaK_semerror(ls, msg); /* error */ + } +} + + +static void labelstat (LexState *ls, TString *name, int line) { + /* label -> '::' NAME '::' */ + checknext(ls, TK_DBCOLON); /* skip double colon */ + while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) + statement(ls); /* skip other no-op statements */ + checkrepeated(ls, name); /* check for repeated labels */ + createlabel(ls, name, line, block_follow(ls, 0)); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_jumpto(fs, whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + statlist(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + leaveblock(fs); /* finish scope */ + if (bl2.upval) { /* upvalues? */ + int exit = luaK_jump(fs); /* normal exit must jump over fix */ + luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ + luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0); + condexit = luaK_jump(fs); /* repeat after closing upvalues */ + luaK_patchtohere(fs, exit); /* normal exit comes to here */ + } + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ + leaveblock(fs); /* finish loop */ +} + + +/* +** Read an expression and generate code to put its results in next +** stack slot. +** +*/ +static void exp1 (LexState *ls) { + expdesc e; + expr(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + lua_assert(e.k == VNONRELOC); +} + + +/* +** Fix for instruction at position 'pc' to jump to 'dest'. +** (Jump addresses are relative in Lua). 'back' true means +** a back jump. +*/ +static void fixforjump (FuncState *fs, int pc, int dest, int back) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + if (back) + offset = -offset; + if (l_unlikely(offset > MAXARG_Bx)) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_Bx(*jmp, offset); +} + + +/* +** Generate code for a 'for' loop. +*/ +static void forbody (LexState *ls, int base, int line, int nvars, int isgen) { + /* forbody -> DO block */ + static const OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP}; + static const OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP}; + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + checknext(ls, TK_DO); + prep = luaK_codeABx(fs, forprep[isgen], base, 0); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + fixforjump(fs, prep, luaK_getlabel(fs), 0); + if (isgen) { /* generic for? */ + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + } + endfor = luaK_codeABx(fs, forloop[isgen], base, 0); + fixforjump(fs, endfor, prep + 1, 1); + luaK_fixline(fs, line); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp,exp[,exp] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvar(ls, varname); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_int(fs, fs->freereg, 1); + luaK_reserveregs(fs, 1); + } + adjustlocalvars(ls, 3); /* control variables */ + forbody(ls, base, line, 1, 0); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 5; /* gen, state, control, toclose, 'indexname' */ + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + /* create declared variables */ + new_localvar(ls, indexname); + while (testnext(ls, ',')) { + new_localvar(ls, str_checkname(ls)); + nvars++; + } + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 4, explist(ls, &e), &e); + adjustlocalvars(ls, 4); /* control variables */ + marktobeclosed(fs); /* last control var. must be closed */ + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 4, 1); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip 'for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, "'=' or 'in' expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope ('break' jumps to this point) */ +} + + +static void test_then_block (LexState *ls, int *escapelist) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + BlockCnt bl; + FuncState *fs = ls->fs; + expdesc v; + int jf; /* instruction to skip 'then' code (if condition is false) */ + luaX_next(ls); /* skip IF or ELSEIF */ + expr(ls, &v); /* read condition */ + checknext(ls, TK_THEN); + if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */ + int line = ls->linenumber; + luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */ + luaX_next(ls); /* skip 'break' */ + enterblock(fs, &bl, 0); /* must enter block before 'goto' */ + newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t); + while (testnext(ls, ';')) {} /* skip semicolons */ + if (block_follow(ls, 0)) { /* jump is the entire block? */ + leaveblock(fs); + return; /* and that is it */ + } + else /* must skip over 'then' part if condition is false */ + jf = luaK_jump(fs); + } + else { /* regular case (not a break) */ + luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ + enterblock(fs, &bl, 0); + jf = v.f; + } + statlist(ls); /* 'then' part */ + leaveblock(fs); + if (ls->t.token == TK_ELSE || + ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ + luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int escapelist = NO_JUMP; /* exit list for finished parts */ + test_then_block(ls, &escapelist); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ + if (testnext(ls, TK_ELSE)) + block(ls); /* 'else' part */ + check_match(ls, TK_END, TK_IF, line); + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ +} + + +static void localfunc (LexState *ls) { + expdesc b; + FuncState *fs = ls->fs; + int fvar = fs->nactvar; /* function's variable index */ + new_localvar(ls, str_checkname(ls)); /* new local variable */ + adjustlocalvars(ls, 1); /* enter its scope */ + body(ls, &b, 0, ls->linenumber); /* function created in next register */ + /* debug information will only see the variable after this point! */ + localdebuginfo(fs, fvar)->startpc = fs->pc; +} + + +static int getlocalattribute (LexState *ls) { + /* ATTRIB -> ['<' Name '>'] */ + if (testnext(ls, '<')) { + const char *attr = getstr(str_checkname(ls)); + checknext(ls, '>'); + if (strcmp(attr, "const") == 0) + return RDKCONST; /* read-only variable */ + else if (strcmp(attr, "close") == 0) + return RDKTOCLOSE; /* to-be-closed variable */ + else + luaK_semerror(ls, + luaO_pushfstring(ls->L, "unknown attribute '%s'", attr)); + } + return VDKREG; /* regular variable */ +} + + +static void checktoclose (FuncState *fs, int level) { + if (level != -1) { /* is there a to-be-closed variable? */ + marktobeclosed(fs); + luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0); + } +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */ + FuncState *fs = ls->fs; + int toclose = -1; /* index of to-be-closed variable (if any) */ + Vardesc *var; /* last variable */ + int vidx, kind; /* index and kind of last variable */ + int nvars = 0; + int nexps; + expdesc e; + do { + vidx = new_localvar(ls, str_checkname(ls)); + kind = getlocalattribute(ls); + getlocalvardesc(fs, vidx)->vd.kind = kind; + if (kind == RDKTOCLOSE) { /* to-be-closed? */ + if (toclose != -1) /* one already present? */ + luaK_semerror(ls, "multiple to-be-closed variables in local list"); + toclose = fs->nactvar + nvars; + } + nvars++; + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + var = getlocalvardesc(fs, vidx); /* get last variable */ + if (nvars == nexps && /* no adjustments? */ + var->vd.kind == RDKCONST && /* last variable is const? */ + luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ + var->vd.kind = RDKCTC; /* variable is a compile-time constant */ + adjustlocalvars(ls, nvars - 1); /* exclude last variable */ + fs->nactvar++; /* but count it */ + } + else { + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); + } + checktoclose(fs, toclose); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {fieldsel} [':' NAME] */ + int ismethod = 0; + singlevar(ls, v); + while (ls->t.token == '.') + fieldsel(ls, v); + if (ls->t.token == ':') { + ismethod = 1; + fieldsel(ls, v); + } + return ismethod; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int ismethod; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); + check_readonly(ls, &v); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + suffixedexp(ls, &v.v); + if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ + v.prev = NULL; + restassign(ls, &v, 1); + } + else { /* stat -> func */ + Instruction *inst; + check_condition(ls, v.v.k == VCALL, "syntax error"); + inst = &getinstruction(fs, &v.v); + SETARG_C(*inst, 1); /* call statement uses no results */ + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN [explist] [';'] */ + FuncState *fs = ls->fs; + expdesc e; + int nret; /* number of values being returned */ + int first = luaY_nvarstack(fs); /* first slot to be returned */ + if (block_follow(ls, 1) || ls->t.token == ';') + nret = 0; /* return no values */ + else { + nret = explist(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1 && !fs->bl->insidetbc) { /* tail call? */ + SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getinstruction(fs,&e)) == luaY_nvarstack(fs)); + } + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); /* can use original slot */ + else { /* values must go to the top of the stack */ + luaK_exp2nextreg(fs, &e); + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); + testnext(ls, ';'); /* skip optional semicolon */ +} + + +static void statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + enterlevel(ls); + switch (ls->t.token) { + case ';': { /* stat -> ';' (empty statement) */ + luaX_next(ls); /* skip ';' */ + break; + } + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + break; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + break; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + break; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + break; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + break; + } + case TK_FUNCTION: { /* stat -> funcstat */ + funcstat(ls, line); + break; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + break; + } + case TK_DBCOLON: { /* stat -> label */ + luaX_next(ls); /* skip double colon */ + labelstat(ls, str_checkname(ls), line); + break; + } + case TK_RETURN: { /* stat -> retstat */ + luaX_next(ls); /* skip RETURN */ + retstat(ls); + break; + } + case TK_BREAK: { /* stat -> breakstat */ + breakstat(ls); + break; + } + case TK_GOTO: { /* stat -> 'goto' NAME */ + luaX_next(ls); /* skip 'goto' */ + gotostat(ls); + break; + } + default: { /* stat -> func | assignment */ + exprstat(ls); + break; + } + } + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= luaY_nvarstack(ls->fs)); + ls->fs->freereg = luaY_nvarstack(ls->fs); /* free registers */ + leavelevel(ls); +} + +/* }====================================================================== */ + + +/* +** compiles the main function, which is a regular vararg function with an +** upvalue named LUA_ENV +*/ +static void mainfunc (LexState *ls, FuncState *fs) { + BlockCnt bl; + Upvaldesc *env; + open_func(ls, fs, &bl); + setvararg(fs, 0); /* main function is always declared vararg */ + env = allocupvalue(fs); /* ...set environment upvalue */ + env->instack = 1; + env->idx = 0; + env->kind = VDKREG; + env->name = ls->envn; + luaC_objbarrier(ls->L, fs->f, env->name); + luaX_next(ls); /* read first token */ + statlist(ls); /* parse main body */ + check(ls, TK_EOS); + close_func(ls); +} + + +LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar) { + LexState lexstate; + FuncState funcstate; + LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ + setclLvalue2s(L, L->top.p, cl); /* anchor it (to avoid being collected) */ + luaD_inctop(L); + lexstate.h = luaH_new(L); /* create table for scanner */ + sethvalue2s(L, L->top.p, lexstate.h); /* anchor it */ + luaD_inctop(L); + funcstate.f = cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ + luaC_objbarrier(L, funcstate.f, funcstate.f->source); + lexstate.buff = buff; + lexstate.dyd = dyd; + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); + mainfunc(&lexstate, &funcstate); + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); + /* all scopes should be correctly finished */ + lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); + L->top.p--; /* remove scanner's table */ + return cl; /* closure is on the stack, too */ +} + diff --git a/arm9/source/lua/lparser.h b/arm9/source/lua/lparser.h new file mode 100644 index 000000000..5e4500f18 --- /dev/null +++ b/arm9/source/lua/lparser.h @@ -0,0 +1,171 @@ +/* +** $Id: lparser.h $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression and variable descriptor. +** Code generation for variables and expressions can be delayed to allow +** optimizations; An 'expdesc' structure describes a potentially-delayed +** variable/expression. It has a description of its "main" value plus a +** list of conditional jumps that can also produce its value (generated +** by short-circuit operators 'and'/'or'). +*/ + +/* kinds of variables/expressions */ +typedef enum { + VVOID, /* when 'expdesc' describes the last expression of a list, + this kind means an empty list (so, no expression) */ + VNIL, /* constant nil */ + VTRUE, /* constant true */ + VFALSE, /* constant false */ + VK, /* constant in 'k'; info = index of constant in 'k' */ + VKFLT, /* floating constant; nval = numerical float value */ + VKINT, /* integer constant; ival = numerical integer value */ + VKSTR, /* string constant; strval = TString address; + (string is fixed by the lexer) */ + VNONRELOC, /* expression has its value in a fixed register; + info = result register */ + VLOCAL, /* local variable; var.ridx = register index; + var.vidx = relative index in 'actvar.arr' */ + VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ + VCONST, /* compile-time variable; + info = absolute index in 'actvar.arr' */ + VINDEXED, /* indexed variable; + ind.t = table register; + ind.idx = key's R index */ + VINDEXUP, /* indexed upvalue; + ind.t = table upvalue; + ind.idx = key's K index */ + VINDEXI, /* indexed variable with constant integer; + ind.t = table register; + ind.idx = key's value */ + VINDEXSTR, /* indexed variable with literal string; + ind.t = table register; + ind.idx = key's K index */ + VJMP, /* expression is a test/comparison; + info = pc of corresponding jump instruction */ + VRELOC, /* expression can put result in any register; + info = instruction pc */ + VCALL, /* expression is a function call; info = instruction pc */ + VVARARG /* vararg expression; info = instruction pc */ +} expkind; + + +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) +#define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) + + +typedef struct expdesc { + expkind k; + union { + lua_Integer ival; /* for VKINT */ + lua_Number nval; /* for VKFLT */ + TString *strval; /* for VKSTR */ + int info; /* for generic use */ + struct { /* for indexed variables */ + short idx; /* index (R or "long" K) */ + lu_byte t; /* table (register or upvalue) */ + } ind; + struct { /* for local variables */ + lu_byte ridx; /* register holding the variable */ + unsigned short vidx; /* compiler index (in 'actvar.arr') */ + } var; + } u; + int t; /* patch list of 'exit when true' */ + int f; /* patch list of 'exit when false' */ +} expdesc; + + +/* kinds of variables */ +#define VDKREG 0 /* regular */ +#define RDKCONST 1 /* constant */ +#define RDKTOCLOSE 2 /* to-be-closed */ +#define RDKCTC 3 /* compile-time constant */ + +/* description of an active local variable */ +typedef union Vardesc { + struct { + TValuefields; /* constant value (if it is a compile-time constant) */ + lu_byte kind; + lu_byte ridx; /* register holding the variable */ + short pidx; /* index of the variable in the Proto's 'locvars' array */ + TString *name; /* variable name */ + } vd; + TValue k; /* constant value (if any) */ +} Vardesc; + + + +/* description of pending goto statements and label statements */ +typedef struct Labeldesc { + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* number of active variables in that position */ + lu_byte close; /* goto that escapes upvalues */ +} Labeldesc; + + +/* list of labels or gotos */ +typedef struct Labellist { + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ +} Labellist; + + +/* dynamic structures used by the parser */ +typedef struct Dyndata { + struct { /* list of all active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ +} Dyndata; + + +/* control of blocks */ +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to 'ncode') */ + int lasttarget; /* 'label' of last 'jump label' */ + int previousline; /* last line that was saved in 'lineinfo' */ + int nk; /* number of elements in 'k' */ + int np; /* number of elements in 'p' */ + int nabslineinfo; /* number of elements in 'abslineinfo' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + int firstlabel; /* index of first label (in 'dyd->label->arr') */ + short ndebugvars; /* number of elements in 'f->locvars' */ + lu_byte nactvar; /* number of active local variables */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ + lu_byte iwthabs; /* instructions issued since last absolute line info */ + lu_byte needclose; /* function needs to close upvalues when returning */ +} FuncState; + + +LUAI_FUNC int luaY_nvarstack (FuncState *fs); +LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); + + +#endif diff --git a/arm9/source/lua/lprefix.h b/arm9/source/lua/lprefix.h new file mode 100644 index 000000000..484f2ad6f --- /dev/null +++ b/arm9/source/lua/lprefix.h @@ -0,0 +1,45 @@ +/* +** $Id: lprefix.h $ +** Definitions for Lua code that must come before any other header file +** See Copyright Notice in lua.h +*/ + +#ifndef lprefix_h +#define lprefix_h + + +/* +** Allows POSIX/XSI stuff +*/ +#if !defined(LUA_USE_C89) /* { */ + +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 +#elif _XOPEN_SOURCE == 0 +#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ +#endif + +/* +** Allows manipulation of large files in gcc and some other compilers +*/ +#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#endif + +#endif /* } */ + + +/* +** Windows stuff +*/ +#if defined(_WIN32) /* { */ + +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ +#endif + +#endif /* } */ + +#endif + diff --git a/arm9/source/lua/lstate.c b/arm9/source/lua/lstate.c new file mode 100644 index 000000000..703eabb57 --- /dev/null +++ b/arm9/source/lua/lstate.c @@ -0,0 +1,445 @@ +/* +** $Id: lstate.c $ +** Global State +** See Copyright Notice in lua.h +*/ + +#define lstate_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +/* +** thread state + extra space +*/ +typedef struct LX { + lu_byte extra_[LUA_EXTRASPACE]; + lua_State l; +} LX; + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + LX l; + global_State g; +} LG; + + + +#define fromstate(L) (castp(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) + + +/* +** A macro to create a "random" seed when a state is created; +** the seed is used to randomize string hashes. +*/ +#if !defined(luai_makeseed) + +#include + +/* +** Compute an initial seed with some level of randomness. +** Rely on Address Space Layout Randomization (if present) and +** current time. +*/ +#define addbuff(b,p,e) \ + { size_t t = cast_sizet(e); \ + memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } + +static unsigned int luai_makeseed (lua_State *L) { + char buff[3 * sizeof(size_t)]; + unsigned int h = cast_uint(time(NULL)); + int p = 0; + addbuff(buff, p, L); /* heap variable */ + addbuff(buff, p, &h); /* local variable */ + addbuff(buff, p, &lua_newstate); /* public function */ + lua_assert(p == sizeof(buff)); + return luaS_hash(buff, p, h); +} + +#endif + + +/* +** set GCdebt to a new value keeping the value (totalbytes + GCdebt) +** invariant (and avoiding underflows in 'totalbytes') +*/ +void luaE_setdebt (global_State *g, l_mem debt) { + l_mem tb = gettotalbytes(g); + lua_assert(tb > 0); + if (debt < tb - MAX_LMEM) + debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ + g->totalbytes = tb - debt; + g->GCdebt = debt; +} + + +LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { + UNUSED(L); UNUSED(limit); + return LUAI_MAXCCALLS; /* warning?? */ +} + + +CallInfo *luaE_extendCI (lua_State *L) { + CallInfo *ci; + lua_assert(L->ci->next == NULL); + ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); + L->ci->next = ci; + ci->previous = L->ci; + ci->next = NULL; + ci->u.l.trap = 0; + L->nci++; + return ci; +} + + +/* +** free all CallInfo structures not in use by a thread +*/ +static void freeCI (lua_State *L) { + CallInfo *ci = L->ci; + CallInfo *next = ci->next; + ci->next = NULL; + while ((ci = next) != NULL) { + next = ci->next; + luaM_free(L, ci); + L->nci--; + } +} + + +/* +** free half of the CallInfo structures not in use by a thread, +** keeping the first one. +*/ +void luaE_shrinkCI (lua_State *L) { + CallInfo *ci = L->ci->next; /* first free CallInfo */ + CallInfo *next; + if (ci == NULL) + return; /* no extra elements */ + while ((next = ci->next) != NULL) { /* two extra elements? */ + CallInfo *next2 = next->next; /* next's next */ + ci->next = next2; /* remove next from the list */ + L->nci--; + luaM_free(L, next); /* free next */ + if (next2 == NULL) + break; /* no more elements */ + else { + next2->previous = ci; + ci = next2; /* continue */ + } + } +} + + +/* +** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS. +** If equal, raises an overflow error. If value is larger than +** LUAI_MAXCCALLS (which means it is handling an overflow) but +** not much larger, does not report an error (to allow overflow +** handling to work). +*/ +void luaE_checkcstack (lua_State *L) { + if (getCcalls(L) == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) + luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ +} + + +LUAI_FUNC void luaE_incCstack (lua_State *L) { + L->nCcalls++; + if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) + luaE_checkcstack(L); +} + + +static void stack_init (lua_State *L1, lua_State *L) { + int i; CallInfo *ci; + /* initialize stack array */ + L1->stack.p = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); + L1->tbclist.p = L1->stack.p; + for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) + setnilvalue(s2v(L1->stack.p + i)); /* erase new stack */ + L1->top.p = L1->stack.p; + L1->stack_last.p = L1->stack.p + BASIC_STACK_SIZE; + /* initialize first ci */ + ci = &L1->base_ci; + ci->next = ci->previous = NULL; + ci->callstatus = CIST_C; + ci->func.p = L1->top.p; + ci->u.c.k = NULL; + ci->nresults = 0; + setnilvalue(s2v(L1->top.p)); /* 'function' entry for this 'ci' */ + L1->top.p++; + ci->top.p = L1->top.p + LUA_MINSTACK; + L1->ci = ci; +} + + +static void freestack (lua_State *L) { + if (L->stack.p == NULL) + return; /* stack not completely built yet */ + L->ci = &L->base_ci; /* free the entire 'ci' list */ + freeCI(L); + lua_assert(L->nci == 0); + luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */ +} + + +/* +** Create registry table and its predefined values +*/ +static void init_registry (lua_State *L, global_State *g) { + /* create registry */ + Table *registry = luaH_new(L); + sethvalue(L, &g->l_registry, registry); + luaH_resize(L, registry, LUA_RIDX_LAST, 0); + /* registry[LUA_RIDX_MAINTHREAD] = L */ + setthvalue(L, ®istry->array[LUA_RIDX_MAINTHREAD - 1], L); + /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */ + sethvalue(L, ®istry->array[LUA_RIDX_GLOBALS - 1], luaH_new(L)); +} + + +/* +** open parts of the state that may cause memory-allocation errors. +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + init_registry(L, g); + luaS_init(L); + luaT_init(L); + luaX_init(L); + g->gcstp = 0; /* allow gc */ + setnilvalue(&g->nilvalue); /* now state is complete */ + luai_userstateopen(L); +} + + +/* +** preinitialize a thread with consistent values without allocating +** any memory (to avoid errors) +*/ +static void preinit_thread (lua_State *L, global_State *g) { + G(L) = g; + L->stack.p = NULL; + L->ci = NULL; + L->nci = 0; + L->twups = L; /* thread has no upvalues */ + L->nCcalls = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->status = LUA_OK; + L->errfunc = 0; + L->oldpc = 0; +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + if (!completestate(g)) /* closing a partially built state? */ + luaC_freeallobjects(L); /* just collect its objects */ + else { /* closing a fully built state */ + L->ci = &L->base_ci; /* unwind CallInfo list */ + luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ + luaC_freeallobjects(L); /* collect all objects */ + luai_userstateclose(L); + } + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); + freestack(L); + lua_assert(gettotalbytes(g) == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + global_State *g = G(L); + GCObject *o; + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + /* create new thread */ + o = luaC_newobjdt(L, LUA_TTHREAD, sizeof(LX), offsetof(LX, l)); + L1 = gco2th(o); + /* anchor it on L stack */ + setthvalue2s(L, L->top.p, L1); + api_incr_top(L); + preinit_thread(L1, g); + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + /* initialize L1 extra space */ + memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), + LUA_EXTRASPACE); + luai_userstatethread(L, L1); + stack_init(L1, L); /* init stack */ + lua_unlock(L); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + LX *l = fromstate(L1); + luaF_closeupval(L1, L1->stack.p); /* close all upvalues */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L, L1); + freestack(L1); + luaM_free(L, l); +} + + +int luaE_resetthread (lua_State *L, int status) { + CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */ + setnilvalue(s2v(L->stack.p)); /* 'function' entry for basic 'ci' */ + ci->func.p = L->stack.p; + ci->callstatus = CIST_C; + if (status == LUA_YIELD) + status = LUA_OK; + L->status = LUA_OK; /* so it can run __close metamethods */ + status = luaD_closeprotected(L, 1, status); + if (status != LUA_OK) /* errors? */ + luaD_seterrorobj(L, status, L->stack.p + 1); + else + L->top.p = L->stack.p + 1; + ci->top.p = L->top.p + LUA_MINSTACK; + luaD_reallocstack(L, cast_int(ci->top.p - L->stack.p), 0); + return status; +} + + +LUA_API int lua_closethread (lua_State *L, lua_State *from) { + int status; + lua_lock(L); + L->nCcalls = (from) ? getCcalls(from) : 0; + status = luaE_resetthread(L, L->status); + lua_unlock(L); + return status; +} + + +/* +** Deprecated! Use 'lua_closethread' instead. +*/ +LUA_API int lua_resetthread (lua_State *L) { + return lua_closethread(L, NULL); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); + if (l == NULL) return NULL; + L = &l->l.l; + g = &l->g; + L->tt = LUA_VTHREAD; + g->currentwhite = bitmask(WHITE0BIT); + L->marked = luaC_white(g); + preinit_thread(L, g); + g->allgc = obj2gco(L); /* by now, only object is the main thread */ + L->next = NULL; + incnny(L); /* main thread is always non yieldable */ + g->frealloc = f; + g->ud = ud; + g->warnf = NULL; + g->ud_warn = NULL; + g->mainthread = L; + g->seed = luai_makeseed(L); + g->gcstp = GCSTPGC; /* no GC while building state */ + g->strt.size = g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->l_registry); + g->panic = NULL; + g->gcstate = GCSpause; + g->gckind = KGC_INC; + g->gcstopem = 0; + g->gcemergency = 0; + g->finobj = g->tobefnz = g->fixedgc = NULL; + g->firstold1 = g->survival = g->old1 = g->reallyold = NULL; + g->finobjsur = g->finobjold1 = g->finobjrold = NULL; + g->sweepgc = NULL; + g->gray = g->grayagain = NULL; + g->weak = g->ephemeron = g->allweak = NULL; + g->twups = NULL; + g->totalbytes = sizeof(LG); + g->GCdebt = 0; + g->lastatomic = 0; + setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ + setgcparam(g->gcpause, LUAI_GCPAUSE); + setgcparam(g->gcstepmul, LUAI_GCMUL); + g->gcstepsize = LUAI_GCSTEPSIZE; + setgcparam(g->genmajormul, LUAI_GENMAJORMUL); + g->genminormul = LUAI_GENMINORMUL; + for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + return L; +} + + +LUA_API void lua_close (lua_State *L) { + lua_lock(L); + L = G(L)->mainthread; /* only the main thread can be closed */ + close_state(L); +} + + +void luaE_warning (lua_State *L, const char *msg, int tocont) { + lua_WarnFunction wf = G(L)->warnf; + if (wf != NULL) + wf(G(L)->ud_warn, msg, tocont); +} + + +/* +** Generate a warning from an error message +*/ +void luaE_warnerror (lua_State *L, const char *where) { + TValue *errobj = s2v(L->top.p - 1); /* error object */ + const char *msg = (ttisstring(errobj)) + ? getstr(tsvalue(errobj)) + : "error object is not a string"; + /* produce warning "error in %s (%s)" (where, msg) */ + luaE_warning(L, "error in ", 1); + luaE_warning(L, where, 1); + luaE_warning(L, " (", 1); + luaE_warning(L, msg, 1); + luaE_warning(L, ")", 0); +} + diff --git a/arm9/source/lua/lstate.h b/arm9/source/lua/lstate.h new file mode 100644 index 000000000..620f24893 --- /dev/null +++ b/arm9/source/lua/lstate.h @@ -0,0 +1,408 @@ +/* +** $Id: lstate.h $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + + +/* Some header files included here need this definition */ +typedef struct CallInfo CallInfo; + + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + +/* +** Some notes about garbage-collected objects: All objects in Lua must +** be kept somehow accessible until being freed, so all objects always +** belong to one (and only one) of these lists, using field 'next' of +** the 'CommonHeader' for the link: +** +** 'allgc': all objects not marked for finalization; +** 'finobj': all objects marked for finalization; +** 'tobefnz': all objects ready to be finalized; +** 'fixedgc': all objects that are not to be collected (currently +** only small strings, such as reserved words). +** +** For the generational collector, some of these lists have marks for +** generations. Each mark points to the first element in the list for +** that particular generation; that generation goes until the next mark. +** +** 'allgc' -> 'survival': new objects; +** 'survival' -> 'old': objects that survived one collection; +** 'old1' -> 'reallyold': objects that became old in last collection; +** 'reallyold' -> NULL: objects old for more than one cycle. +** +** 'finobj' -> 'finobjsur': new objects marked for finalization; +** 'finobjsur' -> 'finobjold1': survived """"; +** 'finobjold1' -> 'finobjrold': just old """"; +** 'finobjrold' -> NULL: really old """". +** +** All lists can contain elements older than their main ages, due +** to 'luaC_checkfinalizer' and 'udata2finalize', which move +** objects between the normal lists and the "marked for finalization" +** lists. Moreover, barriers can age young objects in young lists as +** OLD0, which then become OLD1. However, a list never contains +** elements younger than their main ages. +** +** The generational collector also uses a pointer 'firstold1', which +** points to the first OLD1 object in the list. It is used to optimize +** 'markold'. (Potentially OLD1 objects can be anywhere between 'allgc' +** and 'reallyold', but often the list has no OLD1 objects or they are +** after 'old1'.) Note the difference between it and 'old1': +** 'firstold1': no OLD1 objects before this point; there can be all +** ages after it. +** 'old1': no objects younger than OLD1 after this point. +*/ + +/* +** Moreover, there is another set of lists that control gray objects. +** These lists are linked by fields 'gclist'. (All objects that +** can become gray have such a field. The field is not the same +** in all objects, but it always has this name.) Any gray object +** must belong to one of these lists, and all objects in these lists +** must be gray (with two exceptions explained below): +** +** 'gray': regular gray objects, still waiting to be visited. +** 'grayagain': objects that must be revisited at the atomic phase. +** That includes +** - black objects got in a write barrier; +** - all kinds of weak tables during propagation phase; +** - all threads. +** 'weak': tables with weak values to be cleared; +** 'ephemeron': ephemeron tables with white->white entries; +** 'allweak': tables with weak keys and/or weak values to be cleared. +** +** The exceptions to that "gray rule" are: +** - TOUCHED2 objects in generational mode stay in a gray list (because +** they must be visited again at the end of the cycle), but they are +** marked black because assignments to them must activate barriers (to +** move them back to TOUCHED1). +** - Open upvales are kept gray to avoid barriers, but they stay out +** of gray lists. (They don't even have a 'gclist' field.) +*/ + + + +/* +** About 'nCcalls': This count has two parts: the lower 16 bits counts +** the number of recursive invocations in the C stack; the higher +** 16 bits counts the number of non-yieldable calls in the stack. +** (They are together so that we can change and save both with one +** instruction.) +*/ + + +/* true if this thread does not have non-yieldable calls in the stack */ +#define yieldable(L) (((L)->nCcalls & 0xffff0000) == 0) + +/* real number of C calls */ +#define getCcalls(L) ((L)->nCcalls & 0xffff) + + +/* Increment the number of non-yieldable calls */ +#define incnny(L) ((L)->nCcalls += 0x10000) + +/* Decrement the number of non-yieldable calls */ +#define decnny(L) ((L)->nCcalls -= 0x10000) + +/* Non-yieldable call increment */ +#define nyci (0x10000 | 1) + + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* +** Atomic type (relative to signals) to better ensure that 'lua_sethook' +** is thread safe +*/ +#if !defined(l_signalT) +#include +#define l_signalT sig_atomic_t +#endif + + +/* +** Extra stack space to handle TM calls and some other extras. This +** space is not included in 'stack_last'. It is used only to avoid stack +** checks, either because the element will be promptly popped or because +** there will be a stack check soon after the push. Function frames +** never use this extra space, so it does not need to be kept clean. +*/ +#define EXTRA_STACK 5 + + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + +#define stacksize(th) cast_int((th)->stack_last.p - (th)->stack.p) + + +/* kinds of Garbage Collection */ +#define KGC_INC 0 /* incremental gc */ +#define KGC_GEN 1 /* generational gc */ + + +typedef struct stringtable { + TString **hash; + int nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** Information about a call. +** About union 'u': +** - field 'l' is used only for Lua functions; +** - field 'c' is used only for C functions. +** About union 'u2': +** - field 'funcidx' is used only by C functions while doing a +** protected call; +** - field 'nyield' is used only while a function is "doing" an +** yield (from the yield until the next resume); +** - field 'nres' is used only while closing tbc variables when +** returning from a function; +** - field 'transferinfo' is used only during call/returnhooks, +** before the function starts or after it ends. +*/ +struct CallInfo { + StkIdRel func; /* function index in the stack */ + StkIdRel top; /* top for this function */ + struct CallInfo *previous, *next; /* dynamic call link */ + union { + struct { /* only for Lua functions */ + const Instruction *savedpc; + volatile l_signalT trap; /* function is tracing lines/counts */ + int nextraargs; /* # of extra arguments in vararg functions */ + } l; + struct { /* only for C functions */ + lua_KFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lua_KContext ctx; /* context info. in case of yields */ + } c; + } u; + union { + int funcidx; /* called-function index */ + int nyield; /* number of values yielded */ + int nres; /* number of values returned */ + struct { /* info about transferred values (for call/return hooks) */ + unsigned short ftransfer; /* offset of first value transferred */ + unsigned short ntransfer; /* number of values transferred */ + } transferinfo; + } u2; + short nresults; /* expected number of results from this function */ + unsigned short callstatus; +}; + + +/* +** Bits in CallInfo status +*/ +#define CIST_OAH (1<<0) /* original value of 'allowhook' */ +#define CIST_C (1<<1) /* call is running a C function */ +#define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ +#define CIST_HOOKED (1<<3) /* call is running a debug hook */ +#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */ +#define CIST_TAIL (1<<5) /* call was tail called */ +#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ +#define CIST_FIN (1<<7) /* function "called" a finalizer */ +#define CIST_TRAN (1<<8) /* 'ci' has transfer information */ +#define CIST_CLSRET (1<<9) /* function is closing tbc variables */ +/* Bits 10-12 are used for CIST_RECST (see below) */ +#define CIST_RECST 10 +#if defined(LUA_COMPAT_LT_LE) +#define CIST_LEQ (1<<13) /* using __lt for __le */ +#endif + + +/* +** Field CIST_RECST stores the "recover status", used to keep the error +** status while closing to-be-closed variables in coroutines, so that +** Lua can correctly resume after an yield from a __close method called +** because of an error. (Three bits are enough for error status.) +*/ +#define getcistrecst(ci) (((ci)->callstatus >> CIST_RECST) & 7) +#define setcistrecst(ci,st) \ + check_exp(((st) & 7) == (st), /* status must fit in three bits */ \ + ((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \ + | ((st) << CIST_RECST))) + + +/* active function is a Lua function */ +#define isLua(ci) (!((ci)->callstatus & CIST_C)) + +/* call is running Lua code (not a hook) */ +#define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED))) + +/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ +#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) +#define getoah(st) ((st) & CIST_OAH) + + +/* +** 'global state', shared by all threads of this state +*/ +typedef struct global_State { + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to 'frealloc' */ + l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + TValue nilvalue; /* a nil value */ + unsigned int seed; /* randomized seed for hashes */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcstopem; /* stops emergency collections */ + lu_byte genminormul; /* control for minor generational collections */ + lu_byte genmajormul; /* control for major generational collections */ + lu_byte gcstp; /* control whether GC is running */ + lu_byte gcemergency; /* true if this is an emergency collection */ + lu_byte gcpause; /* size of pause between successive GCs */ + lu_byte gcstepmul; /* GC "speed" */ + lu_byte gcstepsize; /* (log2 of) GC granularity */ + GCObject *allgc; /* list of all collectable objects */ + GCObject **sweepgc; /* current position of sweep in list */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + GCObject *fixedgc; /* list of objects not to be collected */ + /* fields for generational collector */ + GCObject *survival; /* start of objects that survived one GC cycle */ + GCObject *old1; /* start of old1 objects */ + GCObject *reallyold; /* objects more than one cycle old ("really old") */ + GCObject *firstold1; /* first OLD1 object in the list (if any) */ + GCObject *finobjsur; /* list of survival objects with finalizers */ + GCObject *finobjold1; /* list of old1 objects with finalizers */ + GCObject *finobjrold; /* list of really old objects with finalizers */ + struct lua_State *twups; /* list of threads with open upvalues */ + lua_CFunction panic; /* to be called in unprotected errors */ + struct lua_State *mainthread; + TString *memerrmsg; /* message for memory-allocation errors */ + TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTYPES]; /* metatables for basic types */ + TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ + lua_WarnFunction warnf; /* warning function */ + void *ud_warn; /* auxiliary data to 'warnf' */ +} global_State; + + +/* +** 'per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + lu_byte allowhook; + unsigned short nci; /* number of items in 'ci' list */ + StkIdRel top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + StkIdRel stack_last; /* end of stack (last element + 1) */ + StkIdRel stack; /* stack base */ + UpVal *openupval; /* list of open upvalues in this stack */ + StkIdRel tbclist; /* list of to-be-closed variables */ + GCObject *gclist; + struct lua_State *twups; /* list of threads with open upvalues */ + struct lua_longjmp *errorJmp; /* current error recover point */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ + volatile lua_Hook hook; + ptrdiff_t errfunc; /* current error handling function (stack index) */ + l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ + int oldpc; /* last pc traced */ + int basehookcount; + int hookcount; + volatile l_signalT hookmask; +}; + + +#define G(L) (L->l_G) + +/* +** 'g->nilvalue' being a nil value flags that the state was completely +** build. +*/ +#define completestate(g) ttisnil(&g->nilvalue) + + +/* +** Union of all collectable objects (only for conversions) +** ISO C99, 6.5.2.3 p.5: +** "if a union contains several structures that share a common initial +** sequence [...], and if the union object currently contains one +** of these structures, it is permitted to inspect the common initial +** part of any of them anywhere that a declaration of the complete type +** of the union is visible." +*/ +union GCUnion { + GCObject gc; /* common header */ + struct TString ts; + struct Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct lua_State th; /* thread */ + struct UpVal upv; +}; + + +/* +** ISO C99, 6.7.2.1 p.14: +** "A pointer to a union object, suitably converted, points to each of +** its members [...], and vice versa." +*/ +#define cast_u(o) castp(union GCUnion *, (o)) + +/* macros to convert a GCObject into a specific value */ +#define gco2ts(o) \ + check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) +#define gco2u(o) check_exp((o)->tt == LUA_VUSERDATA, &((cast_u(o))->u)) +#define gco2lcl(o) check_exp((o)->tt == LUA_VLCL, &((cast_u(o))->cl.l)) +#define gco2ccl(o) check_exp((o)->tt == LUA_VCCL, &((cast_u(o))->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) +#define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h)) +#define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p)) +#define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th)) +#define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv)) + + +/* +** macro to convert a Lua object into a GCObject +** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.) +*/ +#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc)) + + +/* actual number of total bytes allocated */ +#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) + +LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC void luaE_shrinkCI (lua_State *L); +LUAI_FUNC void luaE_checkcstack (lua_State *L); +LUAI_FUNC void luaE_incCstack (lua_State *L); +LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); +LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); +LUAI_FUNC int luaE_resetthread (lua_State *L, int status); + + +#endif + diff --git a/arm9/source/lua/lstring.c b/arm9/source/lua/lstring.c new file mode 100644 index 000000000..97757355c --- /dev/null +++ b/arm9/source/lua/lstring.c @@ -0,0 +1,274 @@ +/* +** $Id: lstring.c $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#define lstring_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + +/* +** Maximum size for string table. +*/ +#define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) + + +/* +** equality for long strings +*/ +int luaS_eqlngstr (TString *a, TString *b) { + size_t len = a->u.lnglen; + lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); + return (a == b) || /* same instance or... */ + ((len == b->u.lnglen) && /* equal length and ... */ + (memcmp(getlngstr(a), getlngstr(b), len) == 0)); /* equal contents */ +} + + +unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { + unsigned int h = seed ^ cast_uint(l); + for (; l > 0; l--) + h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); + return h; +} + + +unsigned int luaS_hashlongstr (TString *ts) { + lua_assert(ts->tt == LUA_VLNGSTR); + if (ts->extra == 0) { /* no hash? */ + size_t len = ts->u.lnglen; + ts->hash = luaS_hash(getlngstr(ts), len, ts->hash); + ts->extra = 1; /* now it has its hash */ + } + return ts->hash; +} + + +static void tablerehash (TString **vect, int osize, int nsize) { + int i; + for (i = osize; i < nsize; i++) /* clear new elements */ + vect[i] = NULL; + for (i = 0; i < osize; i++) { /* rehash old part of the array */ + TString *p = vect[i]; + vect[i] = NULL; + while (p) { /* for each string in the list */ + TString *hnext = p->u.hnext; /* save next */ + unsigned int h = lmod(p->hash, nsize); /* new position */ + p->u.hnext = vect[h]; /* chain it into array */ + vect[h] = p; + p = hnext; + } + } +} + + +/* +** Resize the string table. If allocation fails, keep the current size. +** (This can degrade performance, but any non-zero size should work +** correctly.) +*/ +void luaS_resize (lua_State *L, int nsize) { + stringtable *tb = &G(L)->strt; + int osize = tb->size; + TString **newvect; + if (nsize < osize) /* shrinking table? */ + tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */ + newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*); + if (l_unlikely(newvect == NULL)) { /* reallocation failed? */ + if (nsize < osize) /* was it shrinking table? */ + tablerehash(tb->hash, nsize, osize); /* restore to original size */ + /* leave table as it was */ + } + else { /* allocation succeeded */ + tb->hash = newvect; + tb->size = nsize; + if (nsize > osize) + tablerehash(newvect, osize, nsize); /* rehash for new size */ + } +} + + +/* +** Clear API string cache. (Entries cannot be empty, so fill them with +** a non-collectable string.) +*/ +void luaS_clearcache (global_State *g) { + int i, j; + for (i = 0; i < STRCACHE_N; i++) + for (j = 0; j < STRCACHE_M; j++) { + if (iswhite(g->strcache[i][j])) /* will entry be collected? */ + g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ + } +} + + +/* +** Initialize the string table and the string cache +*/ +void luaS_init (lua_State *L) { + global_State *g = G(L); + int i, j; + stringtable *tb = &G(L)->strt; + tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*); + tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */ + tb->size = MINSTRTABSIZE; + /* pre-create memory-error message */ + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); + luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ + for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */ + for (j = 0; j < STRCACHE_M; j++) + g->strcache[i][j] = g->memerrmsg; +} + + + +/* +** creates a new string object +*/ +static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { + TString *ts; + GCObject *o; + size_t totalsize; /* total size of TString object */ + totalsize = sizelstring(l); + o = luaC_newobj(L, tag, totalsize); + ts = gco2ts(o); + ts->hash = h; + ts->extra = 0; + getstr(ts)[l] = '\0'; /* ending 0 */ + return ts; +} + + +TString *luaS_createlngstrobj (lua_State *L, size_t l) { + TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); + ts->u.lnglen = l; + ts->shrlen = 0xFF; /* signals that it is a long string */ + return ts; +} + + +void luaS_remove (lua_State *L, TString *ts) { + stringtable *tb = &G(L)->strt; + TString **p = &tb->hash[lmod(ts->hash, tb->size)]; + while (*p != ts) /* find previous element */ + p = &(*p)->u.hnext; + *p = (*p)->u.hnext; /* remove element from its list */ + tb->nuse--; +} + + +static void growstrtab (lua_State *L, stringtable *tb) { + if (l_unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ + luaC_fullgc(L, 1); /* try to free some... */ + if (tb->nuse == MAX_INT) /* still too many? */ + luaM_error(L); /* cannot even create a message... */ + } + if (tb->size <= MAXSTRTB / 2) /* can grow string table? */ + luaS_resize(L, tb->size * 2); +} + + +/* +** Checks whether short string exists and reuses it or creates a new one. +*/ +static TString *internshrstr (lua_State *L, const char *str, size_t l) { + TString *ts; + global_State *g = G(L); + stringtable *tb = &g->strt; + unsigned int h = luaS_hash(str, l, g->seed); + TString **list = &tb->hash[lmod(h, tb->size)]; + lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ + for (ts = *list; ts != NULL; ts = ts->u.hnext) { + if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { + /* found! */ + if (isdead(g, ts)) /* dead (but not collected yet)? */ + changewhite(ts); /* resurrect it */ + return ts; + } + } + /* else must create a new string */ + if (tb->nuse >= tb->size) { /* need to grow string table? */ + growstrtab(L, tb); + list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ + } + ts = createstrobj(L, l, LUA_VSHRSTR, h); + ts->shrlen = cast_byte(l); + memcpy(getshrstr(ts), str, l * sizeof(char)); + ts->u.hnext = *list; + *list = ts; + tb->nuse++; + return ts; +} + + +/* +** new string (with explicit length) +*/ +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + if (l <= LUAI_MAXSHORTLEN) /* short string? */ + return internshrstr(L, str, l); + else { + TString *ts; + if (l_unlikely(l * sizeof(char) >= (MAX_SIZE - sizeof(TString)))) + luaM_toobig(L); + ts = luaS_createlngstrobj(L, l); + memcpy(getlngstr(ts), str, l * sizeof(char)); + return ts; + } +} + + +/* +** Create or reuse a zero-terminated string, first checking in the +** cache (using the string address as a key). The cache can contain +** only zero-terminated strings, so it is safe to use 'strcmp' to +** check hits. +*/ +TString *luaS_new (lua_State *L, const char *str) { + unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ + int j; + TString **p = G(L)->strcache[i]; + for (j = 0; j < STRCACHE_M; j++) { + if (strcmp(str, getstr(p[j])) == 0) /* hit? */ + return p[j]; /* that is it */ + } + /* normal route */ + for (j = STRCACHE_M - 1; j > 0; j--) + p[j] = p[j - 1]; /* move out last element */ + /* new element is first in the list */ + p[0] = luaS_newlstr(L, str, strlen(str)); + return p[0]; +} + + +Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) { + Udata *u; + int i; + GCObject *o; + if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) + luaM_toobig(L); + o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s)); + u = gco2u(o); + u->len = s; + u->nuvalue = nuvalue; + u->metatable = NULL; + for (i = 0; i < nuvalue; i++) + setnilvalue(&u->uv[i].uv); + return u; +} + diff --git a/arm9/source/lua/lstring.h b/arm9/source/lua/lstring.h new file mode 100644 index 000000000..450c2390d --- /dev/null +++ b/arm9/source/lua/lstring.h @@ -0,0 +1,57 @@ +/* +** $Id: lstring.h $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +/* +** Memory-allocation error message must be preallocated (it cannot +** be created after memory is exhausted) +*/ +#define MEMERRMSG "not enough memory" + + +/* +** Size of a TString: Size of the header plus space for the string +** itself (including final '\0'). +*/ +#define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) + +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + + +/* +** test whether a string is a reserved word +*/ +#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) + + +/* +** equality for short strings, which are always internalized +*/ +#define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) + + +LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); +LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC void luaS_clearcache (global_State *g); +LUAI_FUNC void luaS_init (lua_State *L); +LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); +LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); + + +#endif diff --git a/arm9/source/lua/lstrlib.c b/arm9/source/lua/lstrlib.c new file mode 100644 index 000000000..03167161d --- /dev/null +++ b/arm9/source/lua/lstrlib.c @@ -0,0 +1,1874 @@ +/* +** $Id: lstrlib.c $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + +#define lstrlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** maximum number of captures that a pattern can do during +** pattern-matching. This limit is arbitrary, but must fit in +** an unsigned char. +*/ +#if !defined(LUA_MAXCAPTURES) +#define LUA_MAXCAPTURES 32 +#endif + + +/* macro to 'unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + +/* +** Some sizes are better limited to fit in 'int', but must also fit in +** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) +*/ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +#define MAXSIZE \ + (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) + + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, (lua_Integer)l); + return 1; +} + + +/* +** translate a relative initial string position +** (negative means back from end): clip result to [1, inf). +** The length of any string in Lua must fit in a lua_Integer, +** so there are no overflows in the casts. +** The inverted comparison avoids a possible overflow +** computing '-pos'. +*/ +static size_t posrelatI (lua_Integer pos, size_t len) { + if (pos > 0) + return (size_t)pos; + else if (pos == 0) + return 1; + else if (pos < -(lua_Integer)len) /* inverted comparison */ + return 1; /* clip to 1 */ + else return len + (size_t)pos + 1; +} + + +/* +** Gets an optional ending string position from argument 'arg', +** with default value 'def'. +** Negative means back from end: clip result to [0, len] +*/ +static size_t getendpos (lua_State *L, int arg, lua_Integer def, + size_t len) { + lua_Integer pos = luaL_optinteger(L, arg, def); + if (pos > (lua_Integer)len) + return len; + else if (pos >= 0) + return (size_t)pos; + else if (pos < -(lua_Integer)len) + return 0; + else return len + (size_t)pos + 1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t start = posrelatI(luaL_checkinteger(L, 2), l); + size_t end = getendpos(L, 3, -1, l); + if (start <= end) + lua_pushlstring(L, s + start - 1, (end - start) + 1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l, i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i = 0; i < l; i++) + p[i] = s[l - i - 1]; + luaL_pushresultsize(&b, l); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i=0; i MAXSIZE / n)) + return luaL_error(L, "resulting string too large"); + else { + size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, totallen); + while (n-- > 1) { /* first n-1 copies (followed by separator) */ + memcpy(p, s, l * sizeof(char)); p += l; + if (lsep > 0) { /* empty 'memcpy' is not that cheap */ + memcpy(p, sep, lsep * sizeof(char)); + p += lsep; + } + } + memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ + luaL_pushresultsize(&b, totallen); + } + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + lua_Integer pi = luaL_optinteger(L, 2, 1); + size_t posi = posrelatI(pi, l); + size_t pose = getendpos(L, 3, pi, l); + int n, i; + if (posi > pose) return 0; /* empty interval; return no values */ + if (l_unlikely(pose - posi >= (size_t)INT_MAX)) /* arithmetic overflow? */ + return luaL_error(L, "string slice too long"); + n = (int)(pose - posi) + 1; + luaL_checkstack(L, n, "string slice too long"); + for (i=0; iinit) { + state->init = 1; + luaL_buffinit(L, &state->B); + } + luaL_addlstring(&state->B, (const char *)b, size); + return 0; +} + + +static int str_dump (lua_State *L) { + struct str_Writer state; + int strip = lua_toboolean(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 1); /* ensure function is on the top of the stack */ + state.init = 0; + if (l_unlikely(lua_dump(L, writer, &state, strip) != 0)) + return luaL_error(L, "unable to dump given function"); + luaL_pushresult(&state.B); + return 1; +} + + + +/* +** {====================================================== +** METAMETHODS +** ======================================================= +*/ + +#if defined(LUA_NOCVTS2N) /* { */ + +/* no coercion from strings to numbers */ + +static const luaL_Reg stringmetamethods[] = { + {"__index", NULL}, /* placeholder */ + {NULL, NULL} +}; + +#else /* }{ */ + +static int tonum (lua_State *L, int arg) { + if (lua_type(L, arg) == LUA_TNUMBER) { /* already a number? */ + lua_pushvalue(L, arg); + return 1; + } + else { /* check whether it is a numerical string */ + size_t len; + const char *s = lua_tolstring(L, arg, &len); + return (s != NULL && lua_stringtonumber(L, s) == len + 1); + } +} + + +static void trymt (lua_State *L, const char *mtname) { + lua_settop(L, 2); /* back to the original arguments */ + if (l_unlikely(lua_type(L, 2) == LUA_TSTRING || + !luaL_getmetafield(L, 2, mtname))) + luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, + luaL_typename(L, -2), luaL_typename(L, -1)); + lua_insert(L, -3); /* put metamethod before arguments */ + lua_call(L, 2, 1); /* call metamethod */ +} + + +static int arith (lua_State *L, int op, const char *mtname) { + if (tonum(L, 1) && tonum(L, 2)) + lua_arith(L, op); /* result will be on the top */ + else + trymt(L, mtname); + return 1; +} + + +static int arith_add (lua_State *L) { + return arith(L, LUA_OPADD, "__add"); +} + +static int arith_sub (lua_State *L) { + return arith(L, LUA_OPSUB, "__sub"); +} + +static int arith_mul (lua_State *L) { + return arith(L, LUA_OPMUL, "__mul"); +} + +static int arith_mod (lua_State *L) { + return arith(L, LUA_OPMOD, "__mod"); +} + +static int arith_pow (lua_State *L) { + return arith(L, LUA_OPPOW, "__pow"); +} + +static int arith_div (lua_State *L) { + return arith(L, LUA_OPDIV, "__div"); +} + +static int arith_idiv (lua_State *L) { + return arith(L, LUA_OPIDIV, "__idiv"); +} + +static int arith_unm (lua_State *L) { + return arith(L, LUA_OPUNM, "__unm"); +} + + +static const luaL_Reg stringmetamethods[] = { + {"__add", arith_add}, + {"__sub", arith_sub}, + {"__mul", arith_mul}, + {"__mod", arith_mod}, + {"__pow", arith_pow}, + {"__div", arith_div}, + {"__idiv", arith_idiv}, + {"__unm", arith_unm}, + {"__index", NULL}, /* placeholder */ + {NULL, NULL} +}; + +#endif /* } */ + +/* }====================================================== */ + +/* +** {====================================================== +** PATTERN MATCHING +** ======================================================= +*/ + + +#define CAP_UNFINISHED (-1) +#define CAP_POSITION (-2) + + +typedef struct MatchState { + const char *src_init; /* init of source string */ + const char *src_end; /* end ('\0') of source string */ + const char *p_end; /* end ('\0') of pattern */ + lua_State *L; + int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ + unsigned char level; /* total number of captures (finished or unfinished) */ + struct { + const char *init; + ptrdiff_t len; + } capture[LUA_MAXCAPTURES]; +} MatchState; + + +/* recursive function */ +static const char *match (MatchState *ms, const char *s, const char *p); + + +/* maximum recursion depth for 'match' */ +#if !defined(MAXCCALLS) +#define MAXCCALLS 200 +#endif + + +#define L_ESC '%' +#define SPECIALS "^$*+?.([%-" + + +static int check_capture (MatchState *ms, int l) { + l -= '1'; + if (l_unlikely(l < 0 || l >= ms->level || + ms->capture[l].len == CAP_UNFINISHED)) + return luaL_error(ms->L, "invalid capture index %%%d", l + 1); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (l_unlikely(p == ms->p_end)) + luaL_error(ms->L, "malformed pattern (ends with '%%')"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a ']' */ + if (l_unlikely(p == ms->p_end)) + luaL_error(ms->L, "malformed pattern (missing ']')"); + if (*(p++) == L_ESC && p < ms->p_end) + p++; /* skip escapes (e.g. '%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'g' : res = isgraph(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; /* deprecated option */ + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the '^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (MatchState *ms, const char *s, const char *p, + const char *ep) { + if (s >= ms->src_end) + return 0; + else { + int c = uchar(*s); + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } + } +} + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (l_unlikely(p >= ms->p_end - 1)) + luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while (singlematch(ms, s + i, p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (singlematch(ms, s, p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + if (l_unlikely(ms->matchdepth-- == 0)) + luaL_error(ms->L, "pattern too complex"); + init: /* using goto to optimize tail recursion */ + if (p != ms->p_end) { /* end of pattern? */ + switch (*p) { + case '(': { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; + } + case ')': { /* end capture */ + s = end_capture(ms, s, p + 1); + break; + } + case '$': { + if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */ + goto dflt; /* no; go to default */ + s = (s == ms->src_end) ? s : NULL; /* check end of string */ + break; + } + case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ + switch (*(p + 1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s != NULL) { + p += 4; goto init; /* return match(ms, s, p + 4); */ + } /* else fail (s == NULL) */ + break; + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (l_unlikely(*p != '[')) + luaL_error(ms->L, "missing '[' after '%%f' in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && + matchbracketclass(uchar(*s), p, ep - 1)) { + p = ep; goto init; /* return match(ms, s, ep); */ + } + s = NULL; /* match failed */ + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) { + p += 2; goto init; /* return match(ms, s, p + 2) */ + } + break; + } + default: goto dflt; + } + break; + } + default: dflt: { /* pattern class plus optional suffix */ + const char *ep = classend(ms, p); /* points to optional suffix */ + /* does not match at least once? */ + if (!singlematch(ms, s, p, ep)) { + if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ + p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ + } + else /* '+' or no suffix */ + s = NULL; /* fail */ + } + else { /* matched once */ + switch (*ep) { /* handle optional suffix */ + case '?': { /* optional */ + const char *res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else { + p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ + } + break; + } + case '+': /* 1 or more repetitions */ + s++; /* 1 match already done */ + /* FALLTHROUGH */ + case '*': /* 0 or more repetitions */ + s = max_expand(ms, s, p, ep); + break; + case '-': /* 0 or more repetitions (minimum) */ + s = min_expand(ms, s, p, ep); + break; + default: /* no suffix */ + s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ + } + } + break; + } + } + } + ms->matchdepth++; + return s; +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ + else { + const char *init; /* to search for a '*s2' inside 's1' */ + l2--; /* 1st char will be checked by 'memchr' */ + l1 = l1-l2; /* 's2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct 'l1' and 's1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +/* +** get information about the i-th capture. If there are no captures +** and 'i==0', return information about the whole match, which +** is the range 's'..'e'. If the capture is a string, return +** its length and put its address in '*cap'. If it is an integer +** (a position), push it on the stack and return CAP_POSITION. +*/ +static size_t get_onecapture (MatchState *ms, int i, const char *s, + const char *e, const char **cap) { + if (i >= ms->level) { + if (l_unlikely(i != 0)) + luaL_error(ms->L, "invalid capture index %%%d", i + 1); + *cap = s; + return e - s; + } + else { + ptrdiff_t capl = ms->capture[i].len; + *cap = ms->capture[i].init; + if (l_unlikely(capl == CAP_UNFINISHED)) + luaL_error(ms->L, "unfinished capture"); + else if (capl == CAP_POSITION) + lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); + return capl; + } +} + + +/* +** Push the i-th capture on the stack. +*/ +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + const char *cap; + ptrdiff_t l = get_onecapture(ms, i, s, e, &cap); + if (l != CAP_POSITION) + lua_pushlstring(ms->L, cap, l); + /* else position was already pushed */ +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +/* check whether pattern has no special characters */ +static int nospecials (const char *p, size_t l) { + size_t upto = 0; + do { + if (strpbrk(p + upto, SPECIALS)) + return 0; /* pattern has a special character */ + upto += strlen(p + upto) + 1; /* may have more after \0 */ + } while (upto <= l); + return 1; /* no special chars found */ +} + + +static void prepstate (MatchState *ms, lua_State *L, + const char *s, size_t ls, const char *p, size_t lp) { + ms->L = L; + ms->matchdepth = MAXCCALLS; + ms->src_init = s; + ms->src_end = s + ls; + ms->p_end = p + lp; +} + + +static void reprepstate (MatchState *ms) { + ms->level = 0; + lua_assert(ms->matchdepth == MAXCCALLS); +} + + +static int str_find_aux (lua_State *L, int find) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; + if (init > ls) { /* start after string's end? */ + luaL_pushfail(L); /* cannot find anything */ + return 1; + } + /* explicit request or no special characters? */ + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { + /* do a plain search */ + const char *s2 = lmemfind(s + init, ls - init, p, lp); + if (s2) { + lua_pushinteger(L, (s2 - s) + 1); + lua_pushinteger(L, (s2 - s) + lp); + return 2; + } + } + else { + MatchState ms; + const char *s1 = s + init; + int anchor = (*p == '^'); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + prepstate(&ms, L, s, ls, p, lp); + do { + const char *res; + reprepstate(&ms); + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, (s1 - s) + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + luaL_pushfail(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +/* state for 'gmatch' */ +typedef struct GMatchState { + const char *src; /* current position */ + const char *p; /* pattern */ + const char *lastmatch; /* end of last match */ + MatchState ms; /* match state */ +} GMatchState; + + +static int gmatch_aux (lua_State *L) { + GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); + const char *src; + gm->ms.L = L; + for (src = gm->src; src <= gm->ms.src_end; src++) { + const char *e; + reprepstate(&gm->ms); + if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) { + gm->src = gm->lastmatch = e; + return push_captures(&gm->ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; + GMatchState *gm; + lua_settop(L, 2); /* keep strings on closure to avoid being collected */ + gm = (GMatchState *)lua_newuserdatauv(L, sizeof(GMatchState), 0); + if (init > ls) /* start after string's end? */ + init = ls + 1; /* avoid overflows in 's + init' */ + prepstate(&gm->ms, L, s, ls, p, lp); + gm->src = s + init; gm->p = p; gm->lastmatch = NULL; + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l; + lua_State *L = ms->L; + const char *news = lua_tolstring(L, 3, &l); + const char *p; + while ((p = (char *)memchr(news, L_ESC, l)) != NULL) { + luaL_addlstring(b, news, p - news); + p++; /* skip ESC */ + if (*p == L_ESC) /* '%%' */ + luaL_addchar(b, *p); + else if (*p == '0') /* '%0' */ + luaL_addlstring(b, s, e - s); + else if (isdigit(uchar(*p))) { /* '%n' */ + const char *cap; + ptrdiff_t resl = get_onecapture(ms, *p - '1', s, e, &cap); + if (resl == CAP_POSITION) + luaL_addvalue(b); /* add position to accumulated result */ + else + luaL_addlstring(b, cap, resl); + } + else + luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); + l -= p + 1 - news; + news = p + 1; + } + luaL_addlstring(b, news, l); +} + + +/* +** Add the replacement value to the string buffer 'b'. +** Return true if the original string was changed. (Function calls and +** table indexing resulting in nil or false do not change the subject.) +*/ +static int add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e, int tr) { + lua_State *L = ms->L; + switch (tr) { + case LUA_TFUNCTION: { /* call the function */ + int n; + lua_pushvalue(L, 3); /* push the function */ + n = push_captures(ms, s, e); /* all captures as arguments */ + lua_call(L, n, 1); /* call it */ + break; + } + case LUA_TTABLE: { /* index the table */ + push_onecapture(ms, 0, s, e); /* first capture is the index */ + lua_gettable(L, 3); + break; + } + default: { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); /* add value to the buffer */ + return 1; /* something changed */ + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); /* remove value */ + luaL_addlstring(b, s, e - s); /* keep original text */ + return 0; /* no changes */ + } + else if (l_unlikely(!lua_isstring(L, -1))) + return luaL_error(L, "invalid replacement value (a %s)", + luaL_typename(L, -1)); + else { + luaL_addvalue(b); /* add result to accumulator */ + return 1; /* something changed */ + } +} + + +static int str_gsub (lua_State *L) { + size_t srcl, lp; + const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ + const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ + const char *lastmatch = NULL; /* end of last match */ + int tr = lua_type(L, 3); /* replacement type */ + lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ + int anchor = (*p == '^'); + lua_Integer n = 0; /* replacement count */ + int changed = 0; /* change flag */ + MatchState ms; + luaL_Buffer b; + luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table"); + luaL_buffinit(L, &b); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + prepstate(&ms, L, src, srcl, p, lp); + while (n < max_s) { + const char *e; + reprepstate(&ms); /* (re)prepare state for new match */ + if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ + n++; + changed = add_value(&ms, &b, src, e, tr) | changed; + src = lastmatch = e; + } + else if (src < ms.src_end) /* otherwise, skip one character */ + luaL_addchar(&b, *src++); + else break; /* end of subject */ + if (anchor) break; + } + if (!changed) /* no changes? */ + lua_pushvalue(L, 1); /* return original string */ + else { /* something changed */ + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); /* create and return new string */ + } + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** STRING FORMAT +** ======================================================= +*/ + +#if !defined(lua_number2strx) /* { */ + +/* +** Hexadecimal floating-point formatter +*/ + +#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) + + +/* +** Number of bits that goes into the first digit. It can be any value +** between 1 and 4; the following definition tries to align the number +** to nibble boundaries by making what is left after that first digit a +** multiple of 4. +*/ +#define L_NBFD ((l_floatatt(MANT_DIG) - 1)%4 + 1) + + +/* +** Add integer part of 'x' to buffer and return new 'x' +*/ +static lua_Number adddigit (char *buff, int n, lua_Number x) { + lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */ + int d = (int)dd; + buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */ + return x - dd; /* return what is left */ +} + + +static int num2straux (char *buff, int sz, lua_Number x) { + /* if 'inf' or 'NaN', format it like '%g' */ + if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL) + return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x); + else if (x == 0) { /* can be -0... */ + /* create "0" or "-0" followed by exponent */ + return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x); + } + else { + int e; + lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ + int n = 0; /* character count */ + if (m < 0) { /* is number negative? */ + buff[n++] = '-'; /* add sign */ + m = -m; /* make it positive */ + } + buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ + m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */ + e -= L_NBFD; /* this digit goes before the radix point */ + if (m > 0) { /* more digits? */ + buff[n++] = lua_getlocaledecpoint(); /* add radix point */ + do { /* add as many digits as needed */ + m = adddigit(buff, n++, m * 16); + } while (m > 0); + } + n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ + lua_assert(n < sz); + return n; + } +} + + +static int lua_number2strx (lua_State *L, char *buff, int sz, + const char *fmt, lua_Number x) { + int n = num2straux(buff, sz, x); + if (fmt[SIZELENMOD] == 'A') { + int i; + for (i = 0; i < n; i++) + buff[i] = toupper(uchar(buff[i])); + } + else if (l_unlikely(fmt[SIZELENMOD] != 'a')) + return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); + return n; +} + +#endif /* } */ + + +/* +** Maximum size for items formatted with '%f'. This size is produced +** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', +** and '\0') + number of decimal digits to represent maxfloat (which +** is maximum exponent + 1). (99+3+1, adding some extra, 110) +*/ +#define MAX_ITEMF (110 + l_floatatt(MAX_10_EXP)) + + +/* +** All formats except '%f' do not need that large limit. The other +** float formats use exponents, so that they fit in the 99 limit for +** significant digits; 's' for large strings and 'q' add items directly +** to the buffer; all integer formats also fit in the 99 limit. The +** worst case are floats: they may need 99 significant digits, plus +** '0x', '-', '.', 'e+XXXX', and '\0'. Adding some extra, 120. +*/ +#define MAX_ITEM 120 + + +/* valid flags in a format specification */ +#if !defined(L_FMTFLAGSF) + +/* valid flags for a, A, e, E, f, F, g, and G conversions */ +#define L_FMTFLAGSF "-+#0 " + +/* valid flags for o, x, and X conversions */ +#define L_FMTFLAGSX "-#0" + +/* valid flags for d and i conversions */ +#define L_FMTFLAGSI "-+0 " + +/* valid flags for u conversions */ +#define L_FMTFLAGSU "-0" + +/* valid flags for c, p, and s conversions */ +#define L_FMTFLAGSC "-" + +#endif + + +/* +** Maximum size of each format specification (such as "%-099.99d"): +** Initial '%', flags (up to 5), width (2), period, precision (2), +** length modifier (8), conversion specifier, and final '\0', plus some +** extra. +*/ +#define MAX_FORMAT 32 + + +static void addquoted (luaL_Buffer *b, const char *s, size_t len) { + luaL_addchar(b, '"'); + while (len--) { + if (*s == '"' || *s == '\\' || *s == '\n') { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + } + else if (iscntrl(uchar(*s))) { + char buff[10]; + if (!isdigit(uchar(*(s+1)))) + l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); + else + l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); + luaL_addstring(b, buff); + } + else + luaL_addchar(b, *s); + s++; + } + luaL_addchar(b, '"'); +} + + +/* +** Serialize a floating-point number in such a way that it can be +** scanned back by Lua. Use hexadecimal format for "common" numbers +** (to preserve precision); inf, -inf, and NaN are handled separately. +** (NaN cannot be expressed as a numeral, so we write '(0/0)' for it.) +*/ +static int quotefloat (lua_State *L, char *buff, lua_Number n) { + const char *s; /* for the fixed representations */ + if (n == (lua_Number)HUGE_VAL) /* inf? */ + s = "1e9999"; + else if (n == -(lua_Number)HUGE_VAL) /* -inf? */ + s = "-1e9999"; + else if (n != n) /* NaN? */ + s = "(0/0)"; + else { /* format number as hexadecimal */ + int nb = lua_number2strx(L, buff, MAX_ITEM, + "%" LUA_NUMBER_FRMLEN "a", n); + /* ensures that 'buff' string uses a dot as the radix character */ + if (memchr(buff, '.', nb) == NULL) { /* no dot? */ + char point = lua_getlocaledecpoint(); /* try locale point */ + char *ppoint = (char *)memchr(buff, point, nb); + if (ppoint) *ppoint = '.'; /* change it to a dot */ + } + return nb; + } + /* for the fixed representations */ + return l_sprintf(buff, MAX_ITEM, "%s", s); +} + + +static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { + switch (lua_type(L, arg)) { + case LUA_TSTRING: { + size_t len; + const char *s = lua_tolstring(L, arg, &len); + addquoted(b, s, len); + break; + } + case LUA_TNUMBER: { + char *buff = luaL_prepbuffsize(b, MAX_ITEM); + int nb; + if (!lua_isinteger(L, arg)) /* float? */ + nb = quotefloat(L, buff, lua_tonumber(L, arg)); + else { /* integers */ + lua_Integer n = lua_tointeger(L, arg); + const char *format = (n == LUA_MININTEGER) /* corner case? */ + ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hex */ + : LUA_INTEGER_FMT; /* else use default format */ + nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); + } + luaL_addsize(b, nb); + break; + } + case LUA_TNIL: case LUA_TBOOLEAN: { + luaL_tolstring(L, arg, NULL); + luaL_addvalue(b); + break; + } + default: { + luaL_argerror(L, arg, "value has no literal form"); + } + } +} + + +static const char *get2digits (const char *s) { + if (isdigit(uchar(*s))) { + s++; + if (isdigit(uchar(*s))) s++; /* (2 digits at most) */ + } + return s; +} + + +/* +** Check whether a conversion specification is valid. When called, +** first character in 'form' must be '%' and last character must +** be a valid conversion specifier. 'flags' are the accepted flags; +** 'precision' signals whether to accept a precision. +*/ +static void checkformat (lua_State *L, const char *form, const char *flags, + int precision) { + const char *spec = form + 1; /* skip '%' */ + spec += strspn(spec, flags); /* skip flags */ + if (*spec != '0') { /* a width cannot start with '0' */ + spec = get2digits(spec); /* skip width */ + if (*spec == '.' && precision) { + spec++; + spec = get2digits(spec); /* skip precision */ + } + } + if (!isalpha(uchar(*spec))) /* did not go to the end? */ + luaL_error(L, "invalid conversion specification: '%s'", form); +} + + +/* +** Get a conversion specification and copy it to 'form'. +** Return the address of its last character. +*/ +static const char *getformat (lua_State *L, const char *strfrmt, + char *form) { + /* spans flags, width, and precision ('0' is included as a flag) */ + size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789."); + len++; /* adds following character (should be the specifier) */ + /* still needs space for '%', '\0', plus a length modifier */ + if (len >= MAX_FORMAT - 10) + luaL_error(L, "invalid format (too long)"); + *(form++) = '%'; + memcpy(form, strfrmt, len * sizeof(char)); + *(form + len) = '\0'; + return strfrmt + len - 1; +} + + +/* +** add length modifier into formats +*/ +static void addlenmod (char *form, const char *lenmod) { + size_t l = strlen(form); + size_t lm = strlen(lenmod); + char spec = form[l - 1]; + strcpy(form + l - 1, lenmod); + form[l + lm - 1] = spec; + form[l + lm] = '\0'; +} + + +static int str_format (lua_State *L) { + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + const char *flags; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format ('%...') */ + int maxitem = MAX_ITEM; /* maximum length for the result */ + char *buff = luaL_prepbuffsize(&b, maxitem); /* to put result */ + int nb = 0; /* number of bytes in result */ + if (++arg > top) + return luaL_argerror(L, arg, "no value"); + strfrmt = getformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + checkformat(L, form, L_FMTFLAGSC, 0); + nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); + break; + } + case 'd': case 'i': + flags = L_FMTFLAGSI; + goto intcase; + case 'u': + flags = L_FMTFLAGSU; + goto intcase; + case 'o': case 'x': case 'X': + flags = L_FMTFLAGSX; + intcase: { + lua_Integer n = luaL_checkinteger(L, arg); + checkformat(L, form, flags, 1); + addlenmod(form, LUA_INTEGER_FRMLEN); + nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); + break; + } + case 'a': case 'A': + checkformat(L, form, L_FMTFLAGSF, 1); + addlenmod(form, LUA_NUMBER_FRMLEN); + nb = lua_number2strx(L, buff, maxitem, form, + luaL_checknumber(L, arg)); + break; + case 'f': + maxitem = MAX_ITEMF; /* extra space for '%f' */ + buff = luaL_prepbuffsize(&b, maxitem); + /* FALLTHROUGH */ + case 'e': case 'E': case 'g': case 'G': { + lua_Number n = luaL_checknumber(L, arg); + checkformat(L, form, L_FMTFLAGSF, 1); + addlenmod(form, LUA_NUMBER_FRMLEN); + nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); + break; + } + case 'p': { + const void *p = lua_topointer(L, arg); + checkformat(L, form, L_FMTFLAGSC, 0); + if (p == NULL) { /* avoid calling 'printf' with argument NULL */ + p = "(null)"; /* result */ + form[strlen(form) - 1] = 's'; /* format it as a string */ + } + nb = l_sprintf(buff, maxitem, form, p); + break; + } + case 'q': { + if (form[2] != '\0') /* modifiers? */ + return luaL_error(L, "specifier '%%q' cannot have modifiers"); + addliteral(L, &b, arg); + break; + } + case 's': { + size_t l; + const char *s = luaL_tolstring(L, arg, &l); + if (form[2] == '\0') /* no modifiers? */ + luaL_addvalue(&b); /* keep entire string */ + else { + luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); + checkformat(L, form, L_FMTFLAGSC, 1); + if (strchr(form, '.') == NULL && l >= 100) { + /* no precision and string is too long to be formatted */ + luaL_addvalue(&b); /* keep entire string */ + } + else { /* format the string into 'buff' */ + nb = l_sprintf(buff, maxitem, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + } + } + break; + } + default: { /* also treat cases 'pnLlh' */ + return luaL_error(L, "invalid conversion '%s' to 'format'", form); + } + } + lua_assert(nb < maxitem); + luaL_addsize(&b, nb); + } + } + luaL_pushresult(&b); + return 1; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** PACK/UNPACK +** ======================================================= +*/ + + +/* value used for padding */ +#if !defined(LUAL_PACKPADBYTE) +#define LUAL_PACKPADBYTE 0x00 +#endif + +/* maximum size for the binary representation of an integer */ +#define MAXINTSIZE 16 + +/* number of bits in a character */ +#define NB CHAR_BIT + +/* mask for one character (NB 1's) */ +#define MC ((1 << NB) - 1) + +/* size of a lua_Integer */ +#define SZINT ((int)sizeof(lua_Integer)) + + +/* dummy union to get native endianness */ +static const union { + int dummy; + char little; /* true iff machine is little endian */ +} nativeendian = {1}; + + +/* +** information to pack/unpack stuff +*/ +typedef struct Header { + lua_State *L; + int islittle; + int maxalign; +} Header; + + +/* +** options for pack/unpack +*/ +typedef enum KOption { + Kint, /* signed integers */ + Kuint, /* unsigned integers */ + Kfloat, /* single-precision floating-point numbers */ + Knumber, /* Lua "native" floating-point numbers */ + Kdouble, /* double-precision floating-point numbers */ + Kchar, /* fixed-length strings */ + Kstring, /* strings with prefixed length */ + Kzstr, /* zero-terminated strings */ + Kpadding, /* padding */ + Kpaddalign, /* padding for alignment */ + Knop /* no-op (configuration or spaces) */ +} KOption; + + +/* +** Read an integer numeral from string 'fmt' or return 'df' if +** there is no numeral +*/ +static int digit (int c) { return '0' <= c && c <= '9'; } + +static int getnum (const char **fmt, int df) { + if (!digit(**fmt)) /* no number? */ + return df; /* return default value */ + else { + int a = 0; + do { + a = a*10 + (*((*fmt)++) - '0'); + } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); + return a; + } +} + + +/* +** Read an integer numeral and raises an error if it is larger +** than the maximum size for integers. +*/ +static int getnumlimit (Header *h, const char **fmt, int df) { + int sz = getnum(fmt, df); + if (l_unlikely(sz > MAXINTSIZE || sz <= 0)) + return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", + sz, MAXINTSIZE); + return sz; +} + + +/* +** Initialize Header +*/ +static void initheader (lua_State *L, Header *h) { + h->L = L; + h->islittle = nativeendian.little; + h->maxalign = 1; +} + + +/* +** Read and classify next option. 'size' is filled with option's size. +*/ +static KOption getoption (Header *h, const char **fmt, int *size) { + /* dummy structure to get native alignment requirements */ + struct cD { char c; union { LUAI_MAXALIGN; } u; }; + int opt = *((*fmt)++); + *size = 0; /* default */ + switch (opt) { + case 'b': *size = sizeof(char); return Kint; + case 'B': *size = sizeof(char); return Kuint; + case 'h': *size = sizeof(short); return Kint; + case 'H': *size = sizeof(short); return Kuint; + case 'l': *size = sizeof(long); return Kint; + case 'L': *size = sizeof(long); return Kuint; + case 'j': *size = sizeof(lua_Integer); return Kint; + case 'J': *size = sizeof(lua_Integer); return Kuint; + case 'T': *size = sizeof(size_t); return Kuint; + case 'f': *size = sizeof(float); return Kfloat; + case 'n': *size = sizeof(lua_Number); return Knumber; + case 'd': *size = sizeof(double); return Kdouble; + case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; + case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; + case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; + case 'c': + *size = getnum(fmt, -1); + if (l_unlikely(*size == -1)) + luaL_error(h->L, "missing size for format option 'c'"); + return Kchar; + case 'z': return Kzstr; + case 'x': *size = 1; return Kpadding; + case 'X': return Kpaddalign; + case ' ': break; + case '<': h->islittle = 1; break; + case '>': h->islittle = 0; break; + case '=': h->islittle = nativeendian.little; break; + case '!': { + const int maxalign = offsetof(struct cD, u); + h->maxalign = getnumlimit(h, fmt, maxalign); + break; + } + default: luaL_error(h->L, "invalid format option '%c'", opt); + } + return Knop; +} + + +/* +** Read, classify, and fill other details about the next option. +** 'psize' is filled with option's size, 'notoalign' with its +** alignment requirements. +** Local variable 'size' gets the size to be aligned. (Kpadal option +** always gets its full alignment, other options are limited by +** the maximum alignment ('maxalign'). Kchar option needs no alignment +** despite its size. +*/ +static KOption getdetails (Header *h, size_t totalsize, + const char **fmt, int *psize, int *ntoalign) { + KOption opt = getoption(h, fmt, psize); + int align = *psize; /* usually, alignment follows size */ + if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ + if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) + luaL_argerror(h->L, 1, "invalid next option for option 'X'"); + } + if (align <= 1 || opt == Kchar) /* need no alignment? */ + *ntoalign = 0; + else { + if (align > h->maxalign) /* enforce maximum alignment */ + align = h->maxalign; + if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */ + luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); + } + return opt; +} + + +/* +** Pack integer 'n' with 'size' bytes and 'islittle' endianness. +** The final 'if' handles the case when 'size' is larger than +** the size of a Lua integer, correcting the extra sign-extension +** bytes if necessary (by default they would be zeros). +*/ +static void packint (luaL_Buffer *b, lua_Unsigned n, + int islittle, int size, int neg) { + char *buff = luaL_prepbuffsize(b, size); + int i; + buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ + for (i = 1; i < size; i++) { + n >>= NB; + buff[islittle ? i : size - 1 - i] = (char)(n & MC); + } + if (neg && size > SZINT) { /* negative number need sign extension? */ + for (i = SZINT; i < size; i++) /* correct extra bytes */ + buff[islittle ? i : size - 1 - i] = (char)MC; + } + luaL_addsize(b, size); /* add result to buffer */ +} + + +/* +** Copy 'size' bytes from 'src' to 'dest', correcting endianness if +** given 'islittle' is different from native endianness. +*/ +static void copywithendian (char *dest, const char *src, + int size, int islittle) { + if (islittle == nativeendian.little) + memcpy(dest, src, size); + else { + dest += size - 1; + while (size-- != 0) + *(dest--) = *(src++); + } +} + + +static int str_pack (lua_State *L) { + luaL_Buffer b; + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + int arg = 1; /* current argument to pack */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + lua_pushnil(L); /* mark to separate arguments from string buffer */ + luaL_buffinit(L, &b); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + totalsize += ntoalign + size; + while (ntoalign-- > 0) + luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ + arg++; + switch (opt) { + case Kint: { /* signed integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) { /* need overflow check? */ + lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); + luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); + } + packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); + break; + } + case Kuint: { /* unsigned integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) /* need overflow check? */ + luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), + arg, "unsigned overflow"); + packint(&b, (lua_Unsigned)n, h.islittle, size, 0); + break; + } + case Kfloat: { /* C float */ + float f = (float)luaL_checknumber(L, arg); /* get argument */ + char *buff = luaL_prepbuffsize(&b, sizeof(f)); + /* move 'f' to final result, correcting endianness if needed */ + copywithendian(buff, (char *)&f, sizeof(f), h.islittle); + luaL_addsize(&b, size); + break; + } + case Knumber: { /* Lua float */ + lua_Number f = luaL_checknumber(L, arg); /* get argument */ + char *buff = luaL_prepbuffsize(&b, sizeof(f)); + /* move 'f' to final result, correcting endianness if needed */ + copywithendian(buff, (char *)&f, sizeof(f), h.islittle); + luaL_addsize(&b, size); + break; + } + case Kdouble: { /* C double */ + double f = (double)luaL_checknumber(L, arg); /* get argument */ + char *buff = luaL_prepbuffsize(&b, sizeof(f)); + /* move 'f' to final result, correcting endianness if needed */ + copywithendian(buff, (char *)&f, sizeof(f), h.islittle); + luaL_addsize(&b, size); + break; + } + case Kchar: { /* fixed-size string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, len <= (size_t)size, arg, + "string longer than given size"); + luaL_addlstring(&b, s, len); /* add string */ + while (len++ < (size_t)size) /* pad extra space */ + luaL_addchar(&b, LUAL_PACKPADBYTE); + break; + } + case Kstring: { /* strings with length count */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, size >= (int)sizeof(size_t) || + len < ((size_t)1 << (size * NB)), + arg, "string length does not fit in given size"); + packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ + luaL_addlstring(&b, s, len); + totalsize += len; + break; + } + case Kzstr: { /* zero-terminated string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); + luaL_addlstring(&b, s, len); + luaL_addchar(&b, '\0'); /* add zero at the end */ + totalsize += len + 1; + break; + } + case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ + case Kpaddalign: case Knop: + arg--; /* undo increment */ + break; + } + } + luaL_pushresult(&b); + return 1; +} + + +static int str_packsize (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, + "variable-length format"); + size += ntoalign; /* total space used by option */ + luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, + "format result too large"); + totalsize += size; + } + lua_pushinteger(L, (lua_Integer)totalsize); + return 1; +} + + +/* +** Unpack an integer with 'size' bytes and 'islittle' endianness. +** If size is smaller than the size of a Lua integer and integer +** is signed, must do sign extension (propagating the sign to the +** higher bits); if size is larger than the size of a Lua integer, +** it must check the unread bytes to see whether they do not cause an +** overflow. +*/ +static lua_Integer unpackint (lua_State *L, const char *str, + int islittle, int size, int issigned) { + lua_Unsigned res = 0; + int i; + int limit = (size <= SZINT) ? size : SZINT; + for (i = limit - 1; i >= 0; i--) { + res <<= NB; + res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; + } + if (size < SZINT) { /* real size smaller than lua_Integer? */ + if (issigned) { /* needs sign extension? */ + lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); + res = ((res ^ mask) - mask); /* do sign extension */ + } + } + else if (size > SZINT) { /* must check unread bytes */ + int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; + for (i = limit; i < size; i++) { + if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask)) + luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); + } + } + return (lua_Integer)res; +} + + +static int str_unpack (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); + size_t ld; + const char *data = luaL_checklstring(L, 2, &ld); + size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1; + int n = 0; /* number of results */ + luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); + luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, + "data string too short"); + pos += ntoalign; /* skip alignment */ + /* stack space for item + next position */ + luaL_checkstack(L, 2, "too many results"); + n++; + switch (opt) { + case Kint: + case Kuint: { + lua_Integer res = unpackint(L, data + pos, h.islittle, size, + (opt == Kint)); + lua_pushinteger(L, res); + break; + } + case Kfloat: { + float f; + copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); + lua_pushnumber(L, (lua_Number)f); + break; + } + case Knumber: { + lua_Number f; + copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); + lua_pushnumber(L, f); + break; + } + case Kdouble: { + double f; + copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); + lua_pushnumber(L, (lua_Number)f); + break; + } + case Kchar: { + lua_pushlstring(L, data + pos, size); + break; + } + case Kstring: { + size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); + luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); + lua_pushlstring(L, data + pos + size, len); + pos += len; /* skip string */ + break; + } + case Kzstr: { + size_t len = strlen(data + pos); + luaL_argcheck(L, pos + len < ld, 2, + "unfinished string for format 'z'"); + lua_pushlstring(L, data + pos, len); + pos += len + 1; /* skip string plus final '\0' */ + break; + } + case Kpaddalign: case Kpadding: case Knop: + n--; /* undo increment */ + break; + } + pos += size; + } + lua_pushinteger(L, pos + 1); /* next position */ + return n + 1; +} + +/* }====================================================== */ + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {"pack", str_pack}, + {"packsize", str_packsize}, + {"unpack", str_unpack}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + /* table to be metatable for strings */ + luaL_newlibtable(L, stringmetamethods); + luaL_setfuncs(L, stringmetamethods, 0); + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, "__index"); /* metatable.__index = string */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUAMOD_API int luaopen_string (lua_State *L) { + luaL_newlib(L, strlib); + createmetatable(L); + return 1; +} + diff --git a/arm9/source/lua/ltable.c b/arm9/source/lua/ltable.c new file mode 100644 index 000000000..3353c0479 --- /dev/null +++ b/arm9/source/lua/ltable.c @@ -0,0 +1,995 @@ +/* +** $Id: ltable.c $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#define ltable_c +#define LUA_CORE + +#include "lprefix.h" + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest 'n' such that +** more than half the slots between 1 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the 'original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* +** MAXABITS is the largest integer such that MAXASIZE fits in an +** unsigned int. +*/ +#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) + + +/* +** MAXASIZE is the maximum size of the array part. It is the minimum +** between 2^MAXABITS and the maximum size that, measured in bytes, +** fits in a 'size_t'. +*/ +#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue) + +/* +** MAXHBITS is the largest integer such that 2^MAXHBITS fits in a +** signed int. +*/ +#define MAXHBITS (MAXABITS - 1) + + +/* +** MAXHSIZE is the maximum size of the hash part. It is the minimum +** between 2^MAXHBITS and the maximum size such that, measured in bytes, +** it fits in a 'size_t'. +*/ +#define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node) + + +/* +** When the original hash value is good, hashing by a power of 2 +** avoids the cost of '%'. +*/ +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +/* +** for other types, it is better to avoid modulo by power of 2, as +** they can have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashstr(t,str) hashpow2(t, (str)->hash) +#define hashboolean(t,p) hashpow2(t, p) + + +#define hashpointer(t,p) hashmod(t, point2uint(p)) + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {{NULL}, LUA_VEMPTY, /* value's value and type */ + LUA_VNIL, 0, {NULL}} /* key type, next, and key value */ +}; + + +static const TValue absentkey = {ABSTKEYCONSTANT}; + + +/* +** Hash for integers. To allow a good hash, use the remainder operator +** ('%'). If integer fits as a non-negative int, compute an int +** remainder, which is faster. Otherwise, use an unsigned-integer +** remainder, which uses all bits and ensures a non-negative result. +*/ +static Node *hashint (const Table *t, lua_Integer i) { + lua_Unsigned ui = l_castS2U(i); + if (ui <= cast_uint(INT_MAX)) + return hashmod(t, cast_int(ui)); + else + return hashmod(t, ui); +} + + +/* +** Hash for floating-point numbers. +** The main computation should be just +** n = frexp(n, &i); return (n * INT_MAX) + i +** but there are some numerical subtleties. +** In a two-complement representation, INT_MAX does not has an exact +** representation as a float, but INT_MIN does; because the absolute +** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the +** absolute value of the product 'frexp * -INT_MIN' is smaller or equal +** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when +** adding 'i'; the use of '~u' (instead of '-u') avoids problems with +** INT_MIN. +*/ +#if !defined(l_hashfloat) +static int l_hashfloat (lua_Number n) { + int i; + lua_Integer ni; + n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN); + if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */ + lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL)); + return 0; + } + else { /* normal case */ + unsigned int u = cast_uint(i) + cast_uint(ni); + return cast_int(u <= cast_uint(INT_MAX) ? u : ~u); + } +} +#endif + + +/* +** returns the 'main' position of an element in a table (that is, +** the index of its hash value). +*/ +static Node *mainpositionTV (const Table *t, const TValue *key) { + switch (ttypetag(key)) { + case LUA_VNUMINT: { + lua_Integer i = ivalue(key); + return hashint(t, i); + } + case LUA_VNUMFLT: { + lua_Number n = fltvalue(key); + return hashmod(t, l_hashfloat(n)); + } + case LUA_VSHRSTR: { + TString *ts = tsvalue(key); + return hashstr(t, ts); + } + case LUA_VLNGSTR: { + TString *ts = tsvalue(key); + return hashpow2(t, luaS_hashlongstr(ts)); + } + case LUA_VFALSE: + return hashboolean(t, 0); + case LUA_VTRUE: + return hashboolean(t, 1); + case LUA_VLIGHTUSERDATA: { + void *p = pvalue(key); + return hashpointer(t, p); + } + case LUA_VLCF: { + lua_CFunction f = fvalue(key); + return hashpointer(t, f); + } + default: { + GCObject *o = gcvalue(key); + return hashpointer(t, o); + } + } +} + + +l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) { + TValue key; + getnodekey(cast(lua_State *, NULL), &key, nd); + return mainpositionTV(t, &key); +} + + +/* +** Check whether key 'k1' is equal to the key in node 'n2'. This +** equality is raw, so there are no metamethods. Floats with integer +** values have been normalized, so integers cannot be equal to +** floats. It is assumed that 'eqshrstr' is simply pointer equality, so +** that short strings are handled in the default case. +** A true 'deadok' means to accept dead keys as equal to their original +** values. All dead keys are compared in the default case, by pointer +** identity. (Only collectable objects can produce dead keys.) Note that +** dead long strings are also compared by identity. +** Once a key is dead, its corresponding value may be collected, and +** then another value can be created with the same address. If this +** other value is given to 'next', 'equalkey' will signal a false +** positive. In a regular traversal, this situation should never happen, +** as all keys given to 'next' came from the table itself, and therefore +** could not have been collected. Outside a regular traversal, we +** have garbage in, garbage out. What is relevant is that this false +** positive does not break anything. (In particular, 'next' will return +** some other valid item on the table or nil.) +*/ +static int equalkey (const TValue *k1, const Node *n2, int deadok) { + if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ + !(deadok && keyisdead(n2) && iscollectable(k1))) + return 0; /* cannot be same key */ + switch (keytt(n2)) { + case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: + return 1; + case LUA_VNUMINT: + return (ivalue(k1) == keyival(n2)); + case LUA_VNUMFLT: + return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2))); + case LUA_VLIGHTUSERDATA: + return pvalue(k1) == pvalueraw(keyval(n2)); + case LUA_VLCF: + return fvalue(k1) == fvalueraw(keyval(n2)); + case ctb(LUA_VLNGSTR): + return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); + default: + return gcvalue(k1) == gcvalueraw(keyval(n2)); + } +} + + +/* +** True if value of 'alimit' is equal to the real size of the array +** part of table 't'. (Otherwise, the array part must be larger than +** 'alimit'.) +*/ +#define limitequalsasize(t) (isrealasize(t) || ispow2((t)->alimit)) + + +/* +** Returns the real size of the 'array' array +*/ +LUAI_FUNC unsigned int luaH_realasize (const Table *t) { + if (limitequalsasize(t)) + return t->alimit; /* this is the size */ + else { + unsigned int size = t->alimit; + /* compute the smallest power of 2 not smaller than 'size' */ + size |= (size >> 1); + size |= (size >> 2); + size |= (size >> 4); + size |= (size >> 8); +#if (UINT_MAX >> 14) > 3 /* unsigned int has more than 16 bits */ + size |= (size >> 16); +#if (UINT_MAX >> 30) > 3 + size |= (size >> 32); /* unsigned int has more than 32 bits */ +#endif +#endif + size++; + lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size); + return size; + } +} + + +/* +** Check whether real size of the array is a power of 2. +** (If it is not, 'alimit' cannot be changed to any other value +** without changing the real size.) +*/ +static int ispow2realasize (const Table *t) { + return (!isrealasize(t) || ispow2(t->alimit)); +} + + +static unsigned int setlimittosize (Table *t) { + t->alimit = luaH_realasize(t); + setrealasize(t); + return t->alimit; +} + + +#define limitasasize(t) check_exp(isrealasize(t), t->alimit) + + + +/* +** "Generic" get version. (Not that generic: not valid for integers, +** which may be in array part, nor for floats with integral values.) +** See explanation about 'deadok' in function 'equalkey'. +*/ +static const TValue *getgeneric (Table *t, const TValue *key, int deadok) { + Node *n = mainpositionTV(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (equalkey(key, n, deadok)) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) + return &absentkey; /* not found */ + n += nx; + } + } +} + + +/* +** returns the index for 'k' if 'k' is an appropriate key to live in +** the array part of a table, 0 otherwise. +*/ +static unsigned int arrayindex (lua_Integer k) { + if (l_castS2U(k) - 1u < MAXASIZE) /* 'k' in [1, MAXASIZE]? */ + return cast_uint(k); /* 'key' is an appropriate array index */ + else + return 0; +} + + +/* +** returns the index of a 'key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signaled by 0. +*/ +static unsigned int findindex (lua_State *L, Table *t, TValue *key, + unsigned int asize) { + unsigned int i; + if (ttisnil(key)) return 0; /* first iteration */ + i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0; + if (i - 1u < asize) /* is 'key' inside array part? */ + return i; /* yes; that's the index */ + else { + const TValue *n = getgeneric(t, key, 1); + if (l_unlikely(isabstkey(n))) + luaG_runerror(L, "invalid key to 'next'"); /* key not found */ + i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return (i + 1) + asize; + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + unsigned int asize = luaH_realasize(t); + unsigned int i = findindex(L, t, s2v(key), asize); /* find original key */ + for (; i < asize; i++) { /* try first array part */ + if (!isempty(&t->array[i])) { /* a non-empty entry? */ + setivalue(s2v(key), i + 1); + setobj2s(L, key + 1, &t->array[i]); + return 1; + } + } + for (i -= asize; cast_int(i) < sizenode(t); i++) { /* hash part */ + if (!isempty(gval(gnode(t, i)))) { /* a non-empty entry? */ + Node *n = gnode(t, i); + getnodekey(L, s2v(key), n); + setobj2s(L, key + 1, gval(n)); + return 1; + } + } + return 0; /* no more elements */ +} + + +static void freehash (lua_State *L, Table *t) { + if (!isdummy(t)) + luaM_freearray(L, t->node, cast_sizet(sizenode(t))); +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + +/* +** Compute the optimal size for the array part of table 't'. 'nums' is a +** "count array" where 'nums[i]' is the number of integers in the table +** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of +** integer keys in the table and leaves with the number of keys that +** will go to the array part; return the optimal size. (The condition +** 'twotoi > 0' in the for loop stops the loop if 'twotoi' overflows.) +*/ +static unsigned int computesizes (unsigned int nums[], unsigned int *pna) { + int i; + unsigned int twotoi; /* 2^i (candidate for optimal size) */ + unsigned int a = 0; /* number of elements smaller than 2^i */ + unsigned int na = 0; /* number of elements to go to array part */ + unsigned int optimal = 0; /* optimal size for array part */ + /* loop while keys can fill more than half of total size */ + for (i = 0, twotoi = 1; + twotoi > 0 && *pna > twotoi / 2; + i++, twotoi *= 2) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + optimal = twotoi; /* optimal size (till now) */ + na = a; /* all elements up to 'optimal' will go to array part */ + } + } + lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal); + *pna = na; + return optimal; +} + + +static int countint (lua_Integer key, unsigned int *nums) { + unsigned int k = arrayindex(key); + if (k != 0) { /* is 'key' an appropriate array index? */ + nums[luaO_ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +/* +** Count keys in array part of table 't': Fill 'nums[i]' with +** number of keys that will go into corresponding slice and return +** total number of non-nil keys. +*/ +static unsigned int numusearray (const Table *t, unsigned int *nums) { + int lg; + unsigned int ttlg; /* 2^lg */ + unsigned int ause = 0; /* summation of 'nums' */ + unsigned int i = 1; /* count to traverse all array keys */ + unsigned int asize = limitasasize(t); /* real array size */ + /* traverse each slice */ + for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { + unsigned int lc = 0; /* counter */ + unsigned int lim = ttlg; + if (lim > asize) { + lim = asize; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg - 1), 2^lg] */ + for (; i <= lim; i++) { + if (!isempty(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* elements added to 'nums' (can go to array part) */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!isempty(gval(n))) { + if (keyisinteger(n)) + ause += countint(keyival(n), nums); + totaluse++; + } + } + *pna += ause; + return totaluse; +} + + +/* +** Creates an array for the hash part of a table with the given +** size, or reuses the dummy node if size is zero. +** The computation for size overflow is in two steps: the first +** comparison ensures that the shift in the second one does not +** overflow. +*/ +static void setnodevector (lua_State *L, Table *t, unsigned int size) { + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common 'dummynode' */ + t->lsizenode = 0; + t->lastfree = NULL; /* signal that it is using dummy node */ + } + else { + int i; + int lsize = luaO_ceillog2(size); + if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i = 0; i < cast_int(size); i++) { + Node *n = gnode(t, i); + gnext(n) = 0; + setnilkey(n); + setempty(gval(n)); + } + t->lsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ + } +} + + +/* +** (Re)insert all elements from the hash part of 'ot' into table 't'. +*/ +static void reinsert (lua_State *L, Table *ot, Table *t) { + int j; + int size = sizenode(ot); + for (j = 0; j < size; j++) { + Node *old = gnode(ot, j); + if (!isempty(gval(old))) { + /* doesn't need barrier/invalidate cache, as entry was + already present in the table */ + TValue k; + getnodekey(L, &k, old); + luaH_set(L, t, &k, gval(old)); + } + } +} + + +/* +** Exchange the hash part of 't1' and 't2'. +*/ +static void exchangehashpart (Table *t1, Table *t2) { + lu_byte lsizenode = t1->lsizenode; + Node *node = t1->node; + Node *lastfree = t1->lastfree; + t1->lsizenode = t2->lsizenode; + t1->node = t2->node; + t1->lastfree = t2->lastfree; + t2->lsizenode = lsizenode; + t2->node = node; + t2->lastfree = lastfree; +} + + +/* +** Resize table 't' for the new given sizes. Both allocations (for +** the hash part and for the array part) can fail, which creates some +** subtleties. If the first allocation, for the hash part, fails, an +** error is raised and that is it. Otherwise, it copies the elements from +** the shrinking part of the array (if it is shrinking) into the new +** hash. Then it reallocates the array part. If that fails, the table +** is in its original state; the function frees the new hash part and then +** raises the allocation error. Otherwise, it sets the new hash part +** into the table, initializes the new part of the array (if any) with +** nils and reinserts the elements of the old hash back into the new +** parts of the table. +*/ +void luaH_resize (lua_State *L, Table *t, unsigned int newasize, + unsigned int nhsize) { + unsigned int i; + Table newt; /* to keep the new hash part */ + unsigned int oldasize = setlimittosize(t); + TValue *newarray; + /* create new hash part with appropriate size into 'newt' */ + setnodevector(L, &newt, nhsize); + if (newasize < oldasize) { /* will array shrink? */ + t->alimit = newasize; /* pretend array has new size... */ + exchangehashpart(t, &newt); /* and new hash */ + /* re-insert into the new hash the elements from vanishing slice */ + for (i = newasize; i < oldasize; i++) { + if (!isempty(&t->array[i])) + luaH_setint(L, t, i + 1, &t->array[i]); + } + t->alimit = oldasize; /* restore current size... */ + exchangehashpart(t, &newt); /* and hash (in case of errors) */ + } + /* allocate new array */ + newarray = luaM_reallocvector(L, t->array, oldasize, newasize, TValue); + if (l_unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ + freehash(L, &newt); /* release new hash part */ + luaM_error(L); /* raise error (with array unchanged) */ + } + /* allocation ok; initialize new part of the array */ + exchangehashpart(t, &newt); /* 't' has the new hash ('newt' has the old) */ + t->array = newarray; /* set new array part */ + t->alimit = newasize; + for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ + setempty(&t->array[i]); + /* re-insert elements from old hash part into new parts */ + reinsert(L, &newt, t); /* 'newt' now has the old hash */ + freehash(L, &newt); /* free old hash part */ +} + + +void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { + int nsize = allocsizenode(t); + luaH_resize(L, t, nasize, nsize); +} + +/* +** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i +*/ +static void rehash (lua_State *L, Table *t, const TValue *ek) { + unsigned int asize; /* optimal size for array part */ + unsigned int na; /* number of keys in the array part */ + unsigned int nums[MAXABITS + 1]; + int i; + int totaluse; + for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */ + setlimittosize(t); + na = numusearray(t, nums); /* count keys in array part */ + totaluse = na; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &na); /* count keys in hash part */ + /* count extra key */ + if (ttisinteger(ek)) + na += countint(ivalue(ek), nums); + totaluse++; + /* compute new size for array part */ + asize = computesizes(nums, &na); + /* resize the table to new computed sizes */ + luaH_resize(L, t, asize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L) { + GCObject *o = luaC_newobj(L, LUA_VTABLE, sizeof(Table)); + Table *t = gco2t(o); + t->metatable = NULL; + t->flags = cast_byte(maskflags); /* table has no metamethod fields */ + t->array = NULL; + t->alimit = 0; + setnodevector(L, t, 0); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + freehash(L, t); + luaM_freearray(L, t->array, luaH_realasize(t)); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + if (!isdummy(t)) { + while (t->lastfree > t->node) { + t->lastfree--; + if (keyisnil(t->lastfree)) + return t->lastfree; + } + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static void luaH_newkey (lua_State *L, Table *t, const TValue *key, + TValue *value) { + Node *mp; + TValue aux; + if (l_unlikely(ttisnil(key))) + luaG_runerror(L, "table index is nil"); + else if (ttisfloat(key)) { + lua_Number f = fltvalue(key); + lua_Integer k; + if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */ + setivalue(&aux, k); + key = &aux; /* insert it as an integer */ + } + else if (l_unlikely(luai_numisnan(f))) + luaG_runerror(L, "table index is NaN"); + } + if (ttisnil(value)) + return; /* do not insert nil values */ + mp = mainpositionTV(t, key); + if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */ + Node *othern; + Node *f = getfreepos(t); /* get a free place */ + if (f == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + /* whatever called 'newkey' takes care of TM cache */ + luaH_set(L, t, key, value); /* insert key into grown table */ + return; + } + lua_assert(!isdummy(t)); + othern = mainpositionfromnode(t, mp); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (othern + gnext(othern) != mp) /* find previous */ + othern += gnext(othern); + gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */ + *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + if (gnext(mp) != 0) { + gnext(f) += cast_int(mp - f); /* correct 'next' */ + gnext(mp) = 0; /* now 'mp' is free */ + } + setempty(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + if (gnext(mp) != 0) + gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */ + else lua_assert(gnext(f) == 0); + gnext(mp) = cast_int(f - mp); + mp = f; + } + } + setnodekey(L, mp, key); + luaC_barrierback(L, obj2gco(t), key); + lua_assert(isempty(gval(mp))); + setobj2t(L, gval(mp), value); +} + + +/* +** Search function for integers. If integer is inside 'alimit', get it +** directly from the array part. Otherwise, if 'alimit' is not +** the real size of the array, the key still can be in the array part. +** In this case, do the "Xmilia trick" to check whether 'key-1' is +** smaller than the real size. +** The trick works as follow: let 'p' be an integer such that +** '2^(p+1) >= alimit > 2^p', or '2^(p+1) > alimit-1 >= 2^p'. +** That is, 2^(p+1) is the real size of the array, and 'p' is the highest +** bit on in 'alimit-1'. What we have to check becomes 'key-1 < 2^(p+1)'. +** We compute '(key-1) & ~(alimit-1)', which we call 'res'; it will +** have the 'p' bit cleared. If the key is outside the array, that is, +** 'key-1 >= 2^(p+1)', then 'res' will have some bit on higher than 'p', +** therefore it will be larger or equal to 'alimit', and the check +** will fail. If 'key-1 < 2^(p+1)', then 'res' has no bit on higher than +** 'p', and as the bit 'p' itself was cleared, 'res' will be smaller +** than 2^p, therefore smaller than 'alimit', and the check succeeds. +** As special cases, when 'alimit' is 0 the condition is trivially false, +** and when 'alimit' is 1 the condition simplifies to 'key-1 < alimit'. +** If key is 0 or negative, 'res' will have its higher bit on, so that +** if cannot be smaller than alimit. +*/ +const TValue *luaH_getint (Table *t, lua_Integer key) { + lua_Unsigned alimit = t->alimit; + if (l_castS2U(key) - 1u < alimit) /* 'key' in [1, t->alimit]? */ + return &t->array[key - 1]; + else if (!isrealasize(t) && /* key still may be in the array part? */ + (((l_castS2U(key) - 1u) & ~(alimit - 1u)) < alimit)) { + t->alimit = cast_uint(key); /* probably '#t' is here now */ + return &t->array[key - 1]; + } + else { /* key is not in the array part; check the hash */ + Node *n = hashint(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (keyisinteger(n) && keyival(n) == key) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + } + return &absentkey; + } +} + + +/* +** search function for short strings +*/ +const TValue *luaH_getshortstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + lua_assert(key->tt == LUA_VSHRSTR); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (keyisshrstr(n) && eqshrstr(keystrval(n), key)) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) + return &absentkey; /* not found */ + n += nx; + } + } +} + + +const TValue *luaH_getstr (Table *t, TString *key) { + if (key->tt == LUA_VSHRSTR) + return luaH_getshortstr(t, key); + else { /* for long strings, use generic case */ + TValue ko; + setsvalue(cast(lua_State *, NULL), &ko, key); + return getgeneric(t, &ko, 0); + } +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttypetag(key)) { + case LUA_VSHRSTR: return luaH_getshortstr(t, tsvalue(key)); + case LUA_VNUMINT: return luaH_getint(t, ivalue(key)); + case LUA_VNIL: return &absentkey; + case LUA_VNUMFLT: { + lua_Integer k; + if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ + return luaH_getint(t, k); /* use specialized version */ + /* else... */ + } /* FALLTHROUGH */ + default: + return getgeneric(t, key, 0); + } +} + + +/* +** Finish a raw "set table" operation, where 'slot' is where the value +** should have been (the result of a previous "get table"). +** Beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ +void luaH_finishset (lua_State *L, Table *t, const TValue *key, + const TValue *slot, TValue *value) { + if (isabstkey(slot)) + luaH_newkey(L, t, key, value); + else + setobj2t(L, cast(TValue *, slot), value); +} + + +/* +** beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ +void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { + const TValue *slot = luaH_get(t, key); + luaH_finishset(L, t, key, slot, value); +} + + +void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { + const TValue *p = luaH_getint(t, key); + if (isabstkey(p)) { + TValue k; + setivalue(&k, key); + luaH_newkey(L, t, &k, value); + } + else + setobj2t(L, cast(TValue *, p), value); +} + + +/* +** Try to find a boundary in the hash part of table 't'. From the +** caller, we know that 'j' is zero or present and that 'j + 1' is +** present. We want to find a larger key that is absent from the +** table, so that we can do a binary search between the two keys to +** find a boundary. We keep doubling 'j' until we get an absent index. +** If the doubling would overflow, we try LUA_MAXINTEGER. If it is +** absent, we are ready for the binary search. ('j', being max integer, +** is larger or equal to 'i', but it cannot be equal because it is +** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a +** boundary. ('j + 1' cannot be a present integer key because it is +** not a valid integer in Lua.) +*/ +static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { + lua_Unsigned i; + if (j == 0) j++; /* the caller ensures 'j + 1' is present */ + do { + i = j; /* 'i' is a present index */ + if (j <= l_castS2U(LUA_MAXINTEGER) / 2) + j *= 2; + else { + j = LUA_MAXINTEGER; + if (isempty(luaH_getint(t, j))) /* t[j] not present? */ + break; /* 'j' now is an absent index */ + else /* weird case */ + return j; /* well, max integer is a boundary... */ + } + } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */ + /* i < j && t[i] present && t[j] absent */ + while (j - i > 1u) { /* do a binary search between them */ + lua_Unsigned m = (i + j) / 2; + if (isempty(luaH_getint(t, m))) j = m; + else i = m; + } + return i; +} + + +static unsigned int binsearch (const TValue *array, unsigned int i, + unsigned int j) { + while (j - i > 1u) { /* binary search */ + unsigned int m = (i + j) / 2; + if (isempty(&array[m - 1])) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table 't'. (A 'boundary' is an integer index +** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent +** and 'maxinteger' if t[maxinteger] is present.) +** (In the next explanation, we use Lua indices, that is, with base 1. +** The code itself uses base 0 when indexing the array part of the table.) +** The code starts with 'limit = t->alimit', a position in the array +** part that may be a boundary. +** +** (1) If 't[limit]' is empty, there must be a boundary before it. +** As a common case (e.g., after 't[#t]=nil'), check whether 'limit-1' +** is present. If so, it is a boundary. Otherwise, do a binary search +** between 0 and limit to find a boundary. In both cases, try to +** use this boundary as the new 'alimit', as a hint for the next call. +** +** (2) If 't[limit]' is not empty and the array has more elements +** after 'limit', try to find a boundary there. Again, try first +** the special case (which should be quite frequent) where 'limit+1' +** is empty, so that 'limit' is a boundary. Otherwise, check the +** last element of the array part. If it is empty, there must be a +** boundary between the old limit (present) and the last element +** (absent), which is found with a binary search. (This boundary always +** can be a new limit.) +** +** (3) The last case is when there are no elements in the array part +** (limit == 0) or its last element (the new limit) is present. +** In this case, must check the hash part. If there is no hash part +** or 'limit+1' is absent, 'limit' is a boundary. Otherwise, call +** 'hash_search' to find a boundary in the hash part of the table. +** (In those cases, the boundary is not inside the array part, and +** therefore cannot be used as a new limit.) +*/ +lua_Unsigned luaH_getn (Table *t) { + unsigned int limit = t->alimit; + if (limit > 0 && isempty(&t->array[limit - 1])) { /* (1)? */ + /* there must be a boundary before 'limit' */ + if (limit >= 2 && !isempty(&t->array[limit - 2])) { + /* 'limit - 1' is a boundary; can it be a new limit? */ + if (ispow2realasize(t) && !ispow2(limit - 1)) { + t->alimit = limit - 1; + setnorealasize(t); /* now 'alimit' is not the real size */ + } + return limit - 1; + } + else { /* must search for a boundary in [0, limit] */ + unsigned int boundary = binsearch(t->array, 0, limit); + /* can this boundary represent the real size of the array? */ + if (ispow2realasize(t) && boundary > luaH_realasize(t) / 2) { + t->alimit = boundary; /* use it as the new limit */ + setnorealasize(t); + } + return boundary; + } + } + /* 'limit' is zero or present in table */ + if (!limitequalsasize(t)) { /* (2)? */ + /* 'limit' > 0 and array has more elements after 'limit' */ + if (isempty(&t->array[limit])) /* 'limit + 1' is empty? */ + return limit; /* this is the boundary */ + /* else, try last element in the array */ + limit = luaH_realasize(t); + if (isempty(&t->array[limit - 1])) { /* empty? */ + /* there must be a boundary in the array after old limit, + and it must be a valid new limit */ + unsigned int boundary = binsearch(t->array, t->alimit, limit); + t->alimit = boundary; + return boundary; + } + /* else, new limit is present in the table; check the hash part */ + } + /* (3) 'limit' is the last element and either is zero or present in table */ + lua_assert(limit == luaH_realasize(t) && + (limit == 0 || !isempty(&t->array[limit - 1]))); + if (isdummy(t) || isempty(luaH_getint(t, cast(lua_Integer, limit + 1)))) + return limit; /* 'limit + 1' is absent */ + else /* 'limit + 1' is also present */ + return hash_search(t, limit); +} + + + +#if defined(LUA_DEBUG) + +/* export these functions for the test library */ + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainpositionTV(t, key); +} + +#endif diff --git a/arm9/source/lua/ltable.h b/arm9/source/lua/ltable.h new file mode 100644 index 000000000..8e6890342 --- /dev/null +++ b/arm9/source/lua/ltable.h @@ -0,0 +1,63 @@ +/* +** $Id: ltable.h $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->u.next) + + +/* +** Clear all bits of fast-access metamethods, which means that the table +** may have any of these metamethods. (First access that fails after the +** clearing will set the bit again.) +*/ +#define invalidateTMcache(t) ((t)->flags &= ~maskflags) + + +/* true when 't' is using 'dummynode' as its hash part */ +#define isdummy(t) ((t)->lastfree == NULL) + + +/* allocated size for hash nodes */ +#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) + + +/* returns the Node, given the value of a table entry */ +#define nodefromval(v) cast(Node *, (v)) + + +LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); +LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, + TValue *value); +LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, + TValue *value); +LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, + const TValue *slot, TValue *value); +LUAI_FUNC Table *luaH_new (lua_State *L); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, + unsigned int nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC lua_Unsigned luaH_getn (Table *t); +LUAI_FUNC unsigned int luaH_realasize (const Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +#endif + + +#endif diff --git a/arm9/source/lua/ltablib.c b/arm9/source/lua/ltablib.c new file mode 100644 index 000000000..e6bc4d04a --- /dev/null +++ b/arm9/source/lua/ltablib.c @@ -0,0 +1,430 @@ +/* +** $Id: ltablib.c $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + +#define ltablib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** Operations that an object must define to mimic a table +** (some functions only need some of them) +*/ +#define TAB_R 1 /* read */ +#define TAB_W 2 /* write */ +#define TAB_L 4 /* length */ +#define TAB_RW (TAB_R | TAB_W) /* read/write */ + + +#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) + + +static int checkfield (lua_State *L, const char *key, int n) { + lua_pushstring(L, key); + return (lua_rawget(L, -n) != LUA_TNIL); +} + + +/* +** Check that 'arg' either is a table or can behave like one (that is, +** has a metatable with the required metamethods) +*/ +static void checktab (lua_State *L, int arg, int what) { + if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ + int n = 1; /* number of elements to pop */ + if (lua_getmetatable(L, arg) && /* must have metatable */ + (!(what & TAB_R) || checkfield(L, "__index", ++n)) && + (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && + (!(what & TAB_L) || checkfield(L, "__len", ++n))) { + lua_pop(L, n); /* pop metatable and tested metamethods */ + } + else + luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ + } +} + + +static int tinsert (lua_State *L) { + lua_Integer pos; /* where to insert new element */ + lua_Integer e = aux_getn(L, 1, TAB_RW); + e = luaL_intop(+, e, 1); /* first empty element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + lua_Integer i; + pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ + /* check whether 'pos' is in [1, e] */ + luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2, + "position out of bounds"); + for (i = e; i > pos; i--) { /* move up elements */ + lua_geti(L, 1, i - 1); + lua_seti(L, 1, i); /* t[i] = t[i - 1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to 'insert'"); + } + } + lua_seti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + lua_Integer size = aux_getn(L, 1, TAB_RW); + lua_Integer pos = luaL_optinteger(L, 2, size); + if (pos != size) /* validate 'pos' if given */ + /* check whether 'pos' is in [1, size + 1] */ + luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 2, + "position out of bounds"); + lua_geti(L, 1, pos); /* result = t[pos] */ + for ( ; pos < size; pos++) { + lua_geti(L, 1, pos + 1); + lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ + } + lua_pushnil(L); + lua_seti(L, 1, pos); /* remove entry t[pos] */ + return 1; +} + + +/* +** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever +** possible, copy in increasing order, which is better for rehashing. +** "possible" means destination after original range, or smaller +** than origin, or copying to another table. +*/ +static int tmove (lua_State *L) { + lua_Integer f = luaL_checkinteger(L, 2); + lua_Integer e = luaL_checkinteger(L, 3); + lua_Integer t = luaL_checkinteger(L, 4); + int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ + checktab(L, 1, TAB_R); + checktab(L, tt, TAB_W); + if (e >= f) { /* otherwise, nothing to move */ + lua_Integer n, i; + luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, + "too many elements to move"); + n = e - f + 1; /* number of elements to move */ + luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, + "destination wrap around"); + if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { + for (i = 0; i < n; i++) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); + } + } + else { + for (i = n - 1; i >= 0; i--) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); + } + } + } + lua_pushvalue(L, tt); /* return destination table */ + return 1; +} + + +static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { + lua_geti(L, 1, i); + if (l_unlikely(!lua_isstring(L, -1))) + luaL_error(L, "invalid value (%s) at index %I in table for 'concat'", + luaL_typename(L, -1), (LUAI_UACINT)i); + luaL_addvalue(b); +} + + +static int tconcat (lua_State *L) { + luaL_Buffer b; + lua_Integer last = aux_getn(L, 1, TAB_R); + size_t lsep; + const char *sep = luaL_optlstring(L, 2, "", &lsep); + lua_Integer i = luaL_optinteger(L, 3, 1); + last = luaL_optinteger(L, 4, last); + luaL_buffinit(L, &b); + for (; i < last; i++) { + addfield(L, &b, i); + luaL_addlstring(&b, sep, lsep); + } + if (i == last) /* add last value (if interval was not empty) */ + addfield(L, &b, i); + luaL_pushresult(&b); + return 1; +} + + +/* +** {====================================================== +** Pack/unpack +** ======================================================= +*/ + +static int tpack (lua_State *L) { + int i; + int n = lua_gettop(L); /* number of elements to pack */ + lua_createtable(L, n, 1); /* create result table */ + lua_insert(L, 1); /* put it at index 1 */ + for (i = n; i >= 1; i--) /* assign elements */ + lua_seti(L, 1, i); + lua_pushinteger(L, n); + lua_setfield(L, 1, "n"); /* t.n = number of elements */ + return 1; /* return table */ +} + + +static int tunpack (lua_State *L) { + lua_Unsigned n; + lua_Integer i = luaL_optinteger(L, 2, 1); + lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); + if (i > e) return 0; /* empty range */ + n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ + if (l_unlikely(n >= (unsigned int)INT_MAX || + !lua_checkstack(L, (int)(++n)))) + return luaL_error(L, "too many results to unpack"); + for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ + lua_geti(L, 1, i); + } + lua_geti(L, 1, e); /* push last element */ + return (int)n; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Quicksort +** (based on 'Algorithms in MODULA-3', Robert Sedgewick; +** Addison-Wesley, 1993.) +** ======================================================= +*/ + + +/* type for array indices */ +typedef unsigned int IdxT; + + +/* +** Produce a "random" 'unsigned int' to randomize pivot choice. This +** macro is used only when 'sort' detects a big imbalance in the result +** of a partition. (If you don't want/need this "randomness", ~0 is a +** good choice.) +*/ +#if !defined(l_randomizePivot) /* { */ + +#include + +/* size of 'e' measured in number of 'unsigned int's */ +#define sof(e) (sizeof(e) / sizeof(unsigned int)) + +/* +** Use 'time' and 'clock' as sources of "randomness". Because we don't +** know the types 'clock_t' and 'time_t', we cannot cast them to +** anything without risking overflows. A safe way to use their values +** is to copy them to an array of a known type and use the array values. +*/ +static unsigned int l_randomizePivot (void) { + clock_t c = clock(); + time_t t = time(NULL); + unsigned int buff[sof(c) + sof(t)]; + unsigned int i, rnd = 0; + memcpy(buff, &c, sof(c) * sizeof(unsigned int)); + memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); + for (i = 0; i < sof(buff); i++) + rnd += buff[i]; + return rnd; +} + +#endif /* } */ + + +/* arrays larger than 'RANLIMIT' may use randomized pivots */ +#define RANLIMIT 100u + + +static void set2 (lua_State *L, IdxT i, IdxT j) { + lua_seti(L, 1, i); + lua_seti(L, 1, j); +} + + +/* +** Return true iff value at stack index 'a' is less than the value at +** index 'b' (according to the order of the sort). +*/ +static int sort_comp (lua_State *L, int a, int b) { + if (lua_isnil(L, 2)) /* no function? */ + return lua_compare(L, a, b, LUA_OPLT); /* a < b */ + else { /* function */ + int res; + lua_pushvalue(L, 2); /* push function */ + lua_pushvalue(L, a-1); /* -1 to compensate function */ + lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ + lua_call(L, 2, 1); /* call function */ + res = lua_toboolean(L, -1); /* get result */ + lua_pop(L, 1); /* pop result */ + return res; + } +} + + +/* +** Does the partition: Pivot P is at the top of the stack. +** precondition: a[lo] <= P == a[up-1] <= a[up], +** so it only needs to do the partition from lo + 1 to up - 2. +** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] +** returns 'i'. +*/ +static IdxT partition (lua_State *L, IdxT lo, IdxT up) { + IdxT i = lo; /* will be incremented before first use */ + IdxT j = up - 1; /* will be decremented before first use */ + /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ + for (;;) { + /* next loop: repeat ++i while a[i] < P */ + while ((void)lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (l_unlikely(i == up - 1)) /* a[i] < P but a[up - 1] == P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ + /* next loop: repeat --j while P < a[j] */ + while ((void)lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { + if (l_unlikely(j < i)) /* j < i but a[j] > P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ + if (j < i) { /* no elements out of place? */ + /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ + lua_pop(L, 1); /* pop a[j] */ + /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ + set2(L, up - 1, i); + return i; + } + /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ + set2(L, i, j); + } +} + + +/* +** Choose an element in the middle (2nd-3th quarters) of [lo,up] +** "randomized" by 'rnd' +*/ +static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { + IdxT r4 = (up - lo) / 4; /* range/4 */ + IdxT p = rnd % (r4 * 2) + (lo + r4); + lua_assert(lo + r4 <= p && p <= up - r4); + return p; +} + + +/* +** Quicksort algorithm (recursive function) +*/ +static void auxsort (lua_State *L, IdxT lo, IdxT up, + unsigned int rnd) { + while (lo < up) { /* loop for tail recursion */ + IdxT p; /* Pivot index */ + IdxT n; /* to be used later */ + /* sort elements 'lo', 'p', and 'up' */ + lua_geti(L, 1, lo); + lua_geti(L, 1, up); + if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ + set2(L, lo, up); /* swap a[lo] - a[up] */ + else + lua_pop(L, 2); /* remove both values */ + if (up - lo == 1) /* only 2 elements? */ + return; /* already sorted */ + if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ + p = (lo + up)/2; /* middle element is a good pivot */ + else /* for larger intervals, it is worth a random pivot */ + p = choosePivot(lo, up, rnd); + lua_geti(L, 1, p); + lua_geti(L, 1, lo); + if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ + set2(L, p, lo); /* swap a[p] - a[lo] */ + else { + lua_pop(L, 1); /* remove a[lo] */ + lua_geti(L, 1, up); + if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ + set2(L, p, up); /* swap a[up] - a[p] */ + else + lua_pop(L, 2); + } + if (up - lo == 2) /* only 3 elements? */ + return; /* already sorted */ + lua_geti(L, 1, p); /* get middle element (Pivot) */ + lua_pushvalue(L, -1); /* push Pivot */ + lua_geti(L, 1, up - 1); /* push a[up - 1] */ + set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ + p = partition(L, lo, up); + /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ + if (p - lo < up - p) { /* lower interval is smaller? */ + auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ + n = p - lo; /* size of smaller interval */ + lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ + } + else { + auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ + n = up - p; /* size of smaller interval */ + up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ + } + if ((up - lo) / 128 > n) /* partition too imbalanced? */ + rnd = l_randomizePivot(); /* try a new randomization */ + } /* tail call auxsort(L, lo, up, rnd) */ +} + + +static int sort (lua_State *L) { + lua_Integer n = aux_getn(L, 1, TAB_RW); + if (n > 1) { /* non-trivial interval? */ + luaL_argcheck(L, n < INT_MAX, 1, "array too big"); + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ + luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ + lua_settop(L, 2); /* make sure there are two arguments */ + auxsort(L, 1, (IdxT)n, 0); + } + return 0; +} + +/* }====================================================== */ + + +static const luaL_Reg tab_funcs[] = { + {"concat", tconcat}, + {"insert", tinsert}, + {"pack", tpack}, + {"unpack", tunpack}, + {"remove", tremove}, + {"move", tmove}, + {"sort", sort}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_table (lua_State *L) { + luaL_newlib(L, tab_funcs); + return 1; +} + diff --git a/arm9/source/lua/ltm.c b/arm9/source/lua/ltm.c new file mode 100644 index 000000000..07a060811 --- /dev/null +++ b/arm9/source/lua/ltm.c @@ -0,0 +1,271 @@ +/* +** $Id: ltm.c $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#define ltm_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +static const char udatatypename[] = "userdata"; + +LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTYPES] = { + "no value", + "nil", "boolean", udatatypename, "number", + "string", "table", "function", udatatypename, "thread", + "upvalue", "proto" /* these last cases are used for tests only */ +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__len", "__eq", + "__add", "__sub", "__mul", "__mod", "__pow", + "__div", "__idiv", + "__band", "__bor", "__bxor", "__shl", "__shr", + "__unm", "__bnot", "__lt", "__le", + "__concat", "__call", "__close" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getshortstr(events, ename); + lua_assert(event <= TM_EQ); + if (notm(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); +} + + +/* +** Return the name of the type of an object. For tables and userdata +** with metatable, use their '__name' metafield, if present. +*/ +const char *luaT_objtypename (lua_State *L, const TValue *o) { + Table *mt; + if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || + (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { + const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); + if (ttisstring(name)) /* is '__name' a string? */ + return getstr(tsvalue(name)); /* use it as type name */ + } + return ttypename(ttype(o)); /* else use standard type name */ +} + + +void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3) { + StkId func = L->top.p; + setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ + setobj2s(L, func + 1, p1); /* 1st argument */ + setobj2s(L, func + 2, p2); /* 2nd argument */ + setobj2s(L, func + 3, p3); /* 3rd argument */ + L->top.p = func + 4; + /* metamethod may yield only when called from Lua code */ + if (isLuacode(L->ci)) + luaD_call(L, func, 0); + else + luaD_callnoyield(L, func, 0); +} + + +void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, StkId res) { + ptrdiff_t result = savestack(L, res); + StkId func = L->top.p; + setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ + setobj2s(L, func + 1, p1); /* 1st argument */ + setobj2s(L, func + 2, p2); /* 2nd argument */ + L->top.p += 3; + /* metamethod may yield only when called from Lua code */ + if (isLuacode(L->ci)) + luaD_call(L, func, 1); + else + luaD_callnoyield(L, func, 1); + res = restorestack(L, result); + setobjs2s(L, res, --L->top.p); /* move result to its place */ +} + + +static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (notm(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (notm(tm)) return 0; + luaT_callTMres(L, tm, p1, p2, res); + return 1; +} + + +void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { + switch (event) { + case TM_BAND: case TM_BOR: case TM_BXOR: + case TM_SHL: case TM_SHR: case TM_BNOT: { + if (ttisnumber(p1) && ttisnumber(p2)) + luaG_tointerror(L, p1, p2); + else + luaG_opinterror(L, p1, p2, "perform bitwise operation on"); + } + /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ + default: + luaG_opinterror(L, p1, p2, "perform arithmetic on"); + } + } +} + + +void luaT_tryconcatTM (lua_State *L) { + StkId top = L->top.p; + if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, + TM_CONCAT))) + luaG_concaterror(L, s2v(top - 2), s2v(top - 1)); +} + + +void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, + int flip, StkId res, TMS event) { + if (flip) + luaT_trybinTM(L, p2, p1, res, event); + else + luaT_trybinTM(L, p1, p2, res, event); +} + + +void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, + int flip, StkId res, TMS event) { + TValue aux; + setivalue(&aux, i2); + luaT_trybinassocTM(L, p1, &aux, flip, res, event); +} + + +/* +** Calls an order tag method. +** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old +** behavior: if there is no '__le', try '__lt', based on l <= r iff +** !(r < l) (assuming a total order). If the metamethod yields during +** this substitution, the continuation has to know about it (to negate +** the result of rtop.p, event)) /* try original event */ + return !l_isfalse(s2v(L->top.p)); +#if defined(LUA_COMPAT_LT_LE) + else if (event == TM_LE) { + /* try '!(p2 < p1)' for '(p1 <= p2)' */ + L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ + if (callbinTM(L, p2, p1, L->top.p, TM_LT)) { + L->ci->callstatus ^= CIST_LEQ; /* clear mark */ + return l_isfalse(s2v(L->top.p)); + } + /* else error will remove this 'ci'; no need to clear mark */ + } +#endif + luaG_ordererror(L, p1, p2); /* no metamethod found */ + return 0; /* to avoid warnings */ +} + + +int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, + int flip, int isfloat, TMS event) { + TValue aux; const TValue *p2; + if (isfloat) { + setfltvalue(&aux, cast_num(v2)); + } + else + setivalue(&aux, v2); + if (flip) { /* arguments were exchanged? */ + p2 = p1; p1 = &aux; /* correct them */ + } + else + p2 = &aux; + return luaT_callorderTM(L, p1, p2, event); +} + + +void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, + const Proto *p) { + int i; + int actual = cast_int(L->top.p - ci->func.p) - 1; /* number of arguments */ + int nextra = actual - nfixparams; /* number of extra arguments */ + ci->u.l.nextraargs = nextra; + luaD_checkstack(L, p->maxstacksize + 1); + /* copy function to the top of the stack */ + setobjs2s(L, L->top.p++, ci->func.p); + /* move fixed parameters to the top of the stack */ + for (i = 1; i <= nfixparams; i++) { + setobjs2s(L, L->top.p++, ci->func.p + i); + setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ + } + ci->func.p += actual + 1; + ci->top.p += actual + 1; + lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); +} + + +void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { + int i; + int nextra = ci->u.l.nextraargs; + if (wanted < 0) { + wanted = nextra; /* get all extra arguments available */ + checkstackGCp(L, nextra, where); /* ensure stack space */ + L->top.p = where + nextra; /* next instruction will need top */ + } + for (i = 0; i < wanted && i < nextra; i++) + setobjs2s(L, where + i, ci->func.p - nextra + i); + for (; i < wanted; i++) /* complete required results with nil */ + setnilvalue(s2v(where + i)); +} + diff --git a/arm9/source/lua/ltm.h b/arm9/source/lua/ltm.h new file mode 100644 index 000000000..73b833c60 --- /dev/null +++ b/arm9/source/lua/ltm.h @@ -0,0 +1,103 @@ +/* +** $Id: ltm.h $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" and "ORDER OP" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_LEN, + TM_EQ, /* last tag method with fast access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_MOD, + TM_POW, + TM_DIV, + TM_IDIV, + TM_BAND, + TM_BOR, + TM_BXOR, + TM_SHL, + TM_SHR, + TM_UNM, + TM_BNOT, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_CLOSE, + TM_N /* number of elements in the enum */ +} TMS; + + +/* +** Mask with 1 in all fast-access methods. A 1 in any of these bits +** in the flag of a (meta)table means the metatable does not have the +** corresponding metamethod field. (Bit 7 of the flag is used for +** 'isrealasize'.) +*/ +#define maskflags (~(~0u << (TM_EQ + 1))) + + +/* +** Test whether there is no tagmethod. +** (Because tagmethods use raw accesses, the result may be an "empty" nil.) +*/ +#define notm(tm) ttisnil(tm) + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +#define ttypename(x) luaT_typenames_[(x) + 1] + +LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];) + + +LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3); +LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, + const TValue *p1, const TValue *p2, StkId p3); +LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event); +LUAI_FUNC void luaT_tryconcatTM (lua_State *L); +LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, + const TValue *p2, int inv, StkId res, TMS event); +LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, + int inv, StkId res, TMS event); +LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, + const TValue *p2, TMS event); +LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, + int inv, int isfloat, TMS event); + +LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, + struct CallInfo *ci, const Proto *p); +LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, + StkId where, int wanted); + + +#endif diff --git a/arm9/source/lua/lua.h b/arm9/source/lua/lua.h new file mode 100644 index 000000000..f050dac09 --- /dev/null +++ b/arm9/source/lua/lua.h @@ -0,0 +1,523 @@ +/* +** $Id: lua.h $ +** Lua - A Scripting Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "4" +#define LUA_VERSION_RELEASE "7" + +#define LUA_VERSION_NUM 504 +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 7) + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2024 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" + + +/* mark for precompiled code ('Lua') */ +#define LUA_SIGNATURE "\x1bLua" + +/* option for multiple returns in 'lua_pcall' and 'lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** Pseudo-indices +** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty +** space after that to help overflow detection) +*/ +#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) + + +/* thread status */ +#define LUA_OK 0 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + +#define LUA_NUMTYPES 9 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* predefined values in the registry */ +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + +/* type for continuation-function contexts */ +typedef LUA_KCONTEXT lua_KContext; + + +/* +** Type for C functions registered with Lua +*/ +typedef int (*lua_CFunction) (lua_State *L); + +/* +** Type for continuation functions +*/ +typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); + + +/* +** Type for functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); + + +/* +** Type for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** Type for warning functions +*/ +typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); + + +/* +** Type used by the debug API to collect debug information +*/ +typedef struct lua_Debug lua_Debug; + + +/* +** Functions to be called by the debugger in specific events +*/ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* +** RCS ident string +*/ +extern const char lua_ident[]; + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); +LUA_API int (lua_closethread) (lua_State *L, lua_State *from); +LUA_API int (lua_resetthread) (lua_State *L); /* Deprecated! */ + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +LUA_API lua_Number (lua_version) (lua_State *L); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_absindex) (lua_State *L, int idx); +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_rotate) (lua_State *L, int idx, int n); +LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); +LUA_API int (lua_checkstack) (lua_State *L, int n); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isinteger) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API lua_Unsigned (lua_rawlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** Comparison and arithmetic functions +*/ + +#define LUA_OPADD 0 /* ORDER TM, ORDER OP */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPMOD 3 +#define LUA_OPPOW 4 +#define LUA_OPDIV 5 +#define LUA_OPIDIV 6 +#define LUA_OPBAND 7 +#define LUA_OPBOR 8 +#define LUA_OPBXOR 9 +#define LUA_OPSHL 10 +#define LUA_OPSHR 11 +#define LUA_OPUNM 12 +#define LUA_OPBNOT 13 + +LUA_API void (lua_arith) (lua_State *L, int op); + +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 + +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len); +LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API int (lua_getglobal) (lua_State *L, const char *name); +LUA_API int (lua_gettable) (lua_State *L, int idx); +LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n); +LUA_API int (lua_rawget) (lua_State *L, int idx); +LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); +LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); + +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API int (lua_getiuservalue) (lua_State *L, int idx, int n); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_setglobal) (lua_State *L, const char *name); +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); +LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setiuservalue) (lua_State *L, int idx, int n); + + +/* +** 'load' and 'call' functions (load and run Lua code) +*/ +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k); +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, + lua_KContext ctx, lua_KFunction k); +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) + +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, const char *mode); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, + lua_KFunction k); +LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg, + int *nres); +LUA_API int (lua_status) (lua_State *L); +LUA_API int (lua_isyieldable) (lua_State *L); + +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) + + +/* +** Warning-related functions +*/ +LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud); +LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); + + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 + +LUA_API int (lua_gc) (lua_State *L, int what, ...); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); +LUA_API void (lua_len) (lua_State *L, int idx); + +LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); + +LUA_API void (lua_toclose) (lua_State *L, int idx); +LUA_API void (lua_closeslot) (lua_State *L, int idx); + + +/* +** {============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) + +#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL) + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) lua_pushstring(L, "" s) + +#define lua_pushglobaltable(L) \ + ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + +#define lua_insert(L,idx) lua_rotate(L, (idx), 1) + +#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) + +#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) + +/* }============================================================== */ + + +/* +** {============================================================== +** compatibility macros +** =============================================================== +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) +#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) +#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) + +#endif + +#define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) +#define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) +#define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) + +#define LUA_NUMTAGS LUA_NUMTYPES + +/* }============================================================== */ + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILCALL 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + + +LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); +LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); +LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); + +LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); +LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, + int fidx2, int n2); + +LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook (lua_gethook) (lua_State *L); +LUA_API int (lua_gethookmask) (lua_State *L); +LUA_API int (lua_gethookcount) (lua_State *L); + +LUA_API int (lua_setcstacklimit) (lua_State *L, unsigned int limit); + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ + const char *source; /* (S) */ + size_t srclen; /* (S) */ + int currentline; /* (l) */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams;/* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ + unsigned short ftransfer; /* (r) index of first value transferred */ + unsigned short ntransfer; /* (r) number of transferred values */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct CallInfo *i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2024 Lua.org, PUC-Rio. +* +* 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. +******************************************************************************/ + + +#endif diff --git a/arm9/source/lua/luaconf.h b/arm9/source/lua/luaconf.h new file mode 100644 index 000000000..33bb580d1 --- /dev/null +++ b/arm9/source/lua/luaconf.h @@ -0,0 +1,802 @@ +/* +** $Id: luaconf.h $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef luaconf_h +#define luaconf_h + +#include +#include + + +/* +** =================================================================== +** General Configuration File for Lua +** +** Some definitions here can be changed externally, through the compiler +** (e.g., with '-D' options): They are commented out or protected +** by '#if !defined' guards. However, several other definitions +** should be changed directly here, either because they affect the +** Lua ABI (by making the changes here, you ensure that all software +** connected to Lua, such as C libraries, will be compiled with the same +** configuration); or because they are seldom changed. +** +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +** {==================================================================== +** System Configuration: macros to adapt (if needed) Lua to some +** particular platform, for instance restricting it to C89. +** ===================================================================== +*/ + +/* +@@ LUA_USE_C89 controls the use of non-ISO-C89 features. +** Define it if you want Lua to avoid the use of a few C99 features +** or Windows-specific features on Windows. +*/ +/* #define LUA_USE_C89 */ + + +/* +** By default, Lua on Windows use (some) specific Windows features +*/ +#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_USE_WINDOWS /* enable goodies for regular Windows */ +#endif + + +#if defined(LUA_USE_WINDOWS) +#define LUA_DL_DLL /* enable support for DLL */ +#define LUA_USE_C89 /* broadly, Windows is C89 */ +#endif + + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#endif + + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ +#endif + + +#if defined(LUA_USE_IOS) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN +#endif + + +/* +@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits. +*/ +#define LUAI_IS32INT ((UINT_MAX >> 30) >= 3) + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Number types. These options should not be +** set externally, because any other code connected to Lua must +** use the same configuration. +** =================================================================== +*/ + +/* +@@ LUA_INT_TYPE defines the type for Lua integers. +@@ LUA_FLOAT_TYPE defines the type for Lua floats. +** Lua should work fine with any mix of these options supported +** by your C compiler. The usual configurations are 64-bit integers +** and 'double' (the default), 32-bit integers and 'float' (for +** restricted platforms), and 'long'/'double' (for C compilers not +** compliant with C99, which may not have support for 'long long'). +*/ + +/* predefined options for LUA_INT_TYPE */ +#define LUA_INT_INT 1 +#define LUA_INT_LONG 2 +#define LUA_INT_LONGLONG 3 + +/* predefined options for LUA_FLOAT_TYPE */ +#define LUA_FLOAT_FLOAT 1 +#define LUA_FLOAT_DOUBLE 2 +#define LUA_FLOAT_LONGDOUBLE 3 + + +/* Default configuration ('long long' and 'double', for 64-bit Lua) */ +#define LUA_INT_DEFAULT LUA_INT_LONGLONG +#define LUA_FLOAT_DEFAULT LUA_FLOAT_DOUBLE + + +/* +@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. +*/ +#define LUA_32BITS 0 + + +/* +@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for +** C89 ('long' and 'double'); Windows always has '__int64', so it does +** not need to use this case. +*/ +#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) +#define LUA_C89_NUMBERS 1 +#else +#define LUA_C89_NUMBERS 0 +#endif + + +#if LUA_32BITS /* { */ +/* +** 32-bit integers and 'float' +*/ +#if LUAI_IS32INT /* use 'int' if big enough */ +#define LUA_INT_TYPE LUA_INT_INT +#else /* otherwise use 'long' */ +#define LUA_INT_TYPE LUA_INT_LONG +#endif +#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT + +#elif LUA_C89_NUMBERS /* }{ */ +/* +** largest types available for C89 ('long' and 'double') +*/ +#define LUA_INT_TYPE LUA_INT_LONG +#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE + +#else /* }{ */ +/* use defaults */ + +#define LUA_INT_TYPE LUA_INT_DEFAULT +#define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT + +#endif /* } */ + + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Paths. +** =================================================================== +*/ + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +*/ +#define LUA_PATH_SEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXEC_DIR "!" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +** Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +** C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ + +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#if defined(_WIN32) /* { */ +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ + LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ + ".\\?.lua;" ".\\?\\init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.dll;" \ + LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ + LUA_CDIR"loadall.dll;" ".\\?.dll" +#endif + +#else /* }{ */ + +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ + "./?.lua;" "./?/init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif + +#endif /* } */ + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if !defined(LUA_DIRSEP) + +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + +#endif + + +/* +** LUA_IGMARK is a mark to ignore all after it when building the +** module name (e.g., used to build the luaopen_ function name). +** Typically, the suffix after the mark is the module version, +** as in "mod-v1.2.so". +*/ +#define LUA_IGMARK "-" + +/* }================================================================== */ + + +/* +** {================================================================== +** Marks for exported symbols in the C code +** =================================================================== +*/ + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* +** More often than not the libs go together with the core. +*/ +#define LUALIB_API LUA_API +#define LUAMOD_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +** exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables, +** none of which to be exported to outside modules (LUAI_DDEF for +** definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("internal"))) extern +#else /* }{ */ +#define LUAI_FUNC extern +#endif /* } */ + +#define LUAI_DDEC(dec) LUAI_FUNC dec +#define LUAI_DDEF /* empty */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_5_3) /* { */ + +/* +@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated +** functions in the mathematical library. +** (These functions were already officially removed in 5.3; +** nevertheless they are still available here.) +*/ +#define LUA_COMPAT_MATHLIB + +/* +@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for +** manipulating other integer types (lua_pushunsigned, lua_tounsigned, +** luaL_checkint, luaL_checklong, etc.) +** (These macros were also officially removed in 5.3, but they are still +** available here.) +*/ +#define LUA_COMPAT_APIINTCASTS + + +/* +@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod +** using '__lt'. +*/ +#define LUA_COMPAT_LT_LE + + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +** (Once more, these macros were officially removed in 5.3, but they are +** still available here.) +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +#endif /* } */ + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Numbers (low-level part). +** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* +** satisfy your needs. +** =================================================================== +*/ + +/* +@@ LUAI_UACNUMBER is the result of a 'default argument promotion' +@@ over a floating number. +@@ l_floatatt(x) corrects float attribute 'x' to the proper float type +** by prefixing it with one of FLT/DBL/LDBL. +@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. +@@ LUA_NUMBER_FMT is the format for writing floats. +@@ lua_number2str converts a float to a string. +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations. +@@ l_floor takes the floor of a float. +@@ lua_str2number converts a decimal numeral to a number. +*/ + + +/* The following definitions are good for most cases here */ + +#define l_floor(x) (l_mathop(floor)(x)) + +#define lua_number2str(s,sz,n) \ + l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) + +/* +@@ lua_numbertointeger converts a float number with an integral value +** to an integer, or returns 0 if float is not within the range of +** a lua_Integer. (The range comparisons are tricky because of +** rounding. The tests here assume a two-complement representation, +** where MININTEGER always has an exact representation as a float; +** MAXINTEGER may not have one, and therefore its conversion to float +** may have an ill-defined value.) +*/ +#define lua_numbertointeger(n,p) \ + ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ + (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ + (*(p) = (LUA_INTEGER)(n), 1)) + + +/* now the variable definitions */ + +#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */ + +#define LUA_NUMBER float + +#define l_floatatt(n) (FLT_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.7g" + +#define l_mathop(op) op##f + +#define lua_str2number(s,p) strtof((s), (p)) + + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */ + +#define LUA_NUMBER long double + +#define l_floatatt(n) (LDBL_##n) + +#define LUAI_UACNUMBER long double + +#define LUA_NUMBER_FRMLEN "L" +#define LUA_NUMBER_FMT "%.19Lg" + +#define l_mathop(op) op##l + +#define lua_str2number(s,p) strtold((s), (p)) + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */ + +#define LUA_NUMBER double + +#define l_floatatt(n) (DBL_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.14g" + +#define l_mathop(op) op + +#define lua_str2number(s,p) strtod((s), (p)) + +#else /* }{ */ + +#error "numeric float type not defined" + +#endif /* } */ + + + +/* +@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. +@@ LUAI_UACINT is the result of a 'default argument promotion' +@@ over a LUA_INTEGER. +@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. +@@ LUA_INTEGER_FMT is the format for writing integers. +@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. +@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. +@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. +@@ lua_integer2str converts an integer to a string. +*/ + + +/* The following definitions are good for most cases here */ + +#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" + +#define LUAI_UACINT LUA_INTEGER + +#define lua_integer2str(s,sz,n) \ + l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n)) + +/* +** use LUAI_UACINT here to avoid problems with promotions (which +** can turn a comparison between unsigneds into a signed comparison) +*/ +#define LUA_UNSIGNED unsigned LUAI_UACINT + + +/* now the variable definitions */ + +#if LUA_INT_TYPE == LUA_INT_INT /* { int */ + +#define LUA_INTEGER int +#define LUA_INTEGER_FRMLEN "" + +#define LUA_MAXINTEGER INT_MAX +#define LUA_MININTEGER INT_MIN + +#define LUA_MAXUNSIGNED UINT_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ + +#define LUA_INTEGER long +#define LUA_INTEGER_FRMLEN "l" + +#define LUA_MAXINTEGER LONG_MAX +#define LUA_MININTEGER LONG_MIN + +#define LUA_MAXUNSIGNED ULONG_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ + +/* use presence of macro LLONG_MAX as proxy for C99 compliance */ +#if defined(LLONG_MAX) /* { */ +/* use ISO C99 stuff */ + +#define LUA_INTEGER long long +#define LUA_INTEGER_FRMLEN "ll" + +#define LUA_MAXINTEGER LLONG_MAX +#define LUA_MININTEGER LLONG_MIN + +#define LUA_MAXUNSIGNED ULLONG_MAX + +#elif defined(LUA_USE_WINDOWS) /* }{ */ +/* in Windows, can use specific Windows types */ + +#define LUA_INTEGER __int64 +#define LUA_INTEGER_FRMLEN "I64" + +#define LUA_MAXINTEGER _I64_MAX +#define LUA_MININTEGER _I64_MIN + +#define LUA_MAXUNSIGNED _UI64_MAX + +#else /* }{ */ + +#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ + or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)" + +#endif /* } */ + +#else /* }{ */ + +#error "numeric integer type not defined" + +#endif /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Dependencies with C99 and other C details +** =================================================================== +*/ + +/* +@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89. +** (All uses in Lua have only one format item.) +*/ +#if !defined(LUA_USE_C89) +#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i) +#else +#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i)) +#endif + + +/* +@@ lua_strx2number converts a hexadecimal numeral to a number. +** In C99, 'strtod' does that conversion. Otherwise, you can +** leave 'lua_strx2number' undefined and Lua will provide its own +** implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_strx2number(s,p) lua_str2number(s,p) +#endif + + +/* +@@ lua_pointer2str converts a pointer to a readable string in a +** non-specified way. +*/ +#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p) + + +/* +@@ lua_number2strx converts a float to a hexadecimal numeral. +** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. +** Otherwise, you can leave 'lua_number2strx' undefined and Lua will +** provide its own implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_number2strx(L,b,sz,f,n) \ + ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n))) +#endif + + +/* +** 'strtof' and 'opf' variants for math functions are not valid in +** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the +** availability of these variants. ('math.h' is already included in +** all files that use these macros.) +*/ +#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF)) +#undef l_mathop /* variants not available */ +#undef lua_str2number +#define l_mathop(op) (lua_Number)op /* no variant */ +#define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) +#endif + + +/* +@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation +** functions. It must be a numerical type; Lua will use 'intptr_t' if +** available, otherwise it will use 'ptrdiff_t' (the nearest thing to +** 'intptr_t' in C89) +*/ +#define LUA_KCONTEXT ptrdiff_t + +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(INTPTR_MAX) /* even in C99 this type is optional */ +#undef LUA_KCONTEXT +#define LUA_KCONTEXT intptr_t +#endif +#endif + + +/* +@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). +** Change that if you do not want to use C locales. (Code using this +** macro must include the header 'locale.h'.) +*/ +#if !defined(lua_getlocaledecpoint) +#define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + + +/* +** macros to improve jump prediction, used mostly for error handling +** and debug facilities. (Some macros in the Lua API use these macros. +** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your +** code.) +*/ +#if !defined(luai_likely) + +#if defined(__GNUC__) && !defined(LUA_NOBUILTIN) +#define luai_likely(x) (__builtin_expect(((x) != 0), 1)) +#define luai_unlikely(x) (__builtin_expect(((x) != 0), 0)) +#else +#define luai_likely(x) (x) +#define luai_unlikely(x) (x) +#endif + +#endif + + +#if defined(LUA_CORE) || defined(LUA_LIB) +/* shorter names for Lua's own use */ +#define l_likely(x) luai_likely(x) +#define l_unlikely(x) luai_unlikely(x) +#endif + + + +/* }================================================================== */ + + +/* +** {================================================================== +** Language Variations +** ===================================================================== +*/ + +/* +@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some +** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from +** numbers to strings. Define LUA_NOCVTS2N to turn off automatic +** coercion from strings to numbers. +*/ +/* #define LUA_NOCVTN2S */ +/* #define LUA_NOCVTS2N */ + + +/* +@@ LUA_USE_APICHECK turns on several consistency checks on the C API. +** Define it as a help when debugging C code. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(l,e) assert(e) +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Macros that affect the API and must be stable (that is, must be the +** same when you compile Lua and when you compile code that links to +** Lua). +** ===================================================================== +*/ + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua from consuming unlimited stack +** space (and to reserve some numbers for pseudo-indices). +** (It must fit into max(size_t)/32 and max(int)/2.) +*/ +#if LUAI_IS32INT +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + + +/* +@@ LUA_EXTRASPACE defines the size of a raw memory area associated with +** a Lua state with very fast access. +** CHANGE it if you need a different size. +*/ +#define LUA_EXTRASPACE (sizeof(void *)) + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +** of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ LUAL_BUFFERSIZE is the initial buffer size used by the lauxlib +** buffer system. +*/ +#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number))) + + +/* +@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure +** maximum alignment for the other items in that union. +*/ +#define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l + +/* }================================================================== */ + + + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + + + +#endif + diff --git a/arm9/source/lua/lualib.h b/arm9/source/lua/lualib.h new file mode 100644 index 000000000..262552907 --- /dev/null +++ b/arm9/source/lua/lualib.h @@ -0,0 +1,52 @@ +/* +** $Id: lualib.h $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* version suffix for environment variable names */ +#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + + +LUAMOD_API int (luaopen_base) (lua_State *L); + +#define LUA_COLIBNAME "coroutine" +LUAMOD_API int (luaopen_coroutine) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUAMOD_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUAMOD_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUAMOD_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUAMOD_API int (luaopen_string) (lua_State *L); + +#define LUA_UTF8LIBNAME "utf8" +LUAMOD_API int (luaopen_utf8) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUAMOD_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUAMOD_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUAMOD_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + +#endif diff --git a/arm9/source/lua/lundump.c b/arm9/source/lua/lundump.c new file mode 100644 index 000000000..e8d92a853 --- /dev/null +++ b/arm9/source/lua/lundump.c @@ -0,0 +1,335 @@ +/* +** $Id: lundump.c $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#define lundump_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + + +#if !defined(luai_verifycode) +#define luai_verifycode(L,f) /* empty */ +#endif + + +typedef struct { + lua_State *L; + ZIO *Z; + const char *name; +} LoadState; + + +static l_noret error (LoadState *S, const char *why) { + luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); + luaD_throw(S->L, LUA_ERRSYNTAX); +} + + +/* +** All high-level loads go through loadVector; you can change it to +** adapt to the endianness of the input +*/ +#define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) + +static void loadBlock (LoadState *S, void *b, size_t size) { + if (luaZ_read(S->Z, b, size) != 0) + error(S, "truncated chunk"); +} + + +#define loadVar(S,x) loadVector(S,&x,1) + + +static lu_byte loadByte (LoadState *S) { + int b = zgetc(S->Z); + if (b == EOZ) + error(S, "truncated chunk"); + return cast_byte(b); +} + + +static size_t loadUnsigned (LoadState *S, size_t limit) { + size_t x = 0; + int b; + limit >>= 7; + do { + b = loadByte(S); + if (x >= limit) + error(S, "integer overflow"); + x = (x << 7) | (b & 0x7f); + } while ((b & 0x80) == 0); + return x; +} + + +static size_t loadSize (LoadState *S) { + return loadUnsigned(S, MAX_SIZET); +} + + +static int loadInt (LoadState *S) { + return cast_int(loadUnsigned(S, INT_MAX)); +} + + +static lua_Number loadNumber (LoadState *S) { + lua_Number x; + loadVar(S, x); + return x; +} + + +static lua_Integer loadInteger (LoadState *S) { + lua_Integer x; + loadVar(S, x); + return x; +} + + +/* +** Load a nullable string into prototype 'p'. +*/ +static TString *loadStringN (LoadState *S, Proto *p) { + lua_State *L = S->L; + TString *ts; + size_t size = loadSize(S); + if (size == 0) /* no string? */ + return NULL; + else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ + char buff[LUAI_MAXSHORTLEN]; + loadVector(S, buff, size); /* load string into buffer */ + ts = luaS_newlstr(L, buff, size); /* create string */ + } + else { /* long string */ + ts = luaS_createlngstrobj(L, size); /* create string */ + setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ + luaD_inctop(L); + loadVector(S, getlngstr(ts), size); /* load directly in final place */ + L->top.p--; /* pop string */ + } + luaC_objbarrier(L, p, ts); + return ts; +} + + +/* +** Load a non-nullable string into prototype 'p'. +*/ +static TString *loadString (LoadState *S, Proto *p) { + TString *st = loadStringN(S, p); + if (st == NULL) + error(S, "bad format for constant string"); + return st; +} + + +static void loadCode (LoadState *S, Proto *f) { + int n = loadInt(S); + f->code = luaM_newvectorchecked(S->L, n, Instruction); + f->sizecode = n; + loadVector(S, f->code, n); +} + + +static void loadFunction(LoadState *S, Proto *f, TString *psource); + + +static void loadConstants (LoadState *S, Proto *f) { + int i; + int n = loadInt(S); + f->k = luaM_newvectorchecked(S->L, n, TValue); + f->sizek = n; + for (i = 0; i < n; i++) + setnilvalue(&f->k[i]); + for (i = 0; i < n; i++) { + TValue *o = &f->k[i]; + int t = loadByte(S); + switch (t) { + case LUA_VNIL: + setnilvalue(o); + break; + case LUA_VFALSE: + setbfvalue(o); + break; + case LUA_VTRUE: + setbtvalue(o); + break; + case LUA_VNUMFLT: + setfltvalue(o, loadNumber(S)); + break; + case LUA_VNUMINT: + setivalue(o, loadInteger(S)); + break; + case LUA_VSHRSTR: + case LUA_VLNGSTR: + setsvalue2n(S->L, o, loadString(S, f)); + break; + default: lua_assert(0); + } + } +} + + +static void loadProtos (LoadState *S, Proto *f) { + int i; + int n = loadInt(S); + f->p = luaM_newvectorchecked(S->L, n, Proto *); + f->sizep = n; + for (i = 0; i < n; i++) + f->p[i] = NULL; + for (i = 0; i < n; i++) { + f->p[i] = luaF_newproto(S->L); + luaC_objbarrier(S->L, f, f->p[i]); + loadFunction(S, f->p[i], f->source); + } +} + + +/* +** Load the upvalues for a function. The names must be filled first, +** because the filling of the other fields can raise read errors and +** the creation of the error message can call an emergency collection; +** in that case all prototypes must be consistent for the GC. +*/ +static void loadUpvalues (LoadState *S, Proto *f) { + int i, n; + n = loadInt(S); + f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); + f->sizeupvalues = n; + for (i = 0; i < n; i++) /* make array valid for GC */ + f->upvalues[i].name = NULL; + for (i = 0; i < n; i++) { /* following calls can raise errors */ + f->upvalues[i].instack = loadByte(S); + f->upvalues[i].idx = loadByte(S); + f->upvalues[i].kind = loadByte(S); + } +} + + +static void loadDebug (LoadState *S, Proto *f) { + int i, n; + n = loadInt(S); + f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); + f->sizelineinfo = n; + loadVector(S, f->lineinfo, n); + n = loadInt(S); + f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); + f->sizeabslineinfo = n; + for (i = 0; i < n; i++) { + f->abslineinfo[i].pc = loadInt(S); + f->abslineinfo[i].line = loadInt(S); + } + n = loadInt(S); + f->locvars = luaM_newvectorchecked(S->L, n, LocVar); + f->sizelocvars = n; + for (i = 0; i < n; i++) + f->locvars[i].varname = NULL; + for (i = 0; i < n; i++) { + f->locvars[i].varname = loadStringN(S, f); + f->locvars[i].startpc = loadInt(S); + f->locvars[i].endpc = loadInt(S); + } + n = loadInt(S); + if (n != 0) /* does it have debug information? */ + n = f->sizeupvalues; /* must be this many */ + for (i = 0; i < n; i++) + f->upvalues[i].name = loadStringN(S, f); +} + + +static void loadFunction (LoadState *S, Proto *f, TString *psource) { + f->source = loadStringN(S, f); + if (f->source == NULL) /* no source in dump? */ + f->source = psource; /* reuse parent's source */ + f->linedefined = loadInt(S); + f->lastlinedefined = loadInt(S); + f->numparams = loadByte(S); + f->is_vararg = loadByte(S); + f->maxstacksize = loadByte(S); + loadCode(S, f); + loadConstants(S, f); + loadUpvalues(S, f); + loadProtos(S, f); + loadDebug(S, f); +} + + +static void checkliteral (LoadState *S, const char *s, const char *msg) { + char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ + size_t len = strlen(s); + loadVector(S, buff, len); + if (memcmp(s, buff, len) != 0) + error(S, msg); +} + + +static void fchecksize (LoadState *S, size_t size, const char *tname) { + if (loadByte(S) != size) + error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); +} + + +#define checksize(S,t) fchecksize(S,sizeof(t),#t) + +static void checkHeader (LoadState *S) { + /* skip 1st char (already read and checked) */ + checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); + if (loadByte(S) != LUAC_VERSION) + error(S, "version mismatch"); + if (loadByte(S) != LUAC_FORMAT) + error(S, "format mismatch"); + checkliteral(S, LUAC_DATA, "corrupted chunk"); + checksize(S, Instruction); + checksize(S, lua_Integer); + checksize(S, lua_Number); + if (loadInteger(S) != LUAC_INT) + error(S, "integer format mismatch"); + if (loadNumber(S) != LUAC_NUM) + error(S, "float format mismatch"); +} + + +/* +** Load precompiled chunk. +*/ +LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { + LoadState S; + LClosure *cl; + if (*name == '@' || *name == '=') + S.name = name + 1; + else if (*name == LUA_SIGNATURE[0]) + S.name = "binary string"; + else + S.name = name; + S.L = L; + S.Z = Z; + checkHeader(&S); + cl = luaF_newLclosure(L, loadByte(&S)); + setclLvalue2s(L, L->top.p, cl); + luaD_inctop(L); + cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); + loadFunction(&S, cl->p, NULL); + lua_assert(cl->nupvalues == cl->p->sizeupvalues); + luai_verifycode(L, cl->p); + return cl; +} + diff --git a/arm9/source/lua/lundump.h b/arm9/source/lua/lundump.h new file mode 100644 index 000000000..a97676ca1 --- /dev/null +++ b/arm9/source/lua/lundump.h @@ -0,0 +1,35 @@ +/* +** $Id: lundump.h $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* data to catch conversion errors */ +#define LUAC_DATA "\x19\x93\r\n\x1a\n" + +#define LUAC_INT 0x5678 +#define LUAC_NUM cast_num(370.5) + +/* +** Encode major-minor version in one byte, one nibble for each +*/ +#define LUAC_VERSION (((LUA_VERSION_NUM / 100) * 16) + LUA_VERSION_NUM % 100) + +#define LUAC_FORMAT 0 /* this is the official format */ + +/* load one chunk; from lundump.c */ +LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, + void* data, int strip); + +#endif diff --git a/arm9/source/lua/lutf8lib.c b/arm9/source/lua/lutf8lib.c new file mode 100644 index 000000000..3a5b9bc38 --- /dev/null +++ b/arm9/source/lua/lutf8lib.c @@ -0,0 +1,291 @@ +/* +** $Id: lutf8lib.c $ +** Standard library for UTF-8 manipulation +** See Copyright Notice in lua.h +*/ + +#define lutf8lib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define MAXUNICODE 0x10FFFFu + +#define MAXUTF 0x7FFFFFFFu + + +#define MSGInvalid "invalid UTF-8 code" + +/* +** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits. +*/ +#if (UINT_MAX >> 30) >= 1 +typedef unsigned int utfint; +#else +typedef unsigned long utfint; +#endif + + +#define iscont(c) (((c) & 0xC0) == 0x80) +#define iscontp(p) iscont(*(p)) + + +/* from strlib */ +/* translate a relative string position: negative means back from end */ +static lua_Integer u_posrelat (lua_Integer pos, size_t len) { + if (pos >= 0) return pos; + else if (0u - (size_t)pos > len) return 0; + else return (lua_Integer)len + pos + 1; +} + + +/* +** Decode one UTF-8 sequence, returning NULL if byte sequence is +** invalid. The array 'limits' stores the minimum value for each +** sequence length, to check for overlong representations. Its first +** entry forces an error for non-ascii bytes with no continuation +** bytes (count == 0). +*/ +static const char *utf8_decode (const char *s, utfint *val, int strict) { + static const utfint limits[] = + {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; + unsigned int c = (unsigned char)s[0]; + utfint res = 0; /* final result */ + if (c < 0x80) /* ascii? */ + res = c; + else { + int count = 0; /* to count number of continuation bytes */ + for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ + unsigned int cc = (unsigned char)s[++count]; /* read next byte */ + if (!iscont(cc)) /* not a continuation byte? */ + return NULL; /* invalid byte sequence */ + res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ + } + res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ + if (count > 5 || res > MAXUTF || res < limits[count]) + return NULL; /* invalid byte sequence */ + s += count; /* skip continuation bytes read */ + } + if (strict) { + /* check for invalid code points; too large or surrogates */ + if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu)) + return NULL; + } + if (val) *val = res; + return s + 1; /* +1 to include first byte */ +} + + +/* +** utf8len(s [, i [, j [, lax]]]) --> number of characters that +** start in the range [i,j], or nil + current position if 's' is not +** well formed in that interval +*/ +static int utflen (lua_State *L) { + lua_Integer n = 0; /* counter for the number of characters */ + size_t len; /* string length in bytes */ + const char *s = luaL_checklstring(L, 1, &len); + lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); + lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); + int lax = lua_toboolean(L, 4); + luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, + "initial position out of bounds"); + luaL_argcheck(L, --posj < (lua_Integer)len, 3, + "final position out of bounds"); + while (posi <= posj) { + const char *s1 = utf8_decode(s + posi, NULL, !lax); + if (s1 == NULL) { /* conversion error? */ + luaL_pushfail(L); /* return fail ... */ + lua_pushinteger(L, posi + 1); /* ... and current position */ + return 2; + } + posi = s1 - s; + n++; + } + lua_pushinteger(L, n); + return 1; +} + + +/* +** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all +** characters that start in the range [i,j] +*/ +static int codepoint (lua_State *L) { + size_t len; + const char *s = luaL_checklstring(L, 1, &len); + lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); + lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); + int lax = lua_toboolean(L, 4); + int n; + const char *se; + luaL_argcheck(L, posi >= 1, 2, "out of bounds"); + luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds"); + if (posi > pose) return 0; /* empty interval; return no values */ + if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ + return luaL_error(L, "string slice too long"); + n = (int)(pose - posi) + 1; /* upper bound for number of returns */ + luaL_checkstack(L, n, "string slice too long"); + n = 0; /* count the number of returns */ + se = s + pose; /* string end */ + for (s += posi - 1; s < se;) { + utfint code; + s = utf8_decode(s, &code, !lax); + if (s == NULL) + return luaL_error(L, MSGInvalid); + lua_pushinteger(L, code); + n++; + } + return n; +} + + +static void pushutfchar (lua_State *L, int arg) { + lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg); + luaL_argcheck(L, code <= MAXUTF, arg, "value out of range"); + lua_pushfstring(L, "%U", (long)code); +} + + +/* +** utfchar(n1, n2, ...) -> char(n1)..char(n2)... +*/ +static int utfchar (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + if (n == 1) /* optimize common case of single char */ + pushutfchar(L, 1); + else { + int i; + luaL_Buffer b; + luaL_buffinit(L, &b); + for (i = 1; i <= n; i++) { + pushutfchar(L, i); + luaL_addvalue(&b); + } + luaL_pushresult(&b); + } + return 1; +} + + +/* +** offset(s, n, [i]) -> index where n-th character counting from +** position 'i' starts; 0 means character at 'i'. +*/ +static int byteoffset (lua_State *L) { + size_t len; + const char *s = luaL_checklstring(L, 1, &len); + lua_Integer n = luaL_checkinteger(L, 2); + lua_Integer posi = (n >= 0) ? 1 : len + 1; + posi = u_posrelat(luaL_optinteger(L, 3, posi), len); + luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, + "position out of bounds"); + if (n == 0) { + /* find beginning of current byte sequence */ + while (posi > 0 && iscontp(s + posi)) posi--; + } + else { + if (iscontp(s + posi)) + return luaL_error(L, "initial position is a continuation byte"); + if (n < 0) { + while (n < 0 && posi > 0) { /* move back */ + do { /* find beginning of previous character */ + posi--; + } while (posi > 0 && iscontp(s + posi)); + n++; + } + } + else { + n--; /* do not move for 1st character */ + while (n > 0 && posi < (lua_Integer)len) { + do { /* find beginning of next character */ + posi++; + } while (iscontp(s + posi)); /* (cannot pass final '\0') */ + n--; + } + } + } + if (n == 0) /* did it find given character? */ + lua_pushinteger(L, posi + 1); + else /* no such character */ + luaL_pushfail(L); + return 1; +} + + +static int iter_aux (lua_State *L, int strict) { + size_t len; + const char *s = luaL_checklstring(L, 1, &len); + lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2); + if (n < len) { + while (iscontp(s + n)) n++; /* go to next character */ + } + if (n >= len) /* (also handles original 'n' being negative) */ + return 0; /* no more codepoints */ + else { + utfint code; + const char *next = utf8_decode(s + n, &code, strict); + if (next == NULL || iscontp(next)) + return luaL_error(L, MSGInvalid); + lua_pushinteger(L, n + 1); + lua_pushinteger(L, code); + return 2; + } +} + + +static int iter_auxstrict (lua_State *L) { + return iter_aux(L, 1); +} + +static int iter_auxlax (lua_State *L) { + return iter_aux(L, 0); +} + + +static int iter_codes (lua_State *L) { + int lax = lua_toboolean(L, 2); + const char *s = luaL_checkstring(L, 1); + luaL_argcheck(L, !iscontp(s), 1, MSGInvalid); + lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict); + lua_pushvalue(L, 1); + lua_pushinteger(L, 0); + return 3; +} + + +/* pattern to match a single UTF-8 character */ +#define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" + + +static const luaL_Reg funcs[] = { + {"offset", byteoffset}, + {"codepoint", codepoint}, + {"char", utfchar}, + {"len", utflen}, + {"codes", iter_codes}, + /* placeholders */ + {"charpattern", NULL}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_utf8 (lua_State *L) { + luaL_newlib(L, funcs); + lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); + lua_setfield(L, -2, "charpattern"); + return 1; +} + diff --git a/arm9/source/lua/lvm.c b/arm9/source/lua/lvm.c new file mode 100644 index 000000000..fcd24e11d --- /dev/null +++ b/arm9/source/lua/lvm.c @@ -0,0 +1,1899 @@ +/* +** $Id: lvm.c $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#define lvm_c +#define LUA_CORE + +#include "lprefix.h" + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +/* +** By default, use jump tables in the main interpreter loop on gcc +** and compatible compilers. +*/ +#if !defined(LUA_USE_JUMPTABLE) +#if defined(__GNUC__) +#define LUA_USE_JUMPTABLE 1 +#else +#define LUA_USE_JUMPTABLE 0 +#endif +#endif + + + +/* limit for table tag-method chains (to avoid infinite loops) */ +#define MAXTAGLOOP 2000 + + +/* +** 'l_intfitsf' checks whether a given integer is in the range that +** can be converted to a float without rounding. Used in comparisons. +*/ + +/* number of bits in the mantissa of a float */ +#define NBM (l_floatatt(MANT_DIG)) + +/* +** Check whether some integers may not fit in a float, testing whether +** (maxinteger >> NBM) > 0. (That implies (1 << NBM) <= maxinteger.) +** (The shifts are done in parts, to avoid shifting by more than the size +** of an integer. In a worst case, NBM == 113 for long double and +** sizeof(long) == 32.) +*/ +#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \ + >> (NBM - (3 * (NBM / 4)))) > 0 + +/* limit for integers that fit in a float */ +#define MAXINTFITSF ((lua_Unsigned)1 << NBM) + +/* check whether 'i' is in the interval [-MAXINTFITSF, MAXINTFITSF] */ +#define l_intfitsf(i) ((MAXINTFITSF + l_castS2U(i)) <= (2 * MAXINTFITSF)) + +#else /* all integers fit in a float precisely */ + +#define l_intfitsf(i) 1 + +#endif + + +/* +** Try to convert a value from string to a number value. +** If the value is not a string or is a string not representing +** a valid numeral (or if coercions from strings to numbers +** are disabled via macro 'cvt2num'), do not modify 'result' +** and return 0. +*/ +static int l_strton (const TValue *obj, TValue *result) { + lua_assert(obj != result); + if (!cvt2num(obj)) /* is object not a string? */ + return 0; + else { + TString *st = tsvalue(obj); + return (luaO_str2num(getstr(st), result) == tsslen(st) + 1); + } +} + + +/* +** Try to convert a value to a float. The float case is already handled +** by the macro 'tonumber'. +*/ +int luaV_tonumber_ (const TValue *obj, lua_Number *n) { + TValue v; + if (ttisinteger(obj)) { + *n = cast_num(ivalue(obj)); + return 1; + } + else if (l_strton(obj, &v)) { /* string coercible to number? */ + *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ + return 1; + } + else + return 0; /* conversion failed */ +} + + +/* +** try to convert a float to an integer, rounding according to 'mode'. +*/ +int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode) { + lua_Number f = l_floor(n); + if (n != f) { /* not an integral value? */ + if (mode == F2Ieq) return 0; /* fails if mode demands integral value */ + else if (mode == F2Iceil) /* needs ceil? */ + f += 1; /* convert floor to ceil (remember: n != f) */ + } + return lua_numbertointeger(f, p); +} + + +/* +** try to convert a value to an integer, rounding according to 'mode', +** without string coercion. +** ("Fast track" handled by macro 'tointegerns'.) +*/ +int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode) { + if (ttisfloat(obj)) + return luaV_flttointeger(fltvalue(obj), p, mode); + else if (ttisinteger(obj)) { + *p = ivalue(obj); + return 1; + } + else + return 0; +} + + +/* +** try to convert a value to an integer. +*/ +int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode) { + TValue v; + if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ + obj = &v; /* change it to point to its corresponding number */ + return luaV_tointegerns(obj, p, mode); +} + + +/* +** Try to convert a 'for' limit to an integer, preserving the semantics +** of the loop. Return true if the loop must not run; otherwise, '*p' +** gets the integer limit. +** (The following explanation assumes a positive step; it is valid for +** negative steps mutatis mutandis.) +** If the limit is an integer or can be converted to an integer, +** rounding down, that is the limit. +** Otherwise, check whether the limit can be converted to a float. If +** the float is too large, clip it to LUA_MAXINTEGER. If the float +** is too negative, the loop should not run, because any initial +** integer value is greater than such limit; so, the function returns +** true to signal that. (For this latter case, no integer limit would be +** correct; even a limit of LUA_MININTEGER would run the loop once for +** an initial value equal to LUA_MININTEGER.) +*/ +static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, + lua_Integer *p, lua_Integer step) { + if (!luaV_tointeger(lim, p, (step < 0 ? F2Iceil : F2Ifloor))) { + /* not coercible to in integer */ + lua_Number flim; /* try to convert to float */ + if (!tonumber(lim, &flim)) /* cannot convert to float? */ + luaG_forerror(L, lim, "limit"); + /* else 'flim' is a float out of integer bounds */ + if (luai_numlt(0, flim)) { /* if it is positive, it is too large */ + if (step < 0) return 1; /* initial value must be less than it */ + *p = LUA_MAXINTEGER; /* truncate */ + } + else { /* it is less than min integer */ + if (step > 0) return 1; /* initial value must be greater than it */ + *p = LUA_MININTEGER; /* truncate */ + } + } + return (step > 0 ? init > *p : init < *p); /* not to run? */ +} + + +/* +** Prepare a numerical for loop (opcode OP_FORPREP). +** Return true to skip the loop. Otherwise, +** after preparation, stack will be as follows: +** ra : internal index (safe copy of the control variable) +** ra + 1 : loop counter (integer loops) or limit (float loops) +** ra + 2 : step +** ra + 3 : control variable +*/ +static int forprep (lua_State *L, StkId ra) { + TValue *pinit = s2v(ra); + TValue *plimit = s2v(ra + 1); + TValue *pstep = s2v(ra + 2); + if (ttisinteger(pinit) && ttisinteger(pstep)) { /* integer loop? */ + lua_Integer init = ivalue(pinit); + lua_Integer step = ivalue(pstep); + lua_Integer limit; + if (step == 0) + luaG_runerror(L, "'for' step is zero"); + setivalue(s2v(ra + 3), init); /* control variable */ + if (forlimit(L, init, plimit, &limit, step)) + return 1; /* skip the loop */ + else { /* prepare loop counter */ + lua_Unsigned count; + if (step > 0) { /* ascending loop? */ + count = l_castS2U(limit) - l_castS2U(init); + if (step != 1) /* avoid division in the too common case */ + count /= l_castS2U(step); + } + else { /* step < 0; descending loop */ + count = l_castS2U(init) - l_castS2U(limit); + /* 'step+1' avoids negating 'mininteger' */ + count /= l_castS2U(-(step + 1)) + 1u; + } + /* store the counter in place of the limit (which won't be + needed anymore) */ + setivalue(plimit, l_castU2S(count)); + } + } + else { /* try making all values floats */ + lua_Number init; lua_Number limit; lua_Number step; + if (l_unlikely(!tonumber(plimit, &limit))) + luaG_forerror(L, plimit, "limit"); + if (l_unlikely(!tonumber(pstep, &step))) + luaG_forerror(L, pstep, "step"); + if (l_unlikely(!tonumber(pinit, &init))) + luaG_forerror(L, pinit, "initial value"); + if (step == 0) + luaG_runerror(L, "'for' step is zero"); + if (luai_numlt(0, step) ? luai_numlt(limit, init) + : luai_numlt(init, limit)) + return 1; /* skip the loop */ + else { + /* make sure internal values are all floats */ + setfltvalue(plimit, limit); + setfltvalue(pstep, step); + setfltvalue(s2v(ra), init); /* internal index */ + setfltvalue(s2v(ra + 3), init); /* control variable */ + } + } + return 0; +} + + +/* +** Execute a step of a float numerical for loop, returning +** true iff the loop must continue. (The integer case is +** written online with opcode OP_FORLOOP, for performance.) +*/ +static int floatforloop (StkId ra) { + lua_Number step = fltvalue(s2v(ra + 2)); + lua_Number limit = fltvalue(s2v(ra + 1)); + lua_Number idx = fltvalue(s2v(ra)); /* internal index */ + idx = luai_numadd(L, idx, step); /* increment index */ + if (luai_numlt(0, step) ? luai_numle(idx, limit) + : luai_numle(limit, idx)) { + chgfltvalue(s2v(ra), idx); /* update internal index */ + setfltvalue(s2v(ra + 3), idx); /* and control variable */ + return 1; /* jump back */ + } + else + return 0; /* finish the loop */ +} + + +/* +** Finish the table access 'val = t[key]'. +** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to +** t[k] entry (which must be empty). +*/ +void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, + const TValue *slot) { + int loop; /* counter to avoid infinite loops */ + const TValue *tm; /* metamethod */ + for (loop = 0; loop < MAXTAGLOOP; loop++) { + if (slot == NULL) { /* 't' is not a table? */ + lua_assert(!ttistable(t)); + tm = luaT_gettmbyobj(L, t, TM_INDEX); + if (l_unlikely(notm(tm))) + luaG_typeerror(L, t, "index"); /* no metamethod */ + /* else will try the metamethod */ + } + else { /* 't' is a table */ + lua_assert(isempty(slot)); + tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ + if (tm == NULL) { /* no metamethod? */ + setnilvalue(s2v(val)); /* result is nil */ + return; + } + /* else will try the metamethod */ + } + if (ttisfunction(tm)) { /* is metamethod a function? */ + luaT_callTMres(L, tm, t, key, val); /* call it */ + return; + } + t = tm; /* else try to access 'tm[key]' */ + if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */ + setobj2s(L, val, slot); /* done */ + return; + } + /* else repeat (tail call 'luaV_finishget') */ + } + luaG_runerror(L, "'__index' chain too long; possible loop"); +} + + +/* +** Finish a table assignment 't[key] = val'. +** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points +** to the entry 't[key]', or to a value with an absent key if there +** is no such entry. (The value at 'slot' must be empty, otherwise +** 'luaV_fastget' would have done the job.) +*/ +void luaV_finishset (lua_State *L, const TValue *t, TValue *key, + TValue *val, const TValue *slot) { + int loop; /* counter to avoid infinite loops */ + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; /* '__newindex' metamethod */ + if (slot != NULL) { /* is 't' a table? */ + Table *h = hvalue(t); /* save 't' table */ + lua_assert(isempty(slot)); /* slot must be empty */ + tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ + if (tm == NULL) { /* no metamethod? */ + luaH_finishset(L, h, key, slot, val); /* set new value */ + invalidateTMcache(h); + luaC_barrierback(L, obj2gco(h), val); + return; + } + /* else will try the metamethod */ + } + else { /* not a table; check metamethod */ + tm = luaT_gettmbyobj(L, t, TM_NEWINDEX); + if (l_unlikely(notm(tm))) + luaG_typeerror(L, t, "index"); + } + /* try the metamethod */ + if (ttisfunction(tm)) { + luaT_callTM(L, tm, t, key, val); + return; + } + t = tm; /* else repeat assignment over 'tm' */ + if (luaV_fastget(L, t, key, slot, luaH_get)) { + luaV_finishfastset(L, t, slot, val); + return; /* done */ + } + /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ + } + luaG_runerror(L, "'__newindex' chain too long; possible loop"); +} + + +/* +** Compare two strings 'ts1' x 'ts2', returning an integer less-equal- +** -greater than zero if 'ts1' is less-equal-greater than 'ts2'. +** The code is a little tricky because it allows '\0' in the strings +** and it uses 'strcoll' (to respect locales) for each segment +** of the strings. Note that segments can compare equal but still +** have different lengths. +*/ +static int l_strcmp (const TString *ts1, const TString *ts2) { + const char *s1 = getstr(ts1); + size_t rl1 = tsslen(ts1); /* real length */ + const char *s2 = getstr(ts2); + size_t rl2 = tsslen(ts2); + for (;;) { /* for each segment */ + int temp = strcoll(s1, s2); + if (temp != 0) /* not equal? */ + return temp; /* done */ + else { /* strings are equal up to a '\0' */ + size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */ + size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */ + if (zl2 == rl2) /* 's2' is finished? */ + return (zl1 == rl1) ? 0 : 1; /* check 's1' */ + else if (zl1 == rl1) /* 's1' is finished? */ + return -1; /* 's1' is less than 's2' ('s2' is not finished) */ + /* both strings longer than 'zl'; go on comparing after the '\0' */ + zl1++; zl2++; + s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2; + } + } +} + + +/* +** Check whether integer 'i' is less than float 'f'. If 'i' has an +** exact representation as a float ('l_intfitsf'), compare numbers as +** floats. Otherwise, use the equivalence 'i < f <=> i < ceil(f)'. +** If 'ceil(f)' is out of integer range, either 'f' is greater than +** all integers or less than all integers. +** (The test with 'l_intfitsf' is only for performance; the else +** case is correct for all values, but it is slow due to the conversion +** from float to int.) +** When 'f' is NaN, comparisons must result in false. +*/ +l_sinline int LTintfloat (lua_Integer i, lua_Number f) { + if (l_intfitsf(i)) + return luai_numlt(cast_num(i), f); /* compare them as floats */ + else { /* i < f <=> i < ceil(f) */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ + return i < fi; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f > 0; /* greater? */ + } +} + + +/* +** Check whether integer 'i' is less than or equal to float 'f'. +** See comments on previous function. +*/ +l_sinline int LEintfloat (lua_Integer i, lua_Number f) { + if (l_intfitsf(i)) + return luai_numle(cast_num(i), f); /* compare them as floats */ + else { /* i <= f <=> i <= floor(f) */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ + return i <= fi; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f > 0; /* greater? */ + } +} + + +/* +** Check whether float 'f' is less than integer 'i'. +** See comments on previous function. +*/ +l_sinline int LTfloatint (lua_Number f, lua_Integer i) { + if (l_intfitsf(i)) + return luai_numlt(f, cast_num(i)); /* compare them as floats */ + else { /* f < i <=> floor(f) < i */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ + return fi < i; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f < 0; /* less? */ + } +} + + +/* +** Check whether float 'f' is less than or equal to integer 'i'. +** See comments on previous function. +*/ +l_sinline int LEfloatint (lua_Number f, lua_Integer i) { + if (l_intfitsf(i)) + return luai_numle(f, cast_num(i)); /* compare them as floats */ + else { /* f <= i <=> ceil(f) <= i */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ + return fi <= i; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f < 0; /* less? */ + } +} + + +/* +** Return 'l < r', for numbers. +*/ +l_sinline int LTnum (const TValue *l, const TValue *r) { + lua_assert(ttisnumber(l) && ttisnumber(r)); + if (ttisinteger(l)) { + lua_Integer li = ivalue(l); + if (ttisinteger(r)) + return li < ivalue(r); /* both are integers */ + else /* 'l' is int and 'r' is float */ + return LTintfloat(li, fltvalue(r)); /* l < r ? */ + } + else { + lua_Number lf = fltvalue(l); /* 'l' must be float */ + if (ttisfloat(r)) + return luai_numlt(lf, fltvalue(r)); /* both are float */ + else /* 'l' is float and 'r' is int */ + return LTfloatint(lf, ivalue(r)); + } +} + + +/* +** Return 'l <= r', for numbers. +*/ +l_sinline int LEnum (const TValue *l, const TValue *r) { + lua_assert(ttisnumber(l) && ttisnumber(r)); + if (ttisinteger(l)) { + lua_Integer li = ivalue(l); + if (ttisinteger(r)) + return li <= ivalue(r); /* both are integers */ + else /* 'l' is int and 'r' is float */ + return LEintfloat(li, fltvalue(r)); /* l <= r ? */ + } + else { + lua_Number lf = fltvalue(l); /* 'l' must be float */ + if (ttisfloat(r)) + return luai_numle(lf, fltvalue(r)); /* both are float */ + else /* 'l' is float and 'r' is int */ + return LEfloatint(lf, ivalue(r)); + } +} + + +/* +** return 'l < r' for non-numbers. +*/ +static int lessthanothers (lua_State *L, const TValue *l, const TValue *r) { + lua_assert(!ttisnumber(l) || !ttisnumber(r)); + if (ttisstring(l) && ttisstring(r)) /* both are strings? */ + return l_strcmp(tsvalue(l), tsvalue(r)) < 0; + else + return luaT_callorderTM(L, l, r, TM_LT); +} + + +/* +** Main operation less than; return 'l < r'. +*/ +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ + return LTnum(l, r); + else return lessthanothers(L, l, r); +} + + +/* +** return 'l <= r' for non-numbers. +*/ +static int lessequalothers (lua_State *L, const TValue *l, const TValue *r) { + lua_assert(!ttisnumber(l) || !ttisnumber(r)); + if (ttisstring(l) && ttisstring(r)) /* both are strings? */ + return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; + else + return luaT_callorderTM(L, l, r, TM_LE); +} + + +/* +** Main operation less than or equal to; return 'l <= r'. +*/ +int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { + if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ + return LEnum(l, r); + else return lessequalothers(L, l, r); +} + + +/* +** Main operation for equality of Lua values; return 't1 == t2'. +** L == NULL means raw equality (no metamethods) +*/ +int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + if (ttypetag(t1) != ttypetag(t2)) { /* not the same variant? */ + if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER) + return 0; /* only numbers can be equal with different variants */ + else { /* two numbers with different variants */ + /* One of them is an integer. If the other does not have an + integer value, they cannot be equal; otherwise, compare their + integer values. */ + lua_Integer i1, i2; + return (luaV_tointegerns(t1, &i1, F2Ieq) && + luaV_tointegerns(t2, &i2, F2Ieq) && + i1 == i2); + } + } + /* values have same type and same variant */ + switch (ttypetag(t1)) { + case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: return 1; + case LUA_VNUMINT: return (ivalue(t1) == ivalue(t2)); + case LUA_VNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); + case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_VLCF: return fvalue(t1) == fvalue(t2); + case LUA_VSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); + case LUA_VLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2)); + case LUA_VUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = fasttm(L, uvalue(t1)->metatable, TM_EQ); + if (tm == NULL) + tm = fasttm(L, uvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + case LUA_VTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = fasttm(L, hvalue(t1)->metatable, TM_EQ); + if (tm == NULL) + tm = fasttm(L, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: + return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) /* no TM? */ + return 0; /* objects are different */ + else { + luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */ + return !l_isfalse(s2v(L->top.p)); + } +} + + +/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */ +#define tostring(L,o) \ + (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) + +#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) + +/* copy strings in stack from top - n up to top - 1 to buffer */ +static void copy2buff (StkId top, int n, char *buff) { + size_t tl = 0; /* size already copied */ + do { + TString *st = tsvalue(s2v(top - n)); + size_t l = tsslen(st); /* length of string being copied */ + memcpy(buff + tl, getstr(st), l * sizeof(char)); + tl += l; + } while (--n > 0); +} + + +/* +** Main operation for concatenation: concat 'total' values in the stack, +** from 'L->top.p - total' up to 'L->top.p - 1'. +*/ +void luaV_concat (lua_State *L, int total) { + if (total == 1) + return; /* "all" values already concatenated */ + do { + StkId top = L->top.p; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) || + !tostring(L, s2v(top - 1))) + luaT_tryconcatTM(L); /* may invalidate 'top' */ + else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ + cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ + else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */ + setobjs2s(L, top - 2, top - 1); /* result is second op. */ + } + else { + /* at least two non-empty string values; get as many as possible */ + size_t tl = tsslen(tsvalue(s2v(top - 1))); + TString *ts; + /* collect total length and number of strings */ + for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { + size_t l = tsslen(tsvalue(s2v(top - n - 1))); + if (l_unlikely(l >= MAX_SIZE - sizeof(TString) - tl)) { + L->top.p = top - total; /* pop strings to avoid wasting stack */ + luaG_runerror(L, "string length overflow"); + } + tl += l; + } + if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ + char buff[LUAI_MAXSHORTLEN]; + copy2buff(top, n, buff); /* copy strings to buffer */ + ts = luaS_newlstr(L, buff, tl); + } + else { /* long string; copy strings directly to final result */ + ts = luaS_createlngstrobj(L, tl); + copy2buff(top, n, getlngstr(ts)); + } + setsvalue2s(L, top - n, ts); /* create result */ + } + total -= n - 1; /* got 'n' strings to create one new */ + L->top.p -= n - 1; /* popped 'n' strings and pushed one */ + } while (total > 1); /* repeat until only 1 result left */ +} + + +/* +** Main operation 'ra = #rb'. +*/ +void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { + const TValue *tm; + switch (ttypetag(rb)) { + case LUA_VTABLE: { + Table *h = hvalue(rb); + tm = fasttm(L, h->metatable, TM_LEN); + if (tm) break; /* metamethod? break switch to call it */ + setivalue(s2v(ra), luaH_getn(h)); /* else primitive len */ + return; + } + case LUA_VSHRSTR: { + setivalue(s2v(ra), tsvalue(rb)->shrlen); + return; + } + case LUA_VLNGSTR: { + setivalue(s2v(ra), tsvalue(rb)->u.lnglen); + return; + } + default: { /* try metamethod */ + tm = luaT_gettmbyobj(L, rb, TM_LEN); + if (l_unlikely(notm(tm))) /* no metamethod? */ + luaG_typeerror(L, rb, "get length of"); + break; + } + } + luaT_callTMres(L, tm, rb, rb, ra); +} + + +/* +** Integer division; return 'm // n', that is, floor(m/n). +** C division truncates its result (rounds towards zero). +** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer, +** otherwise 'floor(q) == trunc(q) - 1'. +*/ +lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) { + if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ + if (n == 0) + luaG_runerror(L, "attempt to divide by zero"); + return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ + } + else { + lua_Integer q = m / n; /* perform C division */ + if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */ + q -= 1; /* correct result for different rounding */ + return q; + } +} + + +/* +** Integer modulus; return 'm % n'. (Assume that C '%' with +** negative operands follows C99 behavior. See previous comment +** about luaV_idiv.) +*/ +lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { + if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ + if (n == 0) + luaG_runerror(L, "attempt to perform 'n%%0'"); + return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ + } + else { + lua_Integer r = m % n; + if (r != 0 && (r ^ n) < 0) /* 'm/n' would be non-integer negative? */ + r += n; /* correct result for different rounding */ + return r; + } +} + + +/* +** Float modulus +*/ +lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { + lua_Number r; + luai_nummod(L, m, n, r); + return r; +} + + +/* number of bits in an integer */ +#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) + + +/* +** Shift left operation. (Shift right just negates 'y'.) +*/ +lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { + if (y < 0) { /* shift right? */ + if (y <= -NBITS) return 0; + else return intop(>>, x, -y); + } + else { /* shift left */ + if (y >= NBITS) return 0; + else return intop(<<, x, y); + } +} + + +/* +** create a new Lua closure, push it in the stack, and initialize +** its upvalues. +*/ +static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, + StkId ra) { + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + LClosure *ncl = luaF_newLclosure(L, nup); + ncl->p = p; + setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */ + for (i = 0; i < nup; i++) { /* fill in its upvalues */ + if (uv[i].instack) /* upvalue refers to local variable? */ + ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx); + else /* get upvalue from enclosing function */ + ncl->upvals[i] = encup[uv[i].idx]; + luaC_objbarrier(L, ncl, ncl->upvals[i]); + } +} + + +/* +** finish execution of an opcode interrupted by a yield +*/ +void luaV_finishOp (lua_State *L) { + CallInfo *ci = L->ci; + StkId base = ci->func.p + 1; + Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ + OpCode op = GET_OPCODE(inst); + switch (op) { /* finish its execution */ + case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { + setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top.p); + break; + } + case OP_UNM: case OP_BNOT: case OP_LEN: + case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: + case OP_GETFIELD: case OP_SELF: { + setobjs2s(L, base + GETARG_A(inst), --L->top.p); + break; + } + case OP_LT: case OP_LE: + case OP_LTI: case OP_LEI: + case OP_GTI: case OP_GEI: + case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */ + int res = !l_isfalse(s2v(L->top.p - 1)); + L->top.p--; +#if defined(LUA_COMPAT_LT_LE) + if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ + ci->callstatus ^= CIST_LEQ; /* clear mark */ + res = !res; /* negate result */ + } +#endif + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); + if (res != GETARG_k(inst)) /* condition failed? */ + ci->u.l.savedpc++; /* skip jump instruction */ + break; + } + case OP_CONCAT: { + StkId top = L->top.p - 1; /* top when 'luaT_tryconcatTM' was called */ + int a = GETARG_A(inst); /* first element to concatenate */ + int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */ + setobjs2s(L, top - 2, top); /* put TM result in proper position */ + L->top.p = top - 1; /* top is one after last element (at top-2) */ + luaV_concat(L, total); /* concat them (may yield again) */ + break; + } + case OP_CLOSE: { /* yielded closing variables */ + ci->u.l.savedpc--; /* repeat instruction to close other vars. */ + break; + } + case OP_RETURN: { /* yielded closing variables */ + StkId ra = base + GETARG_A(inst); + /* adjust top to signal correct number of returns, in case the + return is "up to top" ('isIT') */ + L->top.p = ra + ci->u2.nres; + /* repeat instruction to close other vars. and complete the return */ + ci->u.l.savedpc--; + break; + } + default: { + /* only these other opcodes can yield */ + lua_assert(op == OP_TFORCALL || op == OP_CALL || + op == OP_TAILCALL || op == OP_SETTABUP || op == OP_SETTABLE || + op == OP_SETI || op == OP_SETFIELD); + break; + } + } +} + + + + +/* +** {================================================================== +** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute' +** =================================================================== +*/ + +#define l_addi(L,a,b) intop(+, a, b) +#define l_subi(L,a,b) intop(-, a, b) +#define l_muli(L,a,b) intop(*, a, b) +#define l_band(a,b) intop(&, a, b) +#define l_bor(a,b) intop(|, a, b) +#define l_bxor(a,b) intop(^, a, b) + +#define l_lti(a,b) (a < b) +#define l_lei(a,b) (a <= b) +#define l_gti(a,b) (a > b) +#define l_gei(a,b) (a >= b) + + +/* +** Arithmetic operations with immediate operands. 'iop' is the integer +** operation, 'fop' is the float operation. +*/ +#define op_arithI(L,iop,fop) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + int imm = GETARG_sC(i); \ + if (ttisinteger(v1)) { \ + lua_Integer iv1 = ivalue(v1); \ + pc++; setivalue(s2v(ra), iop(L, iv1, imm)); \ + } \ + else if (ttisfloat(v1)) { \ + lua_Number nb = fltvalue(v1); \ + lua_Number fimm = cast_num(imm); \ + pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \ + }} + + +/* +** Auxiliary function for arithmetic operations over floats and others +** with two register operands. +*/ +#define op_arithf_aux(L,v1,v2,fop) { \ + lua_Number n1; lua_Number n2; \ + if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ + pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ + }} + + +/* +** Arithmetic operations over floats and others with register operands. +*/ +#define op_arithf(L,fop) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = vRC(i); \ + op_arithf_aux(L, v1, v2, fop); } + + +/* +** Arithmetic operations with K operands for floats. +*/ +#define op_arithfK(L,fop) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ + op_arithf_aux(L, v1, v2, fop); } + + +/* +** Arithmetic operations over integers and floats. +*/ +#define op_arith_aux(L,v1,v2,iop,fop) { \ + StkId ra = RA(i); \ + if (ttisinteger(v1) && ttisinteger(v2)) { \ + lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ + pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ + } \ + else op_arithf_aux(L, v1, v2, fop); } + + +/* +** Arithmetic operations with register operands. +*/ +#define op_arith(L,iop,fop) { \ + TValue *v1 = vRB(i); \ + TValue *v2 = vRC(i); \ + op_arith_aux(L, v1, v2, iop, fop); } + + +/* +** Arithmetic operations with K operands. +*/ +#define op_arithK(L,iop,fop) { \ + TValue *v1 = vRB(i); \ + TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ + op_arith_aux(L, v1, v2, iop, fop); } + + +/* +** Bitwise operations with constant operand. +*/ +#define op_bitwiseK(L,op) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = KC(i); \ + lua_Integer i1; \ + lua_Integer i2 = ivalue(v2); \ + if (tointegerns(v1, &i1)) { \ + pc++; setivalue(s2v(ra), op(i1, i2)); \ + }} + + +/* +** Bitwise operations with register operands. +*/ +#define op_bitwise(L,op) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = vRC(i); \ + lua_Integer i1; lua_Integer i2; \ + if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ + pc++; setivalue(s2v(ra), op(i1, i2)); \ + }} + + +/* +** Order operations with register operands. 'opn' actually works +** for all numbers, but the fast track improves performance for +** integers. +*/ +#define op_order(L,opi,opn,other) { \ + StkId ra = RA(i); \ + int cond; \ + TValue *rb = vRB(i); \ + if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \ + lua_Integer ia = ivalue(s2v(ra)); \ + lua_Integer ib = ivalue(rb); \ + cond = opi(ia, ib); \ + } \ + else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ + cond = opn(s2v(ra), rb); \ + else \ + Protect(cond = other(L, s2v(ra), rb)); \ + docondjump(); } + + +/* +** Order operations with immediate operand. (Immediate operand is +** always small enough to have an exact representation as a float.) +*/ +#define op_orderI(L,opi,opf,inv,tm) { \ + StkId ra = RA(i); \ + int cond; \ + int im = GETARG_sB(i); \ + if (ttisinteger(s2v(ra))) \ + cond = opi(ivalue(s2v(ra)), im); \ + else if (ttisfloat(s2v(ra))) { \ + lua_Number fa = fltvalue(s2v(ra)); \ + lua_Number fim = cast_num(im); \ + cond = opf(fa, fim); \ + } \ + else { \ + int isf = GETARG_C(i); \ + Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \ + } \ + docondjump(); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Function 'luaV_execute': main interpreter loop +** =================================================================== +*/ + +/* +** some macros for common tasks in 'luaV_execute' +*/ + + +#define RA(i) (base+GETARG_A(i)) +#define RB(i) (base+GETARG_B(i)) +#define vRB(i) s2v(RB(i)) +#define KB(i) (k+GETARG_B(i)) +#define RC(i) (base+GETARG_C(i)) +#define vRC(i) s2v(RC(i)) +#define KC(i) (k+GETARG_C(i)) +#define RKC(i) ((TESTARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i))) + + + +#define updatetrap(ci) (trap = ci->u.l.trap) + +#define updatebase(ci) (base = ci->func.p + 1) + + +#define updatestack(ci) \ + { if (l_unlikely(trap)) { updatebase(ci); ra = RA(i); } } + + +/* +** Execute a jump instruction. The 'updatetrap' allows signals to stop +** tight loops. (Without it, the local copy of 'trap' could never change.) +*/ +#define dojump(ci,i,e) { pc += GETARG_sJ(i) + e; updatetrap(ci); } + + +/* for test instructions, execute the jump instruction that follows it */ +#define donextjump(ci) { Instruction ni = *pc; dojump(ci, ni, 1); } + +/* +** do a conditional jump: skip next instruction if 'cond' is not what +** was expected (parameter 'k'), else do next instruction, which must +** be a jump. +*/ +#define docondjump() if (cond != GETARG_k(i)) pc++; else donextjump(ci); + + +/* +** Correct global 'pc'. +*/ +#define savepc(L) (ci->u.l.savedpc = pc) + + +/* +** Whenever code can raise errors, the global 'pc' and the global +** 'top' must be correct to report occasional errors. +*/ +#define savestate(L,ci) (savepc(L), L->top.p = ci->top.p) + + +/* +** Protect code that, in general, can raise errors, reallocate the +** stack, and change the hooks. +*/ +#define Protect(exp) (savestate(L,ci), (exp), updatetrap(ci)) + +/* special version that does not change the top */ +#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) + +/* +** Protect code that can only raise errors. (That is, it cannot change +** the stack or hooks.) +*/ +#define halfProtect(exp) (savestate(L,ci), (exp)) + +/* 'c' is the limit of live values in the stack */ +#define checkGC(L,c) \ + { luaC_condGC(L, (savepc(L), L->top.p = (c)), \ + updatetrap(ci)); \ + luai_threadyield(L); } + + +/* fetch an instruction and prepare its execution */ +#define vmfetch() { \ + if (l_unlikely(trap)) { /* stack reallocation or hooks? */ \ + trap = luaG_traceexec(L, pc); /* handle hooks */ \ + updatebase(ci); /* correct stack */ \ + } \ + i = *(pc++); \ +} + +#define vmdispatch(o) switch(o) +#define vmcase(l) case l: +#define vmbreak break + + +void luaV_execute (lua_State *L, CallInfo *ci) { + LClosure *cl; + TValue *k; + StkId base; + const Instruction *pc; + int trap; +#if LUA_USE_JUMPTABLE +#include "ljumptab.h" +#endif + startfunc: + trap = L->hookmask; + returning: /* trap already set */ + cl = ci_func(ci); + k = cl->p->k; + pc = ci->u.l.savedpc; + if (l_unlikely(trap)) + trap = luaG_tracecall(L); + base = ci->func.p + 1; + /* main loop of interpreter */ + for (;;) { + Instruction i; /* instruction being executed */ + vmfetch(); + #if 0 + /* low-level line tracing for debugging Lua */ + printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); + #endif + lua_assert(base == ci->func.p + 1); + lua_assert(base <= L->top.p && L->top.p <= L->stack_last.p); + /* invalidate top for instructions not expecting it */ + lua_assert(isIT(i) || (cast_void(L->top.p = base), 1)); + vmdispatch (GET_OPCODE(i)) { + vmcase(OP_MOVE) { + StkId ra = RA(i); + setobjs2s(L, ra, RB(i)); + vmbreak; + } + vmcase(OP_LOADI) { + StkId ra = RA(i); + lua_Integer b = GETARG_sBx(i); + setivalue(s2v(ra), b); + vmbreak; + } + vmcase(OP_LOADF) { + StkId ra = RA(i); + int b = GETARG_sBx(i); + setfltvalue(s2v(ra), cast_num(b)); + vmbreak; + } + vmcase(OP_LOADK) { + StkId ra = RA(i); + TValue *rb = k + GETARG_Bx(i); + setobj2s(L, ra, rb); + vmbreak; + } + vmcase(OP_LOADKX) { + StkId ra = RA(i); + TValue *rb; + rb = k + GETARG_Ax(*pc); pc++; + setobj2s(L, ra, rb); + vmbreak; + } + vmcase(OP_LOADFALSE) { + StkId ra = RA(i); + setbfvalue(s2v(ra)); + vmbreak; + } + vmcase(OP_LFALSESKIP) { + StkId ra = RA(i); + setbfvalue(s2v(ra)); + pc++; /* skip next instruction */ + vmbreak; + } + vmcase(OP_LOADTRUE) { + StkId ra = RA(i); + setbtvalue(s2v(ra)); + vmbreak; + } + vmcase(OP_LOADNIL) { + StkId ra = RA(i); + int b = GETARG_B(i); + do { + setnilvalue(s2v(ra++)); + } while (b--); + vmbreak; + } + vmcase(OP_GETUPVAL) { + StkId ra = RA(i); + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v.p); + vmbreak; + } + vmcase(OP_SETUPVAL) { + StkId ra = RA(i); + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v.p, s2v(ra)); + luaC_barrier(L, uv, s2v(ra)); + vmbreak; + } + vmcase(OP_GETTABUP) { + StkId ra = RA(i); + const TValue *slot; + TValue *upval = cl->upvals[GETARG_B(i)]->v.p; + TValue *rc = KC(i); + TString *key = tsvalue(rc); /* key must be a short string */ + if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, upval, rc, ra, slot)); + vmbreak; + } + vmcase(OP_GETTABLE) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + TValue *rc = vRC(i); + lua_Unsigned n; + if (ttisinteger(rc) /* fast track for integers? */ + ? (cast_void(n = ivalue(rc)), luaV_fastgeti(L, rb, n, slot)) + : luaV_fastget(L, rb, rc, slot, luaH_get)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, rb, rc, ra, slot)); + vmbreak; + } + vmcase(OP_GETI) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + int c = GETARG_C(i); + if (luaV_fastgeti(L, rb, c, slot)) { + setobj2s(L, ra, slot); + } + else { + TValue key; + setivalue(&key, c); + Protect(luaV_finishget(L, rb, &key, ra, slot)); + } + vmbreak; + } + vmcase(OP_GETFIELD) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + TValue *rc = KC(i); + TString *key = tsvalue(rc); /* key must be a short string */ + if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, rb, rc, ra, slot)); + vmbreak; + } + vmcase(OP_SETTABUP) { + const TValue *slot; + TValue *upval = cl->upvals[GETARG_A(i)]->v.p; + TValue *rb = KB(i); + TValue *rc = RKC(i); + TString *key = tsvalue(rb); /* key must be a short string */ + if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { + luaV_finishfastset(L, upval, slot, rc); + } + else + Protect(luaV_finishset(L, upval, rb, rc, slot)); + vmbreak; + } + vmcase(OP_SETTABLE) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); /* key (table is in 'ra') */ + TValue *rc = RKC(i); /* value */ + lua_Unsigned n; + if (ttisinteger(rb) /* fast track for integers? */ + ? (cast_void(n = ivalue(rb)), luaV_fastgeti(L, s2v(ra), n, slot)) + : luaV_fastget(L, s2v(ra), rb, slot, luaH_get)) { + luaV_finishfastset(L, s2v(ra), slot, rc); + } + else + Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); + vmbreak; + } + vmcase(OP_SETI) { + StkId ra = RA(i); + const TValue *slot; + int c = GETARG_B(i); + TValue *rc = RKC(i); + if (luaV_fastgeti(L, s2v(ra), c, slot)) { + luaV_finishfastset(L, s2v(ra), slot, rc); + } + else { + TValue key; + setivalue(&key, c); + Protect(luaV_finishset(L, s2v(ra), &key, rc, slot)); + } + vmbreak; + } + vmcase(OP_SETFIELD) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = KB(i); + TValue *rc = RKC(i); + TString *key = tsvalue(rb); /* key must be a short string */ + if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { + luaV_finishfastset(L, s2v(ra), slot, rc); + } + else + Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); + vmbreak; + } + vmcase(OP_NEWTABLE) { + StkId ra = RA(i); + int b = GETARG_B(i); /* log2(hash size) + 1 */ + int c = GETARG_C(i); /* array size */ + Table *t; + if (b > 0) + b = 1 << (b - 1); /* size is 2^(b - 1) */ + lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0)); + if (TESTARG_k(i)) /* non-zero extra argument? */ + c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ + pc++; /* skip extra argument */ + L->top.p = ra + 1; /* correct top in case of emergency GC */ + t = luaH_new(L); /* memory allocation */ + sethvalue2s(L, ra, t); + if (b != 0 || c != 0) + luaH_resize(L, t, c, b); /* idem */ + checkGC(L, ra + 1); + vmbreak; + } + vmcase(OP_SELF) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + TValue *rc = RKC(i); + TString *key = tsvalue(rc); /* key must be a string */ + setobj2s(L, ra + 1, rb); + if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, rb, rc, ra, slot)); + vmbreak; + } + vmcase(OP_ADDI) { + op_arithI(L, l_addi, luai_numadd); + vmbreak; + } + vmcase(OP_ADDK) { + op_arithK(L, l_addi, luai_numadd); + vmbreak; + } + vmcase(OP_SUBK) { + op_arithK(L, l_subi, luai_numsub); + vmbreak; + } + vmcase(OP_MULK) { + op_arithK(L, l_muli, luai_nummul); + vmbreak; + } + vmcase(OP_MODK) { + savestate(L, ci); /* in case of division by 0 */ + op_arithK(L, luaV_mod, luaV_modf); + vmbreak; + } + vmcase(OP_POWK) { + op_arithfK(L, luai_numpow); + vmbreak; + } + vmcase(OP_DIVK) { + op_arithfK(L, luai_numdiv); + vmbreak; + } + vmcase(OP_IDIVK) { + savestate(L, ci); /* in case of division by 0 */ + op_arithK(L, luaV_idiv, luai_numidiv); + vmbreak; + } + vmcase(OP_BANDK) { + op_bitwiseK(L, l_band); + vmbreak; + } + vmcase(OP_BORK) { + op_bitwiseK(L, l_bor); + vmbreak; + } + vmcase(OP_BXORK) { + op_bitwiseK(L, l_bxor); + vmbreak; + } + vmcase(OP_SHRI) { + StkId ra = RA(i); + TValue *rb = vRB(i); + int ic = GETARG_sC(i); + lua_Integer ib; + if (tointegerns(rb, &ib)) { + pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic)); + } + vmbreak; + } + vmcase(OP_SHLI) { + StkId ra = RA(i); + TValue *rb = vRB(i); + int ic = GETARG_sC(i); + lua_Integer ib; + if (tointegerns(rb, &ib)) { + pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib)); + } + vmbreak; + } + vmcase(OP_ADD) { + op_arith(L, l_addi, luai_numadd); + vmbreak; + } + vmcase(OP_SUB) { + op_arith(L, l_subi, luai_numsub); + vmbreak; + } + vmcase(OP_MUL) { + op_arith(L, l_muli, luai_nummul); + vmbreak; + } + vmcase(OP_MOD) { + savestate(L, ci); /* in case of division by 0 */ + op_arith(L, luaV_mod, luaV_modf); + vmbreak; + } + vmcase(OP_POW) { + op_arithf(L, luai_numpow); + vmbreak; + } + vmcase(OP_DIV) { /* float division (always with floats) */ + op_arithf(L, luai_numdiv); + vmbreak; + } + vmcase(OP_IDIV) { /* floor division */ + savestate(L, ci); /* in case of division by 0 */ + op_arith(L, luaV_idiv, luai_numidiv); + vmbreak; + } + vmcase(OP_BAND) { + op_bitwise(L, l_band); + vmbreak; + } + vmcase(OP_BOR) { + op_bitwise(L, l_bor); + vmbreak; + } + vmcase(OP_BXOR) { + op_bitwise(L, l_bxor); + vmbreak; + } + vmcase(OP_SHR) { + op_bitwise(L, luaV_shiftr); + vmbreak; + } + vmcase(OP_SHL) { + op_bitwise(L, luaV_shiftl); + vmbreak; + } + vmcase(OP_MMBIN) { + StkId ra = RA(i); + Instruction pi = *(pc - 2); /* original arith. expression */ + TValue *rb = vRB(i); + TMS tm = (TMS)GETARG_C(i); + StkId result = RA(pi); + lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR); + Protect(luaT_trybinTM(L, s2v(ra), rb, result, tm)); + vmbreak; + } + vmcase(OP_MMBINI) { + StkId ra = RA(i); + Instruction pi = *(pc - 2); /* original arith. expression */ + int imm = GETARG_sB(i); + TMS tm = (TMS)GETARG_C(i); + int flip = GETARG_k(i); + StkId result = RA(pi); + Protect(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm)); + vmbreak; + } + vmcase(OP_MMBINK) { + StkId ra = RA(i); + Instruction pi = *(pc - 2); /* original arith. expression */ + TValue *imm = KB(i); + TMS tm = (TMS)GETARG_C(i); + int flip = GETARG_k(i); + StkId result = RA(pi); + Protect(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm)); + vmbreak; + } + vmcase(OP_UNM) { + StkId ra = RA(i); + TValue *rb = vRB(i); + lua_Number nb; + if (ttisinteger(rb)) { + lua_Integer ib = ivalue(rb); + setivalue(s2v(ra), intop(-, 0, ib)); + } + else if (tonumberns(rb, nb)) { + setfltvalue(s2v(ra), luai_numunm(L, nb)); + } + else + Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); + vmbreak; + } + vmcase(OP_BNOT) { + StkId ra = RA(i); + TValue *rb = vRB(i); + lua_Integer ib; + if (tointegerns(rb, &ib)) { + setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); + } + else + Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); + vmbreak; + } + vmcase(OP_NOT) { + StkId ra = RA(i); + TValue *rb = vRB(i); + if (l_isfalse(rb)) + setbtvalue(s2v(ra)); + else + setbfvalue(s2v(ra)); + vmbreak; + } + vmcase(OP_LEN) { + StkId ra = RA(i); + Protect(luaV_objlen(L, ra, vRB(i))); + vmbreak; + } + vmcase(OP_CONCAT) { + StkId ra = RA(i); + int n = GETARG_B(i); /* number of elements to concatenate */ + L->top.p = ra + n; /* mark the end of concat operands */ + ProtectNT(luaV_concat(L, n)); + checkGC(L, L->top.p); /* 'luaV_concat' ensures correct top */ + vmbreak; + } + vmcase(OP_CLOSE) { + StkId ra = RA(i); + Protect(luaF_close(L, ra, LUA_OK, 1)); + vmbreak; + } + vmcase(OP_TBC) { + StkId ra = RA(i); + /* create new to-be-closed upvalue */ + halfProtect(luaF_newtbcupval(L, ra)); + vmbreak; + } + vmcase(OP_JMP) { + dojump(ci, i, 0); + vmbreak; + } + vmcase(OP_EQ) { + StkId ra = RA(i); + int cond; + TValue *rb = vRB(i); + Protect(cond = luaV_equalobj(L, s2v(ra), rb)); + docondjump(); + vmbreak; + } + vmcase(OP_LT) { + op_order(L, l_lti, LTnum, lessthanothers); + vmbreak; + } + vmcase(OP_LE) { + op_order(L, l_lei, LEnum, lessequalothers); + vmbreak; + } + vmcase(OP_EQK) { + StkId ra = RA(i); + TValue *rb = KB(i); + /* basic types do not use '__eq'; we can use raw equality */ + int cond = luaV_rawequalobj(s2v(ra), rb); + docondjump(); + vmbreak; + } + vmcase(OP_EQI) { + StkId ra = RA(i); + int cond; + int im = GETARG_sB(i); + if (ttisinteger(s2v(ra))) + cond = (ivalue(s2v(ra)) == im); + else if (ttisfloat(s2v(ra))) + cond = luai_numeq(fltvalue(s2v(ra)), cast_num(im)); + else + cond = 0; /* other types cannot be equal to a number */ + docondjump(); + vmbreak; + } + vmcase(OP_LTI) { + op_orderI(L, l_lti, luai_numlt, 0, TM_LT); + vmbreak; + } + vmcase(OP_LEI) { + op_orderI(L, l_lei, luai_numle, 0, TM_LE); + vmbreak; + } + vmcase(OP_GTI) { + op_orderI(L, l_gti, luai_numgt, 1, TM_LT); + vmbreak; + } + vmcase(OP_GEI) { + op_orderI(L, l_gei, luai_numge, 1, TM_LE); + vmbreak; + } + vmcase(OP_TEST) { + StkId ra = RA(i); + int cond = !l_isfalse(s2v(ra)); + docondjump(); + vmbreak; + } + vmcase(OP_TESTSET) { + StkId ra = RA(i); + TValue *rb = vRB(i); + if (l_isfalse(rb) == GETARG_k(i)) + pc++; + else { + setobj2s(L, ra, rb); + donextjump(ci); + } + vmbreak; + } + vmcase(OP_CALL) { + StkId ra = RA(i); + CallInfo *newci; + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) /* fixed number of arguments? */ + L->top.p = ra + b; /* top signals number of arguments */ + /* else previous instruction set top */ + savepc(L); /* in case of errors */ + if ((newci = luaD_precall(L, ra, nresults)) == NULL) + updatetrap(ci); /* C call; nothing else to be done */ + else { /* Lua call: run function in this same C frame */ + ci = newci; + goto startfunc; + } + vmbreak; + } + vmcase(OP_TAILCALL) { + StkId ra = RA(i); + int b = GETARG_B(i); /* number of arguments + 1 (function) */ + int n; /* number of results when calling a C function */ + int nparams1 = GETARG_C(i); + /* delta is virtual 'func' - real 'func' (vararg functions) */ + int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; + if (b != 0) + L->top.p = ra + b; + else /* previous instruction set top */ + b = cast_int(L->top.p - ra); + savepc(ci); /* several calls here can raise errors */ + if (TESTARG_k(i)) { + luaF_closeupval(L, base); /* close upvalues from current call */ + lua_assert(L->tbclist.p < base); /* no pending tbc variables */ + lua_assert(base == ci->func.p + 1); + } + if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */ + goto startfunc; /* execute the callee */ + else { /* C function? */ + ci->func.p -= delta; /* restore 'func' (if vararg) */ + luaD_poscall(L, ci, n); /* finish caller */ + updatetrap(ci); /* 'luaD_poscall' can change hooks */ + goto ret; /* caller returns after the tail call */ + } + } + vmcase(OP_RETURN) { + StkId ra = RA(i); + int n = GETARG_B(i) - 1; /* number of results */ + int nparams1 = GETARG_C(i); + if (n < 0) /* not fixed? */ + n = cast_int(L->top.p - ra); /* get what is available */ + savepc(ci); + if (TESTARG_k(i)) { /* may there be open upvalues? */ + ci->u2.nres = n; /* save number of returns */ + if (L->top.p < ci->top.p) + L->top.p = ci->top.p; + luaF_close(L, base, CLOSEKTOP, 1); + updatetrap(ci); + updatestack(ci); + } + if (nparams1) /* vararg function? */ + ci->func.p -= ci->u.l.nextraargs + nparams1; + L->top.p = ra + n; /* set call for 'luaD_poscall' */ + luaD_poscall(L, ci, n); + updatetrap(ci); /* 'luaD_poscall' can change hooks */ + goto ret; + } + vmcase(OP_RETURN0) { + if (l_unlikely(L->hookmask)) { + StkId ra = RA(i); + L->top.p = ra; + savepc(ci); + luaD_poscall(L, ci, 0); /* no hurry... */ + trap = 1; + } + else { /* do the 'poscall' here */ + int nres; + L->ci = ci->previous; /* back to caller */ + L->top.p = base - 1; + for (nres = ci->nresults; l_unlikely(nres > 0); nres--) + setnilvalue(s2v(L->top.p++)); /* all results are nil */ + } + goto ret; + } + vmcase(OP_RETURN1) { + if (l_unlikely(L->hookmask)) { + StkId ra = RA(i); + L->top.p = ra + 1; + savepc(ci); + luaD_poscall(L, ci, 1); /* no hurry... */ + trap = 1; + } + else { /* do the 'poscall' here */ + int nres = ci->nresults; + L->ci = ci->previous; /* back to caller */ + if (nres == 0) + L->top.p = base - 1; /* asked for no results */ + else { + StkId ra = RA(i); + setobjs2s(L, base - 1, ra); /* at least this result */ + L->top.p = base; + for (; l_unlikely(nres > 1); nres--) + setnilvalue(s2v(L->top.p++)); /* complete missing results */ + } + } + ret: /* return from a Lua function */ + if (ci->callstatus & CIST_FRESH) + return; /* end this frame */ + else { + ci = ci->previous; + goto returning; /* continue running caller in this frame */ + } + } + vmcase(OP_FORLOOP) { + StkId ra = RA(i); + if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ + lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1))); + if (count > 0) { /* still more iterations? */ + lua_Integer step = ivalue(s2v(ra + 2)); + lua_Integer idx = ivalue(s2v(ra)); /* internal index */ + chgivalue(s2v(ra + 1), count - 1); /* update counter */ + idx = intop(+, idx, step); /* add step to index */ + chgivalue(s2v(ra), idx); /* update internal index */ + setivalue(s2v(ra + 3), idx); /* and control variable */ + pc -= GETARG_Bx(i); /* jump back */ + } + } + else if (floatforloop(ra)) /* float loop */ + pc -= GETARG_Bx(i); /* jump back */ + updatetrap(ci); /* allows a signal to break the loop */ + vmbreak; + } + vmcase(OP_FORPREP) { + StkId ra = RA(i); + savestate(L, ci); /* in case of errors */ + if (forprep(L, ra)) + pc += GETARG_Bx(i) + 1; /* skip the loop */ + vmbreak; + } + vmcase(OP_TFORPREP) { + StkId ra = RA(i); + /* create to-be-closed upvalue (if needed) */ + halfProtect(luaF_newtbcupval(L, ra + 3)); + pc += GETARG_Bx(i); + i = *(pc++); /* go to next instruction */ + lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i)); + goto l_tforcall; + } + vmcase(OP_TFORCALL) { + l_tforcall: { + StkId ra = RA(i); + /* 'ra' has the iterator function, 'ra + 1' has the state, + 'ra + 2' has the control variable, and 'ra + 3' has the + to-be-closed variable. The call will use the stack after + these values (starting at 'ra + 4') + */ + /* push function, state, and control variable */ + memcpy(ra + 4, ra, 3 * sizeof(*ra)); + L->top.p = ra + 4 + 3; + ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ + updatestack(ci); /* stack may have changed */ + i = *(pc++); /* go to next instruction */ + lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); + goto l_tforloop; + }} + vmcase(OP_TFORLOOP) { + l_tforloop: { + StkId ra = RA(i); + if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ + setobjs2s(L, ra + 2, ra + 4); /* save control variable */ + pc -= GETARG_Bx(i); /* jump back */ + } + vmbreak; + }} + vmcase(OP_SETLIST) { + StkId ra = RA(i); + int n = GETARG_B(i); + unsigned int last = GETARG_C(i); + Table *h = hvalue(s2v(ra)); + if (n == 0) + n = cast_int(L->top.p - ra) - 1; /* get up to the top */ + else + L->top.p = ci->top.p; /* correct top in case of emergency GC */ + last += n; + if (TESTARG_k(i)) { + last += GETARG_Ax(*pc) * (MAXARG_C + 1); + pc++; + } + if (last > luaH_realasize(h)) /* needs more space? */ + luaH_resizearray(L, h, last); /* preallocate it at once */ + for (; n > 0; n--) { + TValue *val = s2v(ra + n); + setobj2t(L, &h->array[last - 1], val); + last--; + luaC_barrierback(L, obj2gco(h), val); + } + vmbreak; + } + vmcase(OP_CLOSURE) { + StkId ra = RA(i); + Proto *p = cl->p->p[GETARG_Bx(i)]; + halfProtect(pushclosure(L, p, cl->upvals, base, ra)); + checkGC(L, ra + 1); + vmbreak; + } + vmcase(OP_VARARG) { + StkId ra = RA(i); + int n = GETARG_C(i) - 1; /* required results */ + Protect(luaT_getvarargs(L, ci, ra, n)); + vmbreak; + } + vmcase(OP_VARARGPREP) { + ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p)); + if (l_unlikely(trap)) { /* previous "Protect" updated trap */ + luaD_hookcall(L, ci); + L->oldpc = 1; /* next opcode will be seen as a "new" line */ + } + updatebase(ci); /* function has new base after adjustment */ + vmbreak; + } + vmcase(OP_EXTRAARG) { + lua_assert(0); + vmbreak; + } + } + } +} + +/* }================================================================== */ diff --git a/arm9/source/lua/lvm.h b/arm9/source/lua/lvm.h new file mode 100644 index 000000000..dba1ad277 --- /dev/null +++ b/arm9/source/lua/lvm.h @@ -0,0 +1,141 @@ +/* +** $Id: lvm.h $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#if !defined(LUA_NOCVTN2S) +#define cvt2str(o) ttisnumber(o) +#else +#define cvt2str(o) 0 /* no conversion from numbers to strings */ +#endif + + +#if !defined(LUA_NOCVTS2N) +#define cvt2num(o) ttisstring(o) +#else +#define cvt2num(o) 0 /* no conversion from strings to numbers */ +#endif + + +/* +** You can define LUA_FLOORN2I if you want to convert floats to integers +** by flooring them (instead of raising an error if they are not +** integral values) +*/ +#if !defined(LUA_FLOORN2I) +#define LUA_FLOORN2I F2Ieq +#endif + + +/* +** Rounding modes for float->integer coercion + */ +typedef enum { + F2Ieq, /* no rounding; accepts only integral values */ + F2Ifloor, /* takes the floor of the number */ + F2Iceil /* takes the ceil of the number */ +} F2Imod; + + +/* convert an object to a float (including string coercion) */ +#define tonumber(o,n) \ + (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) + + +/* convert an object to a float (without string coercion) */ +#define tonumberns(o,n) \ + (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ + (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) + + +/* convert an object to an integer (including string coercion) */ +#define tointeger(o,i) \ + (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ + : luaV_tointeger(o,i,LUA_FLOORN2I)) + + +/* convert an object to an integer (without string coercion) */ +#define tointegerns(o,i) \ + (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ + : luaV_tointegerns(o,i,LUA_FLOORN2I)) + + +#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) + +#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) + + +/* +** fast track for 'gettable': if 't' is a table and 't[k]' is present, +** return 1 with 'slot' pointing to 't[k]' (position of final result). +** Otherwise, return 0 (meaning it will have to check metamethod) +** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL +** (otherwise). 'f' is the raw get function to use. +*/ +#define luaV_fastget(L,t,k,slot,f) \ + (!ttistable(t) \ + ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ + : (slot = f(hvalue(t), k), /* else, do raw access */ \ + !isempty(slot))) /* result not empty? */ + + +/* +** Special case of 'luaV_fastget' for integers, inlining the fast case +** of 'luaH_getint'. +*/ +#define luaV_fastgeti(L,t,k,slot) \ + (!ttistable(t) \ + ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ + : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ + ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ + !isempty(slot))) /* result not empty? */ + + +/* +** Finish a fast set operation (when fast get succeeds). In that case, +** 'slot' points to the place to put the value. +*/ +#define luaV_finishfastset(L,t,slot,v) \ + { setobj2t(L, cast(TValue *,slot), v); \ + luaC_barrierback(L, gcvalue(t), v); } + + +/* +** Shift right is the same as shift left with a negative 'y' +*/ +#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) + + + +LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); +LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); +LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, + F2Imod mode); +LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); +LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, + StkId val, const TValue *slot); +LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, + TValue *val, const TValue *slot); +LUAI_FUNC void luaV_finishOp (lua_State *L); +LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); +LUAI_FUNC void luaV_concat (lua_State *L, int total); +LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); +LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); +LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); +LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); +LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); + +#endif diff --git a/arm9/source/lua/lzio.c b/arm9/source/lua/lzio.c new file mode 100644 index 000000000..cd0a02d5f --- /dev/null +++ b/arm9/source/lua/lzio.c @@ -0,0 +1,68 @@ +/* +** $Id: lzio.c $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + +#define lzio_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) + return EOZ; + z->n = size - 1; /* discount char being returned */ + z->p = buff; + return cast_uchar(*(z->p++)); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (z->n == 0) { /* no bytes in buffer? */ + if (luaZ_fill(z) == EOZ) /* try to read more */ + return n; /* no more input; return number of missing bytes */ + else { + z->n++; /* luaZ_fill consumed first byte; put it back */ + z->p--; + } + } + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + diff --git a/arm9/source/lua/lzio.h b/arm9/source/lua/lzio.h new file mode 100644 index 000000000..38f397fd2 --- /dev/null +++ b/arm9/source/lua/lzio.h @@ -0,0 +1,66 @@ +/* +** $Id: lzio.h $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) + + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_buffremove(buff,i) ((buff)->n -= (i)) +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ + (buff)->buffsize, size), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; /* reader function */ + void *data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/arm9/source/system/vram0.h b/arm9/source/system/vram0.h index 62811a710..3e4d916d1 100644 --- a/arm9/source/system/vram0.h +++ b/arm9/source/system/vram0.h @@ -11,21 +11,25 @@ // known file names inside VRAM0 TAR #define VRAM0_AUTORUN_GM9 "autorun.gm9" +#define VRAM0_AUTORUN_LUA "autorun.lua" #define VRAM0_FONT DEFAULT_FONT #define VRAM0_SCRIPTS "scripts" +#define VRAM0_LUASCRIPTS "luascripts" #define VRAM0_README_MD "README_internal.md" #define VRAM0_SPLASH_PNG FLAVOR "_splash.png" #define VRAM0_EASTER_BIN "easter.bin" -#define VRAM0_OFFSET 0x080C0000 -#define VRAM0_LIMIT 0x00040000 +extern const char vram_data[]; +extern const char vram_data_end[]; + +#define VRAM0_OFFSET (uintptr_t)(vram_data) +#define VRAM0_LIMIT (uintptr_t)(vram_data_end - vram_data) #define TARDATA ((void*) VRAM0_OFFSET) #define TARDATA_(off) ((void*) (u32) (VRAM0_OFFSET + (off))) #define TARDATA_END TARDATA_(VRAM0_LIMIT) - #define CheckVram0Tar() \ (ValidateTarHeader(TARDATA, TARDATA_END) == 0) diff --git a/arm9/source/system/vram_data.s b/arm9/source/system/vram_data.s new file mode 100644 index 000000000..725768aab --- /dev/null +++ b/arm9/source/system/vram_data.s @@ -0,0 +1,8 @@ +.section .rodata.vram_data + +.align 2 +.global vram_data +vram_data: + .incbin "../output/vram0.tar" +.global vram_data_end +vram_data_end: diff --git a/arm9/source/system/xrq.c b/arm9/source/system/xrq.c index aa36af20f..c8367f2aa 100644 --- a/arm9/source/system/xrq.c +++ b/arm9/source/system/xrq.c @@ -6,6 +6,7 @@ #include "common.h" #include "fsinit.h" #include "fsutil.h" +#include "language.h" #include "qrcodegen.h" #include "power.h" #include "rtc.h" @@ -94,7 +95,7 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) u32 draw_y_upd = draw_y + draw_height - 10; ClearScreen(MAIN_SCREEN, COLOR_STD_BG); - DrawStringF(MAIN_SCREEN, draw_x, draw_y, COLOR_STD_FONT, COLOR_STD_BG, dumpstr); + DrawStringF(MAIN_SCREEN, draw_x, draw_y, COLOR_STD_FONT, COLOR_STD_BG, "%s", dumpstr); /* Dump STACK */ sp = regs[13] & ~0xF; @@ -118,16 +119,17 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) /* Draw QR Code */ u8 qrcode[qrcodegen_BUFFER_LEN_MAX]; u8 temp[qrcodegen_BUFFER_LEN_MAX]; - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Generating QR code..."); + char tempstr[UTF_BUFFER_BYTESIZE(29)]; + ResizeString(tempstr, STR_GENERATING_QR_CODE, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); if (qrcodegen_encodeText(dumpstr, temp, qrcode, qrcodegen_Ecc_LOW, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true)) { DrawQrCode(ALT_SCREEN, qrcode); } /* Reinitialize SD */ - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Reinitializing SD card..."); + ResizeString(tempstr, STR_REINITIALIZING_SD_CARD, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); while (!InitSDCardFS()) { if (InputWait(1) & BUTTON_POWER) PowerOff(); DeinitSDCardFS(); @@ -136,19 +138,19 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) /* Dump to SD */ char path[64]; - snprintf(path, 64, "%s/exception_dump_%02lX%02lX%02lX%02lX%02lX%02lX.txt", OUTPUT_PATH, + snprintf(path, sizeof(path), "%s/exception_dump_%02lX%02lX%02lX%02lX%02lX%02lX.txt", OUTPUT_PATH, (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D, (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Dumping state to SD card..."); + ResizeString(tempstr, STR_DUMPING_STATE_TO_SD_CARD, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); FileSetData(path, dumpstr, wstr - dumpstr, 0, true); /* Deinit SD */ DeinitSDCardFS(); /* Done, wait for user power off */ - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Press POWER to turn off"); + ResizeString(tempstr, STR_PRESS_POWER_TO_TURN_OFF, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); while (!(InputWait(0) & BUTTON_POWER)); PowerOff(); diff --git a/arm9/source/utils/ctrtransfer.c b/arm9/source/utils/ctrtransfer.c index 5258360bf..3f7177d05 100644 --- a/arm9/source/utils/ctrtransfer.c +++ b/arm9/source/utils/ctrtransfer.c @@ -2,6 +2,7 @@ #include "nandcmac.h" #include "fs.h" #include "essentials.h" +#include "language.h" #include "ui.h" #include "sha.h" @@ -63,11 +64,11 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { char path_tickdb[32]; char path_tickdb_bak[32]; - snprintf(path_secnfo_a, 32, "%s/rw/sys/SecureInfo_A", drv); - snprintf(path_secnfo_b, 32, "%s/rw/sys/SecureInfo_B", drv); - snprintf(path_secnfo_c, 32, "%s/rw/sys/SecureInfo_C", drv); - snprintf(path_tickdb, 32, "%s/dbs/ticket.db", drv); - snprintf(path_tickdb_bak, 32, "%s/dbs/ticket.bak", drv); + snprintf(path_secnfo_a, sizeof(path_secnfo_a), "%s/rw/sys/SecureInfo_A", drv); + snprintf(path_secnfo_b, sizeof(path_secnfo_b), "%s/rw/sys/SecureInfo_B", drv); + snprintf(path_secnfo_c, sizeof(path_secnfo_c), "%s/rw/sys/SecureInfo_C", drv); + snprintf(path_tickdb, sizeof(path_tickdb), "%s/dbs/ticket.db", drv); + snprintf(path_tickdb_bak, sizeof(path_tickdb_bak), "%s/dbs/ticket.bak", drv); // special handling for out of region images (create SecureInfo_C) PathDelete(path_secnfo_c); // not required when transfering back to original region @@ -87,11 +88,11 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { char path_movable[32]; char path_asr[96]; u8 sd_keyy[0x10] __attribute__((aligned(4))); - snprintf(path_movable, 32, "%s/private/movable.sed", drv); + snprintf(path_movable, sizeof(path_movable), "%s/private/movable.sed", drv); if (FileGetData(path_movable, sd_keyy, 0x10, 0x110) == 0x10) { u32 sha256sum[8]; sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE); - snprintf(path_asr, 96, "%s/data/%08lx%08lx%08lx%08lx/sysdata/00010011/00000000", + snprintf(path_asr, sizeof(path_asr), "%s/data/%08lx%08lx%08lx%08lx/sysdata/00010011/00000000", drv, sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); PathDelete(path_asr); } @@ -102,17 +103,17 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { char path_from[32]; char path_dbs[32]; u32 flags = OVERWRITE_ALL; - snprintf(path_dbs, 32, "%s/dbs", drv); + snprintf(path_dbs, sizeof(path_dbs), "%s/dbs", drv); for (u32 i = 0; i < sizeof(dbnames) / sizeof(char*); i++) { - snprintf(path_to, 32, "%s/dbs/%s", drv, dbnames[i]); - snprintf(path_from, 32, "7:/dbs/%s", dbnames[i]); + snprintf(path_to, sizeof(path_to), "%s/dbs/%s", drv, dbnames[i]); + snprintf(path_from, sizeof(path_from), "7:/dbs/%s", dbnames[i]); PathDelete(path_to); PathCopy(path_dbs, path_from, &flags); FixFileCmac(path_to, true); } - ShowString("Cleaning up titles, please wait..."); - snprintf(path_to, 32, "%s/title", drv); - snprintf(path_from, 32, "7:/title"); + ShowString("%s", STR_CLEANING_UP_TITLES_PLEASE_WAIT); + snprintf(path_to, sizeof(path_to), "%s/title", drv); + snprintf(path_from, sizeof(path_from), "7:/title"); PathDelete(path_to); PathCopy(drv, path_from, &flags); diff --git a/arm9/source/utils/gameutil.c b/arm9/source/utils/gameutil.c index 6ec9c4caf..ded8852f9 100644 --- a/arm9/source/utils/gameutil.c +++ b/arm9/source/utils/gameutil.c @@ -294,7 +294,7 @@ u32 LoadCdnTicketFile(Ticket** ticket, const char* path_cnt) { char* name_cetk = strrchr(path_cetk, '/'); if (!name_cetk) return 1; // will not happen name_cetk++; - snprintf(name_cetk, 256 - (name_cetk - path_cetk), "cetk"); + snprintf(name_cetk, sizeof(path_cetk) - (name_cetk - path_cetk), "cetk"); // ticket is loaded and validated here return LoadTicketFile(ticket, path_cetk); } @@ -313,7 +313,7 @@ u32 LoadTicketForTitleId(Ticket** ticket, const u64 title_id) { // path to ticket.db char path_ticketdb[32]; char drv = *path_store; - snprintf(path_ticketdb, 32, "%2.2s/dbs/ticket.db", + snprintf(path_ticketdb, sizeof(path_ticketdb), "%2.2s/dbs/ticket.db", ((drv == 'B') || (drv == '5') || (drv == '4')) ? "4:" : "1:"); // load ticket @@ -335,7 +335,7 @@ u32 GetTmdContentPath(char* path_content, const char* path_tmd) { // content path string char* name_content; - snprintf(path_content, 255, "%s", path_tmd); + snprintf(path_content, 256, "%s", path_tmd); path_content[255] = '\0'; name_content = strrchr(path_content, '/'); if (!name_content) return 1; // will not happen @@ -352,7 +352,7 @@ u32 GetTmdContentPath(char* path_content, const char* path_tmd) { free(tmd); return 1; } - snprintf(name_content, 255 - (name_content - path_content), cdn ? "%08lx" : + snprintf(name_content, 256 - (name_content - path_content), cdn ? "%08lx" : (memcmp(tmd->title_id, dlc_tid_high, sizeof(dlc_tid_high)) == 0) ? "00000000/%08lx.app" : "%08lx.app", getbe32(chunk->id)); free(tmd); @@ -418,7 +418,7 @@ u32 GetTitleIdTmdPath(char* path_tmd, const u64 title_id, bool from_emunand) { if (tid_high & 0x8000) tid_high = 0x00030000 | (tid_high&0xFF); char path_pat[64]; - snprintf(path_pat, 64, "%2.2s/title/%08lX/%08lX/content/*.tmd", + snprintf(path_pat, sizeof(path_pat), "%2.2s/title/%08lX/%08lX/content/*.tmd", drv, tid_high, tid_low); if (fvx_findpath(path_tmd, path_pat, FN_HIGHEST) != FR_OK) @@ -537,7 +537,7 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { // fetch and check NCCH header fvx_lseek(&file, offset); if (GetNcchHeaders(&ncch, NULL, NULL, &file, cryptofix) != 0) { - if (!offset) ShowPrompt(false, "%s\nError: Not a NCCH file", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_NOT_NCCH_FILE); fvx_close(&file); return 1; } @@ -545,7 +545,7 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { // check NCCH size if (!size) size = fvx_size(&file) - offset; if ((fvx_size(&file) < offset) || (size < ncch.size * NCCH_MEDIA_UNIT)) { - if (!offset) ShowPrompt(false, "%s\nError: File is too small", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_FILE_IS_TOO_SMALL); fvx_close(&file); return 1; } @@ -561,15 +561,15 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { if (GetNcchHeaders(&ncch, NULL, &exefs, &file, cryptofix) == 0) { if (cryptofix_always) borkedflags = true; else { - const char* optionstr[3] = { "Attempt fix this time", "Attempt fix always", "Abort verification" }; - u32 user_select = ShowSelectPrompt(3, optionstr, "%s\nError: Bad crypto flags", pathstr); + const char* optionstr[3] = { STR_ATTEMPT_FIX_THIS_TIME, STR_ATTEMPT_FIX_ALWAYS, STR_ABORT_VERIFICATION }; + u32 user_select = ShowSelectPrompt(3, optionstr, "%s\n%s", pathstr, STR_ERROR_BAD_CRYPTO_FLAGS); if ((user_select == 1) || (user_select == 2)) borkedflags = true; if (user_select == 2) cryptofix_always = true; } } } if (!borkedflags) { - if (!offset) ShowPrompt(false, "%s\nError: Bad ExeFS header", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_BAD_EXEFS_HEADER); fvx_close(&file); return 1; } @@ -578,14 +578,14 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { // fetch and check ExtHeader fvx_lseek(&file, offset); if (ncch.size_exthdr && (GetNcchHeaders(&ncch, &exthdr, NULL, &file, cryptofix) != 0)) { - if (!offset) ShowPrompt(false, "%s\nError: Missing ExtHeader", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_MISSING_EXTHEADER); fvx_close(&file); return 1; } // check / setup crypto if (SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) { - if (!offset) ShowPrompt(false, "%s\nError: Crypto not set up", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_CRYPTO_NOT_SET_UP); fvx_close(&file); return 1; } @@ -712,10 +712,10 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { } if (!offset && (ver_exthdr|ver_exefs|ver_romfs)) { // verification summary - ShowPrompt(false, "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", pathstr, - (!ncch.size_exthdr) ? "-" : (ver_exthdr == 0) ? "ok" : "fail", - (!ncch.size_exefs) ? "-" : (ver_exefs == 0) ? "ok" : "fail", - (!ncch.size_romfs) ? "-" : (ver_romfs == 0) ? "ok" : "fail"); + ShowPrompt(false, STR_PATH_NCCH_VERIFICATION_FAILED_INFO, pathstr, + (!ncch.size_exthdr) ? "-" : (ver_exthdr == 0) ? STR_OK : STR_FAIL, + (!ncch.size_exefs) ? "-" : (ver_exefs == 0) ? STR_OK : STR_FAIL, + (!ncch.size_romfs) ? "-" : (ver_romfs == 0) ? STR_OK : STR_FAIL); } fvx_close(&file); @@ -732,7 +732,7 @@ u32 VerifyNcsdFile(const char* path) { // load NCSD header if (LoadNcsdHeader(&ncsd, path) != 0) { - ShowPrompt(false, "%s\nError: Not a NCSD file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_NOT_NCSD_FILE); return 1; } @@ -743,8 +743,8 @@ u32 VerifyNcsdFile(const char* path) { u32 size = partition->size * NCSD_MEDIA_UNIT; if (!size) continue; if (VerifyNcchFile(path, offset, size) != 0) { - ShowPrompt(false, "%s\nContent%lu (%08lX@%08lX):\nVerification failed", - pathstr, i, size, offset, i); + ShowPrompt(false, STR_PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED, + pathstr, i, size, offset); return 1; } } @@ -767,14 +767,14 @@ u32 VerifyCiaFile(const char* path) { if ((LoadCiaStub(cia, path) != 0) || (GetCiaInfo(&info, &(cia->header)) != 0) || (GetTitleKey(titlekey, (Ticket*)&(cia->ticket)) != 0)) { - ShowPrompt(false, "%s\nError: Probably not a CIA file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_PROBABLY_NOT_CIA_FILE); free(cia); return 1; } // verify TMD if (VerifyTmd(&(cia->tmd)) != 0) { - ShowPrompt(false, "%s\nError: TMD probably corrupted", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_TMD_PROBABLY_CORRUPTED); free(cia); return 1; } @@ -788,8 +788,8 @@ u32 VerifyCiaFile(const char* path) { u16 index = getbe16(chunk->index); if (!(cnt_index[index/8] & (1 << (7-(index%8))))) continue; // don't check missing contents if (VerifyTmdContent(path, next_offset, chunk, titlekey) != 0) { - ShowPrompt(false, "%s\nID %08lX (%08llX@%08llX)\nVerification failed", - pathstr, getbe32(chunk->id), getbe64(chunk->size), next_offset, i); + ShowPrompt(false, STR_PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED, + pathstr, getbe32(chunk->id), getbe64(chunk->size), next_offset); free(cia); return 1; } @@ -821,7 +821,7 @@ u32 VerifyTmdFile(const char* path, bool cdn) { TitleMetaData* tmd = (TitleMetaData*) malloc(TMD_SIZE_MAX); TmdContentChunk* content_list = (TmdContentChunk*) (tmd + 1); if ((LoadTmdFile(tmd, path) != 0) || (VerifyTmd(tmd) != 0)) { - ShowPrompt(false, "%s\nError: TMD probably corrupted", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_TMD_PROBABLY_CORRUPTED); free(tmd); return 1; } @@ -834,7 +834,7 @@ u32 VerifyTmdFile(const char* path, bool cdn) { (BuildFakeTicket(ticket, tmd->title_id) == 0) && (FindTitleKey(ticket, tmd->title_id) == 0))) || (GetTitleKey(titlekey, ticket) != 0)) { - ShowPrompt(false, "%s\nError: CDN titlekey not found", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_CDN_TITLEKEY_NOT_FOUND); free(ticket); free(tmd); return 1; @@ -853,12 +853,12 @@ u32 VerifyTmdFile(const char* path, bool cdn) { (cdn) ? "%08lx" : (dlc) ? "00000000/%08lx.app" : "%08lx.app", getbe32(chunk->id)); TruncateString(pathstr, path_content, 32, 8); if (dlc && i && !PathExist(path_content)) { - if (!ignore_missing_dlc && !ShowPrompt(true, "%s\nDLC content is missing\n \nIgnore all and continue?", pathstr)) res = 1; + if (!ignore_missing_dlc && !ShowPrompt(true, "%s\n%s", pathstr, STR_DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE)) res = 1; ignore_missing_dlc = true; continue; } if (VerifyTmdContent(path_content, 0, chunk, titlekey) != 0) { - ShowPrompt(false, "%s\n%s", pathstr, PathExist(path_content) ? "Verification failed" : "Content is missing"); + ShowPrompt(false, "%s\n%s", pathstr, PathExist(path_content) ? STR_VERIFICATION_FAILED : STR_CONTENT_IS_MISSING); res = 1; } } @@ -927,7 +927,7 @@ u32 VerifyFirmFile(const char* path) { void* section = ((u8*) firm_buffer) + sct->offset; if (!(sct->size)) continue; if (sha_cmp(sct->hash, section, sct->size, SHA256_MODE) != 0) { - ShowPrompt(false, "%s\nSection %u hash mismatch", pathstr, i); + ShowPrompt(false, STR_PATH_SECTION_N_HASH_MISMATCH, pathstr, i); free(firm_buffer); return 1; } @@ -935,11 +935,11 @@ u32 VerifyFirmFile(const char* path) { // no arm11 / arm9 entrypoints? if (!header.entry_arm9) { - ShowPrompt(false, "%s\nARM9 entrypoint is missing", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ARM9_ENTRYPOINT_IS_MISSING); free(firm_buffer); return 1; } else if (!header.entry_arm11) { - ShowPrompt(false, "%s\nWarning: ARM11 entrypoint is missing", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_WARNING_ARM11_ENTRYPOINT_IS_MISSING); } free(firm_buffer); @@ -962,7 +962,7 @@ u32 VerifyBossFile(const char* path) { fvx_lseek(&file, 0); if ((fvx_read(&file, &boss, sizeof(BossHeader), &btr) != FR_OK) || (btr != sizeof(BossHeader)) || (ValidateBossHeader(&boss, 0) != 0)) { - ShowPrompt(false, "%s\nError: Not a BOSS file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_NOT_A_BOSS_FILE); fvx_close(&file); return 1; } @@ -1007,7 +1007,7 @@ u32 VerifyBossFile(const char* path) { free(buffer); if (memcmp(hash, boss.hash_payload, 0x20) != 0) { - if (ShowPrompt(true, "%s\nBOSS payload hash mismatch.\n \nTry to fix it?", pathstr)) { + if (ShowPrompt(true, "%s\n%s", pathstr, STR_BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT)) { // fix hash, reencrypt BOSS header if required, write to file memcpy(boss.hash_payload, hash, 0x20); if (encrypted) CryptBoss((void*) &boss, 0, sizeof(BossHeader), &boss); @@ -1317,12 +1317,18 @@ u32 CryptCiaFile(const char* orig, const char* dest, u16 crypto) { // if not inplace: take over CIA metadata if (!inplace && (info.size_meta == CIA_META_SIZE)) { - CiaMeta* meta = (CiaMeta*) (void*) (cia + 1); + CiaMeta* meta = (CiaMeta*) malloc(sizeof(CiaMeta)); + if (!meta) { + free(cia); + return 1; + } if ((fvx_qread(orig, meta, info.offset_meta, CIA_META_SIZE, NULL) != FR_OK) || (fvx_qwrite(dest, meta, info.offset_meta, CIA_META_SIZE, NULL) != FR_OK)) { free(cia); + free(meta); return 1; } + free(meta); } // fix TMD hashes, write CIA stub to destination @@ -1452,12 +1458,12 @@ u32 CryptGameFile(const char* path, bool inplace, bool encrypt) { if (!inplace) { // build output name // build output name - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if ((strncmp(path + 1, ":/title/", 8) != 0) || (GetGoodName(dname, path, false) != 0)) { char* name = strrchr(path, '/'); if (!name) return 1; - snprintf(dest, 256, "%s/%s", OUTPUT_PATH, ++name); + snprintf(dest, sizeof(dest), "%s/%s", OUTPUT_PATH, ++name); } destptr = dest; } @@ -1555,13 +1561,13 @@ u32 CreateSaveData(const char* drv, u64 tid64, const char* name, u32 save_size, u8 sd_keyy[16] __attribute__((aligned(4))); char path_movable[32]; u32 sha256sum[8]; - snprintf(path_movable, 32, "%2.2s/private/movable.sed", drv); + snprintf(path_movable, sizeof(path_movable), "%2.2s/private/movable.sed", drv); if (fvx_qread(path_movable, sd_keyy, 0x110, 0x10, NULL) != FR_OK) return 1; memset(sd_keyy, 0x00, 16); sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE); // build path u32 tid_low = (u32) (tid64 & 0xFFFFFFFF); - snprintf(path_save, 128, "%2.2s/data/%08lx%08lx%08lx%08lx/sysdata/%08lx%s", + snprintf(path_save, sizeof(path_save), "%2.2s/data/%08lx%08lx%08lx%08lx/sysdata/%08lx%s", drv, sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3], tid_low | 0x00020000, name ? "/00000000" : ""); return 0; @@ -1569,7 +1575,7 @@ u32 CreateSaveData(const char* drv, u64 tid64, const char* name, u32 save_size, GetInstallPath(path_save, drv, tid64, NULL, name ? "data/00000001.sav" : "data"); } else { char substr[64]; - snprintf(substr, 64, "data/%s", name); + snprintf(substr, sizeof(substr), "data/%s", name); GetInstallPath(path_save, drv, tid64, NULL, substr); } @@ -1942,9 +1948,9 @@ u32 InstallCiaSystemData(CiaStub* cia, const char* drv) { if (!syscmd) cmd->unknown = 0xFFFFFFFE; // mark this as custom built // generate all the paths - snprintf(path_titledb, 32, "%2.2s/dbs/title.db", + snprintf(path_titledb, sizeof(path_titledb), "%2.2s/dbs/title.db", (*drv == '2') ? "1:" : *drv == '5' ? "4:" : drv); - snprintf(path_ticketdb, 32, "%2.2s/dbs/ticket.db", + snprintf(path_ticketdb, sizeof(path_ticketdb), "%2.2s/dbs/ticket.db", ((*drv == 'A') || (*drv == '2')) ? "1:" : ((*drv == 'B') || (*drv == '5')) ? "4:" : drv); GetInstallPath(path_tmd, drv, tid64, NULL, "content/00000000.tmd"); @@ -2186,11 +2192,11 @@ u32 BuildCiaLegitTicket(Ticket* ticket, u8* title_id, const char* path_cnt, bool // check the tickets' console id, warn if it isn't zero if (copy && getbe32(ticket_tmp->console_id)) { static u32 default_action = 0; - static const char* optionstr[2] = - {"Generic ticket (\"pirate legit\")", "Personalized ticket (legit)"}; + const char* optionstr[2] = + {STR_GENERIC_TICKET_PIRATE_LEGIT, STR_PERSONALIZED_TICKET_LEGIT}; if (!default_action) { default_action = ShowSelectPrompt(2, optionstr, - "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", getbe64(title_id)); + STR_ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION, getbe64(title_id)); ShowProgress(0, 0, path_cnt); } if (!default_action) { @@ -2216,7 +2222,7 @@ u32 BuildCiaLegitTicket(Ticket* ticket, u8* title_id, const char* path_cnt, bool ticket->commonkey_idx = ticket_tmp->commonkey_idx; free(ticket_tmp); } else if (FindTitleKey(ticket, title_id) != 0) { - ShowPrompt(false, "ID %016llX\nTitlekey not found.", getbe64(title_id)); + ShowPrompt(false, STR_ID_N_TITLEKEY_NOT_FOUND, getbe64(title_id)); return 1; } } else { @@ -2273,7 +2279,7 @@ u32 BuildCiaFromTadFile(const char* path_tad, const char* path_dest, bool force_ // check for legit TMD if (force_legit && ((ValidateTmdSignature(tmd) != 0) || VerifyTmd(tmd) != 0)) { - ShowPrompt(false, "ID %016llX\nTMD in TAD is not legit.", getbe64(title_id)); + ShowPrompt(false, STR_ID_N_TMD_IN_TAD_NOT_LEGIT, getbe64(title_id)); free(cia); return 1; } @@ -2357,7 +2363,7 @@ u32 BuildInstallFromTmdFileBuffered(const char* path_tmd, const char* path_dest, // check for legit TMD if (force_legit && ((ValidateTmdSignature(tmd) != 0) || VerifyTmd(tmd) != 0)) { - ShowPrompt(false, "ID %016llX\nTMD is not legit.", getbe64(title_id)); + ShowPrompt(false, STR_ID_N_TMD_NOT_LEGIT, getbe64(title_id)); return 1; } @@ -2412,13 +2418,13 @@ u32 BuildInstallFromTmdFileBuffered(const char* path_tmd, const char* path_dest, (cdn) ? "%08lx" : (dlc && !cdn) ? "00000000/%08lx.app" : "%08lx.app", getbe32(chunk->id)); if (!install && ((ret = InsertCiaContent(path_dest, path_content, 0, (u32) getbe64(chunk->size), chunk, titlekey, force_legit, false, cdn)) != 0)) { - ShowPrompt(false, "ID %016llX.%08lX\n%s", getbe64(title_id), getbe32(chunk->id), - (ret == 2) ? "Content is corrupt" : "Insert content failed"); + ShowPrompt(false, STR_ID_N_DOT_N_STATUS, getbe64(title_id), getbe32(chunk->id), + (ret == 2) ? STR_CONTENT_IS_CORRUPT : STR_INSERT_CONTENT_FAILED); return 1; } if (install && (InstallCiaContent(path_dest, path_content, 0, (u32) getbe64(chunk->size), chunk, title_id, titlekey, false, cdn) != 0)) { - ShowPrompt(false, "ID %016llX.%08lX\nInstall content failed", getbe64(title_id), getbe32(chunk->id)); + ShowPrompt(false, STR_ID_N_DOT_N_STATUS, getbe64(title_id), getbe32(chunk->id), STR_INSTALL_CONTENT_FAILED); return 1; } } @@ -2778,7 +2784,7 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) { u32 ret = 0; // build output name - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if (!((filetype & (GAME_TMD|GAME_CDNTMD|GAME_TWLTMD|GAME_TIE)) || (strncmp(path + 1, ":/title/", 8) == 0)) || @@ -2787,8 +2793,8 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) { if (!title_id) { char* name = strrchr(path, '/'); if (!name) return 1; - snprintf(dest, 256, "%s/%s", OUTPUT_PATH, ++name); - } else snprintf(dest, 256, "%s/%016llX", OUTPUT_PATH, title_id); + snprintf(dest, sizeof(dest), "%s/%s", OUTPUT_PATH, ++name); + } else snprintf(dest, sizeof(dest), "%s/%016llX", OUTPUT_PATH, title_id); } // replace extension char* dot = strrchr(dest, '.'); @@ -2861,7 +2867,7 @@ u32 InstallGameFile(const char* path, bool to_emunand) { if (((GetInstallDbsPath(path_db, drv, "title.db" ) != 0) || !fvx_qsize(path_db)) || ((GetInstallDbsPath(path_db, drv, "import.db") != 0) || !fvx_qsize(path_db)) || ((GetInstallDbsPath(path_db, drv, "ticket.db") != 0) || !fvx_qsize(path_db))) { - ShowPrompt(false, "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?"); + ShowPrompt(false, "%s", STR_INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED); return 1; } @@ -2905,7 +2911,7 @@ u32 InstallCifinishFile(const char* path, bool to_emunand) { // check ticket db char path_ticketdb[32]; if ((GetInstallDbsPath(path_ticketdb, to_emunand ? "4:" : "1:", "ticket.db") != 0) || !fvx_qsize(path_ticketdb)) { - ShowPrompt(false, "Install error:\nThis system is missing the\nticket.db file."); + ShowPrompt(false, "%s", STR_INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB); return 1; } @@ -2938,7 +2944,7 @@ u32 InstallCifinishFile(const char* path, bool to_emunand) { } // check for forbidden title id (the "too large dlc") if ((TITLE_MAX_CONTENTS <= 1024) && (cftitle[i].title_id == 0x0004008C000CBD00)) { - ShowPrompt(false, "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags."); + ShowPrompt(false, "%s", STR_SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS); ShowProgress(0, 0, path); continue; } @@ -2979,7 +2985,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { // check ticket db char path_ticketdb[32]; if ((GetInstallDbsPath(path_ticketdb, to_emunand ? "4:" : "1:", "ticket.db") != 0) || !fvx_qsize(path_ticketdb)) { - ShowPrompt(false, "Install error:\nThis system is missing the\nticket.db file."); + ShowPrompt(false, "%s", STR_INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB); return 1; } @@ -2988,7 +2994,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { if (LoadTicketFile(&ticket, path) != 0) return 1; if (ValidateTicketSignature(ticket) != 0) { - ShowPrompt(false, "%s\nError: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED); free(ticket); return 1; } @@ -2996,7 +3002,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { // check ticket console id u32 cid = getbe32(ticket->console_id); if (cid && (cid != (&ARM9_ITCM->otp)->deviceId)) { - ShowPrompt(false, "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", pathstr, cid); + ShowPrompt(false, STR_PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS, pathstr, cid); free(ticket); return 1; } @@ -3008,7 +3014,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { } // let the user know we're working - ShowString("%s\nInstalling ticket...\n", pathstr); + ShowString("%s\n%s\n", pathstr, STR_INSTALLING_TICKET); // write ticket database // ensure remounting the old mount path @@ -3048,10 +3054,10 @@ u32 DumpTicketForGameFile(const char* path, bool force_legit) { // build output name char dest[256]; - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if (GetGoodName(dname, path, false) != 0) - snprintf(dest, 256, "%s/%016llX", OUTPUT_PATH, tid64); + snprintf(dest, sizeof(dest), "%s/%016llX", OUTPUT_PATH, tid64); // replace extension char* dot = strrchr(dest, '.'); @@ -3075,7 +3081,7 @@ u32 DumpCxiSrlFromTmdFile(const char* path) { char dest[256]; // prepare output name - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if (!CheckWritePermissions(dest)) return 1; @@ -3164,7 +3170,7 @@ u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr) // allocate memory u8* code = (u8*) malloc(code_max_size); if (!code) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -3188,7 +3194,7 @@ u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr) else if (ValidateAgbHeader((AgbHeader*)(void*) code) == 0) ext = ".gba"; } if (extstr) strncpy(extstr, ext, 7); - if (!path_out) snprintf(dest, 256, OUTPUT_PATH "/%016llX%s%s", ncch.programId, (exthdr.flag & 0x1) ? ".dec" : "", ext); + if (!path_out) snprintf(dest, sizeof(dest), OUTPUT_PATH "/%016llX%s%s", ncch.programId, (exthdr.flag & 0x1) ? ".dec" : "", ext); // write output file fvx_unlink(dest); @@ -3217,7 +3223,7 @@ u32 CompressCode(const char* path, const char* path_out) { if (!code_dec || !code_cmp) { if (code_dec != NULL) free(code_dec); if (code_cmp != NULL) free(code_cmp); - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -3290,11 +3296,21 @@ u64 GetGameFileTrimmedSize(const char* path) { trimsize = GetAnyFileTrimmedSize(path); } else if (filetype & GAME_NDS) { TwlHeader hdr; - if (fvx_qread(path, &hdr, 0, sizeof(TwlHeader), NULL) != FR_OK) + if (fvx_qread(path, &hdr, 0, sizeof(TwlHeader), NULL) != FR_OK) { return 0; - if (hdr.unit_code != 0x00) // DSi or NDS+DSi + } if (hdr.unit_code != 0x00) { // DSi or NDS+DSi trimsize = hdr.ntr_twl_rom_size; - else trimsize = hdr.ntr_rom_size + 0x88; // regular NDS + } else if (hdr.ntr_rom_size) { // regular NDS + trimsize = hdr.ntr_rom_size; + + // Check if immediately after the reported cart size + // is the magic number string 'ac' (auth code). + // If found, add 0x88 bytes for the download play RSA key. + u16 rsaMagic; + if(fvx_qread(path, &rsaMagic, trimsize, 2, NULL) == FR_OK && rsaMagic == 0x6361) { + trimsize += 0x88; + } + } } else { u8 hdr[0x200]; if (fvx_qread(path, &hdr, 0, 0x200, NULL) != FR_OK) @@ -3411,7 +3427,7 @@ u32 ShowGbaFileTitleInfo(const char* path, u16* screen) { if ((fvx_qread(path, &agb, 0, sizeof(AgbHeader), NULL) != FR_OK) || (ValidateAgbHeader(&agb) != 0)) return 1; ClearScreen(screen, COLOR_STD_BG); - ShowStringF(screen, "%.12s (AGB-%.4s)\n%s", agb.game_title, agb.game_code, AGB_DESTSTR(agb.game_code)); + ShowStringF(screen, "%.12s (AGB-%.4s)\n%s", agb.game_title, agb.game_code, AgbDestStr(agb.game_code)); return 0; } @@ -3499,7 +3515,7 @@ u32 ShowGameCheckerInfo(const char* path) { // load CIA stub if (LoadCiaStub(cia, path) != 0) { - ShowPrompt(false, "%s\nError: Probably not a CIA file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_PROBABLY_NOT_CIA_FILE); free(cia); free(tmd); return 1; @@ -3556,18 +3572,26 @@ u32 ShowGameCheckerInfo(const char* path) { state_tmd = (ValidateTmdSignature(tmd) == 0) ? 2 : 1; // CIA / title type string - char typestr[32]; + const char *typestr; if ((!state_ticket && (type&(GAME_CIA|GAME_TIE))) || !state_tmd || missing_first || (!is_dlc && (content_found != content_count))) - snprintf(typestr, 32, "Possibly Broken"); - else snprintf(typestr, 32, "%s %s%s", - console_id ? "Personal" : "Universal", - ((state_ticket == 2) && (state_tmd == 2)) ? "Legit" : - (state_tmd == 2) ? "Pirate Legit" : "Custom", - is_dlc ? " DLC" : ""); + typestr = STR_POSSIBLY_BROKEN; + else { + if (console_id) { + if (state_tmd == 2) { + if (state_ticket == 2) typestr = is_dlc ? STR_PERSONAL_LEGIT_DLC : STR_PERSONAL_LEGIT; + else typestr = is_dlc ? STR_PERSONAL_PIRATE_LEGIT_DLC : STR_PERSONAL_PIRATE_LEGIT; + } else typestr = is_dlc ? STR_PERSONAL_CUSTOM_DLC : STR_PERSONAL_CUSTOM; + } else { + if (state_tmd == 2) { + if (state_ticket == 2) typestr = is_dlc ? STR_UNIVERSAL_LEGIT_DLC : STR_UNIVERSAL_LEGIT; + else typestr = is_dlc ? STR_UNIVERSAL_PIRATE_LEGIT_DLC : STR_UNIVERSAL_PIRATE_LEGIT; + } else typestr = is_dlc ? STR_UNIVERSAL_CUSTOM_DLC : STR_UNIVERSAL_CUSTOM; + } + } char srcstr[5]; - snprintf(srcstr, 5, "%s", + snprintf(srcstr, sizeof(srcstr), "%s", (type & GAME_TIE) ? (tmd ? (sd_title ? "SD" : "NAND") : "UNK") : (type & GAME_CIA) ? "CIA" : (type & GAME_TMD) ? "TMD" : @@ -3575,30 +3599,23 @@ u32 ShowGameCheckerInfo(const char* path) { (type & GAME_TWLTMD) ? "TWL" : "UNK"); char contents_str[64]; - if (type & GAME_CIA) snprintf(contents_str, 64, "Contents in CIA: %lu/%lu", content_found, content_count); - else snprintf(contents_str, 64, "Contents in TMD: %lu", content_count); + if (type & GAME_CIA) snprintf(contents_str, sizeof(contents_str), STR_CONTENTS_IN_CIA_FOUND_TOTAL, content_found, content_count); + else snprintf(contents_str, sizeof(contents_str), STR_CONTENTS_IN_CIA_TOTAL, content_count); char conid_str[32] = { '\0' }; - if (type & (GAME_CIA|GAME_TIE)) snprintf(conid_str, 64, "Console ID: %08lX\n", console_id); + if (type & (GAME_CIA|GAME_TIE)) snprintf(conid_str, sizeof(conid_str), STR_CONSOLE_ID_N, console_id); // output results s32 state_verify = -1; while (true) { - if (!ShowPrompt(state_verify < 0, - "%s\n%s %s Title\n \n" - "Title ID: %016llX\n" - "Title version: %u.%u.%u\n" - "Contents size: %s\n" - "%s\n%s \n" - "Ticket/TMD: %s/%s\n" - "Verification: %s", + if (!ShowPrompt(state_verify < 0, STR_SHOW_GAME_INFO_DETAILS, pathstr, typestr, srcstr, title_id, (title_version>>10)&0x3F, (title_version>>4)&0x3F, (title_version)&0xF, bytestr, contents_str, conid_str, - (state_ticket == 0) ? "unknown" : (state_ticket == 2) ? "legit" : "illegit", - (state_tmd == 0) ? "invalid" : (state_tmd == 2) ? "legit" : "illegit", - (state_verify < 0) ? "pending\n \nProceed with verification?" : (state_verify == 0) ? "passed" : "failed") || + (state_ticket == 0) ? STR_STATE_UNKNOWN : (state_ticket == 2) ? STR_STATE_LEGIT : STR_STATE_ILLEGIT, + (state_tmd == 0) ? STR_STATE_INVALID : (state_tmd == 2) ? STR_STATE_LEGIT : STR_STATE_ILLEGIT, + (state_verify < 0) ? STR_STATE_PENDING_PROCEED_WITH_VERIFICATION : (state_verify == 0) ? STR_STATE_PASSED : STR_STATE_FAILED) || (state_verify >= 0)) break; state_verify = VerifyGameFile(path); } @@ -3644,7 +3661,7 @@ u32 BuildNcchInfoXorpads(const char* destdir, const char* path) { if (ret != 0) break; char dest[256]; // 256 is the maximum length of a full path - snprintf(dest, 256, "%s/%s", destdir, entry.filename); + snprintf(dest, sizeof(dest), "%s/%s", destdir, entry.filename); if (fvx_open(&fp_xorpad, dest, FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) { if (!ShowProgress(0, 0, entry.filename)) ret = 1; for (u64 p = 0; (p < entry.size_b) && (ret == 0); p += STD_BUFFER_SIZE) { @@ -3674,7 +3691,7 @@ u32 GetHealthAndSafetyPaths(const char* drv, char* path_cxi, char* path_bak) { u8 secinfo[0x111]; u32 region = 0xFF; UINT br; - snprintf(path_secinfo, 32, "%s/rw/sys/SecureInfo_%c", drv, secchar); + snprintf(path_secinfo, sizeof(path_secinfo), "%s/rw/sys/SecureInfo_%c", drv, secchar); if ((fvx_qread(path_secinfo, secinfo, 0, 0x111, &br) != FR_OK) || (br != 0x111)) continue; @@ -3693,7 +3710,7 @@ u32 GetHealthAndSafetyPaths(const char* drv, char* path_cxi, char* path_bak) { TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1); for (u32 i = 0; i < 8; i++) { // 8 is an arbitrary number char path_tmd[64]; - snprintf(path_tmd, 64, "%s/title/00040010/%08lx/content/%08lx.tmd", drv, tidlow_hs, i); + snprintf(path_tmd, sizeof(path_tmd), "%s/title/00040010/%08lx/content/%08lx.tmd", drv, tidlow_hs, i); if (LoadTmdFile(tmd, path_tmd) != 0) continue; if (!getbe16(tmd->content_count)) break; if (path_cxi) snprintf(path_cxi, 64, "%s/title/00040010/%08lx/content/%08lx.app", drv, tidlow_hs, getbe32(chunk->id)); @@ -3721,7 +3738,7 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) { // legacy stuff - remove mark file char path_mrk[32] = { 0 }; - snprintf(path_mrk, 32, "%s/%s", destdrv, "__gm9_hsbak.pth"); + snprintf(path_mrk, sizeof(path_mrk), "%s/%s", destdrv, "__gm9_hsbak.pth"); f_unlink(path_mrk); // get H&S paths @@ -3803,7 +3820,7 @@ u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump) { memset(tik_info, 0, 16); if ((fvx_stat(path_out, NULL) == FR_OK) && - (ShowPrompt(true, "%s\nOutput file already exists.\nUpdate this?", path_out))) + (ShowPrompt(true, "%s\n%s", path_out, STR_OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS))) path_in = path_out; else return 0; } @@ -3896,7 +3913,7 @@ u32 BuildSeedInfo(const char* path, bool dump) { memset(seed_info, 0, 16); if ((fvx_stat(path_out, NULL) == FR_OK) && - (ShowPrompt(true, "%s\nOutput file already exists.\nUpdate this?", path_out))) { + (ShowPrompt(true, "%s\n%s", path_out, STR_OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS))) { path_in = path_out; inputtype = 1; } else return 0; @@ -4057,7 +4074,7 @@ u32 GetGoodName(char* name, const char* path, bool quick) { if (!quick && (type_donor & (GAME_CIA|GAME_TIE|GAME_TMD|GAME_CDNTMD|GAME_TWLTMD))) { u32 version = GetGameFileTitleVersion(path); if (version < 0x10000) - snprintf(version_str, 16, " (v%lu.%lu.%lu)", + snprintf(version_str, sizeof(version_str), " (v%lu.%lu.%lu)", (version>>10)&0x3F, (version>>4)&0x3F, version&0xF); } @@ -4116,17 +4133,17 @@ u32 GetGoodName(char* name, const char* path, bool quick) { if (twl->unit_code & 0x02) { // TWL char region[8] = { 0 }; - if (twl->region_flags == TWL_REGION_FREE) snprintf(region, 8, "W"); - snprintf(region, 8, "%s%s%s%s%s", + if (twl->region_flags == TWL_REGION_FREE) snprintf(region, sizeof(region), "W"); + snprintf(region, sizeof(region), "%s%s%s%s%s", (twl->region_flags & REGION_MASK_JPN) ? "J" : "", (twl->region_flags & REGION_MASK_USA) ? "U" : "", (twl->region_flags & REGION_MASK_EUR) ? "E" : "", (twl->region_flags & REGION_MASK_CHN) ? "C" : "", (twl->region_flags & REGION_MASK_KOR) ? "K" : ""); - if (strncmp(region, "JUECK", 8) == 0) snprintf(region, 8, "W"); - if (!*region) snprintf(region, 8, "UNK"); + if (strncmp(region, "JUECK", 8) == 0) snprintf(region, sizeof(region), "W"); + if (!*region) snprintf(region, sizeof(region), "UNK"); - char* unit_str = (twl->unit_code == TWL_UNITCODE_TWLNTR) ? "DSi Enhanced" : "DSi Exclusive"; + const char* unit_str = (twl->unit_code == TWL_UNITCODE_TWLNTR) ? STR_DSI_ENHANCED : STR_DSI_EXCLUSIVE; snprintf(name, 128, "%016llX%s %s (TWL-%.4s) (%s) (%s)%s.%s", twl->title_id, appid_str, title_name, twl->game_code, unit_str, region, version_str, ext); } else { // NTR @@ -4142,16 +4159,16 @@ u32 GetGoodName(char* name, const char* path, bool quick) { if (GetSmdhDescShort(title_name, smdh) != 0) return 1; char region[8] = { 0 }; - if (smdh->region_lockout == SMDH_REGION_FREE) snprintf(region, 8, "W"); - else snprintf(region, 8, "%s%s%s%s%s%s", + if (smdh->region_lockout == SMDH_REGION_FREE) snprintf(region, sizeof(region), "W"); + else snprintf(region, sizeof(region), "%s%s%s%s%s%s", (smdh->region_lockout & REGION_MASK_JPN) ? "J" : "", (smdh->region_lockout & REGION_MASK_USA) ? "U" : "", (smdh->region_lockout & REGION_MASK_EUR) ? "E" : "", (smdh->region_lockout & REGION_MASK_CHN) ? "C" : "", (smdh->region_lockout & REGION_MASK_KOR) ? "K" : "", (smdh->region_lockout & REGION_MASK_TWN) ? "T" : ""); - if (strncmp(region, "JUECKT", 8) == 0) snprintf(region, 8, "W"); - if (!*region) snprintf(region, 8, "UNK"); + if (strncmp(region, "JUECKT", 8) == 0) snprintf(region, sizeof(region), "W"); + if (!*region) snprintf(region, sizeof(region), "UNK"); snprintf(name, 128, "%016llX%s %s (%.16s) (%s)%s.%s", ncch->programId, appid_str, title_name, ncch->productcode, region, version_str, ext); diff --git a/arm9/source/utils/keydbutil.c b/arm9/source/utils/keydbutil.c index dbc38ebac..371f2bf32 100644 --- a/arm9/source/utils/keydbutil.c +++ b/arm9/source/utils/keydbutil.c @@ -1,6 +1,7 @@ #include "keydbutil.h" #include "fs.h" #include "ui.h" +#include "language.h" #include "unittype.h" #define MAX_KEYDB_SIZE (STD_BUFFER_SIZE) @@ -84,7 +85,7 @@ u32 BuildKeyDb(const char* path, bool dump) { AddKeyToDb(key_info, NULL); if ((fvx_stat(path_out, NULL) == FR_OK) && - (ShowPrompt(true, "%s\nOutput file already exists.\nUpdate this?", path_out))) + (ShowPrompt(true, "%s\n%s", path_out, STR_OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS))) path_in = path_out; else return 0; } diff --git a/arm9/source/utils/nandcmac.c b/arm9/source/utils/nandcmac.c index 569fdbff1..ab749af11 100644 --- a/arm9/source/utils/nandcmac.c +++ b/arm9/source/utils/nandcmac.c @@ -59,7 +59,7 @@ u32 SetupSlot0x30(char drv) { if ((drv == 'A') || (drv == 'S')) drv = '1'; else if ((drv == 'B') || (drv == 'E')) drv = '4'; - snprintf(movable_path, 32, "%c:/private/movable.sed", drv); + snprintf(movable_path, sizeof(movable_path), "%c:/private/movable.sed", drv); if (fvx_qread(movable_path, keyy, 0x110, 0x10, NULL) != FR_OK) return 1; setup_aeskeyY(0x30, keyy); use_aeskey(0x30); @@ -461,7 +461,7 @@ u32 RecursiveFixFileCmacWorker(char* path) { char* fname = path + strnlen(path, 255); *(fname++) = '/'; - ShowString("%s\nFixing CMACs, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_FIXING_CMACS_PLEASE_WAIT); while (f_readdir(&pdir, &fno) == FR_OK) { if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0)) continue; // filter out virtual entries @@ -472,7 +472,7 @@ u32 RecursiveFixFileCmacWorker(char* path) { if (RecursiveFixFileCmacWorker(path) != 0) err = 1; } else if (CheckCmacPath(path) == 0) { // file, try to fix the CMAC if (FixFileCmac(path, true) != 0) err = 1; - ShowString("%s\nFixing CMACs, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_FIXING_CMACS_PLEASE_WAIT); } } f_closedir(&pdir); diff --git a/arm9/source/utils/nandutil.c b/arm9/source/utils/nandutil.c index 745e4d19d..785ff32bc 100644 --- a/arm9/source/utils/nandutil.c +++ b/arm9/source/utils/nandutil.c @@ -150,7 +150,7 @@ u32 DumpGbaVcSavegameBuffered(const char* path, void* buffer) { // generate output path char path_vcsav[64]; - snprintf(path_vcsav, 64, OUTPUT_PATH "/%016llX.gbavc.sav", agbsave->title_id); + snprintf(path_vcsav, sizeof(path_vcsav), OUTPUT_PATH "/%016llX.gbavc.sav", agbsave->title_id); if (fvx_qwrite(path_vcsav, savegame, 0, agbsave->save_size, NULL) != FR_OK) return 1; // write fail return 0; @@ -159,7 +159,7 @@ u32 DumpGbaVcSavegameBuffered(const char* path, void* buffer) { u32 DumpGbaVcSavegame(const char* path) { u8* buffer = (u8*) malloc(AGBSAVE_MAX_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -177,7 +177,7 @@ u32 InjectGbaVcSavegameBuffered(const char* path, const char* path_vcsave, void* char* ext = strrchr(path_vcsave, '.'); if (!ext || ((strncasecmp(ext+1, "sav", 4) != 0) && (strncasecmp(ext+1, "srm", 4) != 0) && (strncasecmp(ext+1, "SaveRAM", 8) != 0))) return 1; // bad extension - if ((fvx_stat(path_vcsave, &fno) != FR_OK) || !GBASAVE_VALID(fno.fsize)) + if ((fvx_stat(path_vcsave, &fno) != FR_OK) || (!GBASAVE_VALID(fno.fsize) && !GBASAVE_VALID(fno.fsize - 16))) return 1; // bad size // read AGBsave header to memory @@ -207,7 +207,7 @@ u32 InjectGbaVcSavegameBuffered(const char* path, const char* path_vcsave, void* u32 slot = 0; // get the SD save path, check SD save size - snprintf(path_sd, 64, "A:/title/%08lx/%08lx/data/00000001.sav", + snprintf(path_sd, sizeof(path_sd), "A:/title/%08lx/%08lx/data/00000001.sav", getle32((u8*) &(agbsave->title_id) + 4), getle32((u8*) &(agbsave->title_id))); if ((fvx_stat(path_sd, &fno) != FR_OK) || (fno.fsize != max(AGBSAVE_MAX_SIZE, 2 * data_size))) return 1; // invalid / non-existant SD save @@ -234,7 +234,7 @@ u32 InjectGbaVcSavegameBuffered(const char* path, const char* path_vcsave, void* u32 InjectGbaVcSavegame(const char* path, const char* path_vcsave) { u8* buffer = (u8*) malloc(AGBSAVE_MAX_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -328,21 +328,20 @@ u32 ValidateNandDump(const char* path) { // check NAND header NandNcsdHeader ncsd; if ((ReadNandFile(&file, &ncsd, 0, 1, 0xFF) != 0) || (ValidateNandNcsdHeader(&ncsd) != 0)) { - ShowPrompt(false, "%s\nNCSD header is not valid", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NCSD_HEADER_IS_NOT_VALID); fvx_close(&file); return 1; } // check size if (fvx_size(&file) < (GetNandNcsdMinSizeSectors(&ncsd) * 0x200)) { - ShowPrompt(false, "%s\nNAND dump misses data", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NAND_DUMP_MISSING_DATA); fvx_close(&file); return 1; } // check TWL & CTR FAT partitions for (u32 i = 0; i < 2; i++) { - char* section_type = (i) ? "CTR" : "MBR"; if (i == 0) { // check TWL first, then CTR if (GetNandNcsdPartitionInfo(&info, NP_TYPE_STD, NP_SUBTYPE_TWL, 0, &ncsd) != 0) return 1; } else if ((GetNandNcsdPartitionInfo(&info, NP_TYPE_STD, NP_SUBTYPE_CTR, 0, &ncsd) != 0) && @@ -350,7 +349,7 @@ u32 ValidateNandDump(const char* path) { MbrHeader mbr; if ((ReadNandFile(&file, &mbr, info.sector, 1, info.keyslot) != 0) || (ValidateMbrHeader(&mbr) != 0)) { - ShowPrompt(false, "%s\nError: %s MBR is corrupt", pathstr, section_type); + ShowPrompt(false, "%s\n%s", pathstr, i ? STR_ERROR_CTR_MBR_IS_CORRUPT : STR_ERROR_TWL_MBR_IS_CORRUPT); fvx_close(&file); return 1; // impossible to happen } @@ -360,7 +359,7 @@ u32 ValidateNandDump(const char* path) { if (!p_sector) continue; if ((ReadNandFile(&file, fat, info.sector + p_sector, 1, info.keyslot) != 0) || (ValidateFatHeader(fat) != 0)) { - ShowPrompt(false, "%s\nError: %s partition%u is corrupt", pathstr, section_type, p); + ShowPrompt(false, i ? STR_PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT : STR_PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT, pathstr, p); fvx_close(&file); return 1; } @@ -374,7 +373,7 @@ u32 ValidateNandDump(const char* path) { // check all 8 firms, also check if ARM9 & ARM11 entrypoints are available for (u32 f = 0; f <= 8; f++) { if (GetNandNcsdPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, f, &ncsd) != 0) { - ShowPrompt(false, "%s\nNo valid FIRM found", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NO_VALID_FIRM_FOUND); fvx_close(&file); free(firm); return 1; @@ -395,19 +394,19 @@ u32 ValidateNandDump(const char* path) { u32 SafeRestoreNandDump(const char* path) { if ((ValidateNandDump(path) != 0) && // NAND dump validation - !ShowPrompt(true, "Error: NAND dump is corrupt.\nStill continue?")) + !ShowPrompt(true, "%s", STR_ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE)) return 1; if (!IS_UNLOCKED) { - ShowPrompt(false, "Error: System is locked."); + ShowPrompt(false, "%s", STR_ERROR_SYSTEM_IS_LOCKED); return 1; } if (fvx_stat("S:/essential.exefs", NULL) != FR_OK) { - if (ShowPrompt(true, "Essential files backup is required.\nCreate one now?")) + if (ShowPrompt(true, "%s", STR_ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW)) EmbedEssentialBackup("S:/nand.bin"); else return 1; } - if (!ShowUnlockSequence(5, "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)")) + if (!ShowUnlockSequence(5, "%s", STR_WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP)) return 1; if (!SetWritePermissions(PERM_SYS_LVL1, true)) return 1; @@ -447,7 +446,7 @@ u32 SafeRestoreNandDump(const char* path) { break; } if (!header_inject || (ValidateNandNcsdHeader(&ncsd_img) != 0) || (ValidateMbrHeader(&twl_mbr_img) != 0)) { - ShowPrompt(false, "Image NCSD corrupt or customized,\nsafe restore is not possible!"); + ShowPrompt(false, "%s", STR_IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE); fvx_close(&file); return 1; } @@ -455,7 +454,7 @@ u32 SafeRestoreNandDump(const char* path) { // additional warning for elevated write permissions if (header_inject) { - if (!ShowPrompt(true, "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?") || + if (!ShowPrompt(true, "%s", STR_WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED) || !SetWritePermissions(PERM_SYS_LVL3, true)) { fvx_close(&file); return 1; @@ -508,8 +507,8 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) UINT firm_size; if ((fvx_qread(path, firm, 0, bufsiz, &firm_size) != FR_OK) || !firm_size || !IsInstallableFirm(firm, firm_size)) { - ShowPrompt(false, IsBootableFirm(firm, firm_size) ? - "%s\nNot a installable FIRM." : "%s\nFIRM load/verify error.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, IsBootableFirm(firm, firm_size) ? + STR_NOT_AN_INSTALLABLE_FIRM : STR_FIRM_LOAD_VERIFY_ERROR); return 1; } @@ -524,7 +523,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) if (!((slots>>s)&0x1)) continue; if ((GetNandPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, s, NAND_SYSNAND) != 0) || ((info.count * 0x200) < firm_size)) { - ShowPrompt(false, "%s\nFIRM%lu not found or too small.", pathstr, s); + ShowPrompt(false, STR_PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL, pathstr, s); return 1; } } @@ -534,7 +533,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) bool fix_sector0x96 = false; ReadNandSectors(sector0x96, 0x96, 1, 0x11, NAND_SYSNAND); if (!IS_O3DS && !CheckSector0x96Crypto()) { - ShowPrompt(false, "%s\nSector 0x96 crypto fail.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_SECTOR_0X96_CRYPTO_FAIL); return 1; } if (!IS_O3DS && (ValidateSecretSector(sector0x96) != 0)) { @@ -546,21 +545,21 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) else *path_sector = '\0'; if ((fvx_qread(path_sector, sector0x96, 0, 0x200, NULL) != FR_OK) || (ValidateSecretSector(sector0x96) != 0)) { - ShowPrompt(false, "%s\nSector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX); return 1; - } else if (ShowPrompt(true, "%s\nSector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", pathstr)) { + } else if (ShowPrompt(true, "%s\n%s", pathstr, STR_SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION)) { fix_sector0x96 = true; } else return 1; } // all checked, ready to go - if (!ShowUnlockSequence(6, "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!")) return 1; + if (!ShowUnlockSequence(6, "%s", STR_WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK)) return 1; // if (!SetWritePermissions(PERM_SYS_LVL3, true)) return 1; // one unlock sequence is enough // point of no return - ShowString(false, "Installing FIRM, please wait..."); + ShowString("%s", STR_INSTALLING_FIRM_PLEASE_WAIT); if (fix_sector0x96 && (WriteNandSectors(sector0x96, 0x96, 1, 0x11, NAND_SYSNAND) != 0)) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!"); + ShowPrompt(false, "%s", STR_THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT); return 1; } for (u32 s = 0; s < 8; s++) { @@ -568,16 +567,16 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) if (!((slots>>s)&0x1)) continue; if ((GetNandPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, s, NAND_SYSNAND) != 0) || (WriteNandBytes(firm, info.sector*0x200, firm_size, info.keyslot, NAND_SYSNAND) != 0)) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", s); + ShowPrompt(false, STR_THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT, s); return 1; } } // done, now check the installation - ShowString(false, "Checking installation, please wait..."); + ShowString("%s", STR_CHECKING_INSTALLATION_PLEASE_WAIT); if (fix_sector0x96 && ((ReadNandSectors(sector0x96, 0x96, 1, 0x11, NAND_SYSNAND) != 0) || (ValidateSecretSector(sector0x96) != 0))) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!"); + ShowPrompt(false, "%s", STR_THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT); return 1; } for (u32 s = 0; s < 8; s++) { @@ -586,7 +585,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) if ((GetNandPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, s, NAND_SYSNAND) != 0) || (ReadNandBytes(firm, info.sector*0x200, firm_size, info.keyslot, NAND_SYSNAND) != 0) || (sha_cmp(firm_sha, firm, firm_size, SHA256_MODE) != 0)) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", s); + ShowPrompt(false, STR_THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT, s); return 1; } } @@ -597,7 +596,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) u32 SafeInstallFirm(const char* path, u32 slots) { u8* buffer = (u8*) malloc(FIRM_MAX_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -616,20 +615,20 @@ u32 SafeInstallKeyDb(const char* path) { // already installed? if ((ReadNandBytes(keydb, SECTOR_KEYDB*0x200, KEYDB_PERFECT_SIZE, 0xFF, NAND_SYSNAND) == 0) && (sha_cmp(perfect_sha, keydb, KEYDB_PERFECT_SIZE, SHA256_MODE) == 0)) { - ShowPrompt(false, "Perfect " KEYDB_NAME " is already installed!"); + ShowPrompt(false, STR_PERFECT_KEYDB_IS_ALREADY_INSTALLED, KEYDB_NAME); return 1; } // check input path... if ((fvx_qread(path, keydb, 0, KEYDB_PERFECT_SIZE, NULL) != FR_OK) || (sha_cmp(perfect_sha, keydb, KEYDB_PERFECT_SIZE, SHA256_MODE) != 0)) { - ShowPrompt(false, "%s\nNot a perfect " KEYDB_NAME " image.\nCannot install to NAND!", pathstr); + ShowPrompt(false, STR_PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND, pathstr, KEYDB_NAME); return 1; } // point of no return, install key database if (WriteNandBytes(keydb, SECTOR_KEYDB*0x200, KEYDB_PERFECT_SIZE, 0xFF, NAND_SYSNAND) != 0) { - ShowPrompt(false, "%s\nFailed writing " KEYDB_NAME " to NAND!", pathstr); + ShowPrompt(false, STR_PATH_FAILED_WRITING_KEYDB_TO_NAND, pathstr, KEYDB_NAME); return 1; } diff --git a/arm9/source/utils/paint9.c b/arm9/source/utils/paint9.c index 7bedd0cf8..213adf0e9 100644 --- a/arm9/source/utils/paint9.c +++ b/arm9/source/utils/paint9.c @@ -3,6 +3,7 @@ #include "png.h" #include "hid.h" #include "ui.h" +#include "language.h" #define PAINT9_BRUSH_SIZE 15 // don't change! @@ -103,7 +104,7 @@ u32 Paint9(void) { u32 brush_id = 0; // clear screens, draw logo - const char* snapstr = "(use L+R to save)"; + const char* snapstr = STR_USE_L_R_TO_SAVE; u64 logo_size; u8* logo = FindVTarFileInfo(VRAM0_EASTER_BIN, &logo_size); ClearScreenF(true, true, COLOR_STD_BG); @@ -114,9 +115,9 @@ u32 Paint9(void) { DrawBitmap(TOP_SCREEN, -1, -1, logo_width, logo_height, bitmap); free(bitmap); } - } else DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, "(" VRAM0_EASTER_BIN " not found)"); + } else DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, STR_EASTER_NOT_FOUND, VRAM0_EASTER_BIN); DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(snapstr), - SCREEN_HEIGHT - 10 - GetDrawStringHeight(snapstr), COLOR_STD_FONT, COLOR_TRANSPARENT, snapstr); + SCREEN_HEIGHT - 10 - GetDrawStringHeight(snapstr), COLOR_STD_FONT, COLOR_TRANSPARENT, "%s", snapstr); // outline canvas DrawRectangle(BOT_SCREEN, 0, 0, 30, SCREEN_HEIGHT, outline_bg); diff --git a/arm9/source/utils/scripting.c b/arm9/source/utils/scripting.c index 1f6b0e9a8..f7c175859 100644 --- a/arm9/source/utils/scripting.c +++ b/arm9/source/utils/scripting.c @@ -127,7 +127,7 @@ typedef enum { CMD_ID_NEXTEMU, CMD_ID_REBOOT, CMD_ID_POWEROFF, - CMD_ID_BKPT + CMD_ID_BKPT, } cmd_id; typedef struct { @@ -422,7 +422,7 @@ void upd_var(const char* name) { if (FileGetData(path, sd_keyy, 0x10, 0x110) == 0x10) { u32 sha256sum[8]; sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE); - snprintf(env_id0, 32+1, "%08lx%08lx%08lx%08lx", + snprintf(env_id0, sizeof(env_id0), "%08lx%08lx%08lx%08lx", sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); } else snprintf(env_id0, 0xF, "UNKNOWN"); set_var(env_id0_name, env_id0); @@ -435,8 +435,8 @@ void upd_var(const char* name) { get_dstime(&dstime); char env_date[16+1]; char env_time[16+1]; - snprintf(env_date, 16, "%02lX%02lX%02lX", (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D); - snprintf(env_time, 16, "%02lX%02lX%02lX", (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); + snprintf(env_date, sizeof(env_date), "%02lX%02lX%02lX", (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D); + snprintf(env_time, sizeof(env_time), "%02lX%02lX%02lX", (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); if (!name || (strncmp(name, "DATESTAMP", _VAR_NAME_LEN) == 0)) set_var("DATESTAMP", env_date); if (!name || (strncmp(name, "TIMESTAMP", _VAR_NAME_LEN) == 0)) set_var("TIMESTAMP", env_time); } @@ -445,7 +445,7 @@ void upd_var(const char* name) { if (!name || (strncmp(name, "EMUBASE", _VAR_NAME_LEN) == 0)) { u32 emu_base = GetEmuNandBase(); char emu_base_str[8+1]; - snprintf(emu_base_str, 8+1, "%08lX", emu_base); + snprintf(emu_base_str, sizeof(emu_base_str), "%08lX", emu_base); set_var("EMUBASE", emu_base_str); } @@ -527,7 +527,6 @@ bool init_vars(const char* path_script) { set_var("RDTYPE", IS_DEVKIT ? "devkit" : "retail"); // devkit / retail char* ptr = set_var("GM9VER", VERSION); // GodMode9 version, truncated below while (*(ptr++) != '\0') if (*ptr == '-') *ptr = '\0'; - upd_var(NULL); // set all dynamic environment vars return true; } @@ -572,11 +571,11 @@ cmd_id get_cmd_id(char* cmd, u32 len, u32 flags, u32 argc, char* err_str) { } if (!cmd_entry) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unknown cmd"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNKNOWN_CMD); } else if (cmd_entry->n_args != argc) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "bad # of args"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BAD_NUMBER_OF_ARGS); } else if (~(cmd_entry->allowed_flags|_FLG('o')|_FLG('s')) & flags) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unrecognized flags"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNRECOGNIZED_FLAGS); } else return cmd_entry->id; return CMD_ID_NONE; @@ -609,7 +608,7 @@ u32 get_flag(char* str, u32 len, char* err_str) { else if (strncmp(str, "--explorer", len) == 0) flag_char = 'x'; if (((flag_char < 'a') || (flag_char > 'z')) && ((flag_char < '0') || (flag_char > '5'))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "illegal flag"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ILLEGAL_FLAG); return 0; } @@ -629,7 +628,7 @@ char* get_string(char* ptr, const char* line_end, u32* len, char** next, char* e str = ++ptr; for (; ((*ptr != '\"') || (*(ptr-1) == '\\')) && (ptr < line_end); ptr++, (*len)++); if (ptr >= line_end) { // failed if unresolved quotes - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unresolved quotes"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNRESOLVED_QUOTES); return NULL; } *next = ptr + 1; @@ -651,29 +650,29 @@ char* skip_block(char* ptr, bool ignore_else, bool stop_after_end) { // grab first string char* str = NULL; - u32 str_len = 0; - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL)) || (str >= line_end)) { + u32 STR_SCRIPTERR_len = 0; + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL)) || (str >= line_end)) { // string error or empty line ptr = line_end + 1; continue; } // check string - if (MATCH_STR(str, str_len, _CMD_END)) { // stop at end + if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_END)) { // stop at end return line_start; // end of block found - } else if (!ignore_else && MATCH_STR(str, str_len, _CMD_ELSE)) { // stop at else + } else if (!ignore_else && MATCH_STR(str, STR_SCRIPTERR_len, _CMD_ELSE)) { // stop at else return line_start; // end of block found - } else if (!ignore_else && MATCH_STR(str, str_len, _CMD_ELIF)) { // stop at elif + } else if (!ignore_else && MATCH_STR(str, STR_SCRIPTERR_len, _CMD_ELIF)) { // stop at elif return line_start; // end of block found - } else if (MATCH_STR(str, str_len, _CMD_IF)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_IF)) { ptr = line_start = skip_block(line_end + 1, true, false); if (ptr == NULL) return NULL; line_end = strchr(ptr, '\n'); if (!line_end) line_end = ptr + strlen(ptr); - str = get_string(ptr, line_end, &str_len, &ptr, NULL); - if (!(MATCH_STR(str, str_len, _CMD_END))) return NULL; + str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL); + if (!(MATCH_STR(str, STR_SCRIPTERR_len, _CMD_END))) return NULL; if (stop_after_end) return line_end + 1; } @@ -694,19 +693,19 @@ char* find_next(char* ptr) { // grab first string char* str = NULL; - u32 str_len = 0; - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL)) || (str >= line_end)) { + u32 STR_SCRIPTERR_len = 0; + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL)) || (str >= line_end)) { // string error or empty line ptr = line_end + 1; continue; } // check string - if (MATCH_STR(str, str_len, _CMD_IF)) { // skip 'if' blocks + if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_IF)) { // skip 'if' blocks ptr = skip_block(ptr, true, true); - } else if (MATCH_STR(str, str_len, _CMD_END) || MATCH_STR(str, str_len, _CMD_FOR)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_END) || MATCH_STR(str, STR_SCRIPTERR_len, _CMD_FOR)) { ptr = NULL; // this should not happen here - } else if (MATCH_STR(str, str_len, _CMD_NEXT)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_NEXT)) { return line_start; } @@ -739,28 +738,28 @@ char* find_label(const char* label, const char* last_found) { // search for label char* str = NULL; - u32 str_len = 0; - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL))) continue; // string error, ignore line + u32 STR_SCRIPTERR_len = 0; + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL))) continue; // string error, ignore line else if (str >= line_end) continue; // empty line if (*str == '@') { // label found - str++; str_len--; + str++; STR_SCRIPTERR_len--; // compare it manually (also check for '*' at end) u32 pdiff = 0; - for (; (pdiff < str_len) && (label[pdiff] == str[pdiff]); pdiff++); + for (; (pdiff < STR_SCRIPTERR_len) && (label[pdiff] == str[pdiff]); pdiff++); if ((pdiff < label_len) && (label[pdiff] != '*')) continue; // no match // otherwise: potential regular or wildcard match // may be a match, see if there are more strings after it - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL))) continue; // string error, ignore line + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL))) continue; // string error, ignore line else if ((str < line_end) && (*str != '#')) continue; // neither end of line nor comment return line_start; // match found - } else if (MATCH_STR(str, str_len, _CMD_IF)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_IF)) { next = skip_block(line_start, true, true); - } else if (MATCH_STR(str, str_len, _CMD_FOR)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_FOR)) { next = find_next(line_start); } // otherwise: irrelevant line } @@ -782,8 +781,8 @@ bool for_handler(char* path, const char* dir, const char* pattern, bool recursiv } if (dir) { // open a dir - snprintf(lpattern, 64, "%s", pattern); - snprintf(ldir, 256, "%s", dir); + snprintf(lpattern, sizeof(lpattern), "%s", pattern); + snprintf(ldir, sizeof(ldir), "%s", dir); if (dp) return false; // <- this should never happen if (fvx_opendir(&fdir[0], dir) != FR_OK) return false; @@ -848,10 +847,10 @@ bool parse_line(const char* line_start, const char* line_end, cmd_id* cmdid, u32 if (!flag_add) return false; // not a proper flag *flags |= flag_add; } else if (*argc >= _MAX_ARGS) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "too many arguments"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_TOO_MANY_ARGUMENTS); return false; // too many arguments } else if (!expand_arg(argv[(*argc)++], str, len)) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "argument expand failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARGUMENT_EXPAND_FAILED); return false; // arg expand failed } } @@ -882,7 +881,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { // check the argument // "not true" or "not false" ret = (strncmp(argv[0], _ARG_FALSE, _ARG_MAX_LEN) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'not' an error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_QUOTE_NOT_AN_ERROR); } else if (id == CMD_ID_IF) { // check the argument @@ -891,13 +890,13 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { ifcnt++; if (syntax_error && err_str) - snprintf(err_str, _ERR_STR_LEN, "syntax error after 'if'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SYNTAX_ERROR_AFTER_IF); ret = !syntax_error; } else if (id == CMD_ID_ELIF) { // check syntax errors if (ifcnt == 0) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'elif' without 'if'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ELIF_WITHOUT_IF); syntax_error = true; return false; } @@ -908,13 +907,13 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { ((strncmp(argv[0], _ARG_TRUE, _ARG_MAX_LEN) == 0) ? 0 : _SKIP_BLOCK); if (syntax_error && err_str) - snprintf(err_str, _ERR_STR_LEN, "syntax error after 'elif'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF); ret = !syntax_error; } else if (id == CMD_ID_ELSE) { // check syntax errors if (ifcnt == 0) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'else' without 'if'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ELSE_WITHOUT_IF); syntax_error = true; return false; } @@ -927,7 +926,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { else if (id == CMD_ID_END) { // check syntax errors if (ifcnt == 0){ - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'end' without 'if'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_END_WITHOUT_IF); syntax_error = true; return false; } @@ -942,11 +941,11 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { // cheating alert(!): actually this does nothing much // just sets up the for_handler and skips to 'next' if (for_ptr) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'for' inside 'for'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FOR_INSIDE_FOR); syntax_error = true; return false; } else if (!for_handler(NULL, argv[0], argv[1], flags & _FLG('r'))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "dir not found"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DIR_NOT_FOUND); skip_state = _SKIP_TO_NEXT; ret = false; } else { @@ -959,11 +958,11 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { char* var = set_var(_VAR_FORPATH, ""); ret = true; if (!for_ptr) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'next' without 'for'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NEXT_WITHOUT_FOR); syntax_error = true; return false; } else if (!var) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "forpath error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FORPATH_ERROR); ret = false; } else { if (!for_handler(var, NULL, NULL, false)) *var = '\0'; @@ -981,7 +980,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { jump_ptr = find_label(argv[0], NULL); if (!jump_ptr) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "label not found"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_LABEL_NOT_FOUND); } } else if (id == CMD_ID_LABELSEL) { @@ -1022,12 +1021,12 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (!result) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); } else jump_ptr = options_jmp[result-1]; } else if (id == CMD_ID_KEYCHK) { ret = CheckButton(StringToButton(argv[0])); - if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "key not pressed"); + if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_KEY_NOT_PRESSED); } else if (id == CMD_ID_ECHO) { ShowPrompt(false, "%s", argv[0]); @@ -1044,12 +1043,12 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { DrawQrCode(ALT_SCREEN, qrcode); ShowPrompt(false, "%s", argv[0]); memcpy(ALT_SCREEN, screen_copy, screen_size); - } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "out of memory"); + } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_OUT_OF_MEMORY); free(screen_copy); } else if (id == CMD_ID_ASK) { ret = ShowPrompt(true, "%s", argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); } else if (id == CMD_ID_INPUT) { char input[_VAR_CNT_LEN] = { 0 }; @@ -1058,10 +1057,10 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { input[_VAR_CNT_LEN - 1] = '\0'; ret = ShowKeyboardOrPrompt(input, _VAR_CNT_LEN, "%s", argv[0]); if (ret) set_var(argv[1], ""); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); if (ret) { ret = set_var(argv[1], input); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if ((id == CMD_ID_FILESEL) || (id == CMD_ID_DIRSEL)) { @@ -1075,31 +1074,31 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { path[_VAR_CNT_LEN - 1] = '\0'; if (strncmp(path, "Z:", 2) == 0) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "forbidden drive"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FORBIDDEN_DRIVE); } else if (id == CMD_ID_FILESEL) { char* npattern = strrchr(path, '/'); if (!npattern) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid path"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INVALID_PATH); } else { u32 flags_ext = (flags & _FLG('d')) ? 0 : NO_DIRS; *(npattern++) = '\0'; ret = FileSelector(choice, argv[0], path, npattern, flags_ext, (flags & _FLG('x'))); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fileselect abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILESELECT_ABORT); } } else { ret = FileSelector(choice, argv[0], path, NULL, NO_FILES | SELECT_DIRS, (flags & _FLG('x'))); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "dirselect abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DIRSELECT_ABORT); } if (ret) { ret = set_var(argv[2], choice); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_SET) { ret = set_var(argv[0], argv[1]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "set fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SET_FAIL); } else if (id == CMD_ID_STRSPLIT) { char str[_ARG_MAX_LEN]; @@ -1111,16 +1110,16 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { char* found; if (flags & _FLG('f')) found = strchr(str, *argv[2]); else found = strrchr(str, *argv[2]); - if (!found && err_str) snprintf(err_str, _ERR_STR_LEN, "char not found"); + if (!found && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CHAR_NOT_FOUND); if (found) { if (flags & _FLG('b')) { *found = '\0'; ret = set_var(argv[0], str); } else ret = set_var(argv[0], found+1); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } - } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "argv[2] is not a char"); + } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARGV_2_IS_NOT_CHAR); } else if (id == CMD_ID_STRREP) { char str[_ARG_MAX_LEN]; @@ -1128,29 +1127,29 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { str[_ARG_MAX_LEN - 1] = '\0'; if (strnlen(argv[2], _ARG_MAX_LEN) != 2) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "argv[2] must be 2 chars"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARGV_2_MUST_BE_2_CHARS); ret = false; } else { for (u32 i = 0; (i < _ARG_MAX_LEN) && str[i]; i++) { if (str[i] == argv[2][0]) str[i] = argv[2][1]; } ret = set_var(argv[0], str); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_CHK) { if (flags & _FLG('u')) { ret = (strncasecmp(argv[0], argv[1], _VAR_CNT_LEN) != 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "arg match"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARG_MATCH); } else { ret = (strncasecmp(argv[0], argv[1], _VAR_CNT_LEN) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "no arg match"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NO_ARG_MATCH); } } else if (id == CMD_ID_ALLOW) { if (flags & _FLG('a')) ret = CheckDirWritePermissions(argv[0]); else ret = CheckWritePermissions(argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "permission fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_PERMISSION_FAIL); } else if (id == CMD_ID_CP) { u32 flags_ext = BUILD_PATH; @@ -1162,7 +1161,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { else if (flags & _FLG('k')) flags_ext |= SKIP_ALL; else if (flags & _FLG('p')) flags_ext |= APPEND_ALL; ret = PathMoveCopy(argv[1], argv[0], &flags_ext, false); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "copy fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_COPY_FAIL); } else if (id == CMD_ID_MV) { u32 flags_ext = BUILD_PATH; @@ -1171,7 +1170,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (flags & _FLG('w')) flags_ext |= OVERWRITE_ALL; else if (flags & _FLG('k')) flags_ext |= SKIP_ALL; ret = PathMoveCopy(argv[1], argv[0], &flags_ext, true); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "move fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_MOVE_FAIL); } else if (id == CMD_ID_INJECT) { char* atstr_dst = strrchr(argv[1], '@'); @@ -1183,7 +1182,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u32 flags_ext = ALLOW_EXPAND; if (flags & _FLG('n')) flags_ext |= NO_CANCEL; ret = FileInjectFile(argv[1], argv[0], at_dst, at_org, sz_org, &flags_ext); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "inject fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INJECT_FAIL); } else if (id == CMD_ID_FILL) { u32 flags_ext = ALLOW_EXPAND; @@ -1191,21 +1190,21 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u8 fillbyte = 0; if ((strnlen(argv[1], _ARG_MAX_LEN) != 2) || !strntohex(argv[1], &fillbyte, 1)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fillbyte fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILLBYTE_FAIL); } else { if (flags & _FLG('n')) flags_ext |= NO_CANCEL; ret = FileSetByte(argv[0], at_org, sz_org, fillbyte, &flags_ext); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fill fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILL_FAIL); } } else if (id == CMD_ID_FDUMMY) { u32 fsize; if (sscanf(argv[1], "%lX", &fsize) != 1) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "bad filesize"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BAD_FILESIZE); } else { ret = FileCreateDummy(argv[0], NULL, fsize); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "create dummy fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CREATE_DUMMY_FILE); } } else if (id == CMD_ID_RM) { @@ -1213,15 +1212,15 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { TruncateString(pathstr, argv[0], 24, 8); ShowString("Deleting %s...", pathstr); ret = PathDelete(argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "remove fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_REMOVE_FAIL); } else if (id == CMD_ID_MKDIR) { ret = (CheckWritePermissions(argv[0])) && (fvx_rmkdir(argv[0]) == FR_OK); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "makedir fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_MAKEDIR_FAIL); } else if (id == CMD_ID_MOUNT) { ret = InitImgFS(argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "mount fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_MOUNT_FAIL); } else if (id == CMD_ID_UMOUNT) { InitImgFS(NULL); @@ -1230,37 +1229,37 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { char path[_VAR_CNT_LEN]; u8 mode = (flags & _FLG('f')) ? FN_LOWEST : FN_HIGHEST; ret = (fvx_findpath(path, argv[0], mode) == FR_OK); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "find fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FIND_FAIL); if (ret) { ret = set_var(argv[1], path); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_FINDNOT) { char path[_VAR_CNT_LEN]; ret = (fvx_findnopath(path, argv[0]) == FR_OK); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "findnot fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FINDNOT_FAIL); if (ret) { ret = set_var(argv[1], path); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_FGET) { u8 data[(_VAR_CNT_LEN-1)/2]; if (sz_org == 0) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "no size given"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NO_SIZE_GIVEN); } else if (sz_org > (_VAR_CNT_LEN-1)/2) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "size too big"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_FIRM_TOO_BIG); } else if (FileGetData(argv[0], data, sz_org, at_org) != sz_org) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "read fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_READ_FAIL); } else { char* var = set_var(argv[1], ""); if (!var) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } else { if (flags & _FLG('e')) { // flip data for (u32 i = 0; i < (sz_org >> 1); i++) { @@ -1270,7 +1269,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } } ret = hexntostr(data, var, sz_org); - if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "conversion fail"); + if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CONVERSION_FAIL); } } } @@ -1287,13 +1286,13 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } if (!len) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid data"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INVALID_DATA); } else if (sz_org > len) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "size too big"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SIZE_TOO_BIG); } else if (!FileSetData(argv[0], data, sz_org, at_org, false)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "write fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_WRITE_FAIL); } } else if (id == CMD_ID_SHA) { @@ -1302,32 +1301,32 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u8 hash_cmp[0x20]; if (!FileGetSha(argv[0], hash_fil, at_org, sz_org, flags & _FLG('1'))) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg0 fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_ARG0_FAIL); } else if ((FileGetData(argv[1], hash_cmp, hashlen, 0) != hashlen) && !strntohex(argv[1], hash_cmp, hashlen)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg1 fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_ARG1_FAIL); } else { ret = (memcmp(hash_fil, hash_cmp, hashlen) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha does not match"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_DOES_NOT_MATCH); } } else if (id == CMD_ID_SHAGET) { const u8 hashlen = (flags & _FLG('1')) ? 20 : 32; u8 hash_fil[0x20]; if (!(ret = FileGetSha(argv[0], hash_fil, at_org, sz_org, flags & _FLG('1')))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg0 fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_ARG0_FAIL); } else if (!strchr(argv[1], ':')) { char hash_str[64+1]; if (flags & _FLG('1')) - snprintf(hash_str, 64+1, "%016llX%016llX%08lX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%016llX%08lX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), getbe32(hash_fil + 16)); else - snprintf(hash_str, 64+1, "%016llX%016llX%016llX%016llX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%016llX%016llX%016llX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), getbe64(hash_fil + 16), getbe64(hash_fil + 24)); ret = set_var(argv[1], hash_str); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } else if (!(ret = FileSetData(argv[1], hash_fil, hashlen, 0, true))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha write fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_WRITE_FAIL); } } else if (id == CMD_ID_DUMPTXT) { @@ -1336,65 +1335,65 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (flags & _FLG('p')) offset = FileGetSize(argv[0]); if (!(ret = FileSetData(argv[0], argv[1], len, offset, offset == 0)) || !(ret = FileSetData(argv[0], "\n", 1, offset + len, false))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "file write fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_WRITE_FAIL); } } else if (id == CMD_ID_FIXCMAC) { - ShowString("Fixing CMACs..."); + ShowString("%s", STR_FIXING_CMACS_PLEASE_WAIT); ret = (RecursiveFixFileCmac(argv[0]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fixcmac failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FIXCMAC_FAILED); } else if (id == CMD_ID_VERIFY) { u64 filetype = IdentifyFileType(argv[0]); if (filetype & IMG_NAND) ret = (ValidateNandDump(argv[0]) == 0); else ret = (VerifyGameFile(argv[0]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "verification failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_VERIFICATION_FAILED); } else if (id == CMD_ID_DECRYPT) { u64 filetype = IdentifyFileType(argv[0]); if (filetype & BIN_KEYDB) ret = (CryptAesKeyDb(argv[0], true, false) == 0); else ret = (CryptGameFile(argv[0], true, false) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "decrypt failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DECRYPT_FAILED); } else if (id == CMD_ID_ENCRYPT) { u64 filetype = IdentifyFileType(argv[0]); if (filetype & BIN_KEYDB) ret = (CryptAesKeyDb(argv[0], true, true) == 0); else ret = (CryptGameFile(argv[0], true, true) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "encrypt failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ENCRYPT_FAILED); } else if (id == CMD_ID_BUILDCIA) { ret = (BuildCiaFromGameFile(argv[0], (flags & _FLG('l'))) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "build CIA failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BUILD_CIA_FAILED); } else if (id == CMD_ID_INSTALL) { ret = (InstallGameFile(argv[0], (flags & _FLG('e'))) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "install game failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INSTALL_GAME_FAILED); } else if (id == CMD_ID_EXTRCODE) { u64 filetype = IdentifyFileType(argv[0]); if (!FTYPE_HASCODE(filetype)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "does not contain .code"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE); } else { - ShowString("Extracting .code, please wait..."); + ShowString("%s", STR_EXTRACTING_DOT_CODE); ret = (ExtractCodeFromCxiFile(argv[0], argv[1], NULL) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "extract .code failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_EXTRACT_DOT_CODE_FAILED); } } else if (id == CMD_ID_CMPRCODE) { - ShowString("Compressing .code, please wait..."); + ShowString("%s", STR_COMPRESSING_DOT_CODE); ret = (CompressCode(argv[0], argv[1]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "compress .code failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_COMPRESS_DOT_CODE_FAILED); } else if (id == CMD_ID_SDUMP) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "build failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BUILD_FAILED); if ((strncasecmp(argv[0], TIKDB_NAME_ENC, _ARG_MAX_LEN) == 0) || (strncasecmp(argv[0], TIKDB_NAME_DEC, _ARG_MAX_LEN) == 0)) { bool tik_dec = (strncasecmp(argv[0], TIKDB_NAME_DEC, _ARG_MAX_LEN) == 0); if (flags & _FLG('w')) fvx_unlink(tik_dec ? OUTPUT_PATH "/" TIKDB_NAME_DEC : OUTPUT_PATH "/" TIKDB_NAME_ENC); if (BuildTitleKeyInfo(NULL, tik_dec, false) == 0) { - ShowString("Building to " OUTPUT_PATH ":\n%s ...", argv[0]); + ShowString(STR_BUILDING_TO_OUT_ARG, OUTPUT_PATH, argv[0]); if (((BuildTitleKeyInfo("1:/dbs/ticket.db", tik_dec, false) == 0) || (BuildTitleKeyInfo("4:/dbs/ticket.db", tik_dec, false) == 0)) && (BuildTitleKeyInfo(NULL, tik_dec, true) == 0)) @@ -1403,31 +1402,31 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } else if (strncasecmp(argv[0], SEEDINFO_NAME, _ARG_MAX_LEN) == 0) { if (flags & _FLG('w')) fvx_unlink(OUTPUT_PATH "/" SEEDINFO_NAME); if (BuildSeedInfo(NULL, false) == 0) { - ShowString("Building to " OUTPUT_PATH ":\n%s ...", argv[0]); + ShowString(STR_BUILDING_TO_OUT_ARG, OUTPUT_PATH, argv[0]); if (((BuildSeedInfo("1:", false) == 0) || (BuildSeedInfo("4:", false) == 0)) && (BuildSeedInfo(NULL, true) == 0)) ret = true; } } else { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unknown file"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNKNOWN_FILE); } } else if (id == CMD_ID_APPLYIPS) { ret = (ApplyIPSPatch(argv[0], argv[1], argv[2]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "apply IPS failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_APPLY_IPS_FAILD); } else if (id == CMD_ID_APPLYBPS) { ret = (ApplyBPSPatch(argv[0], argv[1], argv[2]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "apply BPS failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_APPLY_BPS_FAILED); } else if (id == CMD_ID_APPLYBPM) { ret = (ApplyBPMPatch(argv[0], argv[1], argv[2]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "apply BPM failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_APPLY_BPM_FAILED); } else if (id == CMD_ID_TEXTVIEW) { ret = FileTextViewer(argv[0], false); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "textviewer failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_TEXTVIEWER_FAILED); } else if (id == CMD_ID_CARTDUMP) { CartData* cdata = (CartData*) malloc(sizeof(CartData)); @@ -1435,16 +1434,16 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u64 fsize; ret = false; if (!cdata || !buf) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "out of memory"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_OUT_OF_MEMORY); } else if (sscanf(argv[1], "%llX", &fsize) != 1) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "bad dumpsize"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BAD_DUMPSIZE); } else if (InitCartRead(cdata) != 0){ - if (err_str) snprintf(err_str, _ERR_STR_LEN, "cart init fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CART_INIT_FAIL); } else { SetSecureAreaEncryption(flags & _FLG('e')); fvx_unlink(argv[0]); ret = true; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "cart dump failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CART_DUMP_FAILED); for (u64 p = 0; p < fsize; p += STD_BUFFER_SIZE) { u64 len = min((fsize - p), STD_BUFFER_SIZE); ShowProgress(p, fsize, argv[0]); @@ -1465,7 +1464,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { fvx_closedir(&fdir); ret = true; } else { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "not a dir"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NOT_A_DIR); ret = false; } } @@ -1473,7 +1472,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (fvx_stat(argv[0], NULL) == FR_OK) { ret = true; } else { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "file not found"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILE_NOT_FOUND); ret = false; } } @@ -1481,14 +1480,14 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u8* firm = (u8*) malloc(FIRM_MAX_SIZE); if (!firm) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "out of memory"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_OUT_OF_MEMORY); } else { size_t firm_size = FileGetData(argv[0], firm, FIRM_MAX_SIZE, 0); ret = firm_size && IsBootableFirm(firm, firm_size); if (ret) { char fixpath[256] = { 0 }; if ((*argv[0] == '0') || (*argv[0] == '1')) - snprintf(fixpath, 256, "%s%s", (*argv[0] == '0') ? "sdmc" : "nand", argv[0] + 1); + snprintf(fixpath, sizeof(fixpath), "%s%s", (*argv[0] == '0') ? "sdmc" : "nand", argv[0] + 1); else strncpy(fixpath, argv[0], 256); fixpath[255] = '\0'; DeinitExtFS(); @@ -1497,26 +1496,26 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { PXI_Barrier(PXI_FIRMLAUNCH_BARRIER); BootFirm((FirmHeader*)(void*)firm, fixpath); while(1); - } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "not a bootable firm"); + } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NOT_A_BOOTABLE_FIRM); free(firm); } } else if (id == CMD_ID_SWITCHSD) { DeinitExtFS(); if (!(ret = CheckSDMountState())) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "SD not mounted"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SD_NOT_MOUNTED); } else { u32 pad_state; DeinitSDCardFS(); - ShowString("%s\n \nEject SD card...", argv[0]); + ShowString("%s\n \n%s", argv[0], STR_EJECT_SD_CARD); while (!((pad_state = InputWait(0)) & (BUTTON_B|SD_EJECT))); if (pad_state & SD_EJECT) { - ShowString("%s\n \nInsert SD card...", argv[0]); + ShowString("%s\n \n%s", argv[0], STR_INSERT_SD_CARD); while (!((pad_state = InputWait(0)) & (BUTTON_B|SD_INSERT))); } if (pad_state & BUTTON_B) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); } } InitSDCardFS(); @@ -1544,10 +1543,10 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } else { // command not recognized / bad number of arguments ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unknown error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNKNOWN_ERROR); } - if (ret && err_str) snprintf(err_str, _ERR_STR_LEN, "command success"); + if (ret && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_COMMAND_SUCCESS); return ret; } @@ -1575,7 +1574,7 @@ bool run_line(const char* line_start, const char* line_end, u32* flags, char* er // control flow command handling // block out of control flow commands if (if_cond && IS_CTRLFLOW_CMD(cmdid)) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "control flow error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CONTROL_FLOW_ERROR); syntax_error = true; return false; } @@ -1632,7 +1631,7 @@ void MemTextView(const char* text, u32 len, char* line0, int off_disp, int lno, u32 x_txt = (TV_LNOS >= 0) ? TV_HPAD + ((TV_LNOS+1)*FONT_WIDTH_EXT) : TV_HPAD; u32 x_lno = TV_HPAD; u32 p_al = 0; - u32 p_ar = TV_LLEN_DISP - strnlen(ar_str, 16); + u32 p_ar = TV_LLEN_DISP - strlen(ar_str); u32 x_al = x_txt + (p_al * FONT_WIDTH_EXT); u32 x_ar = x_txt + (p_ar * FONT_WIDTH_EXT); @@ -1659,11 +1658,11 @@ void MemTextView(const char* text, u32 len, char* line0, int off_disp, int lno, if (cmt_start <= 0) color_text = script_color_comment; // build text string - snprintf(txtstr, TV_LLEN_DISP + 1, "%-*.*s", (int) TV_LLEN_DISP, (int) TV_LLEN_DISP, ""); + snprintf(txtstr, sizeof(txtstr), "%-*.*s", (int) TV_LLEN_DISP, (int) TV_LLEN_DISP, ""); if (ncpy) memcpy(txtstr, ptr + off_disp, ncpy); for (char* d = txtstr; *d; d++) if (*d < ' ') *d = ' '; - if (al) memcpy(txtstr + p_al, al_str, strnlen(al_str, 16)); - if (ar) memcpy(txtstr + p_ar, ar_str, strnlen(ar_str, 16)); + if (al) memcpy(txtstr + p_al, al_str, strlen(al_str)); + if (ar) memcpy(txtstr + p_ar, ar_str, strlen(ar_str)); // draw line number & text DrawString(TOP_SCREEN, txtstr, x_txt, y, color_text, COLOR_STD_BG); @@ -1680,8 +1679,8 @@ void MemTextView(const char* text, u32 len, char* line0, int off_disp, int lno, } // colorize arrows - if (al) DrawStringF(TOP_SCREEN, x_al, y, COLOR_TVOFFS, COLOR_TRANSPARENT, al_str); - if (ar) DrawStringF(TOP_SCREEN, x_ar, y, COLOR_TVOFFS, COLOR_TRANSPARENT, ar_str); + if (al) DrawStringF(TOP_SCREEN, x_al, y, COLOR_TVOFFS, COLOR_TRANSPARENT, "%s", al_str); + if (ar) DrawStringF(TOP_SCREEN, x_ar, y, COLOR_TVOFFS, COLOR_TRANSPARENT, "%s", ar_str); // advance pointer / line number for (char* c = ptr; c < ptr_next; c++) if (*c == '\n') ++nln; @@ -1694,7 +1693,7 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) { // check if this really is text if (!ValidateText(text, len)) { - ShowPrompt(false, "Error: Invalid text data"); + ShowPrompt(false, "%s", STR_ERROR_INVALID_TEXT_DATA); return false; } @@ -1702,8 +1701,7 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) { ClearScreenF(true, true, COLOR_STD_BG); // instructions - static const char* instr = "Textviewer Controls:\n \n↑↓→←(+R) - Scroll\nR+Y - Toggle wordwrap\nR+X - Goto line #\nB - Exit\n"; - ShowString(instr); + ShowString("%s", STR_TEXTVIEWER_CONTROLS_DETAILS); // set script colors if (as_script) { @@ -1742,9 +1740,9 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) { else if (pad_state & BUTTON_RIGHT) off_disp += step_lr; else if (pad_state & BUTTON_LEFT) off_disp -= step_lr; else if (switched && (pad_state & BUTTON_X)) { - u64 lnext64 = ShowNumberPrompt(lcurr, "Current line: %i\nEnter new line below.", lcurr); + u64 lnext64 = ShowNumberPrompt(lcurr, STR_CURRENT_LINE_N_ENTER_NEW_LINE_BELOW, lcurr); if (lnext64 && (lnext64 != (u64) -1)) line0_next = line_seek(text, len, 0, line0, (int) lnext64 - lcurr); - ShowString(instr); + ShowString("%s", STR_TEXTVIEWER_CONTROLS_DETAILS); } else if (switched && (pad_state & BUTTON_Y)) { ww = ww ? 0 : TV_LLEN_DISP; line0_next = line_seek(text, len, ww, line0, 0); @@ -1780,7 +1778,7 @@ bool MemToCViewer(const char* text, u32 len, const char* title) { // check if this really is text if (!ValidateText(text, len)) { - ShowPrompt(false, "Error: Invalid text data"); + ShowPrompt(false, "%s", STR_ERROR_INVALID_TEXT_DATA); return false; } @@ -1819,7 +1817,7 @@ bool MemToCViewer(const char* text, u32 len, const char* title) { for (; IS_WHITESPACE(*caption); caption++); for (; caption[len] != '\n' && caption[len] != '\r'; len++); DrawStringF(BOT_SCREEN, x0 + (lvl-1) * (FONT_WIDTH_EXT/2), y0, text_color, COLOR_STD_BG, - "%*.*s", len, len, caption); + "%*.*s", (int) len, (int) len, caption); y0 += FONT_HEIGHT_EXT + (2*TV_VPAD); } @@ -1887,7 +1885,7 @@ bool ExecuteGM9Script(const char* path_script) { if (!var_buffer || !script_buffer) { if (var_buffer) free(var_buffer); if (script_buffer) free(script_buffer); - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return false; } @@ -1931,7 +1929,7 @@ bool ExecuteGM9Script(const char* path_script) { if (!preview_mode || (preview_mode > 2) || !preview_mode_local) ClearScreen(TOP_SCREEN, COLOR_STD_BG); if (preview_mode > 2) { - char* preview_str = get_var("PREVIEW_MODE", NULL); + const char* preview_str = get_var("PREVIEW_MODE", NULL); u32 bitmap_width, bitmap_height; u16* bitmap = NULL; @@ -1947,7 +1945,7 @@ bool ExecuteGM9Script(const char* path_script) { DrawBitmap(TOP_SCREEN, -1, -1, bitmap_width, bitmap_height, bitmap); free(bitmap); } else if (ShowGameFileIcon(preview_str, TOP_SCREEN) != 0) { - if (strncmp(preview_str, "off", _VAR_CNT_LEN) == 0) preview_str = "(preview disabled)"; + if (strncmp(preview_str, "off", _VAR_CNT_LEN) == 0) preview_str = STR_PREVIEW_DISABLED; DrawStringCenter(TOP_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", preview_str); } @@ -1987,14 +1985,14 @@ bool ExecuteGM9Script(const char* path_script) { if ((skip_state == _SKIP_BLOCK) || (skip_state == _SKIP_TILL_END)) { skip_ptr = skip_block(line_end + 1, (skip_state == _SKIP_TILL_END), false); if (!skip_ptr) { - snprintf(err_str, _ERR_STR_LEN, "unclosed conditional"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNCLOSED_CONDITIONAL); result = false; syntax_error = true; } } else if (skip_state == _SKIP_TO_NEXT) { skip_ptr = find_next(ptr); if (!skip_ptr) { - snprintf(err_str, _ERR_STR_LEN, "'for' without 'next'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FOR_WITHOUT_NEXT); result = false; syntax_error = true; } @@ -2002,7 +2000,7 @@ bool ExecuteGM9Script(const char* path_script) { } else if (skip_state == _SKIP_TO_FOR) { skip_ptr = for_ptr; if (!skip_ptr) { - snprintf(err_str, _ERR_STR_LEN, "'next' without 'for'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NEXT_WITHOUT_FOR); result = false; syntax_error = true; } @@ -2018,7 +2016,7 @@ bool ExecuteGM9Script(const char* path_script) { if (!*err_str) { char* msg_fail = get_var("ERRORMSG", NULL); if (msg_fail && *msg_fail) ShowPrompt(false, "%s", msg_fail); - else snprintf(err_str, _ERR_STR_LEN, "error message fail"); + else snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ERROR_MESSAGE_FAIL); } if (*err_str) { char line_str[32+1]; @@ -2026,9 +2024,9 @@ bool ExecuteGM9Script(const char* path_script) { char* lptr1 = line_end; for (; IS_WHITESPACE(*lptr0) && (lptr0 < lptr1); lptr0++); // skip whitespaces if ((lptr1 > lptr0) && (*(lptr1-1) == '\r')) lptr1--; // handle \r - if (lptr1 - lptr0 > 32) snprintf(line_str, 32+1, "%.29s...", lptr0); - else snprintf(line_str, 32+1, "%.*s", lptr1 - lptr0, lptr0); - ShowPrompt(false, "%s\nline %lu: %s\n%s", path_str, lno, err_str, line_str); + if (lptr1 - lptr0 > 32) snprintf(line_str, sizeof(line_str), "%.29s...", lptr0); + else snprintf(line_str, sizeof(line_str), "%.*s", lptr1 - lptr0, lptr0); + ShowPrompt(false, STR_PATH_LINE_N_ERR_LINE, path_str, lno, err_str, line_str); } } if (!(flags & _FLG('o'))) { // failed if not optional @@ -2057,11 +2055,11 @@ bool ExecuteGM9Script(const char* path_script) { if (result) { // all fine(?) up to this point if (ifcnt) { // check for unresolved 'if' - ShowPrompt(false, "%s\nend of script: unresolved 'if'", path_str); + ShowPrompt(false, "%s\n%s", path_str, STR_END_OF_SCRIPT_UNRESOLVED_IF); result = false; } if (for_ptr) { // check for unresolved 'for' - ShowPrompt(false, "%s\nend of script: unresolved 'for'", path_str); + ShowPrompt(false, "%s\n%s", path_str, STR_END_OF_SCRIPT_UNRESOLVED_FOR); for_handler(NULL, NULL, NULL, false); result = false; } diff --git a/arm9/source/utils/scripting.h b/arm9/source/utils/scripting.h index ad1aa5267..c76d07627 100644 --- a/arm9/source/utils/scripting.h +++ b/arm9/source/utils/scripting.h @@ -5,6 +5,8 @@ #define SCRIPT_EXT "gm9" #define SCRIPT_MAX_SIZE STD_BUFFER_SIZE +bool for_handler(char* path, const char* dir, const char* pattern, bool recursive); + bool ValidateText(const char* text, u32 size); bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script); bool MemToCViewer(const char* text, u32 len, const char* title); diff --git a/arm9/source/utils/sysinfo.c b/arm9/source/utils/sysinfo.c index c290b0ab5..3d3b2724d 100644 --- a/arm9/source/utils/sysinfo.c +++ b/arm9/source/utils/sysinfo.c @@ -1,6 +1,7 @@ #include "common.h" #include "i2c.h" #include "itcm.h" +#include "language.h" #include "region.h" #include "unittype.h" #include "essentials.h" // For SecureInfo / movable @@ -28,23 +29,24 @@ static const struct { }; STATIC_ASSERT(countof(s_modelNames) == NUM_MODELS); -// Table of sales regions. -static const struct { - char serial_char; - const char* name; -} s_salesRegions[] = { - // Typical regions. - { 'J', "Japan" }, - { 'W', "Americas" }, // "W" = worldwide? - { 'E', "Europe" }, - { 'C', "China" }, - { 'K', "Korea" }, - { 'T', "Taiwan" }, - // Manufacturing regions that have another region's region lock. - { 'U', "United Kingdom" }, - { 'S', "Middle East" }, // "S" = Saudi Arabia? Singapore? (Southeast Asia included.) - { 'A', "Australia" }, -}; +// Sales regions. +const char* salesRegion(char serial_char) { + switch(serial_char) { + // Typical regions. + case 'J': return STR_REGION_JAPAN; + case 'W': return STR_REGION_AMERICAS; // "W" = worldwide? + case 'E': return STR_REGION_EUROPE; + case 'C': return STR_REGION_CHINA; + case 'K': return STR_REGION_KOREA; + case 'T': return STR_REGION_TAIWAN; + // Manufacturing regions that have another region's region lock. + case 'U': return STR_REGION_UNITED_KINGDOM; + case 'S': return STR_REGION_MIDDLE_EAST; // "S" = Saudi Arabia? Singapore? (Southeast Asia included.) + case 'A': return STR_REGION_AUSTRALIA; + case 'B': return STR_REGION_BRAZIL; + default: return STR_REGION_UNKNOWN; + } +} // Structure of system information. typedef struct _SysInfo { @@ -59,8 +61,8 @@ typedef struct _SysInfo { // From SecureInfo_A/B char sub_model[15 + 1]; char serial[15 + 1]; - char system_region[15 + 1]; - char sales_region[15 + 1]; + char system_region[64 + 1]; + char sales_region[64 + 1]; // From movable.sed char friendcodeseed[16 + 1]; char movablekeyy[32 + 1]; @@ -164,7 +166,7 @@ void GetSysInfo_SecureInfo(SysInfo* info, char nand_drive) { // Decode region. if (data.region < SMDH_NUM_REGIONS) { - strncpy(info->system_region, g_regionNamesLong[data.region], countof(info->system_region)); + strncpy(info->system_region, regionNameLong(data.region), countof(info->system_region)); info->system_region[countof(info->system_region) - 1] = '\0'; } @@ -232,13 +234,8 @@ void GetSysInfo_SecureInfo(SysInfo* info, char nand_drive) { // Determine the sales region from the second letter of the prefix. if (second_letter != '\0') { - for (unsigned x = 0; x < countof(s_salesRegions); ++x) { - if (s_salesRegions[x].serial_char == second_letter) { - strncpy(info->sales_region, s_salesRegions[x].name, countof(info->sales_region)); - info->sales_region[countof(info->sales_region) - 1] = '\0'; - break; - } - } + strncpy(info->sales_region, salesRegion(second_letter), countof(info->sales_region)); + info->sales_region[countof(info->sales_region) - 1] = '\0'; } // Determine the sub-model from the first two digits of the digit part. @@ -598,18 +595,18 @@ void MyriaSysinfo(char* sysinfo_txt) { GetSysInfo_TWLN(&info, '1'); char** meow = &sysinfo_txt; - MeowSprintf(meow, "Model: %s (%s)\r\n", info.model, info.sub_model); - MeowSprintf(meow, "Serial: %s\r\n", info.serial); - MeowSprintf(meow, "Region (system): %s\r\n", info.system_region); - MeowSprintf(meow, "Region (sales): %s\r\n", info.sales_region); - MeowSprintf(meow, "SoC manufacturing date: %s\r\n", info.soc_date); - MeowSprintf(meow, "System assembly date: %s\r\n", info.assembly_date); - MeowSprintf(meow, "Original firmware: %s\r\n", info.original_firmware); + MeowSprintf(meow, STR_SYSINFO_MODEL, info.model, info.sub_model); + MeowSprintf(meow, STR_SYSINFO_SERIAL, info.serial); + MeowSprintf(meow, STR_SYSINFO_REGION_SYSTEM, info.system_region); + MeowSprintf(meow, STR_SYSINFO_REGION_SALES, info.sales_region); + MeowSprintf(meow, STR_SYSINFO_SOC_MANUFACTURING_DATE, info.soc_date); + MeowSprintf(meow, STR_SYSINFO_SYSTEM_ASSEMBLY_DATE, info.assembly_date); + MeowSprintf(meow, STR_SYSINFO_ORIGINAL_FIRMWARE, info.original_firmware); MeowSprintf(meow, "\r\n"); - MeowSprintf(meow, "Friendcode seed: %s\r\n", info.friendcodeseed); - MeowSprintf(meow, "SD keyY: %s\r\n", info.movablekeyy); - MeowSprintf(meow, "NAND CID: %s\r\n", info.nand_cid); - MeowSprintf(meow, "SD CID: %s\r\n", info.sd_cid); - MeowSprintf(meow, "System ID0: %s\r\n", info.nand_id0); - MeowSprintf(meow, "System ID1: %s\r\n", info.nand_id1); + MeowSprintf(meow, STR_SYSINFO_FRIENDCODE_SEED, info.friendcodeseed); + MeowSprintf(meow, STR_SYSINFO_SD_KEYY, info.movablekeyy); + MeowSprintf(meow, STR_SYSINFO_NAND_CID, info.nand_cid); + MeowSprintf(meow, STR_SYSINFO_SD_CID, info.sd_cid); + MeowSprintf(meow, STR_SYSINFO_SYSTEM_ID0, info.nand_id0); + MeowSprintf(meow, STR_SYSINFO_SYSTEM_ID1, info.nand_id1); } diff --git a/arm9/source/virtual/vbdri.c b/arm9/source/virtual/vbdri.c index 2783dc5ae..b743cdd6a 100644 --- a/arm9/source/virtual/vbdri.c +++ b/arm9/source/virtual/vbdri.c @@ -5,6 +5,7 @@ #include "bdri.h" #include "vff.h" #include "ui.h" +#include "language.h" #define VBDRI_MAX_ENTRIES 8192 // Completely arbitrary @@ -65,7 +66,7 @@ bool SortVBDRITickets() { if (!tick_info) return false; - ShowString("Sorting tickets, please wait ..."); + ShowString("%s", STR_SORTING_TICKETS_PLEASE_WAIT); for (u32 i = 0; i < num_entries - 1; i++) { Ticket* ticket; diff --git a/arm9/source/virtual/vkeydb.c b/arm9/source/virtual/vkeydb.c index 1ae7f0aa8..b3d8973b3 100644 --- a/arm9/source/virtual/vkeydb.c +++ b/arm9/source/virtual/vkeydb.c @@ -53,11 +53,11 @@ bool ReadVKeyDbDir(VirtualFile* vfile, VirtualDir* vdir) { if (++vdir->index < (int) n_keys) { AesKeyInfo* key_entry = key_info + vdir->index; u32 keyslot = key_entry->slot; - char typestr[16] = { 0 }; + char typestr[16]; char* unitext = (key_entry->keyUnitType == KEYS_DEVKIT) ? ".dev" : (key_entry->keyUnitType == KEYS_RETAIL) ? ".ret" : ""; - snprintf(typestr, 12 + 1, "%s%.10s", (key_entry->type == 'I') ? "IV" : + snprintf(typestr, sizeof(typestr), "%s%.10s", (key_entry->type == 'I') ? "IV" : (key_entry->type == 'X') ? "X" : (key_entry->type == 'Y') ? "Y" : "", key_entry->id); memset(vfile, 0, sizeof(VirtualFile)); diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 000000000..69e87c2cb --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,7 @@ +project_id: 559689 +api_token_env: CROWDIN_TOKEN +preserve_hierarchy: true + +files: + - source: /resources/languages/source.json + translation: /resources/languages/%two_letters_code%.json diff --git a/data/font_default.frf b/data/font_default.frf index 65f86e6d9..dee9c9811 100644 Binary files a/data/font_default.frf and b/data/font_default.frf differ diff --git a/data/luapackages/fs.lua b/data/luapackages/fs.lua new file mode 100644 index 000000000..e223beb85 --- /dev/null +++ b/data/luapackages/fs.lua @@ -0,0 +1,112 @@ +local fs = {} + +fs.move = _fs.move +fs.remove = _fs.remove +fs.copy = _fs.copy +fs.mkdir = _fs.mkdir +fs.list_dir = _fs.list_dir +fs.stat = _fs.stat +fs.stat_fs = _fs.stat_fs +fs.dir_info = _fs.dir_info +fs.ask_select_file = _fs.ask_select_file +fs.ask_select_dir = _fs.ask_select_dir +fs.find = _fs.find +fs.find_all = _fs.find_all +fs.find_not = _fs.find_not +fs.exists = _fs.exists +fs.is_dir = _fs.is_dir +fs.is_file = _fs.is_file +fs.read_file = _fs.read_file +fs.fill_file = _fs.fill_file +fs.make_dummy_file = _fs.make_dummy_file +fs.truncate = _fs.truncate +fs.img_mount = _fs.img_mount +fs.img_umount = _fs.img_umount +fs.get_img_mount = _fs.get_img_mount +fs.hash_file = _fs.hash_file +fs.hash_data = _fs.hash_data +fs.verify = _fs.verify +fs.allow = _fs.allow +fs.sd_is_mounted = _fs.sd_is_mounted +fs.sd_switch = _fs.sd_switch +fs.fix_cmacs = _fs.fix_cmacs +fs.key_dump = _fs.key_dump +fs.cart_dump = _fs.cart_dump + +-- compatibility +function os.remove(path) + local success, allowed, stat, error + success, stat = pcall(fs.stat, path) + if not success then + return nil, path..": No such file or directory", 2 + end + if stat.type == "dir" then + -- os.remove can remove an empty directory, so we gotta check + success, dir_list = pcall(fs.list_dir, path) + if not success then + return nil, "Error occurred listing directory: "..dir_list, 2001 + end + if #dir_list ~= 0 then + return nil, path..": Directory not empty", 39 + end + end + allowed = fs.allow(path) + if not allowed then + return nil, path..": Operation not permitted", 1 + end + success, error = pcall(fs.remove, path, {recursive=true}) + if success then + return true + else + return nil, "Error occurred removing item: "..error, 2001 + end +end + +-- compatibility +function os.rename(src, dst) + error("os.rename is not implemented yet (try fs.move instead)") + --local success, drv_src, drv_dst, allowed + --drv_src = string.upper(string.sub(src, 1, 1)) + --drv_dst = string.upper(string.sub(dst, 1, 1)) + --if drv_src ~= drv_dst then + -- return nil, "Invalid cross-device link", 18 + --end + --allowed = fs.allow(src) and fs.allow(dst) + --if not allowed then + -- return nil, "Permission denied", 13 + --end +end + +function fs.write_file(path, offset, data) + local success, filestat + if type(offset) == "string" then + if offset == "end" then + success, filestat = pcall(fs.stat, path) + if success then + offset = filestat.size + else + -- allows for this to work on files that don't yet exist + offset = 0 + end + else + error("offset should be an integer or \"end\"") + end + elseif type(offset) ~= "number" then + error("offset should be an integer or \"end\"") + end + + return _fs.write_file(path, offset, data) +end + +function fs.verify_with_sha_file(path) + local success, file_hash, sha_data, path_sha + path_sha = path..".sha" + success, sha_data = pcall(fs.read_file, path_sha, 0, 0x20) + if not success then + return nil + end + file_hash = fs.hash_file(path, 0, 0) + return file_hash == sha_data +end + +return fs diff --git a/data/luapackages/io.lua b/data/luapackages/io.lua new file mode 100644 index 000000000..ab0b6f5a6 --- /dev/null +++ b/data/luapackages/io.lua @@ -0,0 +1,214 @@ +-- This module has not been fully tested against Lua's built-in module. +-- Functionality might be incorrect. + +-- TODO: set up __gc in files so they can clean up properly + +local io = {} + +local file = {} +file.__index = file + +local function debugf(...) + print("DEBUG:", table.unpack({...})) +end + +local function not_impl(fnname) + return function (...) + error(fnname.." is not implemented") + end +end + +-- some errors should return nil, an error string, then an error number +-- example: +-- > io.open("/nix/abc.txt", "w") +-- nil /nix/abc.txt: Permission denied 13 +-- > io.open("/nix/abc.txt", "r") +-- nil /nix/abc.txt: No such file or directory 2 +-- > a = io.open("abc.txt", "w") +-- > a:read() +-- nil Bad file descriptor 9 +function file.new(filename, mode) + -- TODO: make this more accurate (disallow opening dirs as files) + local success, stat, of, allowed + if mode == nil then + mode = "r" + end + debugf("opening", filename, mode) + of = setmetatable({_filename=filename, _mode=mode, _seek=0, _open=true, _readable=false, _writable=false, _append_only=false}, file) + if string.find(mode, "w", 1, true) then + debugf("opening", filename, "for writing") + -- preemptively allow writing instead of having that prompt at file:write + allowed = fs.allow(filename) + debugf("allowed:", allowed) + if not allowed then return nil, filename..": Permission denied", 13 end + -- write mode truncates the file to 0 normally + success = pcall(fs.truncate, filename, 0) + if not success then return nil, filename..": Cannot truncate virtual files", 2001 end + of._stat = {} + of._size = 0 + of._readable = false + of._writable = true + elseif string.find(mode, "r+", 1, true) then + debugf("opening", filename, "for updating") + allowed = fs.allow(filename) + debugf("allowed:", allowed) + if not allowed then return nil, filename..": Permission denied", 13 end + success, stat = pcall(fs.stat, filename) + debugf("stat success:", success) + if success then + debugf("type:", stat.type) + if stat.type == "dir" then return nil end + of._stat = stat + of._size = stat.size + else + of._stat = {} + of._size = 0 + end + elseif string.find(mode, "a", 1, true) then + debugf("opening", filename, "for appending") + allowed = fs.allow(filename) + debugf("allowed:", allowed) + if not allowed then return nil, filename..": Permission denied", 13 end + of._append_only = true + of._writable = true + success, stat = pcall(fs.stat, filename) + debugf("stat success:", success) + if success then + debugf("type:", stat.type) + if stat.type == "dir" then return nil end + of._stat = stat + of._size = stat.size + else + of._stat = {} + of._size = 0 + end + if string.find(mode, "+", 1, true) then + debugf("append update mode") + of._readable = true + else + debugf("append only mode") + of._readable = false + of._seek = of._size + end + else + debugf("opening", filename, "for reading") + -- check if file exists first + success, stat = pcall(fs.stat, filename) + debugf("stat success:", success) + -- lua returns nil if it fails to open for some reason + if not success then return nil, filename..": No such file or directory", 2 end + debugf("type:", stat.type) + if stat.type == "dir" then return nil end + of._stat = stat + -- this is so i can adjust the size when data is written + of._size = stat.size + end + debugf("returning of") + return of +end + +function file:_closed_check() + if not self._open then error("attempt to use a closed file") end +end + +function file:_bad_desc() + debugf("returning bad desc on file", self._filename) + return nil, "Bad file descriptor", 9 +end + +function file:close() + -- yes, this check and error happens even on a closed file + self:_closed_check() + self._open = false + return true +end + +function file:flush() + self:_closed_check() + -- nothing happens here +end + +function file:read(...) + self:_closed_check() + if not self._readable then return file:_bad_desc() end + local to_return = {} + for i, v in ipairs({...}) do + if v == "n" or v == "l" or v == "L" then + error('mode "'..v..'" is not implemented') + elseif v == "a" then + local btr = self._size - self._seek + local data = fs.read_file(self._filename, self._seek, btr) + self._seek = self._seek + string.len(data) + table.insert(to_return, data) + else + -- assuming this is a number... + local data = fs.read_file(self._filename, self._seek, v) + self._seek = self._seek + string.len(data) + table.insert(to_return, data) + end + end + return table.unpack(to_return) +end + +function file:seek(whence, offset) + if whence == nil then + whence = "cur" + end + if offset == nil then + offset = 0 + end + if type(offset) ~= "number" then + error("bad argument #2 to 'seek' (number expected, got "..type(offset)..")") + end + + if whence == "set" then + self._seek = offset + elseif whence == "cur" then + self._seek = self._seek + offset + elseif whence == "end" then + self._seek = self._size + offset + else + error("bad argument #1 to 'seek' (invalid option '"..tostring(whence).."')") + end + + return self._seek +end + +function file:write(...) + if not self._writable then return file:_bad_desc() end + local to_write = '' + for i, v in pairs({...}) do + to_write = to_write..tostring(v) + end + local len = string.len(to_write) + debugf("attempting to write "..tostring(len).." bytes to "..self._filename) + if self._append_only then + self:seek("end") + end + local br = fs.write_file(self._filename, self._seek, to_write) + debugf("wrote "..tostring(br).." bytes to "..self._filename) + self._seek = self._seek + br + if self._seek > self._size then + self._size = self._seek + end + return self +end + +file.lines = not_impl("file:lines") +file.setvbuf = not_impl("file:setvbuf") + +function io.open(filename, mode) + return file.new(filename, mode) +end + +io.close = not_impl("io.close") +io.flush = not_impl("io.flush") +io.lines = not_impl("io.lines") +io.output = not_impl("io.output") +io.popen = not_impl("io.popen") +io.read = not_impl("io.read") +io.tmpfile = not_impl("io.tmpfile") +io.type = not_impl("io.type") +io.write = not_impl("io.write") + +return io diff --git a/data/luapackages/json.lua b/data/luapackages/json.lua new file mode 100644 index 000000000..711ef7861 --- /dev/null +++ b/data/luapackages/json.lua @@ -0,0 +1,388 @@ +-- +-- json.lua +-- +-- Copyright (c) 2020 rxi +-- +-- 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. +-- + +local json = { _version = "0.1.2" } + +------------------------------------------------------------------------------- +-- Encode +------------------------------------------------------------------------------- + +local encode + +local escape_char_map = { + [ "\\" ] = "\\", + [ "\"" ] = "\"", + [ "\b" ] = "b", + [ "\f" ] = "f", + [ "\n" ] = "n", + [ "\r" ] = "r", + [ "\t" ] = "t", +} + +local escape_char_map_inv = { [ "/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if rawget(val, 1) ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 + for k in pairs(val) do + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") + end + n = n + 1 + end + if n ~= #val then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) + end + stack[val] = nil + return "[" .. table.concat(res, ",") .. "]" + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + end + stack[val] = nil + return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then + error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then + return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +------------------------------------------------------------------------------- +-- Decode +------------------------------------------------------------------------------- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do + res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do + if set[str:sub(i, i)] ~= negate then + return i + end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do + col_count = col_count + 1 + if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 + end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa + local f = math.floor + if n <= 0x7f then + return string.char(n) + elseif n <= 0x7ff then + return string.char(f(n / 64) + 192, n % 64 + 128) + elseif n <= 0xffff then + return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) + elseif n <= 0x10ffff then + return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, + f(n % 4096 / 64) + 128, n % 64 + 128) + end + error( string.format("invalid unicode codepoint '%x'", n) ) +end + + +local function parse_unicode_escape(s) + local n1 = tonumber( s:sub(1, 4), 16 ) + local n2 = tonumber( s:sub(7, 10), 16 ) + -- Surrogate pair? + if n2 then + return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) + else + return codepoint_to_utf8(n1) + end +end + + +local function parse_string(str, i) + local res = "" + local j = i + 1 + local k = j + + while j <= #str do + local x = str:byte(j) + + if x < 32 then + decode_error(str, j, "control character in string") + + elseif x == 92 then -- `\`: Escape + res = res .. str:sub(k, j - 1) + j = j + 1 + local c = str:sub(j, j) + if c == "u" then + local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) + or str:match("^%x%x%x%x", j + 1) + or decode_error(str, j - 1, "invalid unicode escape in string") + res = res .. parse_unicode_escape(hex) + j = j + #hex + else + if not escape_chars[c] then + decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") + end + res = res .. escape_char_map_inv[c] + end + k = j + 1 + + elseif x == 34 then -- `"`: End of string + res = res .. str:sub(k, j - 1) + return res, j + 1 + end + + j = j + 1 + end + + decode_error(str, i, "expected closing quote for string") +end + + +local function parse_number(str, i) + local x = next_char(str, i, delim_chars) + local s = str:sub(i, x - 1) + local n = tonumber(s) + if not n then + decode_error(str, i, "invalid number '" .. s .. "'") + end + return n, x +end + + +local function parse_literal(str, i) + local x = next_char(str, i, delim_chars) + local word = str:sub(i, x - 1) + if not literals[word] then + decode_error(str, i, "invalid literal '" .. word .. "'") + end + return literal_map[word], x +end + + +local function parse_array(str, i) + local res = {} + local n = 1 + i = i + 1 + while 1 do + local x + i = next_char(str, i, space_chars, true) + -- Empty / end of array? + if str:sub(i, i) == "]" then + i = i + 1 + break + end + -- Read token + x, i = parse(str, i) + res[n] = x + n = n + 1 + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "]" then break end + if chr ~= "," then decode_error(str, i, "expected ']' or ','") end + end + return res, i +end + + +local function parse_object(str, i) + local res = {} + i = i + 1 + while 1 do + local key, val + i = next_char(str, i, space_chars, true) + -- Empty / end of object? + if str:sub(i, i) == "}" then + i = i + 1 + break + end + -- Read key + if str:sub(i, i) ~= '"' then + decode_error(str, i, "expected string for key") + end + key, i = parse(str, i) + -- Read ':' delimiter + i = next_char(str, i, space_chars, true) + if str:sub(i, i) ~= ":" then + decode_error(str, i, "expected ':' after key") + end + i = next_char(str, i + 1, space_chars, true) + -- Read value + val, i = parse(str, i) + -- Set + res[key] = val + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "}" then break end + if chr ~= "," then decode_error(str, i, "expected '}' or ','") end + end + return res, i +end + + +local char_func_map = { + [ '"' ] = parse_string, + [ "0" ] = parse_number, + [ "1" ] = parse_number, + [ "2" ] = parse_number, + [ "3" ] = parse_number, + [ "4" ] = parse_number, + [ "5" ] = parse_number, + [ "6" ] = parse_number, + [ "7" ] = parse_number, + [ "8" ] = parse_number, + [ "9" ] = parse_number, + [ "-" ] = parse_number, + [ "t" ] = parse_literal, + [ "f" ] = parse_literal, + [ "n" ] = parse_literal, + [ "[" ] = parse_array, + [ "{" ] = parse_object, +} + + +parse = function(str, idx) + local chr = str:sub(idx, idx) + local f = char_func_map[chr] + if f then + return f(str, idx) + end + decode_error(str, idx, "unexpected character '" .. chr .. "'") +end + + +function json.decode(str) + if type(str) ~= "string" then + error("expected argument of type string, got " .. type(str)) + end + local res, idx = parse(str, next_char(str, 1, space_chars, true)) + idx = next_char(str, idx, space_chars, true) + if idx <= #str then + decode_error(str, idx, "trailing garbage") + end + return res +end + + +return json diff --git a/data/luapackages/sys.lua b/data/luapackages/sys.lua new file mode 100644 index 000000000..fe018eb6e --- /dev/null +++ b/data/luapackages/sys.lua @@ -0,0 +1,64 @@ +local sys = {} + +sys.boot = _sys.boot +sys.reboot = _sys.reboot +sys.power_off = _sys.power_off +sys.check_embedded_backup = _sys.check_embedded_backup +sys.check_raw_rtc = _sys.check_raw_rtc + +sys.secureinfo_letter = nil +sys.region = nil +sys.serial = nil +sys.sys_id0 = nil +sys.emu_id0 = nil +sys.emu_base = nil + +local regions = {"JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN"} + +local function refresh_secureinfo() + local letter = nil + if fs.exists("1:/rw/sys/SecureInfo_A") then letter = "A" + elseif fs.exists("1:rw/sys/SecureInfo_B") then letter = "B" + else error("could not read SecureInfo") end + + local secinfo = fs.read_file("1:/rw/sys/SecureInfo_"..letter, 0, 0x111) + + -- remember, Lua starts indexes at 1 so these offsets appear off by one if you're used to other langs + local serial = string.sub(secinfo, 0x103, 0x111) + serial = string.gsub(serial, "\0", "") + + local region_byte = string.sub(secinfo, 0x101, 0x101) + local region_num = string.byte(region_byte) + if region_num > 6 then error("SecureInfo region byte is invalid") end + + sys.serial = serial + sys.region = regions[region_num + 1] + sys.secureinfo_letter = letter +end + +local function refresh_id0() + local sys_id0 = _sys.get_id0("1:/private/movable.sed") + + if fs.exists("4:/private/movable.sed") then + local emu_id0 = _sys.get_id0("4:/private/movable.sed") + end + + sys.sys_id0 = sys_id0 + sys.emu_id0 = emu_id0 +end + +function sys.refresh_info() + refresh_secureinfo() + refresh_id0() + sys.emu_base = _sys.get_emu_base() +end + +function sys.next_emu() + _sys.next_emu() + pcall(sys.refresh_info()) +end + +-- in the preload scripts, we have to avoid possibilities of unhandled exceptions +pcall(sys.refresh_info) + +return sys diff --git a/data/luapackages/util.lua b/data/luapackages/util.lua new file mode 100644 index 000000000..c1f7b5748 --- /dev/null +++ b/data/luapackages/util.lua @@ -0,0 +1,50 @@ +local util = {} + +-- https://stackoverflow.com/a/71896879 +function util.bytes_to_hex(data) + local hex = {} + local char + for i = 1, #data do + char = string.sub(data, i, i) + --hex = hex..string.format("%02x", string.byte(char)) + table.insert(hex, string.format("%02x", string.byte(char))) + end + return table.concat(hex) +end + +-- https://stackoverflow.com/a/9140231 +function util.hex_to_bytes(hexstring) + return (string.gsub(hexstring, '..', function (cc) + return string.char(tonumber(cc, 16)) + end)) +end + +-- returns something like "241202" +function util.get_datestamp() + return os.date("%y%m%d") +end + +-- returns something like "010828" +function util.get_timestamp() + return os.date("%H%M%S") +end + +-- https://stackoverflow.com/a/49376823 +function util.running_as_module() + local success, _, __, required = pcall(debug.getlocal, 4, 1) + if not success then + -- umm uhh + return false + end + -- for the file being executed directly, this seems to be a number + -- but for a file being required by another, it returns the string given to require() + -- example: if foo.lua is executed, this should return a number like 2 + -- but when foo.lua requires bar.lua, bar.lua should get "bar" as the result + -- however, this behavior seems inconsistent between lua versions + -- the Stack Overflow answer seems to suggest the call would fail on some version before 5.4 + -- honestly, I would've liked a better method, but i have yet to find some way to get the executing file + -- in the C code in LoadLuaFile, I could set the string that contains the full filepath, but... where do I set it? + return type(required) == "string" +end + +return util diff --git a/data/preload.lua b/data/preload.lua new file mode 100644 index 000000000..7c78615a8 --- /dev/null +++ b/data/preload.lua @@ -0,0 +1,8 @@ +-- This file is executed when any Lua script is executed in GodMode9. +-- The purpose of this one is to initialize some variables and modules. +-- If you're looking for an auto-running script, you want "autorun.lua"! + +fs = require('fs') +util = require('util') +io = require('io') +sys = require('sys') diff --git a/resources/GodMode9_splash.png b/resources/GodMode9_splash.png index 9d65ccc62..6e90c5364 100644 Binary files a/resources/GodMode9_splash.png and b/resources/GodMode9_splash.png differ diff --git a/resources/GodMode9_splash_6th_anniversary.png b/resources/GodMode9_splash_6th_anniversary.png new file mode 100644 index 000000000..6b464a1d0 Binary files /dev/null and b/resources/GodMode9_splash_6th_anniversary.png differ diff --git a/resources/GodMode9_splash_default.png b/resources/GodMode9_splash_default.png new file mode 100644 index 000000000..9d65ccc62 Binary files /dev/null and b/resources/GodMode9_splash_default.png differ diff --git a/resources/fonts/font_6x10.pbm b/resources/fonts/font_6x10.pbm index aaee90617..245b6a7d9 100644 Binary files a/resources/fonts/font_6x10.pbm and b/resources/fonts/font_6x10.pbm differ diff --git a/resources/fonts/font_6x10.txt b/resources/fonts/font_6x10.txt index 4ad1b8996..99c676026 100644 --- a/resources/fonts/font_6x10.txt +++ b/resources/fonts/font_6x10.txt @@ -1,35 +1,17 @@ -0x0020 0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F -0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F -0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F -0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F -0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F -0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E 0x00A0 -0x00A1 0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00B0 0x00B1 0x00B2 -0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00BA 0x00BB 0x00BC 0x00BD 0x00BF 0x00C0 0x00C1 0x00C2 0x00C3 0x00C4 0x00C5 -0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 0x00D3 0x00D4 0x00D5 -0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 0x00E3 0x00E4 0x00E5 -0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 0x00F3 0x00F4 0x00F5 -0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0192 0x0393 0x0398 0x03A3 0x03A6 0x03A9 -0x03B1 0x03B4 0x03B5 0x03C0 0x03C3 0x03C4 0x03C6 0x0401 0x0404 0x0406 0x0407 0x0410 0x0411 0x0412 0x0413 0x0414 -0x0415 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 -0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C 0x042D 0x042E 0x042F 0x0430 0x0431 0x0432 0x0433 0x0434 -0x0435 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 -0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C 0x044D 0x044E 0x044F 0x0451 0x0454 0x0456 0x0457 0x2022 -0x203C 0x207F 0x20A7 0x20AC 0x2122 0x2190 0x2191 0x2192 0x2193 0x2194 0x2195 0x21A8 0x2219 0x221A 0x221E 0x221F -0x2229 0x2248 0x2261 0x2264 0x2265 0x2302 0x2310 0x2320 0x2321 0x2500 0x2502 0x250C 0x2510 0x2514 0x2518 0x251C -0x2524 0x252C 0x2534 0x253C 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B -0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B -0x256C 0x2580 0x2584 0x2588 0x258C 0x2590 0x2591 0x2592 0x2593 0x25A0 0x25A1 0x25AC 0x25B2 0x25B3 0x25BA 0x25BC -0x25BD 0x25C4 0x25C6 0x25C7 0x25CB 0x25CE 0x25CF 0x25D8 0x25D9 0x2605 0x263A 0x263B 0x263C 0x2640 0x2642 0x2660 -0x2663 0x2665 0x2666 0x266A 0x266B 0x3000 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A -0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A -0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A -0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A -0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A -0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x3094 0x3095 0x3096 0x309B 0x309C 0x309D 0x309E -0x309F 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF -0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF -0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF -0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF -0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF -0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x30F7 0x30F8 0x30F9 0x30FA 0x30FB 0x30FC 0x30FD 0x30FE 0x30FF +0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F 0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F 0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F 0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F 0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F 0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E +0x00A0 0x00A1 0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00B0 0x00B1 0x00B2 0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00BA 0x00BB 0x00BC 0x00BD 0x00BF 0x00C0 0x00C1 0x00C2 0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0102 0x0103 0x0104 +0x0105 0x0106 0x0107 0x0118 0x0119 0x0141 0x0142 0x0143 0x0144 0x0151 0x015A 0x015B 0x0179 0x017A 0x017B 0x017C 0x015E 0x015F 0x0162 0x0163 0x0171 0x0192 0x0218 0x0219 0x021A 0x021B 0x2022 0x203C 0x207F 0x20A7 0x20AC 0x2122 0x2194 0x2195 0x21A8 0x2219 0x221A 0x221E 0x221F 0x2229 0x2248 0x2261 0x2264 0x2265 0x2302 0x2310 0x2320 0x2321 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x2580 0x2584 0x2588 0x258C 0x2590 0x2591 0x2592 0x2593 0x25A0 0x25A1 0x25AC 0x25B2 0x25B3 0x25BA 0x25BC 0x25BD 0x25C4 +0x25C6 0x25C7 0x25CB 0x25CE 0x25CF 0x25D8 0x25D9 0x2605 0x263A 0x263B 0x263C 0x2640 0x2642 0x2660 0x2663 0x2665 0x2666 0x266A 0x266B 0x7B80 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE079 0xE07A 0xE07B 0xE07C 0xE07D 0xE07E 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x3000 0x3001 0x3002 0xFF0C 0xFF0E 0x30FB 0xFF1A 0xFF1B 0xFF1F 0xFF01 0x309B 0x309C 0x00B4 0xFF40 0x00A8 0xFF3E 0xFFE3 0xFF3F 0x30FD 0x30FE 0x309D 0x309E 0x3003 0x4EDD 0x3005 0x3006 0x3007 0x30FC 0x2015 0x2010 0xFF0F 0xFF3C 0xFF5E 0x2225 0xFF5C 0x2026 0x2025 0x2018 0x2019 0x201C 0x201D 0xFF08 0xFF09 0x3014 0x3015 0xFF3B 0xFF3D 0xFF5B 0xFF5D 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0xFF0B 0xFF0D 0x00B1 0x00D7 0x00F7 0xFF1D 0x2260 0xFF1C 0xFF1E 0x2266 0x2267 0x221E 0x2234 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFFE5 0xFF04 0xFFE0 0xFFE1 0xFF05 0xFF03 0xFF06 0xFF0A 0xFF20 0x00A7 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 +0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x203B 0x3012 0x2192 0x2190 0x2191 0x2193 0x3013 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2208 0x220B 0x2286 0x2287 0x2282 0x2283 0x222A 0x2229 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2227 0x2228 0xFFE2 0x21D2 0x21D4 0x2200 0x2203 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2220 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 0x226A 0x226B 0x221A 0x223D 0x221D 0x2235 0x222B 0x222C 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x212B 0x2030 0x266F 0x266D 0x266A 0x2020 0x2021 0x00B6 0x0020 0x0020 0x0020 0x0020 0x25EF +0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0x3000 0x3000 0x3000 0x3000 +0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C 0x042D 0x042E 0x042F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0430 0x0431 0x0432 0x0433 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C 0x044D 0x044E 0x044F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x2500 0x2502 0x250C 0x2510 0x2518 0x2514 0x251C 0x252C 0x2524 0x2534 0x253C 0x2501 0x2503 0x250F 0x2513 0x251B 0x2517 0x2523 0x2533 0x252B 0x253B 0x254B 0x2520 0x252F 0x2528 0x2537 0x253F 0x251D 0x2530 0x2525 0x2538 0x2542 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0386 0x0388 0x0389 0x038A 0x038C 0x038E 0x038F 0x0390 0x03AA 0x03AB 0x03AC 0x03AD 0x03AE 0x03AF 0x03B0 0x03C2 0x03CA 0x03CB 0x03CC 0x03CD 0x03CE 0x0406 0x0407 0x0456 0x0457 0x0490 0x0491 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x65E5 0x672C 0x8A9E 0x7409 0x7403 0x8AF8 0x4E2D 0x6587 0x7B80 0x4F53 0x7E41 0x9AD4 0xD55C 0xAD6D 0xC5B4 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 \ No newline at end of file diff --git a/resources/fonts/font_6x10_japanese.pbm b/resources/fonts/font_6x10_japanese.pbm new file mode 100644 index 000000000..75374137e Binary files /dev/null and b/resources/fonts/font_6x10_japanese.pbm differ diff --git a/resources/fonts/font_misaki_gothic_8x8.txt b/resources/fonts/font_6x10_japanese.txt similarity index 87% rename from resources/fonts/font_misaki_gothic_8x8.txt rename to resources/fonts/font_6x10_japanese.txt index 4ae534f59..51200ad1b 100644 --- a/resources/fonts/font_misaki_gothic_8x8.txt +++ b/resources/fonts/font_6x10_japanese.txt @@ -1,86 +1,94 @@ -0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F 0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F 0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F 0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F 0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F 0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E -0xFF61 0xFF62 0xFF63 0xFF64 0xFF65 0xFF66 0xFF67 0xFF68 0xFF69 0xFF6A 0xFF6B 0xFF6C 0xFF6D 0xFF6E 0xFF6F 0xFF70 0xFF71 0xFF72 0xFF73 0xFF74 0xFF75 0xFF76 0xFF77 0xFF78 0xFF79 0xFF7A 0xFF7B 0xFF7C 0xFF7D 0xFF7E 0xFF7F 0xFF80 0xFF81 0xFF82 0xFF83 0xFF84 0xFF85 0xFF86 0xFF87 0xFF88 0xFF89 0xFF8A 0xFF8B 0xFF8C 0xFF8D 0xFF8E 0xFF8F 0xFF90 0xFF91 0xFF92 0xFF93 0xFF94 0xFF95 0xFF96 0xFF97 0xFF98 0xFF99 0xFF9A 0xFF9B 0xFF9C 0xFF9D 0xFF9E 0xFF9F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x3000 0x3001 0x3002 0xFF0C 0xFF0E 0x30FB 0xFF1A 0xFF1B 0xFF1F 0xFF01 0x309B 0x309C 0x00B4 0xFF40 0x00A8 0xFF3E 0xFFE3 0xFF3F 0x30FD 0x30FE 0x309D 0x309E 0x3003 0x4EDD 0x3005 0x3006 0x3007 0x30FC 0x2015 0x2010 0xFF0F 0xFF3C 0xFF5E 0x2225 0xFF5C 0x2026 0x2025 0x2018 0x2019 0x201C 0x201D 0xFF08 0xFF09 0x3014 0x3015 0xFF3B 0xFF3D 0xFF5B 0xFF5D 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0xFF0B 0xFF0D 0x00B1 0x00D7 0x00F7 0xFF1D 0x2260 0xFF1C 0xFF1E 0x2266 0x2267 0x221E 0x2234 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFFE5 0xFF04 0xFFE0 0xFFE1 0xFF05 0xFF03 0xFF06 0xFF0A 0xFF20 0x00A7 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 -0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x203B 0x3012 0x2192 0x2190 0x2191 0x2193 0x3013 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2208 0x220B 0x2286 0x2287 0x2282 0x2283 0x222A 0x2229 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2227 0x2228 0xFFE2 0x21D2 0x21D4 0x2200 0x2203 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2220 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 0x226A 0x226B 0x221A 0x223D 0x221D 0x2235 0x222B 0x222C 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x212B 0x2030 0x266F 0x266D 0x266A 0x2020 0x2021 0x00B6 0x0020 0x0020 0x0020 0x0020 0x25EF -0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0x3000 0x3000 0x3000 0x3000 -0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 -0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 -0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C 0x042D 0x042E 0x042F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0430 0x0431 0x0432 0x0433 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C 0x044D 0x044E 0x044F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x2500 0x2502 0x250C 0x2510 0x2518 0x2514 0x251C 0x252C 0x2524 0x2534 0x253C 0x2501 0x2503 0x250F 0x2513 0x251B 0x2517 0x2523 0x2533 0x252B 0x253B 0x254B 0x2520 0x252F 0x2528 0x2537 0x253F 0x251D 0x2530 0x2525 0x2538 0x2542 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 -0x4E9C 0x5516 0x5A03 0x963F 0x54C0 0x611B 0x6328 0x59F6 0x9022 0x8475 0x831C 0x7A50 0x60AA 0x63E1 0x6E25 0x65ED 0x8466 0x82A6 0x9BF5 0x6893 0x5727 0x65A1 0x6271 0x5B9B 0x59D0 0x867B 0x98F4 0x7D62 0x7DBE 0x9B8E 0x6216 0x7C9F 0x88B7 0x5B89 0x5EB5 0x6309 0x6697 0x6848 0x95C7 0x978D 0x674F 0x4EE5 0x4F0A 0x4F4D 0x4F9D 0x5049 0x56F2 0x5937 0x59D4 0x5A01 0x5C09 0x60DF 0x610F 0x6170 0x6613 0x6905 0x70BA 0x754F 0x7570 0x79FB 0x7DAD 0x7DEF 0x80C3 0x840E 0x8863 0x8B02 0x9055 0x907A 0x533B 0x4E95 0x4EA5 0x57DF 0x80B2 0x90C1 0x78EF 0x4E00 0x58F1 0x6EA2 0x9038 0x7A32 0x8328 0x828B 0x9C2F 0x5141 0x5370 0x54BD 0x54E1 0x56E0 0x59FB 0x5F15 0x98F2 0x6DEB 0x80E4 0x852D -0x9662 0x9670 0x96A0 0x97FB 0x540B 0x53F3 0x5B87 0x70CF 0x7FBD 0x8FC2 0x96E8 0x536F 0x9D5C 0x7ABA 0x4E11 0x7893 0x81FC 0x6E26 0x5618 0x5504 0x6B1D 0x851A 0x9C3B 0x59E5 0x53A9 0x6D66 0x74DC 0x958F 0x5642 0x4E91 0x904B 0x96F2 0x834F 0x990C 0x53E1 0x55B6 0x5B30 0x5F71 0x6620 0x66F3 0x6804 0x6C38 0x6CF3 0x6D29 0x745B 0x76C8 0x7A4E 0x9834 0x82F1 0x885B 0x8A60 0x92ED 0x6DB2 0x75AB 0x76CA 0x99C5 0x60A6 0x8B01 0x8D8A 0x95B2 0x698E 0x53AD 0x5186 0x5712 0x5830 0x5944 0x5BB4 0x5EF6 0x6028 0x63A9 0x63F4 0x6CBF 0x6F14 0x708E 0x7114 0x7159 0x71D5 0x733F 0x7E01 0x8276 0x82D1 0x8597 0x9060 0x925B 0x9D1B 0x5869 0x65BC 0x6C5A 0x7525 0x51F9 0x592E 0x5965 0x5F80 0x5FDC -0x62BC 0x65FA 0x6A2A 0x6B27 0x6BB4 0x738B 0x7FC1 0x8956 0x9D2C 0x9D0E 0x9EC4 0x5CA1 0x6C96 0x837B 0x5104 0x5C4B 0x61B6 0x81C6 0x6876 0x7261 0x4E59 0x4FFA 0x5378 0x6069 0x6E29 0x7A4F 0x97F3 0x4E0B 0x5316 0x4EEE 0x4F55 0x4F3D 0x4FA1 0x4F73 0x52A0 0x53EF 0x5609 0x590F 0x5AC1 0x5BB6 0x5BE1 0x79D1 0x6687 0x679C 0x67B6 0x6B4C 0x6CB3 0x706B 0x73C2 0x798D 0x79BE 0x7A3C 0x7B87 0x82B1 0x82DB 0x8304 0x8377 0x83EF 0x83D3 0x8766 0x8AB2 0x5629 0x8CA8 0x8FE6 0x904E 0x971E 0x868A 0x4FC4 0x5CE8 0x6211 0x7259 0x753B 0x81E5 0x82BD 0x86FE 0x8CC0 0x96C5 0x9913 0x99D5 0x4ECB 0x4F1A 0x89E3 0x56DE 0x584A 0x58CA 0x5EFB 0x5FEB 0x602A 0x6094 0x6062 0x61D0 0x6212 0x62D0 0x6539 -0x9B41 0x6666 0x68B0 0x6D77 0x7070 0x754C 0x7686 0x7D75 0x82A5 0x87F9 0x958B 0x968E 0x8C9D 0x51F1 0x52BE 0x5916 0x54B3 0x5BB3 0x5D16 0x6168 0x6982 0x6DAF 0x788D 0x84CB 0x8857 0x8A72 0x93A7 0x9AB8 0x6D6C 0x99A8 0x86D9 0x57A3 0x67FF 0x86CE 0x920E 0x5283 0x5687 0x5404 0x5ED3 0x62E1 0x64B9 0x683C 0x6838 0x6BBB 0x7372 0x78BA 0x7A6B 0x899A 0x89D2 0x8D6B 0x8F03 0x90ED 0x95A3 0x9694 0x9769 0x5B66 0x5CB3 0x697D 0x984D 0x984E 0x639B 0x7B20 0x6A2B 0x6A7F 0x68B6 0x9C0D 0x6F5F 0x5272 0x559D 0x6070 0x62EC 0x6D3B 0x6E07 0x6ED1 0x845B 0x8910 0x8F44 0x4E14 0x9C39 0x53F6 0x691B 0x6A3A 0x9784 0x682A 0x515C 0x7AC3 0x84B2 0x91DC 0x938C 0x565B 0x9D28 0x6822 0x8305 0x8431 -0x7CA5 0x5208 0x82C5 0x74E6 0x4E7E 0x4F83 0x51A0 0x5BD2 0x520A 0x52D8 0x52E7 0x5DFB 0x559A 0x582A 0x59E6 0x5B8C 0x5B98 0x5BDB 0x5E72 0x5E79 0x60A3 0x611F 0x6163 0x61BE 0x63DB 0x6562 0x67D1 0x6853 0x68FA 0x6B3E 0x6B53 0x6C57 0x6F22 0x6F97 0x6F45 0x74B0 0x7518 0x76E3 0x770B 0x7AFF 0x7BA1 0x7C21 0x7DE9 0x7F36 0x7FF0 0x809D 0x8266 0x839E 0x89B3 0x8ACC 0x8CAB 0x9084 0x9451 0x9593 0x9591 0x95A2 0x9665 0x97D3 0x9928 0x8218 0x4E38 0x542B 0x5CB8 0x5DCC 0x73A9 0x764C 0x773C 0x5CA9 0x7FEB 0x8D0B 0x96C1 0x9811 0x9854 0x9858 0x4F01 0x4F0E 0x5371 0x559C 0x5668 0x57FA 0x5947 0x5B09 0x5BC4 0x5C90 0x5E0C 0x5E7E 0x5FCC 0x63EE 0x673A 0x65D7 0x65E2 0x671F 0x68CB 0x68C4 -0x6A5F 0x5E30 0x6BC5 0x6C17 0x6C7D 0x757F 0x7948 0x5B63 0x7A00 0x7D00 0x5FBD 0x898F 0x8A18 0x8CB4 0x8D77 0x8ECC 0x8F1D 0x98E2 0x9A0E 0x9B3C 0x4E80 0x507D 0x5100 0x5993 0x5B9C 0x622F 0x6280 0x64EC 0x6B3A 0x72A0 0x7591 0x7947 0x7FA9 0x87FB 0x8ABC 0x8B70 0x63AC 0x83CA 0x97A0 0x5409 0x5403 0x55AB 0x6854 0x6A58 0x8A70 0x7827 0x6775 0x9ECD 0x5374 0x5BA2 0x811A 0x8650 0x9006 0x4E18 0x4E45 0x4EC7 0x4F11 0x53CA 0x5438 0x5BAE 0x5F13 0x6025 0x6551 0x673D 0x6C42 0x6C72 0x6CE3 0x7078 0x7403 0x7A76 0x7AAE 0x7B08 0x7D1A 0x7CFE 0x7D66 0x65E7 0x725B 0x53BB 0x5C45 0x5DE8 0x62D2 0x62E0 0x6319 0x6E20 0x865A 0x8A31 0x8DDD 0x92F8 0x6F01 0x79A6 0x9B5A 0x4EA8 0x4EAB 0x4EAC -0x4F9B 0x4FA0 0x50D1 0x5147 0x7AF6 0x5171 0x51F6 0x5354 0x5321 0x537F 0x53EB 0x55AC 0x5883 0x5CE1 0x5F37 0x5F4A 0x602F 0x6050 0x606D 0x631F 0x6559 0x6A4B 0x6CC1 0x72C2 0x72ED 0x77EF 0x80F8 0x8105 0x8208 0x854E 0x90F7 0x93E1 0x97FF 0x9957 0x9A5A 0x4EF0 0x51DD 0x5C2D 0x6681 0x696D 0x5C40 0x66F2 0x6975 0x7389 0x6850 0x7C81 0x50C5 0x52E4 0x5747 0x5DFE 0x9326 0x65A4 0x6B23 0x6B3D 0x7434 0x7981 0x79BD 0x7B4B 0x7DCA 0x82B9 0x83CC 0x887F 0x895F 0x8B39 0x8FD1 0x91D1 0x541F 0x9280 0x4E5D 0x5036 0x53E5 0x533A 0x72D7 0x7396 0x77E9 0x82E6 0x8EAF 0x99C6 0x99C8 0x99D2 0x5177 0x611A 0x865E 0x55B0 0x7A7A 0x5076 0x5BD3 0x9047 0x9685 0x4E32 0x6ADB 0x91E7 0x5C51 0x5C48 -0x6398 0x7A9F 0x6C93 0x9774 0x8F61 0x7AAA 0x718A 0x9688 0x7C82 0x6817 0x7E70 0x6851 0x936C 0x52F2 0x541B 0x85AB 0x8A13 0x7FA4 0x8ECD 0x90E1 0x5366 0x8888 0x7941 0x4FC2 0x50BE 0x5211 0x5144 0x5553 0x572D 0x73EA 0x578B 0x5951 0x5F62 0x5F84 0x6075 0x6176 0x6167 0x61A9 0x63B2 0x643A 0x656C 0x666F 0x6842 0x6E13 0x7566 0x7A3D 0x7CFB 0x7D4C 0x7D99 0x7E4B 0x7F6B 0x830E 0x834A 0x86CD 0x8A08 0x8A63 0x8B66 0x8EFD 0x981A 0x9D8F 0x82B8 0x8FCE 0x9BE8 0x5287 0x621F 0x6483 0x6FC0 0x9699 0x6841 0x5091 0x6B20 0x6C7A 0x6F54 0x7A74 0x7D50 0x8840 0x8A23 0x6708 0x4EF6 0x5039 0x5026 0x5065 0x517C 0x5238 0x5263 0x55A7 0x570F 0x5805 0x5ACC 0x5EFA 0x61B2 0x61F8 0x62F3 0x6372 -0x691C 0x6A29 0x727D 0x72AC 0x732E 0x7814 0x786F 0x7D79 0x770C 0x80A9 0x898B 0x8B19 0x8CE2 0x8ED2 0x9063 0x9375 0x967A 0x9855 0x9A13 0x9E78 0x5143 0x539F 0x53B3 0x5E7B 0x5F26 0x6E1B 0x6E90 0x7384 0x73FE 0x7D43 0x8237 0x8A00 0x8AFA 0x9650 0x4E4E 0x500B 0x53E4 0x547C 0x56FA 0x59D1 0x5B64 0x5DF1 0x5EAB 0x5F27 0x6238 0x6545 0x67AF 0x6E56 0x72D0 0x7CCA 0x88B4 0x80A1 0x80E1 0x83F0 0x864E 0x8A87 0x8DE8 0x9237 0x96C7 0x9867 0x9F13 0x4E94 0x4E92 0x4F0D 0x5348 0x5449 0x543E 0x5A2F 0x5F8C 0x5FA1 0x609F 0x68A7 0x6A8E 0x745A 0x7881 0x8A9E 0x8AA4 0x8B77 0x9190 0x4E5E 0x9BC9 0x4EA4 0x4F7C 0x4FAF 0x5019 0x5016 0x5149 0x516C 0x529F 0x52B9 0x52FE 0x539A 0x53E3 0x5411 -0x540E 0x5589 0x5751 0x57A2 0x597D 0x5B54 0x5B5D 0x5B8F 0x5DE5 0x5DE7 0x5DF7 0x5E78 0x5E83 0x5E9A 0x5EB7 0x5F18 0x6052 0x614C 0x6297 0x62D8 0x63A7 0x653B 0x6602 0x6643 0x66F4 0x676D 0x6821 0x6897 0x69CB 0x6C5F 0x6D2A 0x6D69 0x6E2F 0x6E9D 0x7532 0x7687 0x786C 0x7A3F 0x7CE0 0x7D05 0x7D18 0x7D5E 0x7DB1 0x8015 0x8003 0x80AF 0x80B1 0x8154 0x818F 0x822A 0x8352 0x884C 0x8861 0x8B1B 0x8CA2 0x8CFC 0x90CA 0x9175 0x9271 0x783F 0x92FC 0x95A4 0x964D 0x9805 0x9999 0x9AD8 0x9D3B 0x525B 0x52AB 0x53F7 0x5408 0x58D5 0x62F7 0x6FE0 0x8C6A 0x8F5F 0x9EB9 0x514B 0x523B 0x544A 0x56FD 0x7A40 0x9177 0x9D60 0x9ED2 0x7344 0x6F09 0x8170 0x7511 0x5FFD 0x60DA 0x9AA8 0x72DB 0x8FBC -0x6B64 0x9803 0x4ECA 0x56F0 0x5764 0x58BE 0x5A5A 0x6068 0x61C7 0x660F 0x6606 0x6839 0x68B1 0x6DF7 0x75D5 0x7D3A 0x826E 0x9B42 0x4E9B 0x4F50 0x53C9 0x5506 0x5D6F 0x5DE6 0x5DEE 0x67FB 0x6C99 0x7473 0x7802 0x8A50 0x9396 0x88DF 0x5750 0x5EA7 0x632B 0x50B5 0x50AC 0x518D 0x6700 0x54C9 0x585E 0x59BB 0x5BB0 0x5F69 0x624D 0x63A1 0x683D 0x6B73 0x6E08 0x707D 0x91C7 0x7280 0x7815 0x7826 0x796D 0x658E 0x7D30 0x83DC 0x88C1 0x8F09 0x969B 0x5264 0x5728 0x6750 0x7F6A 0x8CA1 0x51B4 0x5742 0x962A 0x583A 0x698A 0x80B4 0x54B2 0x5D0E 0x57FC 0x7895 0x9DFA 0x4F5C 0x524A 0x548B 0x643E 0x6628 0x6714 0x67F5 0x7A84 0x7B56 0x7D22 0x932F 0x685C 0x9BAD 0x7B39 0x5319 0x518A 0x5237 -0x5BDF 0x62F6 0x64AE 0x64E6 0x672D 0x6BBA 0x85A9 0x96D1 0x7690 0x9BD6 0x634C 0x9306 0x9BAB 0x76BF 0x6652 0x4E09 0x5098 0x53C2 0x5C71 0x60E8 0x6492 0x6563 0x685F 0x71E6 0x73CA 0x7523 0x7B97 0x7E82 0x8695 0x8B83 0x8CDB 0x9178 0x9910 0x65AC 0x66AB 0x6B8B 0x4ED5 0x4ED4 0x4F3A 0x4F7F 0x523A 0x53F8 0x53F2 0x55E3 0x56DB 0x58EB 0x59CB 0x59C9 0x59FF 0x5B50 0x5C4D 0x5E02 0x5E2B 0x5FD7 0x601D 0x6307 0x652F 0x5B5C 0x65AF 0x65BD 0x65E8 0x679D 0x6B62 0x6B7B 0x6C0F 0x7345 0x7949 0x79C1 0x7CF8 0x7D19 0x7D2B 0x80A2 0x8102 0x81F3 0x8996 0x8A5E 0x8A69 0x8A66 0x8A8C 0x8AEE 0x8CC7 0x8CDC 0x96CC 0x98FC 0x6B6F 0x4E8B 0x4F3C 0x4F8D 0x5150 0x5B57 0x5BFA 0x6148 0x6301 0x6642 -0x6B21 0x6ECB 0x6CBB 0x723E 0x74BD 0x75D4 0x78C1 0x793A 0x800C 0x8033 0x81EA 0x8494 0x8F9E 0x6C50 0x9E7F 0x5F0F 0x8B58 0x9D2B 0x7AFA 0x8EF8 0x5B8D 0x96EB 0x4E03 0x53F1 0x57F7 0x5931 0x5AC9 0x5BA4 0x6089 0x6E7F 0x6F06 0x75BE 0x8CEA 0x5B9F 0x8500 0x7BE0 0x5072 0x67F4 0x829D 0x5C61 0x854A 0x7E1E 0x820E 0x5199 0x5C04 0x6368 0x8D66 0x659C 0x716E 0x793E 0x7D17 0x8005 0x8B1D 0x8ECA 0x906E 0x86C7 0x90AA 0x501F 0x52FA 0x5C3A 0x6753 0x707C 0x7235 0x914C 0x91C8 0x932B 0x82E5 0x5BC2 0x5F31 0x60F9 0x4E3B 0x53D6 0x5B88 0x624B 0x6731 0x6B8A 0x72E9 0x73E0 0x7A2E 0x816B 0x8DA3 0x9152 0x9996 0x5112 0x53D7 0x546A 0x5BFF 0x6388 0x6A39 0x7DAC 0x9700 0x56DA 0x53CE 0x5468 -0x5B97 0x5C31 0x5DDE 0x4FEE 0x6101 0x62FE 0x6D32 0x79C0 0x79CB 0x7D42 0x7E4D 0x7FD2 0x81ED 0x821F 0x8490 0x8846 0x8972 0x8B90 0x8E74 0x8F2F 0x9031 0x914B 0x916C 0x96C6 0x919C 0x4EC0 0x4F4F 0x5145 0x5341 0x5F93 0x620E 0x67D4 0x6C41 0x6E0B 0x7363 0x7E26 0x91CD 0x9283 0x53D4 0x5919 0x5BBF 0x6DD1 0x795D 0x7E2E 0x7C9B 0x587E 0x719F 0x51FA 0x8853 0x8FF0 0x4FCA 0x5CFB 0x6625 0x77AC 0x7AE3 0x821C 0x99FF 0x51C6 0x5FAA 0x65EC 0x696F 0x6B89 0x6DF3 0x6E96 0x6F64 0x76FE 0x7D14 0x5DE1 0x9075 0x9187 0x9806 0x51E6 0x521D 0x6240 0x6691 0x66D9 0x6E1A 0x5EB6 0x7DD2 0x7F72 0x66F8 0x85AF 0x85F7 0x8AF8 0x52A9 0x53D9 0x5973 0x5E8F 0x5F90 0x6055 0x92E4 0x9664 0x50B7 0x511F -0x52DD 0x5320 0x5347 0x53EC 0x54E8 0x5546 0x5531 0x5617 0x5968 0x59BE 0x5A3C 0x5BB5 0x5C06 0x5C0F 0x5C11 0x5C1A 0x5E84 0x5E8A 0x5EE0 0x5F70 0x627F 0x6284 0x62DB 0x638C 0x6377 0x6607 0x660C 0x662D 0x6676 0x677E 0x68A2 0x6A1F 0x6A35 0x6CBC 0x6D88 0x6E09 0x6E58 0x713C 0x7126 0x7167 0x75C7 0x7701 0x785D 0x7901 0x7965 0x79F0 0x7AE0 0x7B11 0x7CA7 0x7D39 0x8096 0x83D6 0x848B 0x8549 0x885D 0x88F3 0x8A1F 0x8A3C 0x8A54 0x8A73 0x8C61 0x8CDE 0x91A4 0x9266 0x937E 0x9418 0x969C 0x9798 0x4E0A 0x4E08 0x4E1E 0x4E57 0x5197 0x5270 0x57CE 0x5834 0x58CC 0x5B22 0x5E38 0x60C5 0x64FE 0x6761 0x6756 0x6D44 0x72B6 0x7573 0x7A63 0x84B8 0x8B72 0x91B8 0x9320 0x5631 0x57F4 0x98FE -0x62ED 0x690D 0x6B96 0x71ED 0x7E54 0x8077 0x8272 0x89E6 0x98DF 0x8755 0x8FB1 0x5C3B 0x4F38 0x4FE1 0x4FB5 0x5507 0x5A20 0x5BDD 0x5BE9 0x5FC3 0x614E 0x632F 0x65B0 0x664B 0x68EE 0x699B 0x6D78 0x6DF1 0x7533 0x75B9 0x771F 0x795E 0x79E6 0x7D33 0x81E3 0x82AF 0x85AA 0x89AA 0x8A3A 0x8EAB 0x8F9B 0x9032 0x91DD 0x9707 0x4EBA 0x4EC1 0x5203 0x5875 0x58EC 0x5C0B 0x751A 0x5C3D 0x814E 0x8A0A 0x8FC5 0x9663 0x976D 0x7B25 0x8ACF 0x9808 0x9162 0x56F3 0x53A8 0x9017 0x5439 0x5782 0x5E25 0x63A8 0x6C34 0x708A 0x7761 0x7C8B 0x7FE0 0x8870 0x9042 0x9154 0x9310 0x9318 0x968F 0x745E 0x9AC4 0x5D07 0x5D69 0x6570 0x67A2 0x8DA8 0x96DB 0x636E 0x6749 0x6919 0x83C5 0x9817 0x96C0 0x88FE -0x6F84 0x647A 0x5BF8 0x4E16 0x702C 0x755D 0x662F 0x51C4 0x5236 0x52E2 0x59D3 0x5F81 0x6027 0x6210 0x653F 0x6574 0x661F 0x6674 0x68F2 0x6816 0x6B63 0x6E05 0x7272 0x751F 0x76DB 0x7CBE 0x8056 0x58F0 0x88FD 0x897F 0x8AA0 0x8A93 0x8ACB 0x901D 0x9192 0x9752 0x9759 0x6589 0x7A0E 0x8106 0x96BB 0x5E2D 0x60DC 0x621A 0x65A5 0x6614 0x6790 0x77F3 0x7A4D 0x7C4D 0x7E3E 0x810A 0x8CAC 0x8D64 0x8DE1 0x8E5F 0x78A9 0x5207 0x62D9 0x63A5 0x6442 0x6298 0x8A2D 0x7A83 0x7BC0 0x8AAC 0x96EA 0x7D76 0x820C 0x8749 0x4ED9 0x5148 0x5343 0x5360 0x5BA3 0x5C02 0x5C16 0x5DDD 0x6226 0x6247 0x64B0 0x6813 0x6834 0x6CC9 0x6D45 0x6D17 0x67D3 0x6F5C 0x714E 0x717D 0x65CB 0x7A7F 0x7BAD 0x7DDA -0x7E4A 0x7FA8 0x817A 0x821B 0x8239 0x85A6 0x8A6E 0x8CCE 0x8DF5 0x9078 0x9077 0x92AD 0x9291 0x9583 0x9BAE 0x524D 0x5584 0x6F38 0x7136 0x5168 0x7985 0x7E55 0x81B3 0x7CCE 0x564C 0x5851 0x5CA8 0x63AA 0x66FE 0x66FD 0x695A 0x72D9 0x758F 0x758E 0x790E 0x7956 0x79DF 0x7C97 0x7D20 0x7D44 0x8607 0x8A34 0x963B 0x9061 0x9F20 0x50E7 0x5275 0x53CC 0x53E2 0x5009 0x55AA 0x58EE 0x594F 0x723D 0x5B8B 0x5C64 0x531D 0x60E3 0x60F3 0x635C 0x6383 0x633F 0x63BB 0x64CD 0x65E9 0x66F9 0x5DE3 0x69CD 0x69FD 0x6F15 0x71E5 0x4E89 0x75E9 0x76F8 0x7A93 0x7CDF 0x7DCF 0x7D9C 0x8061 0x8349 0x8358 0x846C 0x84BC 0x85FB 0x88C5 0x8D70 0x9001 0x906D 0x9397 0x971C 0x9A12 0x50CF 0x5897 0x618E -0x81D3 0x8535 0x8D08 0x9020 0x4FC3 0x5074 0x5247 0x5373 0x606F 0x6349 0x675F 0x6E2C 0x8DB3 0x901F 0x4FD7 0x5C5E 0x8CCA 0x65CF 0x7D9A 0x5352 0x8896 0x5176 0x63C3 0x5B58 0x5B6B 0x5C0A 0x640D 0x6751 0x905C 0x4ED6 0x591A 0x592A 0x6C70 0x8A51 0x553E 0x5815 0x59A5 0x60F0 0x6253 0x67C1 0x8235 0x6955 0x9640 0x99C4 0x9A28 0x4F53 0x5806 0x5BFE 0x8010 0x5CB1 0x5E2F 0x5F85 0x6020 0x614B 0x6234 0x66FF 0x6CF0 0x6EDE 0x80CE 0x817F 0x82D4 0x888B 0x8CB8 0x9000 0x902E 0x968A 0x9EDB 0x9BDB 0x4EE3 0x53F0 0x5927 0x7B2C 0x918D 0x984C 0x9DF9 0x6EDD 0x7027 0x5353 0x5544 0x5B85 0x6258 0x629E 0x62D3 0x6CA2 0x6FEF 0x7422 0x8A17 0x9438 0x6FC1 0x8AFE 0x8338 0x51E7 0x86F8 0x53EA -0x53E9 0x4F46 0x9054 0x8FB0 0x596A 0x8131 0x5DFD 0x7AEA 0x8FBF 0x68DA 0x8C37 0x72F8 0x9C48 0x6A3D 0x8AB0 0x4E39 0x5358 0x5606 0x5766 0x62C5 0x63A2 0x65E6 0x6B4E 0x6DE1 0x6E5B 0x70AD 0x77ED 0x7AEF 0x7BAA 0x7DBB 0x803D 0x80C6 0x86CB 0x8A95 0x935B 0x56E3 0x58C7 0x5F3E 0x65AD 0x6696 0x6A80 0x6BB5 0x7537 0x8AC7 0x5024 0x77E5 0x5730 0x5F1B 0x6065 0x667A 0x6C60 0x75F4 0x7A1A 0x7F6E 0x81F4 0x8718 0x9045 0x99B3 0x7BC9 0x755C 0x7AF9 0x7B51 0x84C4 0x9010 0x79E9 0x7A92 0x8336 0x5AE1 0x7740 0x4E2D 0x4EF2 0x5B99 0x5FE0 0x62BD 0x663C 0x67F1 0x6CE8 0x866B 0x8877 0x8A3B 0x914E 0x92F3 0x99D0 0x6A17 0x7026 0x732A 0x82E7 0x8457 0x8CAF 0x4E01 0x5146 0x51CB 0x558B 0x5BF5 -0x5E16 0x5E33 0x5E81 0x5F14 0x5F35 0x5F6B 0x5FB4 0x61F2 0x6311 0x66A2 0x671D 0x6F6E 0x7252 0x753A 0x773A 0x8074 0x8139 0x8178 0x8776 0x8ABF 0x8ADC 0x8D85 0x8DF3 0x929A 0x9577 0x9802 0x9CE5 0x52C5 0x6357 0x76F4 0x6715 0x6C88 0x73CD 0x8CC3 0x93AE 0x9673 0x6D25 0x589C 0x690E 0x69CC 0x8FFD 0x939A 0x75DB 0x901A 0x585A 0x6802 0x63B4 0x69FB 0x4F43 0x6F2C 0x67D8 0x8FBB 0x8526 0x7DB4 0x9354 0x693F 0x6F70 0x576A 0x58F7 0x5B2C 0x7D2C 0x722A 0x540A 0x91E3 0x9DB4 0x4EAD 0x4F4E 0x505C 0x5075 0x5243 0x8C9E 0x5448 0x5824 0x5B9A 0x5E1D 0x5E95 0x5EAD 0x5EF7 0x5F1F 0x608C 0x62B5 0x633A 0x63D0 0x68AF 0x6C40 0x7887 0x798E 0x7A0B 0x7DE0 0x8247 0x8A02 0x8AE6 0x8E44 0x9013 -0x90B8 0x912D 0x91D8 0x9F0E 0x6CE5 0x6458 0x64E2 0x6575 0x6EF4 0x7684 0x7B1B 0x9069 0x93D1 0x6EBA 0x54F2 0x5FB9 0x64A4 0x8F4D 0x8FED 0x9244 0x5178 0x586B 0x5929 0x5C55 0x5E97 0x6DFB 0x7E8F 0x751C 0x8CBC 0x8EE2 0x985B 0x70B9 0x4F1D 0x6BBF 0x6FB1 0x7530 0x96FB 0x514E 0x5410 0x5835 0x5857 0x59AC 0x5C60 0x5F92 0x6597 0x675C 0x6E21 0x767B 0x83DF 0x8CED 0x9014 0x90FD 0x934D 0x7825 0x783A 0x52AA 0x5EA6 0x571F 0x5974 0x6012 0x5012 0x515A 0x51AC 0x51CD 0x5200 0x5510 0x5854 0x5858 0x5957 0x5B95 0x5CF6 0x5D8B 0x60BC 0x6295 0x642D 0x6771 0x6843 0x68BC 0x68DF 0x76D7 0x6DD8 0x6E6F 0x6D9B 0x706F 0x71C8 0x5F53 0x75D8 0x7977 0x7B49 0x7B54 0x7B52 0x7CD6 0x7D71 0x5230 -0x8463 0x8569 0x85E4 0x8A0E 0x8B04 0x8C46 0x8E0F 0x9003 0x900F 0x9419 0x9676 0x982D 0x9A30 0x95D8 0x50CD 0x52D5 0x540C 0x5802 0x5C0E 0x61A7 0x649E 0x6D1E 0x77B3 0x7AE5 0x80F4 0x8404 0x9053 0x9285 0x5CE0 0x9D07 0x533F 0x5F97 0x5FB3 0x6D9C 0x7279 0x7763 0x79BF 0x7BE4 0x6BD2 0x72EC 0x8AAD 0x6803 0x6A61 0x51F8 0x7A81 0x6934 0x5C4A 0x9CF6 0x82EB 0x5BC5 0x9149 0x701E 0x5678 0x5C6F 0x60C7 0x6566 0x6C8C 0x8C5A 0x9041 0x9813 0x5451 0x66C7 0x920D 0x5948 0x90A3 0x5185 0x4E4D 0x51EA 0x8599 0x8B0E 0x7058 0x637A 0x934B 0x6962 0x99B4 0x7E04 0x7577 0x5357 0x6960 0x8EDF 0x96E3 0x6C5D 0x4E8C 0x5C3C 0x5F10 0x8FE9 0x5302 0x8CD1 0x8089 0x8679 0x5EFF 0x65E5 0x4E73 0x5165 -0x5982 0x5C3F 0x97EE 0x4EFB 0x598A 0x5FCD 0x8A8D 0x6FE1 0x79B0 0x7962 0x5BE7 0x8471 0x732B 0x71B1 0x5E74 0x5FF5 0x637B 0x649A 0x71C3 0x7C98 0x4E43 0x5EFC 0x4E4B 0x57DC 0x56A2 0x60A9 0x6FC3 0x7D0D 0x80FD 0x8133 0x81BF 0x8FB2 0x8997 0x86A4 0x5DF4 0x628A 0x64AD 0x8987 0x6777 0x6CE2 0x6D3E 0x7436 0x7834 0x5A46 0x7F75 0x82AD 0x99AC 0x4FF3 0x5EC3 0x62DD 0x6392 0x6557 0x676F 0x76C3 0x724C 0x80CC 0x80BA 0x8F29 0x914D 0x500D 0x57F9 0x5A92 0x6885 0x6973 0x7164 0x72FD 0x8CB7 0x58F2 0x8CE0 0x966A 0x9019 0x877F 0x79E4 0x77E7 0x8429 0x4F2F 0x5265 0x535A 0x62CD 0x67CF 0x6CCA 0x767D 0x7B94 0x7C95 0x8236 0x8584 0x8FEB 0x66DD 0x6F20 0x7206 0x7E1B 0x83AB 0x99C1 0x9EA6 -0x51FD 0x7BB1 0x7872 0x7BB8 0x8087 0x7B48 0x6AE8 0x5E61 0x808C 0x7551 0x7560 0x516B 0x9262 0x6E8C 0x767A 0x9197 0x9AEA 0x4F10 0x7F70 0x629C 0x7B4F 0x95A5 0x9CE9 0x567A 0x5859 0x86E4 0x96BC 0x4F34 0x5224 0x534A 0x53CD 0x53DB 0x5E06 0x642C 0x6591 0x677F 0x6C3E 0x6C4E 0x7248 0x72AF 0x73ED 0x7554 0x7E41 0x822C 0x85E9 0x8CA9 0x7BC4 0x91C6 0x7169 0x9812 0x98EF 0x633D 0x6669 0x756A 0x76E4 0x78D0 0x8543 0x86EE 0x532A 0x5351 0x5426 0x5983 0x5E87 0x5F7C 0x60B2 0x6249 0x6279 0x62AB 0x6590 0x6BD4 0x6CCC 0x75B2 0x76AE 0x7891 0x79D8 0x7DCB 0x7F77 0x80A5 0x88AB 0x8AB9 0x8CBB 0x907F 0x975E 0x98DB 0x6A0B 0x7C38 0x5099 0x5C3E 0x5FAE 0x6787 0x6BD8 0x7435 0x7709 0x7F8E -0x9F3B 0x67CA 0x7A17 0x5339 0x758B 0x9AED 0x5F66 0x819D 0x83F1 0x8098 0x5F3C 0x5FC5 0x7562 0x7B46 0x903C 0x6867 0x59EB 0x5A9B 0x7D10 0x767E 0x8B2C 0x4FF5 0x5F6A 0x6A19 0x6C37 0x6F02 0x74E2 0x7968 0x8868 0x8A55 0x8C79 0x5EDF 0x63CF 0x75C5 0x79D2 0x82D7 0x9328 0x92F2 0x849C 0x86ED 0x9C2D 0x54C1 0x5F6C 0x658C 0x6D5C 0x7015 0x8CA7 0x8CD3 0x983B 0x654F 0x74F6 0x4E0D 0x4ED8 0x57E0 0x592B 0x5A66 0x5BCC 0x51A8 0x5E03 0x5E9C 0x6016 0x6276 0x6577 0x65A7 0x666E 0x6D6E 0x7236 0x7B26 0x8150 0x819A 0x8299 0x8B5C 0x8CA0 0x8CE6 0x8D74 0x961C 0x9644 0x4FAE 0x64AB 0x6B66 0x821E 0x8461 0x856A 0x90E8 0x5C01 0x6953 0x98A8 0x847A 0x8557 0x4F0F 0x526F 0x5FA9 0x5E45 0x670D -0x798F 0x8179 0x8907 0x8986 0x6DF5 0x5F17 0x6255 0x6CB8 0x4ECF 0x7269 0x9B92 0x5206 0x543B 0x5674 0x58B3 0x61A4 0x626E 0x711A 0x596E 0x7C89 0x7CDE 0x7D1B 0x96F0 0x6587 0x805E 0x4E19 0x4F75 0x5175 0x5840 0x5E63 0x5E73 0x5F0A 0x67C4 0x4E26 0x853D 0x9589 0x965B 0x7C73 0x9801 0x50FB 0x58C1 0x7656 0x78A7 0x5225 0x77A5 0x8511 0x7B86 0x504F 0x5909 0x7247 0x7BC7 0x7DE8 0x8FBA 0x8FD4 0x904D 0x4FBF 0x52C9 0x5A29 0x5F01 0x97AD 0x4FDD 0x8217 0x92EA 0x5703 0x6355 0x6B69 0x752B 0x88DC 0x8F14 0x7A42 0x52DF 0x5893 0x6155 0x620A 0x66AE 0x6BCD 0x7C3F 0x83E9 0x5023 0x4FF8 0x5305 0x5446 0x5831 0x5949 0x5B9D 0x5CF0 0x5CEF 0x5D29 0x5E96 0x62B1 0x6367 0x653E 0x65B9 0x670B -0x6CD5 0x6CE1 0x70F9 0x7832 0x7E2B 0x80DE 0x82B3 0x840C 0x84EC 0x8702 0x8912 0x8A2A 0x8C4A 0x90A6 0x92D2 0x98FD 0x9CF3 0x9D6C 0x4E4F 0x4EA1 0x508D 0x5256 0x574A 0x59A8 0x5E3D 0x5FD8 0x5FD9 0x623F 0x66B4 0x671B 0x67D0 0x68D2 0x5192 0x7D21 0x80AA 0x81A8 0x8B00 0x8C8C 0x8CBF 0x927E 0x9632 0x5420 0x982C 0x5317 0x50D5 0x535C 0x58A8 0x64B2 0x6734 0x7267 0x7766 0x7A46 0x91E6 0x52C3 0x6CA1 0x6B86 0x5800 0x5E4C 0x5954 0x672C 0x7FFB 0x51E1 0x76C6 0x6469 0x78E8 0x9B54 0x9EBB 0x57CB 0x59B9 0x6627 0x679A 0x6BCE 0x54E9 0x69D9 0x5E55 0x819C 0x6795 0x9BAA 0x67FE 0x9C52 0x685D 0x4EA6 0x4FE3 0x53C8 0x62B9 0x672B 0x6CAB 0x8FC4 0x4FAD 0x7E6D 0x9EBF 0x4E07 0x6162 0x6E80 -0x6F2B 0x8513 0x5473 0x672A 0x9B45 0x5DF3 0x7B95 0x5CAC 0x5BC6 0x871C 0x6E4A 0x84D1 0x7A14 0x8108 0x5999 0x7C8D 0x6C11 0x7720 0x52D9 0x5922 0x7121 0x725F 0x77DB 0x9727 0x9D61 0x690B 0x5A7F 0x5A18 0x51A5 0x540D 0x547D 0x660E 0x76DF 0x8FF7 0x9298 0x9CF4 0x59EA 0x725D 0x6EC5 0x514D 0x68C9 0x7DBF 0x7DEC 0x9762 0x9EBA 0x6478 0x6A21 0x8302 0x5984 0x5B5F 0x6BDB 0x731B 0x76F2 0x7DB2 0x8017 0x8499 0x5132 0x6728 0x9ED9 0x76EE 0x6762 0x52FF 0x9905 0x5C24 0x623B 0x7C7E 0x8CB0 0x554F 0x60B6 0x7D0B 0x9580 0x5301 0x4E5F 0x51B6 0x591C 0x723A 0x8036 0x91CE 0x5F25 0x77E2 0x5384 0x5F79 0x7D04 0x85AC 0x8A33 0x8E8D 0x9756 0x67F3 0x85AE 0x9453 0x6109 0x6108 0x6CB9 0x7652 -0x8AED 0x8F38 0x552F 0x4F51 0x512A 0x52C7 0x53CB 0x5BA5 0x5E7D 0x60A0 0x6182 0x63D6 0x6709 0x67DA 0x6E67 0x6D8C 0x7336 0x7337 0x7531 0x7950 0x88D5 0x8A98 0x904A 0x9091 0x90F5 0x96C4 0x878D 0x5915 0x4E88 0x4F59 0x4E0E 0x8A89 0x8F3F 0x9810 0x50AD 0x5E7C 0x5996 0x5BB9 0x5EB8 0x63DA 0x63FA 0x64C1 0x66DC 0x694A 0x69D8 0x6D0B 0x6EB6 0x7194 0x7528 0x7AAF 0x7F8A 0x8000 0x8449 0x84C9 0x8981 0x8B21 0x8E0A 0x9065 0x967D 0x990A 0x617E 0x6291 0x6B32 0x6C83 0x6D74 0x7FCC 0x7FFC 0x6DC0 0x7F85 0x87BA 0x88F8 0x6765 0x83B1 0x983C 0x96F7 0x6D1B 0x7D61 0x843D 0x916A 0x4E71 0x5375 0x5D50 0x6B04 0x6FEB 0x85CD 0x862D 0x89A7 0x5229 0x540F 0x5C65 0x674E 0x68A8 0x7406 0x7483 -0x75E2 0x88CF 0x88E1 0x91CC 0x96E2 0x9678 0x5F8B 0x7387 0x7ACB 0x844E 0x63A0 0x7565 0x5289 0x6D41 0x6E9C 0x7409 0x7559 0x786B 0x7C92 0x9686 0x7ADC 0x9F8D 0x4FB6 0x616E 0x65C5 0x865C 0x4E86 0x4EAE 0x50DA 0x4E21 0x51CC 0x5BEE 0x6599 0x6881 0x6DBC 0x731F 0x7642 0x77AD 0x7A1C 0x7CE7 0x826F 0x8AD2 0x907C 0x91CF 0x9675 0x9818 0x529B 0x7DD1 0x502B 0x5398 0x6797 0x6DCB 0x71D0 0x7433 0x81E8 0x8F2A 0x96A3 0x9C57 0x9E9F 0x7460 0x5841 0x6D99 0x7D2F 0x985E 0x4EE4 0x4F36 0x4F8B 0x51B7 0x52B1 0x5DBA 0x601C 0x73B2 0x793C 0x82D3 0x9234 0x96B7 0x96F6 0x970A 0x9E97 0x9F62 0x66A6 0x6B74 0x5217 0x52A3 0x70C8 0x88C2 0x5EC9 0x604B 0x6190 0x6F23 0x7149 0x7C3E 0x7DF4 0x806F -0x84EE 0x9023 0x932C 0x5442 0x9B6F 0x6AD3 0x7089 0x8CC2 0x8DEF 0x9732 0x52B4 0x5A41 0x5ECA 0x5F04 0x6717 0x697C 0x6994 0x6D6A 0x6F0F 0x7262 0x72FC 0x7BED 0x8001 0x807E 0x874B 0x90CE 0x516D 0x9E93 0x7984 0x808B 0x9332 0x8AD6 0x502D 0x548C 0x8A71 0x6B6A 0x8CC4 0x8107 0x60D1 0x67A0 0x9DF2 0x4E99 0x4E98 0x9C10 0x8A6B 0x85C1 0x8568 0x6900 0x6E7E 0x7897 0x8155 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 -0x5F0C 0x4E10 0x4E15 0x4E2A 0x4E31 0x4E36 0x4E3C 0x4E3F 0x4E42 0x4E56 0x4E58 0x4E82 0x4E85 0x8C6B 0x4E8A 0x8212 0x5F0D 0x4E8E 0x4E9E 0x4E9F 0x4EA0 0x4EA2 0x4EB0 0x4EB3 0x4EB6 0x4ECE 0x4ECD 0x4EC4 0x4EC6 0x4EC2 0x4ED7 0x4EDE 0x4EED 0x4EDF 0x4EF7 0x4F09 0x4F5A 0x4F30 0x4F5B 0x4F5D 0x4F57 0x4F47 0x4F76 0x4F88 0x4F8F 0x4F98 0x4F7B 0x4F69 0x4F70 0x4F91 0x4F6F 0x4F86 0x4F96 0x5118 0x4FD4 0x4FDF 0x4FCE 0x4FD8 0x4FDB 0x4FD1 0x4FDA 0x4FD0 0x4FE4 0x4FE5 0x501A 0x5028 0x5014 0x502A 0x5025 0x5005 0x4F1C 0x4FF6 0x5021 0x5029 0x502C 0x4FFE 0x4FEF 0x5011 0x5006 0x5043 0x5047 0x6703 0x5055 0x5050 0x5048 0x505A 0x5056 0x506C 0x5078 0x5080 0x509A 0x5085 0x50B4 0x50B2 -0x50C9 0x50CA 0x50B3 0x50C2 0x50D6 0x50DE 0x50E5 0x50ED 0x50E3 0x50EE 0x50F9 0x50F5 0x5109 0x5101 0x5102 0x5116 0x5115 0x5114 0x511A 0x5121 0x513A 0x5137 0x513C 0x513B 0x513F 0x5140 0x5152 0x514C 0x5154 0x5162 0x7AF8 0x5169 0x516A 0x516E 0x5180 0x5182 0x56D8 0x518C 0x5189 0x518F 0x5191 0x5193 0x5195 0x5196 0x51A4 0x51A6 0x51A2 0x51A9 0x51AA 0x51AB 0x51B3 0x51B1 0x51B2 0x51B0 0x51B5 0x51BD 0x51C5 0x51C9 0x51DB 0x51E0 0x8655 0x51E9 0x51ED 0x51F0 0x51F5 0x51FE 0x5204 0x520B 0x5214 0x520E 0x5227 0x522A 0x522E 0x5233 0x5239 0x524F 0x5244 0x524B 0x524C 0x525E 0x5254 0x526A 0x5274 0x5269 0x5273 0x527F 0x527D 0x528D 0x5294 0x5292 0x5271 0x5288 0x5291 0x8FA8 -0x8FA7 0x52AC 0x52AD 0x52BC 0x52B5 0x52C1 0x52CD 0x52D7 0x52DE 0x52E3 0x52E6 0x98ED 0x52E0 0x52F3 0x52F5 0x52F8 0x52F9 0x5306 0x5308 0x7538 0x530D 0x5310 0x530F 0x5315 0x531A 0x5323 0x532F 0x5331 0x5333 0x5338 0x5340 0x5346 0x5345 0x4E17 0x5349 0x534D 0x51D6 0x535E 0x5369 0x536E 0x5918 0x537B 0x5377 0x5382 0x5396 0x53A0 0x53A6 0x53A5 0x53AE 0x53B0 0x53B6 0x53C3 0x7C12 0x96D9 0x53DF 0x66FC 0x71EE 0x53EE 0x53E8 0x53ED 0x53FA 0x5401 0x543D 0x5440 0x542C 0x542D 0x543C 0x542E 0x5436 0x5429 0x541D 0x544E 0x548F 0x5475 0x548E 0x545F 0x5471 0x5477 0x5470 0x5492 0x547B 0x5480 0x5476 0x5484 0x5490 0x5486 0x54C7 0x54A2 0x54B8 0x54A5 0x54AC 0x54C4 0x54C8 0x54A8 -0x54AB 0x54C2 0x54A4 0x54BE 0x54BC 0x54D8 0x54E5 0x54E6 0x550F 0x5514 0x54FD 0x54EE 0x54ED 0x54FA 0x54E2 0x5539 0x5540 0x5563 0x554C 0x552E 0x555C 0x5545 0x5556 0x5557 0x5538 0x5533 0x555D 0x5599 0x5580 0x54AF 0x558A 0x559F 0x557B 0x557E 0x5598 0x559E 0x55AE 0x557C 0x5583 0x55A9 0x5587 0x55A8 0x55DA 0x55C5 0x55DF 0x55C4 0x55DC 0x55E4 0x55D4 0x5614 0x55F7 0x5616 0x55FE 0x55FD 0x561B 0x55F9 0x564E 0x5650 0x71DF 0x5634 0x5636 0x5632 0x5638 0x566B 0x5664 0x562F 0x566C 0x566A 0x5686 0x5680 0x568A 0x56A0 0x5694 0x568F 0x56A5 0x56AE 0x56B6 0x56B4 0x56C2 0x56BC 0x56C1 0x56C3 0x56C0 0x56C8 0x56CE 0x56D1 0x56D3 0x56D7 0x56EE 0x56F9 0x5700 0x56FF 0x5704 0x5709 -0x5708 0x570B 0x570D 0x5713 0x5718 0x5716 0x55C7 0x571C 0x5726 0x5737 0x5738 0x574E 0x573B 0x5740 0x574F 0x5769 0x57C0 0x5788 0x5761 0x577F 0x5789 0x5793 0x57A0 0x57B3 0x57A4 0x57AA 0x57B0 0x57C3 0x57C6 0x57D4 0x57D2 0x57D3 0x580A 0x57D6 0x57E3 0x580B 0x5819 0x581D 0x5872 0x5821 0x5862 0x584B 0x5870 0x6BC0 0x5852 0x583D 0x5879 0x5885 0x58B9 0x589F 0x58AB 0x58BA 0x58DE 0x58BB 0x58B8 0x58AE 0x58C5 0x58D3 0x58D1 0x58D7 0x58D9 0x58D8 0x58E5 0x58DC 0x58E4 0x58DF 0x58EF 0x58FA 0x58F9 0x58FB 0x58FC 0x58FD 0x5902 0x590A 0x5910 0x591B 0x68A6 0x5925 0x592C 0x592D 0x5932 0x5938 0x593E 0x7AD2 0x5955 0x5950 0x594E 0x595A 0x5958 0x5962 0x5960 0x5967 0x596C 0x5969 -0x5978 0x5981 0x599D 0x4F5E 0x4FAB 0x59A3 0x59B2 0x59C6 0x59E8 0x59DC 0x598D 0x59D9 0x59DA 0x5A25 0x5A1F 0x5A11 0x5A1C 0x5A09 0x5A1A 0x5A40 0x5A6C 0x5A49 0x5A35 0x5A36 0x5A62 0x5A6A 0x5A9A 0x5ABC 0x5ABE 0x5ACB 0x5AC2 0x5ABD 0x5AE3 0x5AD7 0x5AE6 0x5AE9 0x5AD6 0x5AFA 0x5AFB 0x5B0C 0x5B0B 0x5B16 0x5B32 0x5AD0 0x5B2A 0x5B36 0x5B3E 0x5B43 0x5B45 0x5B40 0x5B51 0x5B55 0x5B5A 0x5B5B 0x5B65 0x5B69 0x5B70 0x5B73 0x5B75 0x5B78 0x6588 0x5B7A 0x5B80 0x5B83 0x5BA6 0x5BB8 0x5BC3 0x5BC7 0x5BC9 0x5BD4 0x5BD0 0x5BE4 0x5BE6 0x5BE2 0x5BDE 0x5BE5 0x5BEB 0x5BF0 0x5BF6 0x5BF3 0x5C05 0x5C07 0x5C08 0x5C0D 0x5C13 0x5C20 0x5C22 0x5C28 0x5C38 0x5C39 0x5C41 0x5C46 0x5C4E 0x5C53 -0x5C50 0x5C4F 0x5B71 0x5C6C 0x5C6E 0x4E62 0x5C76 0x5C79 0x5C8C 0x5C91 0x5C94 0x599B 0x5CAB 0x5CBB 0x5CB6 0x5CBC 0x5CB7 0x5CC5 0x5CBE 0x5CC7 0x5CD9 0x5CE9 0x5CFD 0x5CFA 0x5CED 0x5D8C 0x5CEA 0x5D0B 0x5D15 0x5D17 0x5D5C 0x5D1F 0x5D1B 0x5D11 0x5D14 0x5D22 0x5D1A 0x5D19 0x5D18 0x5D4C 0x5D52 0x5D4E 0x5D4B 0x5D6C 0x5D73 0x5D76 0x5D87 0x5D84 0x5D82 0x5DA2 0x5D9D 0x5DAC 0x5DAE 0x5DBD 0x5D90 0x5DB7 0x5DBC 0x5DC9 0x5DCD 0x5DD3 0x5DD2 0x5DD6 0x5DDB 0x5DEB 0x5DF2 0x5DF5 0x5E0B 0x5E1A 0x5E19 0x5E11 0x5E1B 0x5E36 0x5E37 0x5E44 0x5E43 0x5E40 0x5E4E 0x5E57 0x5E54 0x5E5F 0x5E62 0x5E64 0x5E47 0x5E75 0x5E76 0x5E7A 0x9EBC 0x5E7F 0x5EA0 0x5EC1 0x5EC2 0x5EC8 0x5ED0 0x5ECF -0x5ED6 0x5EE3 0x5EDD 0x5EDA 0x5EDB 0x5EE2 0x5EE1 0x5EE8 0x5EE9 0x5EEC 0x5EF1 0x5EF3 0x5EF0 0x5EF4 0x5EF8 0x5EFE 0x5F03 0x5F09 0x5F5D 0x5F5C 0x5F0B 0x5F11 0x5F16 0x5F29 0x5F2D 0x5F38 0x5F41 0x5F48 0x5F4C 0x5F4E 0x5F2F 0x5F51 0x5F56 0x5F57 0x5F59 0x5F61 0x5F6D 0x5F73 0x5F77 0x5F83 0x5F82 0x5F7F 0x5F8A 0x5F88 0x5F91 0x5F87 0x5F9E 0x5F99 0x5F98 0x5FA0 0x5FA8 0x5FAD 0x5FBC 0x5FD6 0x5FFB 0x5FE4 0x5FF8 0x5FF1 0x5FDD 0x60B3 0x5FFF 0x6021 0x6060 0x6019 0x6010 0x6029 0x600E 0x6031 0x601B 0x6015 0x602B 0x6026 0x600F 0x603A 0x605A 0x6041 0x606A 0x6077 0x605F 0x604A 0x6046 0x604D 0x6063 0x6043 0x6064 0x6042 0x606C 0x606B 0x6059 0x6081 0x608D 0x60E7 0x6083 0x609A -0x6084 0x609B 0x6096 0x6097 0x6092 0x60A7 0x608B 0x60E1 0x60B8 0x60E0 0x60D3 0x60B4 0x5FF0 0x60BD 0x60C6 0x60B5 0x60D8 0x614D 0x6115 0x6106 0x60F6 0x60F7 0x6100 0x60F4 0x60FA 0x6103 0x6121 0x60FB 0x60F1 0x610D 0x610E 0x6147 0x613E 0x6128 0x6127 0x614A 0x613F 0x613C 0x612C 0x6134 0x613D 0x6142 0x6144 0x6173 0x6177 0x6158 0x6159 0x615A 0x616B 0x6174 0x616F 0x6165 0x6171 0x615F 0x615D 0x6153 0x6175 0x6199 0x6196 0x6187 0x61AC 0x6194 0x619A 0x618A 0x6191 0x61AB 0x61AE 0x61CC 0x61CA 0x61C9 0x61F7 0x61C8 0x61C3 0x61C6 0x61BA 0x61CB 0x7F79 0x61CD 0x61E6 0x61E3 0x61F6 0x61FA 0x61F4 0x61FF 0x61FD 0x61FC 0x61FE 0x6200 0x6208 0x6209 0x620D 0x620C 0x6214 0x621B -0x621E 0x6221 0x622A 0x622E 0x6230 0x6232 0x6233 0x6241 0x624E 0x625E 0x6263 0x625B 0x6260 0x6268 0x627C 0x6282 0x6289 0x627E 0x6292 0x6293 0x6296 0x62D4 0x6283 0x6294 0x62D7 0x62D1 0x62BB 0x62CF 0x62FF 0x62C6 0x64D4 0x62C8 0x62DC 0x62CC 0x62CA 0x62C2 0x62C7 0x629B 0x62C9 0x630C 0x62EE 0x62F1 0x6327 0x6302 0x6308 0x62EF 0x62F5 0x6350 0x633E 0x634D 0x641C 0x634F 0x6396 0x638E 0x6380 0x63AB 0x6376 0x63A3 0x638F 0x6389 0x639F 0x63B5 0x636B 0x6369 0x63BE 0x63E9 0x63C0 0x63C6 0x63E3 0x63C9 0x63D2 0x63F6 0x63C4 0x6416 0x6434 0x6406 0x6413 0x6426 0x6436 0x651D 0x6417 0x6428 0x640F 0x6467 0x646F 0x6476 0x644E 0x652A 0x6495 0x6493 0x64A5 0x64A9 0x6488 0x64BC -0x64DA 0x64D2 0x64C5 0x64C7 0x64BB 0x64D8 0x64C2 0x64F1 0x64E7 0x8209 0x64E0 0x64E1 0x62AC 0x64E3 0x64EF 0x652C 0x64F6 0x64F4 0x64F2 0x64FA 0x6500 0x64FD 0x6518 0x651C 0x6505 0x6524 0x6523 0x652B 0x6534 0x6535 0x6537 0x6536 0x6538 0x754B 0x6548 0x6556 0x6555 0x654D 0x6558 0x655E 0x655D 0x6572 0x6578 0x6582 0x6583 0x8B8A 0x659B 0x659F 0x65AB 0x65B7 0x65C3 0x65C6 0x65C1 0x65C4 0x65CC 0x65D2 0x65DB 0x65D9 0x65E0 0x65E1 0x65F1 0x6772 0x660A 0x6603 0x65FB 0x6773 0x6635 0x6636 0x6634 0x661C 0x664F 0x6644 0x6649 0x6641 0x665E 0x665D 0x6664 0x6667 0x6668 0x665F 0x6662 0x6670 0x6683 0x6688 0x668E 0x6689 0x6684 0x6698 0x669D 0x66C1 0x66B9 0x66C9 0x66BE 0x66BC -0x66C4 0x66B8 0x66D6 0x66DA 0x66E0 0x663F 0x66E6 0x66E9 0x66F0 0x66F5 0x66F7 0x670F 0x6716 0x671E 0x6726 0x6727 0x9738 0x672E 0x673F 0x6736 0x6741 0x6738 0x6737 0x6746 0x675E 0x6760 0x6759 0x6763 0x6764 0x6789 0x6770 0x67A9 0x677C 0x676A 0x678C 0x678B 0x67A6 0x67A1 0x6785 0x67B7 0x67EF 0x67B4 0x67EC 0x67B3 0x67E9 0x67B8 0x67E4 0x67DE 0x67DD 0x67E2 0x67EE 0x67B9 0x67CE 0x67C6 0x67E7 0x6A9C 0x681E 0x6846 0x6829 0x6840 0x684D 0x6832 0x684E 0x68B3 0x682B 0x6859 0x6863 0x6877 0x687F 0x689F 0x688F 0x68AD 0x6894 0x689D 0x689B 0x6883 0x6AAE 0x68B9 0x6874 0x68B5 0x68A0 0x68BA 0x690F 0x688D 0x687E 0x6901 0x68CA 0x6908 0x68D8 0x6922 0x6926 0x68E1 0x690C 0x68CD -0x68D4 0x68E7 0x68D5 0x6936 0x6912 0x6904 0x68D7 0x68E3 0x6925 0x68F9 0x68E0 0x68EF 0x6928 0x692A 0x691A 0x6923 0x6921 0x68C6 0x6979 0x6977 0x695C 0x6978 0x696B 0x6954 0x697E 0x696E 0x6939 0x6974 0x693D 0x6959 0x6930 0x6961 0x695E 0x695D 0x6981 0x696A 0x69B2 0x69AE 0x69D0 0x69BF 0x69C1 0x69D3 0x69BE 0x69CE 0x5BE8 0x69CA 0x69DD 0x69BB 0x69C3 0x69A7 0x6A2E 0x6991 0x69A0 0x699C 0x6995 0x69B4 0x69DE 0x69E8 0x6A02 0x6A1B 0x69FF 0x6B0A 0x69F9 0x69F2 0x69E7 0x6A05 0x69B1 0x6A1E 0x69ED 0x6A14 0x69EB 0x6A0A 0x6A12 0x6AC1 0x6A23 0x6A13 0x6A44 0x6A0C 0x6A72 0x6A36 0x6A78 0x6A47 0x6A62 0x6A59 0x6A66 0x6A48 0x6A38 0x6A22 0x6A90 0x6A8D 0x6AA0 0x6A84 0x6AA2 0x6AA3 -0x6A97 0x8617 0x6ABB 0x6AC3 0x6AC2 0x6AB8 0x6AB3 0x6AAC 0x6ADE 0x6AD1 0x6ADF 0x6AAA 0x6ADA 0x6AEA 0x6AFB 0x6B05 0x8616 0x6AFA 0x6B12 0x6B16 0x9B31 0x6B1F 0x6B38 0x6B37 0x76DC 0x6B39 0x98EE 0x6B47 0x6B43 0x6B49 0x6B50 0x6B59 0x6B54 0x6B5B 0x6B5F 0x6B61 0x6B78 0x6B79 0x6B7F 0x6B80 0x6B84 0x6B83 0x6B8D 0x6B98 0x6B95 0x6B9E 0x6BA4 0x6BAA 0x6BAB 0x6BAF 0x6BB2 0x6BB1 0x6BB3 0x6BB7 0x6BBC 0x6BC6 0x6BCB 0x6BD3 0x6BDF 0x6BEC 0x6BEB 0x6BF3 0x6BEF 0x9EBE 0x6C08 0x6C13 0x6C14 0x6C1B 0x6C24 0x6C23 0x6C5E 0x6C55 0x6C62 0x6C6A 0x6C82 0x6C8D 0x6C9A 0x6C81 0x6C9B 0x6C7E 0x6C68 0x6C73 0x6C92 0x6C90 0x6CC4 0x6CF1 0x6CD3 0x6CBD 0x6CD7 0x6CC5 0x6CDD 0x6CAE 0x6CB1 0x6CBE -0x6CBA 0x6CDB 0x6CEF 0x6CD9 0x6CEA 0x6D1F 0x884D 0x6D36 0x6D2B 0x6D3D 0x6D38 0x6D19 0x6D35 0x6D33 0x6D12 0x6D0C 0x6D63 0x6D93 0x6D64 0x6D5A 0x6D79 0x6D59 0x6D8E 0x6D95 0x6FE4 0x6D85 0x6DF9 0x6E15 0x6E0A 0x6DB5 0x6DC7 0x6DE6 0x6DB8 0x6DC6 0x6DEC 0x6DDE 0x6DCC 0x6DE8 0x6DD2 0x6DC5 0x6DFA 0x6DD9 0x6DE4 0x6DD5 0x6DEA 0x6DEE 0x6E2D 0x6E6E 0x6E2E 0x6E19 0x6E72 0x6E5F 0x6E3E 0x6E23 0x6E6B 0x6E2B 0x6E76 0x6E4D 0x6E1F 0x6E43 0x6E3A 0x6E4E 0x6E24 0x6EFF 0x6E1D 0x6E38 0x6E82 0x6EAA 0x6E98 0x6EC9 0x6EB7 0x6ED3 0x6EBD 0x6EAF 0x6EC4 0x6EB2 0x6ED4 0x6ED5 0x6E8F 0x6EA5 0x6EC2 0x6E9F 0x6F41 0x6F11 0x704C 0x6EEC 0x6EF8 0x6EFE 0x6F3F 0x6EF2 0x6F31 0x6EEF 0x6F32 0x6ECC -0x6F3E 0x6F13 0x6EF7 0x6F86 0x6F7A 0x6F78 0x6F81 0x6F80 0x6F6F 0x6F5B 0x6FF3 0x6F6D 0x6F82 0x6F7C 0x6F58 0x6F8E 0x6F91 0x6FC2 0x6F66 0x6FB3 0x6FA3 0x6FA1 0x6FA4 0x6FB9 0x6FC6 0x6FAA 0x6FDF 0x6FD5 0x6FEC 0x6FD4 0x6FD8 0x6FF1 0x6FEE 0x6FDB 0x7009 0x700B 0x6FFA 0x7011 0x7001 0x700F 0x6FFE 0x701B 0x701A 0x6F74 0x701D 0x7018 0x701F 0x7030 0x703E 0x7032 0x7051 0x7063 0x7099 0x7092 0x70AF 0x70F1 0x70AC 0x70B8 0x70B3 0x70AE 0x70DF 0x70CB 0x70DD 0x70D9 0x7109 0x70FD 0x711C 0x7119 0x7165 0x7155 0x7188 0x7166 0x7162 0x714C 0x7156 0x716C 0x718F 0x71FB 0x7184 0x7195 0x71A8 0x71AC 0x71D7 0x71B9 0x71BE 0x71D2 0x71C9 0x71D4 0x71CE 0x71E0 0x71EC 0x71E7 0x71F5 0x71FC -0x71F9 0x71FF 0x720D 0x7210 0x721B 0x7228 0x722D 0x722C 0x7230 0x7232 0x723B 0x723C 0x723F 0x7240 0x7246 0x724B 0x7258 0x7274 0x727E 0x7282 0x7281 0x7287 0x7292 0x7296 0x72A2 0x72A7 0x72B9 0x72B2 0x72C3 0x72C6 0x72C4 0x72CE 0x72D2 0x72E2 0x72E0 0x72E1 0x72F9 0x72F7 0x500F 0x7317 0x730A 0x731C 0x7316 0x731D 0x7334 0x732F 0x7329 0x7325 0x733E 0x734E 0x734F 0x9ED8 0x7357 0x736A 0x7368 0x7370 0x7378 0x7375 0x737B 0x737A 0x73C8 0x73B3 0x73CE 0x73BB 0x73C0 0x73E5 0x73EE 0x73DE 0x74A2 0x7405 0x746F 0x7425 0x73F8 0x7432 0x743A 0x7455 0x743F 0x745F 0x7459 0x7441 0x745C 0x7469 0x7470 0x7463 0x746A 0x7476 0x747E 0x748B 0x749E 0x74A7 0x74CA 0x74CF 0x74D4 0x73F1 -0x74E0 0x74E3 0x74E7 0x74E9 0x74EE 0x74F2 0x74F0 0x74F1 0x74F8 0x74F7 0x7504 0x7503 0x7505 0x750C 0x750E 0x750D 0x7515 0x7513 0x751E 0x7526 0x752C 0x753C 0x7544 0x754D 0x754A 0x7549 0x755B 0x7546 0x755A 0x7569 0x7564 0x7567 0x756B 0x756D 0x7578 0x7576 0x7586 0x7587 0x7574 0x758A 0x7589 0x7582 0x7594 0x759A 0x759D 0x75A5 0x75A3 0x75C2 0x75B3 0x75C3 0x75B5 0x75BD 0x75B8 0x75BC 0x75B1 0x75CD 0x75CA 0x75D2 0x75D9 0x75E3 0x75DE 0x75FE 0x75FF 0x75FC 0x7601 0x75F0 0x75FA 0x75F2 0x75F3 0x760B 0x760D 0x7609 0x761F 0x7627 0x7620 0x7621 0x7622 0x7624 0x7634 0x7630 0x763B 0x7647 0x7648 0x7646 0x765C 0x7658 0x7661 0x7662 0x7668 0x7669 0x766A 0x7667 0x766C 0x7670 -0x7672 0x7676 0x7678 0x767C 0x7680 0x7683 0x7688 0x768B 0x768E 0x7696 0x7693 0x7699 0x769A 0x76B0 0x76B4 0x76B8 0x76B9 0x76BA 0x76C2 0x76CD 0x76D6 0x76D2 0x76DE 0x76E1 0x76E5 0x76E7 0x76EA 0x862F 0x76FB 0x7708 0x7707 0x7704 0x7729 0x7724 0x771E 0x7725 0x7726 0x771B 0x7737 0x7738 0x7747 0x775A 0x7768 0x776B 0x775B 0x7765 0x777F 0x777E 0x7779 0x778E 0x778B 0x7791 0x77A0 0x779E 0x77B0 0x77B6 0x77B9 0x77BF 0x77BC 0x77BD 0x77BB 0x77C7 0x77CD 0x77D7 0x77DA 0x77DC 0x77E3 0x77EE 0x77FC 0x780C 0x7812 0x7926 0x7820 0x792A 0x7845 0x788E 0x7874 0x7886 0x787C 0x789A 0x788C 0x78A3 0x78B5 0x78AA 0x78AF 0x78D1 0x78C6 0x78CB 0x78D4 0x78BE 0x78BC 0x78C5 0x78CA 0x78EC -0x78E7 0x78DA 0x78FD 0x78F4 0x7907 0x7912 0x7911 0x7919 0x792C 0x792B 0x7940 0x7960 0x7957 0x795F 0x795A 0x7955 0x7953 0x797A 0x797F 0x798A 0x799D 0x79A7 0x9F4B 0x79AA 0x79AE 0x79B3 0x79B9 0x79BA 0x79C9 0x79D5 0x79E7 0x79EC 0x79E1 0x79E3 0x7A08 0x7A0D 0x7A18 0x7A19 0x7A20 0x7A1F 0x7980 0x7A31 0x7A3B 0x7A3E 0x7A37 0x7A43 0x7A57 0x7A49 0x7A61 0x7A62 0x7A69 0x9F9D 0x7A70 0x7A79 0x7A7D 0x7A88 0x7A97 0x7A95 0x7A98 0x7A96 0x7AA9 0x7AC8 0x7AB0 0x7AB6 0x7AC5 0x7AC4 0x7ABF 0x9083 0x7AC7 0x7ACA 0x7ACD 0x7ACF 0x7AD5 0x7AD3 0x7AD9 0x7ADA 0x7ADD 0x7AE1 0x7AE2 0x7AE6 0x7AED 0x7AF0 0x7B02 0x7B0F 0x7B0A 0x7B06 0x7B33 0x7B18 0x7B19 0x7B1E 0x7B35 0x7B28 0x7B36 0x7B50 -0x7B7A 0x7B04 0x7B4D 0x7B0B 0x7B4C 0x7B45 0x7B75 0x7B65 0x7B74 0x7B67 0x7B70 0x7B71 0x7B6C 0x7B6E 0x7B9D 0x7B98 0x7B9F 0x7B8D 0x7B9C 0x7B9A 0x7B8B 0x7B92 0x7B8F 0x7B5D 0x7B99 0x7BCB 0x7BC1 0x7BCC 0x7BCF 0x7BB4 0x7BC6 0x7BDD 0x7BE9 0x7C11 0x7C14 0x7BE6 0x7BE5 0x7C60 0x7C00 0x7C07 0x7C13 0x7BF3 0x7BF7 0x7C17 0x7C0D 0x7BF6 0x7C23 0x7C27 0x7C2A 0x7C1F 0x7C37 0x7C2B 0x7C3D 0x7C4C 0x7C43 0x7C54 0x7C4F 0x7C40 0x7C50 0x7C58 0x7C5F 0x7C64 0x7C56 0x7C65 0x7C6C 0x7C75 0x7C83 0x7C90 0x7CA4 0x7CAD 0x7CA2 0x7CAB 0x7CA1 0x7CA8 0x7CB3 0x7CB2 0x7CB1 0x7CAE 0x7CB9 0x7CBD 0x7CC0 0x7CC5 0x7CC2 0x7CD8 0x7CD2 0x7CDC 0x7CE2 0x9B3B 0x7CEF 0x7CF2 0x7CF4 0x7CF6 0x7CFA 0x7D06 -0x7D02 0x7D1C 0x7D15 0x7D0A 0x7D45 0x7D4B 0x7D2E 0x7D32 0x7D3F 0x7D35 0x7D46 0x7D73 0x7D56 0x7D4E 0x7D72 0x7D68 0x7D6E 0x7D4F 0x7D63 0x7D93 0x7D89 0x7D5B 0x7D8F 0x7D7D 0x7D9B 0x7DBA 0x7DAE 0x7DA3 0x7DB5 0x7DC7 0x7DBD 0x7DAB 0x7E3D 0x7DA2 0x7DAF 0x7DDC 0x7DB8 0x7D9F 0x7DB0 0x7DD8 0x7DDD 0x7DE4 0x7DDE 0x7DFB 0x7DF2 0x7DE1 0x7E05 0x7E0A 0x7E23 0x7E21 0x7E12 0x7E31 0x7E1F 0x7E09 0x7E0B 0x7E22 0x7E46 0x7E66 0x7E3B 0x7E35 0x7E39 0x7E43 0x7E37 0x7E32 0x7E3A 0x7E67 0x7E5D 0x7E56 0x7E5E 0x7E59 0x7E5A 0x7E79 0x7E6A 0x7E69 0x7E7C 0x7E7B 0x7E83 0x7DD5 0x7E7D 0x8FAE 0x7E7F 0x7E88 0x7E89 0x7E8C 0x7E92 0x7E90 0x7E93 0x7E94 0x7E96 0x7E8E 0x7E9B 0x7E9C 0x7F38 0x7F3A -0x7F45 0x7F4C 0x7F4D 0x7F4E 0x7F50 0x7F51 0x7F55 0x7F54 0x7F58 0x7F5F 0x7F60 0x7F68 0x7F69 0x7F67 0x7F78 0x7F82 0x7F86 0x7F83 0x7F88 0x7F87 0x7F8C 0x7F94 0x7F9E 0x7F9D 0x7F9A 0x7FA3 0x7FAF 0x7FB2 0x7FB9 0x7FAE 0x7FB6 0x7FB8 0x8B71 0x7FC5 0x7FC6 0x7FCA 0x7FD5 0x7FD4 0x7FE1 0x7FE6 0x7FE9 0x7FF3 0x7FF9 0x98DC 0x8006 0x8004 0x800B 0x8012 0x8018 0x8019 0x801C 0x8021 0x8028 0x803F 0x803B 0x804A 0x8046 0x8052 0x8058 0x805A 0x805F 0x8062 0x8068 0x8073 0x8072 0x8070 0x8076 0x8079 0x807D 0x807F 0x8084 0x8086 0x8085 0x809B 0x8093 0x809A 0x80AD 0x5190 0x80AC 0x80DB 0x80E5 0x80D9 0x80DD 0x80C4 0x80DA 0x80D6 0x8109 0x80EF 0x80F1 0x811B 0x8129 0x8123 0x812F 0x814B -0x968B 0x8146 0x813E 0x8153 0x8151 0x80FC 0x8171 0x816E 0x8165 0x8166 0x8174 0x8183 0x8188 0x818A 0x8180 0x8182 0x81A0 0x8195 0x81A4 0x81A3 0x815F 0x8193 0x81A9 0x81B0 0x81B5 0x81BE 0x81B8 0x81BD 0x81C0 0x81C2 0x81BA 0x81C9 0x81CD 0x81D1 0x81D9 0x81D8 0x81C8 0x81DA 0x81DF 0x81E0 0x81E7 0x81FA 0x81FB 0x81FE 0x8201 0x8202 0x8205 0x8207 0x820A 0x820D 0x8210 0x8216 0x8229 0x822B 0x8238 0x8233 0x8240 0x8259 0x8258 0x825D 0x825A 0x825F 0x8264 0x8262 0x8268 0x826A 0x826B 0x822E 0x8271 0x8277 0x8278 0x827E 0x828D 0x8292 0x82AB 0x829F 0x82BB 0x82AC 0x82E1 0x82E3 0x82DF 0x82D2 0x82F4 0x82F3 0x82FA 0x8393 0x8303 0x82FB 0x82F9 0x82DE 0x8306 0x82DC 0x8309 0x82D9 -0x8335 0x8334 0x8316 0x8332 0x8331 0x8340 0x8339 0x8350 0x8345 0x832F 0x832B 0x8317 0x8318 0x8385 0x839A 0x83AA 0x839F 0x83A2 0x8396 0x8323 0x838E 0x8387 0x838A 0x837C 0x83B5 0x8373 0x8375 0x83A0 0x8389 0x83A8 0x83F4 0x8413 0x83EB 0x83CE 0x83FD 0x8403 0x83D8 0x840B 0x83C1 0x83F7 0x8407 0x83E0 0x83F2 0x840D 0x8422 0x8420 0x83BD 0x8438 0x8506 0x83FB 0x846D 0x842A 0x843C 0x855A 0x8484 0x8477 0x846B 0x84AD 0x846E 0x8482 0x8469 0x8446 0x842C 0x846F 0x8479 0x8435 0x84CA 0x8462 0x84B9 0x84BF 0x849F 0x84D9 0x84CD 0x84BB 0x84DA 0x84D0 0x84C1 0x84C6 0x84D6 0x84A1 0x8521 0x84FF 0x84F4 0x8517 0x8518 0x852C 0x851F 0x8515 0x8514 0x84FC 0x8540 0x8563 0x8558 0x8548 -0x8541 0x8602 0x854B 0x8555 0x8580 0x85A4 0x8588 0x8591 0x858A 0x85A8 0x856D 0x8594 0x859B 0x85EA 0x8587 0x859C 0x8577 0x857E 0x8590 0x85C9 0x85BA 0x85CF 0x85B9 0x85D0 0x85D5 0x85DD 0x85E5 0x85DC 0x85F9 0x860A 0x8613 0x860B 0x85FE 0x85FA 0x8606 0x8622 0x861A 0x8630 0x863F 0x864D 0x4E55 0x8654 0x865F 0x8667 0x8671 0x8693 0x86A3 0x86A9 0x86AA 0x868B 0x868C 0x86B6 0x86AF 0x86C4 0x86C6 0x86B0 0x86C9 0x8823 0x86AB 0x86D4 0x86DE 0x86E9 0x86EC 0x86DF 0x86DB 0x86EF 0x8712 0x8706 0x8708 0x8700 0x8703 0x86FB 0x8711 0x8709 0x870D 0x86F9 0x870A 0x8734 0x873F 0x8737 0x873B 0x8725 0x8729 0x871A 0x8760 0x875F 0x8778 0x874C 0x874E 0x8774 0x8757 0x8768 0x876E 0x8759 -0x8753 0x8763 0x876A 0x8805 0x87A2 0x879F 0x8782 0x87AF 0x87CB 0x87BD 0x87C0 0x87D0 0x96D6 0x87AB 0x87C4 0x87B3 0x87C7 0x87C6 0x87BB 0x87EF 0x87F2 0x87E0 0x880F 0x880D 0x87FE 0x87F6 0x87F7 0x880E 0x87D2 0x8811 0x8816 0x8815 0x8822 0x8821 0x8831 0x8836 0x8839 0x8827 0x883B 0x8844 0x8842 0x8852 0x8859 0x885E 0x8862 0x886B 0x8881 0x887E 0x889E 0x8875 0x887D 0x88B5 0x8872 0x8882 0x8897 0x8892 0x88AE 0x8899 0x88A2 0x888D 0x88A4 0x88B0 0x88BF 0x88B1 0x88C3 0x88C4 0x88D4 0x88D8 0x88D9 0x88DD 0x88F9 0x8902 0x88FC 0x88F4 0x88E8 0x88F2 0x8904 0x890C 0x890A 0x8913 0x8943 0x891E 0x8925 0x892A 0x892B 0x8941 0x8944 0x893B 0x8936 0x8938 0x894C 0x891D 0x8960 0x895E -0x8966 0x8964 0x896D 0x896A 0x896F 0x8974 0x8977 0x897E 0x8983 0x8988 0x898A 0x8993 0x8998 0x89A1 0x89A9 0x89A6 0x89AC 0x89AF 0x89B2 0x89BA 0x89BD 0x89BF 0x89C0 0x89DA 0x89DC 0x89DD 0x89E7 0x89F4 0x89F8 0x8A03 0x8A16 0x8A10 0x8A0C 0x8A1B 0x8A1D 0x8A25 0x8A36 0x8A41 0x8A5B 0x8A52 0x8A46 0x8A48 0x8A7C 0x8A6D 0x8A6C 0x8A62 0x8A85 0x8A82 0x8A84 0x8AA8 0x8AA1 0x8A91 0x8AA5 0x8AA6 0x8A9A 0x8AA3 0x8AC4 0x8ACD 0x8AC2 0x8ADA 0x8AEB 0x8AF3 0x8AE7 0x8AE4 0x8AF1 0x8B14 0x8AE0 0x8AE2 0x8AF7 0x8ADE 0x8ADB 0x8B0C 0x8B07 0x8B1A 0x8AE1 0x8B16 0x8B10 0x8B17 0x8B20 0x8B33 0x97AB 0x8B26 0x8B2B 0x8B3E 0x8B28 0x8B41 0x8B4C 0x8B4F 0x8B4E 0x8B49 0x8B56 0x8B5B 0x8B5A 0x8B6B -0x8B5F 0x8B6C 0x8B6F 0x8B74 0x8B7D 0x8B80 0x8B8C 0x8B8E 0x8B92 0x8B93 0x8B96 0x8B99 0x8B9A 0x8C3A 0x8C41 0x8C3F 0x8C48 0x8C4C 0x8C4E 0x8C50 0x8C55 0x8C62 0x8C6C 0x8C78 0x8C7A 0x8C82 0x8C89 0x8C85 0x8C8A 0x8C8D 0x8C8E 0x8C94 0x8C7C 0x8C98 0x621D 0x8CAD 0x8CAA 0x8CBD 0x8CB2 0x8CB3 0x8CAE 0x8CB6 0x8CC8 0x8CC1 0x8CE4 0x8CE3 0x8CDA 0x8CFD 0x8CFA 0x8CFB 0x8D04 0x8D05 0x8D0A 0x8D07 0x8D0F 0x8D0D 0x8D10 0x9F4E 0x8D13 0x8CCD 0x8D14 0x8D16 0x8D67 0x8D6D 0x8D71 0x8D73 0x8D81 0x8D99 0x8DC2 0x8DBE 0x8DBA 0x8DCF 0x8DDA 0x8DD6 0x8DCC 0x8DDB 0x8DCB 0x8DEA 0x8DEB 0x8DDF 0x8DE3 0x8DFC 0x8E08 0x8E09 0x8DFF 0x8E1D 0x8E1E 0x8E10 0x8E1F 0x8E42 0x8E35 0x8E30 0x8E34 0x8E4A -0x8E47 0x8E49 0x8E4C 0x8E50 0x8E48 0x8E59 0x8E64 0x8E60 0x8E2A 0x8E63 0x8E55 0x8E76 0x8E72 0x8E7C 0x8E81 0x8E87 0x8E85 0x8E84 0x8E8B 0x8E8A 0x8E93 0x8E91 0x8E94 0x8E99 0x8EAA 0x8EA1 0x8EAC 0x8EB0 0x8EC6 0x8EB1 0x8EBE 0x8EC5 0x8EC8 0x8ECB 0x8EDB 0x8EE3 0x8EFC 0x8EFB 0x8EEB 0x8EFE 0x8F0A 0x8F05 0x8F15 0x8F12 0x8F19 0x8F13 0x8F1C 0x8F1F 0x8F1B 0x8F0C 0x8F26 0x8F33 0x8F3B 0x8F39 0x8F45 0x8F42 0x8F3E 0x8F4C 0x8F49 0x8F46 0x8F4E 0x8F57 0x8F5C 0x8F62 0x8F63 0x8F64 0x8F9C 0x8F9F 0x8FA3 0x8FAD 0x8FAF 0x8FB7 0x8FDA 0x8FE5 0x8FE2 0x8FEA 0x8FEF 0x9087 0x8FF4 0x9005 0x8FF9 0x8FFA 0x9011 0x9015 0x9021 0x900D 0x901E 0x9016 0x900B 0x9027 0x9036 0x9035 0x9039 0x8FF8 -0x904F 0x9050 0x9051 0x9052 0x900E 0x9049 0x903E 0x9056 0x9058 0x905E 0x9068 0x906F 0x9076 0x96A8 0x9072 0x9082 0x907D 0x9081 0x9080 0x908A 0x9089 0x908F 0x90A8 0x90AF 0x90B1 0x90B5 0x90E2 0x90E4 0x6248 0x90DB 0x9102 0x9112 0x9119 0x9132 0x9130 0x914A 0x9156 0x9158 0x9163 0x9165 0x9169 0x9173 0x9172 0x918B 0x9189 0x9182 0x91A2 0x91AB 0x91AF 0x91AA 0x91B5 0x91B4 0x91BA 0x91C0 0x91C1 0x91C9 0x91CB 0x91D0 0x91D6 0x91DF 0x91E1 0x91DB 0x91FC 0x91F5 0x91F6 0x921E 0x91FF 0x9214 0x922C 0x9215 0x9211 0x925E 0x9257 0x9245 0x9249 0x9264 0x9248 0x9295 0x923F 0x924B 0x9250 0x929C 0x9296 0x9293 0x929B 0x925A 0x92CF 0x92B9 0x92B7 0x92E9 0x930F 0x92FA 0x9344 0x932E -0x9319 0x9322 0x931A 0x9323 0x933A 0x9335 0x933B 0x935C 0x9360 0x937C 0x936E 0x9356 0x93B0 0x93AC 0x93AD 0x9394 0x93B9 0x93D6 0x93D7 0x93E8 0x93E5 0x93D8 0x93C3 0x93DD 0x93D0 0x93C8 0x93E4 0x941A 0x9414 0x9413 0x9403 0x9407 0x9410 0x9436 0x942B 0x9435 0x9421 0x943A 0x9441 0x9452 0x9444 0x945B 0x9460 0x9462 0x945E 0x946A 0x9229 0x9470 0x9475 0x9477 0x947D 0x945A 0x947C 0x947E 0x9481 0x947F 0x9582 0x9587 0x958A 0x9594 0x9596 0x9598 0x9599 0x95A0 0x95A8 0x95A7 0x95AD 0x95BC 0x95BB 0x95B9 0x95BE 0x95CA 0x6FF6 0x95C3 0x95CD 0x95CC 0x95D5 0x95D4 0x95D6 0x95DC 0x95E1 0x95E5 0x95E2 0x9621 0x9628 0x962E 0x962F 0x9642 0x964C 0x964F 0x964B 0x9677 0x965C 0x965E -0x965D 0x965F 0x9666 0x9672 0x966C 0x968D 0x9698 0x9695 0x9697 0x96AA 0x96A7 0x96B1 0x96B2 0x96B0 0x96B4 0x96B6 0x96B8 0x96B9 0x96CE 0x96CB 0x96C9 0x96CD 0x894D 0x96DC 0x970D 0x96D5 0x96F9 0x9704 0x9706 0x9708 0x9713 0x970E 0x9711 0x970F 0x9716 0x9719 0x9724 0x972A 0x9730 0x9739 0x973D 0x973E 0x9744 0x9746 0x9748 0x9742 0x9749 0x975C 0x9760 0x9764 0x9766 0x9768 0x52D2 0x976B 0x9771 0x9779 0x9785 0x977C 0x9781 0x977A 0x9786 0x978B 0x978F 0x9790 0x979C 0x97A8 0x97A6 0x97A3 0x97B3 0x97B4 0x97C3 0x97C6 0x97C8 0x97CB 0x97DC 0x97ED 0x9F4F 0x97F2 0x7ADF 0x97F6 0x97F5 0x980F 0x980C 0x9838 0x9824 0x9821 0x9837 0x983D 0x9846 0x984F 0x984B 0x986B 0x986F 0x9870 -0x9871 0x9874 0x9873 0x98AA 0x98AF 0x98B1 0x98B6 0x98C4 0x98C3 0x98C6 0x98E9 0x98EB 0x9903 0x9909 0x9912 0x9914 0x9918 0x9921 0x991D 0x991E 0x9924 0x9920 0x992C 0x992E 0x993D 0x993E 0x9942 0x9949 0x9945 0x9950 0x994B 0x9951 0x9952 0x994C 0x9955 0x9997 0x9998 0x99A5 0x99AD 0x99AE 0x99BC 0x99DF 0x99DB 0x99DD 0x99D8 0x99D1 0x99ED 0x99EE 0x99F1 0x99F2 0x99FB 0x99F8 0x9A01 0x9A0F 0x9A05 0x99E2 0x9A19 0x9A2B 0x9A37 0x9A45 0x9A42 0x9A40 0x9A43 0x9A3E 0x9A55 0x9A4D 0x9A5B 0x9A57 0x9A5F 0x9A62 0x9A65 0x9A64 0x9A69 0x9A6B 0x9A6A 0x9AAD 0x9AB0 0x9ABC 0x9AC0 0x9ACF 0x9AD1 0x9AD3 0x9AD4 0x9ADE 0x9ADF 0x9AE2 0x9AE3 0x9AE6 0x9AEF 0x9AEB 0x9AEE 0x9AF4 0x9AF1 0x9AF7 -0x9AFB 0x9B06 0x9B18 0x9B1A 0x9B1F 0x9B22 0x9B23 0x9B25 0x9B27 0x9B28 0x9B29 0x9B2A 0x9B2E 0x9B2F 0x9B32 0x9B44 0x9B43 0x9B4F 0x9B4D 0x9B4E 0x9B51 0x9B58 0x9B74 0x9B93 0x9B83 0x9B91 0x9B96 0x9B97 0x9B9F 0x9BA0 0x9BA8 0x9BB4 0x9BC0 0x9BCA 0x9BB9 0x9BC6 0x9BCF 0x9BD1 0x9BD2 0x9BE3 0x9BE2 0x9BE4 0x9BD4 0x9BE1 0x9C3A 0x9BF2 0x9BF1 0x9BF0 0x9C15 0x9C14 0x9C09 0x9C13 0x9C0C 0x9C06 0x9C08 0x9C12 0x9C0A 0x9C04 0x9C2E 0x9C1B 0x9C25 0x9C24 0x9C21 0x9C30 0x9C47 0x9C32 0x9C46 0x9C3E 0x9C5A 0x9C60 0x9C67 0x9C76 0x9C78 0x9CE7 0x9CEC 0x9CF0 0x9D09 0x9D08 0x9CEB 0x9D03 0x9D06 0x9D2A 0x9D26 0x9DAF 0x9D23 0x9D1F 0x9D44 0x9D15 0x9D12 0x9D41 0x9D3F 0x9D3E 0x9D46 0x9D48 -0x9D5D 0x9D5E 0x9D64 0x9D51 0x9D50 0x9D59 0x9D72 0x9D89 0x9D87 0x9DAB 0x9D6F 0x9D7A 0x9D9A 0x9DA4 0x9DA9 0x9DB2 0x9DC4 0x9DC1 0x9DBB 0x9DB8 0x9DBA 0x9DC6 0x9DCF 0x9DC2 0x9DD9 0x9DD3 0x9DF8 0x9DE6 0x9DED 0x9DEF 0x9DFD 0x9E1A 0x9E1B 0x9E1E 0x9E75 0x9E79 0x9E7D 0x9E81 0x9E88 0x9E8B 0x9E8C 0x9E92 0x9E95 0x9E91 0x9E9D 0x9EA5 0x9EA9 0x9EB8 0x9EAA 0x9EAD 0x9761 0x9ECC 0x9ECE 0x9ECF 0x9ED0 0x9ED4 0x9EDC 0x9EDE 0x9EDD 0x9EE0 0x9EE5 0x9EE8 0x9EEF 0x9EF4 0x9EF6 0x9EF7 0x9EF9 0x9EFB 0x9EFC 0x9EFD 0x9F07 0x9F08 0x76B7 0x9F15 0x9F21 0x9F2C 0x9F3E 0x9F4A 0x9F52 0x9F54 0x9F63 0x9F5F 0x9F60 0x9F61 0x9F66 0x9F67 0x9F6C 0x9F6A 0x9F77 0x9F72 0x9F76 0x9F95 0x9F9C 0x9FA0 -0x582F 0x69C7 0x9059 0x7464 0x51DC 0x7199 +0x3000 0x3001 0x3002 0xFF0C 0xFF0E 0x30FB 0xFF1A 0xFF1B 0xFF1F 0xFF01 0x309B 0x309C 0x00B4 0xFF40 0x00A8 0xFF3E 0xFFE3 0xFF3F 0x30FD 0x30FE 0x309D 0x309E 0x3003 0x4EDD 0x3005 0x3006 0x3007 0x30FC 0x2015 0x2010 0xFF0F 0xFF3C 0xFF5E 0x2225 0xFF5C 0x2026 0x2025 0x2018 0x2019 0x201C 0x201D 0xFF08 0xFF09 0x3014 0x3015 0xFF3B 0xFF3D 0xFF5B 0xFF5D 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0xFF0B 0xFF0D 0x00B1 0x00D7 0x00F7 0xFF1D 0x2260 0xFF1C 0xFF1E 0x2266 0x2267 0x221E 0x2234 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFFE5 0xFF04 0xFFE0 0xFFE1 0xFF05 0xFF03 0xFF06 0xFF0A 0xFF20 0x00A7 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 +0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x203B 0x3012 0x2192 0x2190 0x2191 0x2193 0x3013 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2208 0x220B 0x2286 0x2287 0x2282 0x2283 0x222A 0x2229 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2227 0x2228 0xFFE2 0x21D2 0x21D4 0x2200 0x2203 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2220 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 0x226A 0x226B 0x221A 0x223D 0x221D 0x2235 0x222B 0x222C 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x212B 0x2030 0x266F 0x266D 0x266A 0x2020 0x2021 0x00B6 0x0020 0x0020 0x0020 0x0020 0x25EF +0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0x3000 0x3000 0x3000 0x3000 +0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C 0x042D 0x042E 0x042F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0430 0x0431 0x0432 0x0433 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C 0x044D 0x044E 0x044F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x2500 0x2502 0x250C 0x2510 0x2518 0x2514 0x251C 0x252C 0x2524 0x2534 0x253C 0x2501 0x2503 0x250F 0x2513 0x251B 0x2517 0x2523 0x2533 0x252B 0x253B 0x254B 0x2520 0x252F 0x2528 0x2537 0x253F 0x251D 0x2530 0x2525 0x2538 0x2542 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x4E9C 0x5516 0x5A03 0x963F 0x54C0 0x611B 0x6328 0x59F6 0x9022 0x8475 0x831C 0x7A50 0x60AA 0x63E1 0x6E25 0x65ED 0x8466 0x82A6 0x9BF5 0x6893 0x5727 0x65A1 0x6271 0x5B9B 0x59D0 0x867B 0x98F4 0x7D62 0x7DBE 0x9B8E 0x6216 0x7C9F 0x88B7 0x5B89 0x5EB5 0x6309 0x6697 0x6848 0x95C7 0x978D 0x674F 0x4EE5 0x4F0A 0x4F4D 0x4F9D 0x5049 0x56F2 0x5937 0x59D4 0x5A01 0x5C09 0x60DF 0x610F 0x6170 0x6613 0x6905 0x70BA 0x754F 0x7570 0x79FB 0x7DAD 0x7DEF 0x80C3 0x840E 0x8863 0x8B02 0x9055 0x907A 0x533B 0x4E95 0x4EA5 0x57DF 0x80B2 0x90C1 0x78EF 0x4E00 0x58F1 0x6EA2 0x9038 0x7A32 0x8328 0x828B 0x9C2F 0x5141 0x5370 0x54BD 0x54E1 0x56E0 0x59FB 0x5F15 0x98F2 0x6DEB 0x80E4 0x852D +0x9662 0x9670 0x96A0 0x97FB 0x540B 0x53F3 0x5B87 0x70CF 0x7FBD 0x8FC2 0x96E8 0x536F 0x9D5C 0x7ABA 0x4E11 0x7893 0x81FC 0x6E26 0x5618 0x5504 0x6B1D 0x851A 0x9C3B 0x59E5 0x53A9 0x6D66 0x74DC 0x958F 0x5642 0x4E91 0x904B 0x96F2 0x834F 0x990C 0x53E1 0x55B6 0x5B30 0x5F71 0x6620 0x66F3 0x6804 0x6C38 0x6CF3 0x6D29 0x745B 0x76C8 0x7A4E 0x9834 0x82F1 0x885B 0x8A60 0x92ED 0x6DB2 0x75AB 0x76CA 0x99C5 0x60A6 0x8B01 0x8D8A 0x95B2 0x698E 0x53AD 0x5186 0x5712 0x5830 0x5944 0x5BB4 0x5EF6 0x6028 0x63A9 0x63F4 0x6CBF 0x6F14 0x708E 0x7114 0x7159 0x71D5 0x733F 0x7E01 0x8276 0x82D1 0x8597 0x9060 0x925B 0x9D1B 0x5869 0x65BC 0x6C5A 0x7525 0x51F9 0x592E 0x5965 0x5F80 0x5FDC +0x62BC 0x65FA 0x6A2A 0x6B27 0x6BB4 0x738B 0x7FC1 0x8956 0x9D2C 0x9D0E 0x9EC4 0x5CA1 0x6C96 0x837B 0x5104 0x5C4B 0x61B6 0x81C6 0x6876 0x7261 0x4E59 0x4FFA 0x5378 0x6069 0x6E29 0x7A4F 0x97F3 0x4E0B 0x5316 0x4EEE 0x4F55 0x4F3D 0x4FA1 0x4F73 0x52A0 0x53EF 0x5609 0x590F 0x5AC1 0x5BB6 0x5BE1 0x79D1 0x6687 0x679C 0x67B6 0x6B4C 0x6CB3 0x706B 0x73C2 0x798D 0x79BE 0x7A3C 0x7B87 0x82B1 0x82DB 0x8304 0x8377 0x83EF 0x83D3 0x8766 0x8AB2 0x5629 0x8CA8 0x8FE6 0x904E 0x971E 0x868A 0x4FC4 0x5CE8 0x6211 0x7259 0x753B 0x81E5 0x82BD 0x86FE 0x8CC0 0x96C5 0x9913 0x99D5 0x4ECB 0x4F1A 0x89E3 0x56DE 0x584A 0x58CA 0x5EFB 0x5FEB 0x602A 0x6094 0x6062 0x61D0 0x6212 0x62D0 0x6539 +0x9B41 0x6666 0x68B0 0x6D77 0x7070 0x754C 0x7686 0x7D75 0x82A5 0x87F9 0x958B 0x968E 0x8C9D 0x51F1 0x52BE 0x5916 0x54B3 0x5BB3 0x5D16 0x6168 0x6982 0x6DAF 0x788D 0x84CB 0x8857 0x8A72 0x93A7 0x9AB8 0x6D6C 0x99A8 0x86D9 0x57A3 0x67FF 0x86CE 0x920E 0x5283 0x5687 0x5404 0x5ED3 0x62E1 0x64B9 0x683C 0x6838 0x6BBB 0x7372 0x78BA 0x7A6B 0x899A 0x89D2 0x8D6B 0x8F03 0x90ED 0x95A3 0x9694 0x9769 0x5B66 0x5CB3 0x697D 0x984D 0x984E 0x639B 0x7B20 0x6A2B 0x6A7F 0x68B6 0x9C0D 0x6F5F 0x5272 0x559D 0x6070 0x62EC 0x6D3B 0x6E07 0x6ED1 0x845B 0x8910 0x8F44 0x4E14 0x9C39 0x53F6 0x691B 0x6A3A 0x9784 0x682A 0x515C 0x7AC3 0x84B2 0x91DC 0x938C 0x565B 0x9D28 0x6822 0x8305 0x8431 +0x7CA5 0x5208 0x82C5 0x74E6 0x4E7E 0x4F83 0x51A0 0x5BD2 0x520A 0x52D8 0x52E7 0x5DFB 0x559A 0x582A 0x59E6 0x5B8C 0x5B98 0x5BDB 0x5E72 0x5E79 0x60A3 0x611F 0x6163 0x61BE 0x63DB 0x6562 0x67D1 0x6853 0x68FA 0x6B3E 0x6B53 0x6C57 0x6F22 0x6F97 0x6F45 0x74B0 0x7518 0x76E3 0x770B 0x7AFF 0x7BA1 0x7C21 0x7DE9 0x7F36 0x7FF0 0x809D 0x8266 0x839E 0x89B3 0x8ACC 0x8CAB 0x9084 0x9451 0x9593 0x9591 0x95A2 0x9665 0x97D3 0x9928 0x8218 0x4E38 0x542B 0x5CB8 0x5DCC 0x73A9 0x764C 0x773C 0x5CA9 0x7FEB 0x8D0B 0x96C1 0x9811 0x9854 0x9858 0x4F01 0x4F0E 0x5371 0x559C 0x5668 0x57FA 0x5947 0x5B09 0x5BC4 0x5C90 0x5E0C 0x5E7E 0x5FCC 0x63EE 0x673A 0x65D7 0x65E2 0x671F 0x68CB 0x68C4 +0x6A5F 0x5E30 0x6BC5 0x6C17 0x6C7D 0x757F 0x7948 0x5B63 0x7A00 0x7D00 0x5FBD 0x898F 0x8A18 0x8CB4 0x8D77 0x8ECC 0x8F1D 0x98E2 0x9A0E 0x9B3C 0x4E80 0x507D 0x5100 0x5993 0x5B9C 0x622F 0x6280 0x64EC 0x6B3A 0x72A0 0x7591 0x7947 0x7FA9 0x87FB 0x8ABC 0x8B70 0x63AC 0x83CA 0x97A0 0x5409 0x5403 0x55AB 0x6854 0x6A58 0x8A70 0x7827 0x6775 0x9ECD 0x5374 0x5BA2 0x811A 0x8650 0x9006 0x4E18 0x4E45 0x4EC7 0x4F11 0x53CA 0x5438 0x5BAE 0x5F13 0x6025 0x6551 0x673D 0x6C42 0x6C72 0x6CE3 0x7078 0x7403 0x7A76 0x7AAE 0x7B08 0x7D1A 0x7CFE 0x7D66 0x65E7 0x725B 0x53BB 0x5C45 0x5DE8 0x62D2 0x62E0 0x6319 0x6E20 0x865A 0x8A31 0x8DDD 0x92F8 0x6F01 0x79A6 0x9B5A 0x4EA8 0x4EAB 0x4EAC +0x4F9B 0x4FA0 0x50D1 0x5147 0x7AF6 0x5171 0x51F6 0x5354 0x5321 0x537F 0x53EB 0x55AC 0x5883 0x5CE1 0x5F37 0x5F4A 0x602F 0x6050 0x606D 0x631F 0x6559 0x6A4B 0x6CC1 0x72C2 0x72ED 0x77EF 0x80F8 0x8105 0x8208 0x854E 0x90F7 0x93E1 0x97FF 0x9957 0x9A5A 0x4EF0 0x51DD 0x5C2D 0x6681 0x696D 0x5C40 0x66F2 0x6975 0x7389 0x6850 0x7C81 0x50C5 0x52E4 0x5747 0x5DFE 0x9326 0x65A4 0x6B23 0x6B3D 0x7434 0x7981 0x79BD 0x7B4B 0x7DCA 0x82B9 0x83CC 0x887F 0x895F 0x8B39 0x8FD1 0x91D1 0x541F 0x9280 0x4E5D 0x5036 0x53E5 0x533A 0x72D7 0x7396 0x77E9 0x82E6 0x8EAF 0x99C6 0x99C8 0x99D2 0x5177 0x611A 0x865E 0x55B0 0x7A7A 0x5076 0x5BD3 0x9047 0x9685 0x4E32 0x6ADB 0x91E7 0x5C51 0x5C48 +0x6398 0x7A9F 0x6C93 0x9774 0x8F61 0x7AAA 0x718A 0x9688 0x7C82 0x6817 0x7E70 0x6851 0x936C 0x52F2 0x541B 0x85AB 0x8A13 0x7FA4 0x8ECD 0x90E1 0x5366 0x8888 0x7941 0x4FC2 0x50BE 0x5211 0x5144 0x5553 0x572D 0x73EA 0x578B 0x5951 0x5F62 0x5F84 0x6075 0x6176 0x6167 0x61A9 0x63B2 0x643A 0x656C 0x666F 0x6842 0x6E13 0x7566 0x7A3D 0x7CFB 0x7D4C 0x7D99 0x7E4B 0x7F6B 0x830E 0x834A 0x86CD 0x8A08 0x8A63 0x8B66 0x8EFD 0x981A 0x9D8F 0x82B8 0x8FCE 0x9BE8 0x5287 0x621F 0x6483 0x6FC0 0x9699 0x6841 0x5091 0x6B20 0x6C7A 0x6F54 0x7A74 0x7D50 0x8840 0x8A23 0x6708 0x4EF6 0x5039 0x5026 0x5065 0x517C 0x5238 0x5263 0x55A7 0x570F 0x5805 0x5ACC 0x5EFA 0x61B2 0x61F8 0x62F3 0x6372 +0x691C 0x6A29 0x727D 0x72AC 0x732E 0x7814 0x786F 0x7D79 0x770C 0x80A9 0x898B 0x8B19 0x8CE2 0x8ED2 0x9063 0x9375 0x967A 0x9855 0x9A13 0x9E78 0x5143 0x539F 0x53B3 0x5E7B 0x5F26 0x6E1B 0x6E90 0x7384 0x73FE 0x7D43 0x8237 0x8A00 0x8AFA 0x9650 0x4E4E 0x500B 0x53E4 0x547C 0x56FA 0x59D1 0x5B64 0x5DF1 0x5EAB 0x5F27 0x6238 0x6545 0x67AF 0x6E56 0x72D0 0x7CCA 0x88B4 0x80A1 0x80E1 0x83F0 0x864E 0x8A87 0x8DE8 0x9237 0x96C7 0x9867 0x9F13 0x4E94 0x4E92 0x4F0D 0x5348 0x5449 0x543E 0x5A2F 0x5F8C 0x5FA1 0x609F 0x68A7 0x6A8E 0x745A 0x7881 0x8A9E 0x8AA4 0x8B77 0x9190 0x4E5E 0x9BC9 0x4EA4 0x4F7C 0x4FAF 0x5019 0x5016 0x5149 0x516C 0x529F 0x52B9 0x52FE 0x539A 0x53E3 0x5411 +0x540E 0x5589 0x5751 0x57A2 0x597D 0x5B54 0x5B5D 0x5B8F 0x5DE5 0x5DE7 0x5DF7 0x5E78 0x5E83 0x5E9A 0x5EB7 0x5F18 0x6052 0x614C 0x6297 0x62D8 0x63A7 0x653B 0x6602 0x6643 0x66F4 0x676D 0x6821 0x6897 0x69CB 0x6C5F 0x6D2A 0x6D69 0x6E2F 0x6E9D 0x7532 0x7687 0x786C 0x7A3F 0x7CE0 0x7D05 0x7D18 0x7D5E 0x7DB1 0x8015 0x8003 0x80AF 0x80B1 0x8154 0x818F 0x822A 0x8352 0x884C 0x8861 0x8B1B 0x8CA2 0x8CFC 0x90CA 0x9175 0x9271 0x783F 0x92FC 0x95A4 0x964D 0x9805 0x9999 0x9AD8 0x9D3B 0x525B 0x52AB 0x53F7 0x5408 0x58D5 0x62F7 0x6FE0 0x8C6A 0x8F5F 0x9EB9 0x514B 0x523B 0x544A 0x56FD 0x7A40 0x9177 0x9D60 0x9ED2 0x7344 0x6F09 0x8170 0x7511 0x5FFD 0x60DA 0x9AA8 0x72DB 0x8FBC +0x6B64 0x9803 0x4ECA 0x56F0 0x5764 0x58BE 0x5A5A 0x6068 0x61C7 0x660F 0x6606 0x6839 0x68B1 0x6DF7 0x75D5 0x7D3A 0x826E 0x9B42 0x4E9B 0x4F50 0x53C9 0x5506 0x5D6F 0x5DE6 0x5DEE 0x67FB 0x6C99 0x7473 0x7802 0x8A50 0x9396 0x88DF 0x5750 0x5EA7 0x632B 0x50B5 0x50AC 0x518D 0x6700 0x54C9 0x585E 0x59BB 0x5BB0 0x5F69 0x624D 0x63A1 0x683D 0x6B73 0x6E08 0x707D 0x91C7 0x7280 0x7815 0x7826 0x796D 0x658E 0x7D30 0x83DC 0x88C1 0x8F09 0x969B 0x5264 0x5728 0x6750 0x7F6A 0x8CA1 0x51B4 0x5742 0x962A 0x583A 0x698A 0x80B4 0x54B2 0x5D0E 0x57FC 0x7895 0x9DFA 0x4F5C 0x524A 0x548B 0x643E 0x6628 0x6714 0x67F5 0x7A84 0x7B56 0x7D22 0x932F 0x685C 0x9BAD 0x7B39 0x5319 0x518A 0x5237 +0x5BDF 0x62F6 0x64AE 0x64E6 0x672D 0x6BBA 0x85A9 0x96D1 0x7690 0x9BD6 0x634C 0x9306 0x9BAB 0x76BF 0x6652 0x4E09 0x5098 0x53C2 0x5C71 0x60E8 0x6492 0x6563 0x685F 0x71E6 0x73CA 0x7523 0x7B97 0x7E82 0x8695 0x8B83 0x8CDB 0x9178 0x9910 0x65AC 0x66AB 0x6B8B 0x4ED5 0x4ED4 0x4F3A 0x4F7F 0x523A 0x53F8 0x53F2 0x55E3 0x56DB 0x58EB 0x59CB 0x59C9 0x59FF 0x5B50 0x5C4D 0x5E02 0x5E2B 0x5FD7 0x601D 0x6307 0x652F 0x5B5C 0x65AF 0x65BD 0x65E8 0x679D 0x6B62 0x6B7B 0x6C0F 0x7345 0x7949 0x79C1 0x7CF8 0x7D19 0x7D2B 0x80A2 0x8102 0x81F3 0x8996 0x8A5E 0x8A69 0x8A66 0x8A8C 0x8AEE 0x8CC7 0x8CDC 0x96CC 0x98FC 0x6B6F 0x4E8B 0x4F3C 0x4F8D 0x5150 0x5B57 0x5BFA 0x6148 0x6301 0x6642 +0x6B21 0x6ECB 0x6CBB 0x723E 0x74BD 0x75D4 0x78C1 0x793A 0x800C 0x8033 0x81EA 0x8494 0x8F9E 0x6C50 0x9E7F 0x5F0F 0x8B58 0x9D2B 0x7AFA 0x8EF8 0x5B8D 0x96EB 0x4E03 0x53F1 0x57F7 0x5931 0x5AC9 0x5BA4 0x6089 0x6E7F 0x6F06 0x75BE 0x8CEA 0x5B9F 0x8500 0x7BE0 0x5072 0x67F4 0x829D 0x5C61 0x854A 0x7E1E 0x820E 0x5199 0x5C04 0x6368 0x8D66 0x659C 0x716E 0x793E 0x7D17 0x8005 0x8B1D 0x8ECA 0x906E 0x86C7 0x90AA 0x501F 0x52FA 0x5C3A 0x6753 0x707C 0x7235 0x914C 0x91C8 0x932B 0x82E5 0x5BC2 0x5F31 0x60F9 0x4E3B 0x53D6 0x5B88 0x624B 0x6731 0x6B8A 0x72E9 0x73E0 0x7A2E 0x816B 0x8DA3 0x9152 0x9996 0x5112 0x53D7 0x546A 0x5BFF 0x6388 0x6A39 0x7DAC 0x9700 0x56DA 0x53CE 0x5468 +0x5B97 0x5C31 0x5DDE 0x4FEE 0x6101 0x62FE 0x6D32 0x79C0 0x79CB 0x7D42 0x7E4D 0x7FD2 0x81ED 0x821F 0x8490 0x8846 0x8972 0x8B90 0x8E74 0x8F2F 0x9031 0x914B 0x916C 0x96C6 0x919C 0x4EC0 0x4F4F 0x5145 0x5341 0x5F93 0x620E 0x67D4 0x6C41 0x6E0B 0x7363 0x7E26 0x91CD 0x9283 0x53D4 0x5919 0x5BBF 0x6DD1 0x795D 0x7E2E 0x7C9B 0x587E 0x719F 0x51FA 0x8853 0x8FF0 0x4FCA 0x5CFB 0x6625 0x77AC 0x7AE3 0x821C 0x99FF 0x51C6 0x5FAA 0x65EC 0x696F 0x6B89 0x6DF3 0x6E96 0x6F64 0x76FE 0x7D14 0x5DE1 0x9075 0x9187 0x9806 0x51E6 0x521D 0x6240 0x6691 0x66D9 0x6E1A 0x5EB6 0x7DD2 0x7F72 0x66F8 0x85AF 0x85F7 0x8AF8 0x52A9 0x53D9 0x5973 0x5E8F 0x5F90 0x6055 0x92E4 0x9664 0x50B7 0x511F +0x52DD 0x5320 0x5347 0x53EC 0x54E8 0x5546 0x5531 0x5617 0x5968 0x59BE 0x5A3C 0x5BB5 0x5C06 0x5C0F 0x5C11 0x5C1A 0x5E84 0x5E8A 0x5EE0 0x5F70 0x627F 0x6284 0x62DB 0x638C 0x6377 0x6607 0x660C 0x662D 0x6676 0x677E 0x68A2 0x6A1F 0x6A35 0x6CBC 0x6D88 0x6E09 0x6E58 0x713C 0x7126 0x7167 0x75C7 0x7701 0x785D 0x7901 0x7965 0x79F0 0x7AE0 0x7B11 0x7CA7 0x7D39 0x8096 0x83D6 0x848B 0x8549 0x885D 0x88F3 0x8A1F 0x8A3C 0x8A54 0x8A73 0x8C61 0x8CDE 0x91A4 0x9266 0x937E 0x9418 0x969C 0x9798 0x4E0A 0x4E08 0x4E1E 0x4E57 0x5197 0x5270 0x57CE 0x5834 0x58CC 0x5B22 0x5E38 0x60C5 0x64FE 0x6761 0x6756 0x6D44 0x72B6 0x7573 0x7A63 0x84B8 0x8B72 0x91B8 0x9320 0x5631 0x57F4 0x98FE +0x62ED 0x690D 0x6B96 0x71ED 0x7E54 0x8077 0x8272 0x89E6 0x98DF 0x8755 0x8FB1 0x5C3B 0x4F38 0x4FE1 0x4FB5 0x5507 0x5A20 0x5BDD 0x5BE9 0x5FC3 0x614E 0x632F 0x65B0 0x664B 0x68EE 0x699B 0x6D78 0x6DF1 0x7533 0x75B9 0x771F 0x795E 0x79E6 0x7D33 0x81E3 0x82AF 0x85AA 0x89AA 0x8A3A 0x8EAB 0x8F9B 0x9032 0x91DD 0x9707 0x4EBA 0x4EC1 0x5203 0x5875 0x58EC 0x5C0B 0x751A 0x5C3D 0x814E 0x8A0A 0x8FC5 0x9663 0x976D 0x7B25 0x8ACF 0x9808 0x9162 0x56F3 0x53A8 0x9017 0x5439 0x5782 0x5E25 0x63A8 0x6C34 0x708A 0x7761 0x7C8B 0x7FE0 0x8870 0x9042 0x9154 0x9310 0x9318 0x968F 0x745E 0x9AC4 0x5D07 0x5D69 0x6570 0x67A2 0x8DA8 0x96DB 0x636E 0x6749 0x6919 0x83C5 0x9817 0x96C0 0x88FE +0x6F84 0x647A 0x5BF8 0x4E16 0x702C 0x755D 0x662F 0x51C4 0x5236 0x52E2 0x59D3 0x5F81 0x6027 0x6210 0x653F 0x6574 0x661F 0x6674 0x68F2 0x6816 0x6B63 0x6E05 0x7272 0x751F 0x76DB 0x7CBE 0x8056 0x58F0 0x88FD 0x897F 0x8AA0 0x8A93 0x8ACB 0x901D 0x9192 0x9752 0x9759 0x6589 0x7A0E 0x8106 0x96BB 0x5E2D 0x60DC 0x621A 0x65A5 0x6614 0x6790 0x77F3 0x7A4D 0x7C4D 0x7E3E 0x810A 0x8CAC 0x8D64 0x8DE1 0x8E5F 0x78A9 0x5207 0x62D9 0x63A5 0x6442 0x6298 0x8A2D 0x7A83 0x7BC0 0x8AAC 0x96EA 0x7D76 0x820C 0x8749 0x4ED9 0x5148 0x5343 0x5360 0x5BA3 0x5C02 0x5C16 0x5DDD 0x6226 0x6247 0x64B0 0x6813 0x6834 0x6CC9 0x6D45 0x6D17 0x67D3 0x6F5C 0x714E 0x717D 0x65CB 0x7A7F 0x7BAD 0x7DDA +0x7E4A 0x7FA8 0x817A 0x821B 0x8239 0x85A6 0x8A6E 0x8CCE 0x8DF5 0x9078 0x9077 0x92AD 0x9291 0x9583 0x9BAE 0x524D 0x5584 0x6F38 0x7136 0x5168 0x7985 0x7E55 0x81B3 0x7CCE 0x564C 0x5851 0x5CA8 0x63AA 0x66FE 0x66FD 0x695A 0x72D9 0x758F 0x758E 0x790E 0x7956 0x79DF 0x7C97 0x7D20 0x7D44 0x8607 0x8A34 0x963B 0x9061 0x9F20 0x50E7 0x5275 0x53CC 0x53E2 0x5009 0x55AA 0x58EE 0x594F 0x723D 0x5B8B 0x5C64 0x531D 0x60E3 0x60F3 0x635C 0x6383 0x633F 0x63BB 0x64CD 0x65E9 0x66F9 0x5DE3 0x69CD 0x69FD 0x6F15 0x71E5 0x4E89 0x75E9 0x76F8 0x7A93 0x7CDF 0x7DCF 0x7D9C 0x8061 0x8349 0x8358 0x846C 0x84BC 0x85FB 0x88C5 0x8D70 0x9001 0x906D 0x9397 0x971C 0x9A12 0x50CF 0x5897 0x618E +0x81D3 0x8535 0x8D08 0x9020 0x4FC3 0x5074 0x5247 0x5373 0x606F 0x6349 0x675F 0x6E2C 0x8DB3 0x901F 0x4FD7 0x5C5E 0x8CCA 0x65CF 0x7D9A 0x5352 0x8896 0x5176 0x63C3 0x5B58 0x5B6B 0x5C0A 0x640D 0x6751 0x905C 0x4ED6 0x591A 0x592A 0x6C70 0x8A51 0x553E 0x5815 0x59A5 0x60F0 0x6253 0x67C1 0x8235 0x6955 0x9640 0x99C4 0x9A28 0x4F53 0x5806 0x5BFE 0x8010 0x5CB1 0x5E2F 0x5F85 0x6020 0x614B 0x6234 0x66FF 0x6CF0 0x6EDE 0x80CE 0x817F 0x82D4 0x888B 0x8CB8 0x9000 0x902E 0x968A 0x9EDB 0x9BDB 0x4EE3 0x53F0 0x5927 0x7B2C 0x918D 0x984C 0x9DF9 0x6EDD 0x7027 0x5353 0x5544 0x5B85 0x6258 0x629E 0x62D3 0x6CA2 0x6FEF 0x7422 0x8A17 0x9438 0x6FC1 0x8AFE 0x8338 0x51E7 0x86F8 0x53EA +0x53E9 0x4F46 0x9054 0x8FB0 0x596A 0x8131 0x5DFD 0x7AEA 0x8FBF 0x68DA 0x8C37 0x72F8 0x9C48 0x6A3D 0x8AB0 0x4E39 0x5358 0x5606 0x5766 0x62C5 0x63A2 0x65E6 0x6B4E 0x6DE1 0x6E5B 0x70AD 0x77ED 0x7AEF 0x7BAA 0x7DBB 0x803D 0x80C6 0x86CB 0x8A95 0x935B 0x56E3 0x58C7 0x5F3E 0x65AD 0x6696 0x6A80 0x6BB5 0x7537 0x8AC7 0x5024 0x77E5 0x5730 0x5F1B 0x6065 0x667A 0x6C60 0x75F4 0x7A1A 0x7F6E 0x81F4 0x8718 0x9045 0x99B3 0x7BC9 0x755C 0x7AF9 0x7B51 0x84C4 0x9010 0x79E9 0x7A92 0x8336 0x5AE1 0x7740 0x4E2D 0x4EF2 0x5B99 0x5FE0 0x62BD 0x663C 0x67F1 0x6CE8 0x866B 0x8877 0x8A3B 0x914E 0x92F3 0x99D0 0x6A17 0x7026 0x732A 0x82E7 0x8457 0x8CAF 0x4E01 0x5146 0x51CB 0x558B 0x5BF5 +0x5E16 0x5E33 0x5E81 0x5F14 0x5F35 0x5F6B 0x5FB4 0x61F2 0x6311 0x66A2 0x671D 0x6F6E 0x7252 0x753A 0x773A 0x8074 0x8139 0x8178 0x8776 0x8ABF 0x8ADC 0x8D85 0x8DF3 0x929A 0x9577 0x9802 0x9CE5 0x52C5 0x6357 0x76F4 0x6715 0x6C88 0x73CD 0x8CC3 0x93AE 0x9673 0x6D25 0x589C 0x690E 0x69CC 0x8FFD 0x939A 0x75DB 0x901A 0x585A 0x6802 0x63B4 0x69FB 0x4F43 0x6F2C 0x67D8 0x8FBB 0x8526 0x7DB4 0x9354 0x693F 0x6F70 0x576A 0x58F7 0x5B2C 0x7D2C 0x722A 0x540A 0x91E3 0x9DB4 0x4EAD 0x4F4E 0x505C 0x5075 0x5243 0x8C9E 0x5448 0x5824 0x5B9A 0x5E1D 0x5E95 0x5EAD 0x5EF7 0x5F1F 0x608C 0x62B5 0x633A 0x63D0 0x68AF 0x6C40 0x7887 0x798E 0x7A0B 0x7DE0 0x8247 0x8A02 0x8AE6 0x8E44 0x9013 +0x90B8 0x912D 0x91D8 0x9F0E 0x6CE5 0x6458 0x64E2 0x6575 0x6EF4 0x7684 0x7B1B 0x9069 0x93D1 0x6EBA 0x54F2 0x5FB9 0x64A4 0x8F4D 0x8FED 0x9244 0x5178 0x586B 0x5929 0x5C55 0x5E97 0x6DFB 0x7E8F 0x751C 0x8CBC 0x8EE2 0x985B 0x70B9 0x4F1D 0x6BBF 0x6FB1 0x7530 0x96FB 0x514E 0x5410 0x5835 0x5857 0x59AC 0x5C60 0x5F92 0x6597 0x675C 0x6E21 0x767B 0x83DF 0x8CED 0x9014 0x90FD 0x934D 0x7825 0x783A 0x52AA 0x5EA6 0x571F 0x5974 0x6012 0x5012 0x515A 0x51AC 0x51CD 0x5200 0x5510 0x5854 0x5858 0x5957 0x5B95 0x5CF6 0x5D8B 0x60BC 0x6295 0x642D 0x6771 0x6843 0x68BC 0x68DF 0x76D7 0x6DD8 0x6E6F 0x6D9B 0x706F 0x71C8 0x5F53 0x75D8 0x7977 0x7B49 0x7B54 0x7B52 0x7CD6 0x7D71 0x5230 +0x8463 0x8569 0x85E4 0x8A0E 0x8B04 0x8C46 0x8E0F 0x9003 0x900F 0x9419 0x9676 0x982D 0x9A30 0x95D8 0x50CD 0x52D5 0x540C 0x5802 0x5C0E 0x61A7 0x649E 0x6D1E 0x77B3 0x7AE5 0x80F4 0x8404 0x9053 0x9285 0x5CE0 0x9D07 0x533F 0x5F97 0x5FB3 0x6D9C 0x7279 0x7763 0x79BF 0x7BE4 0x6BD2 0x72EC 0x8AAD 0x6803 0x6A61 0x51F8 0x7A81 0x6934 0x5C4A 0x9CF6 0x82EB 0x5BC5 0x9149 0x701E 0x5678 0x5C6F 0x60C7 0x6566 0x6C8C 0x8C5A 0x9041 0x9813 0x5451 0x66C7 0x920D 0x5948 0x90A3 0x5185 0x4E4D 0x51EA 0x8599 0x8B0E 0x7058 0x637A 0x934B 0x6962 0x99B4 0x7E04 0x7577 0x5357 0x6960 0x8EDF 0x96E3 0x6C5D 0x4E8C 0x5C3C 0x5F10 0x8FE9 0x5302 0x8CD1 0x8089 0x8679 0x5EFF 0x65E5 0x4E73 0x5165 +0x5982 0x5C3F 0x97EE 0x4EFB 0x598A 0x5FCD 0x8A8D 0x6FE1 0x79B0 0x7962 0x5BE7 0x8471 0x732B 0x71B1 0x5E74 0x5FF5 0x637B 0x649A 0x71C3 0x7C98 0x4E43 0x5EFC 0x4E4B 0x57DC 0x56A2 0x60A9 0x6FC3 0x7D0D 0x80FD 0x8133 0x81BF 0x8FB2 0x8997 0x86A4 0x5DF4 0x628A 0x64AD 0x8987 0x6777 0x6CE2 0x6D3E 0x7436 0x7834 0x5A46 0x7F75 0x82AD 0x99AC 0x4FF3 0x5EC3 0x62DD 0x6392 0x6557 0x676F 0x76C3 0x724C 0x80CC 0x80BA 0x8F29 0x914D 0x500D 0x57F9 0x5A92 0x6885 0x6973 0x7164 0x72FD 0x8CB7 0x58F2 0x8CE0 0x966A 0x9019 0x877F 0x79E4 0x77E7 0x8429 0x4F2F 0x5265 0x535A 0x62CD 0x67CF 0x6CCA 0x767D 0x7B94 0x7C95 0x8236 0x8584 0x8FEB 0x66DD 0x6F20 0x7206 0x7E1B 0x83AB 0x99C1 0x9EA6 +0x51FD 0x7BB1 0x7872 0x7BB8 0x8087 0x7B48 0x6AE8 0x5E61 0x808C 0x7551 0x7560 0x516B 0x9262 0x6E8C 0x767A 0x9197 0x9AEA 0x4F10 0x7F70 0x629C 0x7B4F 0x95A5 0x9CE9 0x567A 0x5859 0x86E4 0x96BC 0x4F34 0x5224 0x534A 0x53CD 0x53DB 0x5E06 0x642C 0x6591 0x677F 0x6C3E 0x6C4E 0x7248 0x72AF 0x73ED 0x7554 0x7E41 0x822C 0x85E9 0x8CA9 0x7BC4 0x91C6 0x7169 0x9812 0x98EF 0x633D 0x6669 0x756A 0x76E4 0x78D0 0x8543 0x86EE 0x532A 0x5351 0x5426 0x5983 0x5E87 0x5F7C 0x60B2 0x6249 0x6279 0x62AB 0x6590 0x6BD4 0x6CCC 0x75B2 0x76AE 0x7891 0x79D8 0x7DCB 0x7F77 0x80A5 0x88AB 0x8AB9 0x8CBB 0x907F 0x975E 0x98DB 0x6A0B 0x7C38 0x5099 0x5C3E 0x5FAE 0x6787 0x6BD8 0x7435 0x7709 0x7F8E +0x9F3B 0x67CA 0x7A17 0x5339 0x758B 0x9AED 0x5F66 0x819D 0x83F1 0x8098 0x5F3C 0x5FC5 0x7562 0x7B46 0x903C 0x6867 0x59EB 0x5A9B 0x7D10 0x767E 0x8B2C 0x4FF5 0x5F6A 0x6A19 0x6C37 0x6F02 0x74E2 0x7968 0x8868 0x8A55 0x8C79 0x5EDF 0x63CF 0x75C5 0x79D2 0x82D7 0x9328 0x92F2 0x849C 0x86ED 0x9C2D 0x54C1 0x5F6C 0x658C 0x6D5C 0x7015 0x8CA7 0x8CD3 0x983B 0x654F 0x74F6 0x4E0D 0x4ED8 0x57E0 0x592B 0x5A66 0x5BCC 0x51A8 0x5E03 0x5E9C 0x6016 0x6276 0x6577 0x65A7 0x666E 0x6D6E 0x7236 0x7B26 0x8150 0x819A 0x8299 0x8B5C 0x8CA0 0x8CE6 0x8D74 0x961C 0x9644 0x4FAE 0x64AB 0x6B66 0x821E 0x8461 0x856A 0x90E8 0x5C01 0x6953 0x98A8 0x847A 0x8557 0x4F0F 0x526F 0x5FA9 0x5E45 0x670D +0x798F 0x8179 0x8907 0x8986 0x6DF5 0x5F17 0x6255 0x6CB8 0x4ECF 0x7269 0x9B92 0x5206 0x543B 0x5674 0x58B3 0x61A4 0x626E 0x711A 0x596E 0x7C89 0x7CDE 0x7D1B 0x96F0 0x6587 0x805E 0x4E19 0x4F75 0x5175 0x5840 0x5E63 0x5E73 0x5F0A 0x67C4 0x4E26 0x853D 0x9589 0x965B 0x7C73 0x9801 0x50FB 0x58C1 0x7656 0x78A7 0x5225 0x77A5 0x8511 0x7B86 0x504F 0x5909 0x7247 0x7BC7 0x7DE8 0x8FBA 0x8FD4 0x904D 0x4FBF 0x52C9 0x5A29 0x5F01 0x97AD 0x4FDD 0x8217 0x92EA 0x5703 0x6355 0x6B69 0x752B 0x88DC 0x8F14 0x7A42 0x52DF 0x5893 0x6155 0x620A 0x66AE 0x6BCD 0x7C3F 0x83E9 0x5023 0x4FF8 0x5305 0x5446 0x5831 0x5949 0x5B9D 0x5CF0 0x5CEF 0x5D29 0x5E96 0x62B1 0x6367 0x653E 0x65B9 0x670B +0x6CD5 0x6CE1 0x70F9 0x7832 0x7E2B 0x80DE 0x82B3 0x840C 0x84EC 0x8702 0x8912 0x8A2A 0x8C4A 0x90A6 0x92D2 0x98FD 0x9CF3 0x9D6C 0x4E4F 0x4EA1 0x508D 0x5256 0x574A 0x59A8 0x5E3D 0x5FD8 0x5FD9 0x623F 0x66B4 0x671B 0x67D0 0x68D2 0x5192 0x7D21 0x80AA 0x81A8 0x8B00 0x8C8C 0x8CBF 0x927E 0x9632 0x5420 0x982C 0x5317 0x50D5 0x535C 0x58A8 0x64B2 0x6734 0x7267 0x7766 0x7A46 0x91E6 0x52C3 0x6CA1 0x6B86 0x5800 0x5E4C 0x5954 0x672C 0x7FFB 0x51E1 0x76C6 0x6469 0x78E8 0x9B54 0x9EBB 0x57CB 0x59B9 0x6627 0x679A 0x6BCE 0x54E9 0x69D9 0x5E55 0x819C 0x6795 0x9BAA 0x67FE 0x9C52 0x685D 0x4EA6 0x4FE3 0x53C8 0x62B9 0x672B 0x6CAB 0x8FC4 0x4FAD 0x7E6D 0x9EBF 0x4E07 0x6162 0x6E80 +0x6F2B 0x8513 0x5473 0x672A 0x9B45 0x5DF3 0x7B95 0x5CAC 0x5BC6 0x871C 0x6E4A 0x84D1 0x7A14 0x8108 0x5999 0x7C8D 0x6C11 0x7720 0x52D9 0x5922 0x7121 0x725F 0x77DB 0x9727 0x9D61 0x690B 0x5A7F 0x5A18 0x51A5 0x540D 0x547D 0x660E 0x76DF 0x8FF7 0x9298 0x9CF4 0x59EA 0x725D 0x6EC5 0x514D 0x68C9 0x7DBF 0x7DEC 0x9762 0x9EBA 0x6478 0x6A21 0x8302 0x5984 0x5B5F 0x6BDB 0x731B 0x76F2 0x7DB2 0x8017 0x8499 0x5132 0x6728 0x9ED9 0x76EE 0x6762 0x52FF 0x9905 0x5C24 0x623B 0x7C7E 0x8CB0 0x554F 0x60B6 0x7D0B 0x9580 0x5301 0x4E5F 0x51B6 0x591C 0x723A 0x8036 0x91CE 0x5F25 0x77E2 0x5384 0x5F79 0x7D04 0x85AC 0x8A33 0x8E8D 0x9756 0x67F3 0x85AE 0x9453 0x6109 0x6108 0x6CB9 0x7652 +0x8AED 0x8F38 0x552F 0x4F51 0x512A 0x52C7 0x53CB 0x5BA5 0x5E7D 0x60A0 0x6182 0x63D6 0x6709 0x67DA 0x6E67 0x6D8C 0x7336 0x7337 0x7531 0x7950 0x88D5 0x8A98 0x904A 0x9091 0x90F5 0x96C4 0x878D 0x5915 0x4E88 0x4F59 0x4E0E 0x8A89 0x8F3F 0x9810 0x50AD 0x5E7C 0x5996 0x5BB9 0x5EB8 0x63DA 0x63FA 0x64C1 0x66DC 0x694A 0x69D8 0x6D0B 0x6EB6 0x7194 0x7528 0x7AAF 0x7F8A 0x8000 0x8449 0x84C9 0x8981 0x8B21 0x8E0A 0x9065 0x967D 0x990A 0x617E 0x6291 0x6B32 0x6C83 0x6D74 0x7FCC 0x7FFC 0x6DC0 0x7F85 0x87BA 0x88F8 0x6765 0x83B1 0x983C 0x96F7 0x6D1B 0x7D61 0x843D 0x916A 0x4E71 0x5375 0x5D50 0x6B04 0x6FEB 0x85CD 0x862D 0x89A7 0x5229 0x540F 0x5C65 0x674E 0x68A8 0x7406 0x7483 +0x75E2 0x88CF 0x88E1 0x91CC 0x96E2 0x9678 0x5F8B 0x7387 0x7ACB 0x844E 0x63A0 0x7565 0x5289 0x6D41 0x6E9C 0x7409 0x7559 0x786B 0x7C92 0x9686 0x7ADC 0x9F8D 0x4FB6 0x616E 0x65C5 0x865C 0x4E86 0x4EAE 0x50DA 0x4E21 0x51CC 0x5BEE 0x6599 0x6881 0x6DBC 0x731F 0x7642 0x77AD 0x7A1C 0x7CE7 0x826F 0x8AD2 0x907C 0x91CF 0x9675 0x9818 0x529B 0x7DD1 0x502B 0x5398 0x6797 0x6DCB 0x71D0 0x7433 0x81E8 0x8F2A 0x96A3 0x9C57 0x9E9F 0x7460 0x5841 0x6D99 0x7D2F 0x985E 0x4EE4 0x4F36 0x4F8B 0x51B7 0x52B1 0x5DBA 0x601C 0x73B2 0x793C 0x82D3 0x9234 0x96B7 0x96F6 0x970A 0x9E97 0x9F62 0x66A6 0x6B74 0x5217 0x52A3 0x70C8 0x88C2 0x5EC9 0x604B 0x6190 0x6F23 0x7149 0x7C3E 0x7DF4 0x806F +0x84EE 0x9023 0x932C 0x5442 0x9B6F 0x6AD3 0x7089 0x8CC2 0x8DEF 0x9732 0x52B4 0x5A41 0x5ECA 0x5F04 0x6717 0x697C 0x6994 0x6D6A 0x6F0F 0x7262 0x72FC 0x7BED 0x8001 0x807E 0x874B 0x90CE 0x516D 0x9E93 0x7984 0x808B 0x9332 0x8AD6 0x502D 0x548C 0x8A71 0x6B6A 0x8CC4 0x8107 0x60D1 0x67A0 0x9DF2 0x4E99 0x4E98 0x9C10 0x8A6B 0x85C1 0x8568 0x6900 0x6E7E 0x7897 0x8155 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x5F0C 0x4E10 0x4E15 0x4E2A 0x4E31 0x4E36 0x4E3C 0x4E3F 0x4E42 0x4E56 0x4E58 0x4E82 0x4E85 0x8C6B 0x4E8A 0x8212 0x5F0D 0x4E8E 0x4E9E 0x4E9F 0x4EA0 0x4EA2 0x4EB0 0x4EB3 0x4EB6 0x4ECE 0x4ECD 0x4EC4 0x4EC6 0x4EC2 0x4ED7 0x4EDE 0x4EED 0x4EDF 0x4EF7 0x4F09 0x4F5A 0x4F30 0x4F5B 0x4F5D 0x4F57 0x4F47 0x4F76 0x4F88 0x4F8F 0x4F98 0x4F7B 0x4F69 0x4F70 0x4F91 0x4F6F 0x4F86 0x4F96 0x5118 0x4FD4 0x4FDF 0x4FCE 0x4FD8 0x4FDB 0x4FD1 0x4FDA 0x4FD0 0x4FE4 0x4FE5 0x501A 0x5028 0x5014 0x502A 0x5025 0x5005 0x4F1C 0x4FF6 0x5021 0x5029 0x502C 0x4FFE 0x4FEF 0x5011 0x5006 0x5043 0x5047 0x6703 0x5055 0x5050 0x5048 0x505A 0x5056 0x506C 0x5078 0x5080 0x509A 0x5085 0x50B4 0x50B2 +0x50C9 0x50CA 0x50B3 0x50C2 0x50D6 0x50DE 0x50E5 0x50ED 0x50E3 0x50EE 0x50F9 0x50F5 0x5109 0x5101 0x5102 0x5116 0x5115 0x5114 0x511A 0x5121 0x513A 0x5137 0x513C 0x513B 0x513F 0x5140 0x5152 0x514C 0x5154 0x5162 0x7AF8 0x5169 0x516A 0x516E 0x5180 0x5182 0x56D8 0x518C 0x5189 0x518F 0x5191 0x5193 0x5195 0x5196 0x51A4 0x51A6 0x51A2 0x51A9 0x51AA 0x51AB 0x51B3 0x51B1 0x51B2 0x51B0 0x51B5 0x51BD 0x51C5 0x51C9 0x51DB 0x51E0 0x8655 0x51E9 0x51ED 0x51F0 0x51F5 0x51FE 0x5204 0x520B 0x5214 0x520E 0x5227 0x522A 0x522E 0x5233 0x5239 0x524F 0x5244 0x524B 0x524C 0x525E 0x5254 0x526A 0x5274 0x5269 0x5273 0x527F 0x527D 0x528D 0x5294 0x5292 0x5271 0x5288 0x5291 0x8FA8 +0x8FA7 0x52AC 0x52AD 0x52BC 0x52B5 0x52C1 0x52CD 0x52D7 0x52DE 0x52E3 0x52E6 0x98ED 0x52E0 0x52F3 0x52F5 0x52F8 0x52F9 0x5306 0x5308 0x7538 0x530D 0x5310 0x530F 0x5315 0x531A 0x5323 0x532F 0x5331 0x5333 0x5338 0x5340 0x5346 0x5345 0x4E17 0x5349 0x534D 0x51D6 0x535E 0x5369 0x536E 0x5918 0x537B 0x5377 0x5382 0x5396 0x53A0 0x53A6 0x53A5 0x53AE 0x53B0 0x53B6 0x53C3 0x7C12 0x96D9 0x53DF 0x66FC 0x71EE 0x53EE 0x53E8 0x53ED 0x53FA 0x5401 0x543D 0x5440 0x542C 0x542D 0x543C 0x542E 0x5436 0x5429 0x541D 0x544E 0x548F 0x5475 0x548E 0x545F 0x5471 0x5477 0x5470 0x5492 0x547B 0x5480 0x5476 0x5484 0x5490 0x5486 0x54C7 0x54A2 0x54B8 0x54A5 0x54AC 0x54C4 0x54C8 0x54A8 +0x54AB 0x54C2 0x54A4 0x54BE 0x54BC 0x54D8 0x54E5 0x54E6 0x550F 0x5514 0x54FD 0x54EE 0x54ED 0x54FA 0x54E2 0x5539 0x5540 0x5563 0x554C 0x552E 0x555C 0x5545 0x5556 0x5557 0x5538 0x5533 0x555D 0x5599 0x5580 0x54AF 0x558A 0x559F 0x557B 0x557E 0x5598 0x559E 0x55AE 0x557C 0x5583 0x55A9 0x5587 0x55A8 0x55DA 0x55C5 0x55DF 0x55C4 0x55DC 0x55E4 0x55D4 0x5614 0x55F7 0x5616 0x55FE 0x55FD 0x561B 0x55F9 0x564E 0x5650 0x71DF 0x5634 0x5636 0x5632 0x5638 0x566B 0x5664 0x562F 0x566C 0x566A 0x5686 0x5680 0x568A 0x56A0 0x5694 0x568F 0x56A5 0x56AE 0x56B6 0x56B4 0x56C2 0x56BC 0x56C1 0x56C3 0x56C0 0x56C8 0x56CE 0x56D1 0x56D3 0x56D7 0x56EE 0x56F9 0x5700 0x56FF 0x5704 0x5709 +0x5708 0x570B 0x570D 0x5713 0x5718 0x5716 0x55C7 0x571C 0x5726 0x5737 0x5738 0x574E 0x573B 0x5740 0x574F 0x5769 0x57C0 0x5788 0x5761 0x577F 0x5789 0x5793 0x57A0 0x57B3 0x57A4 0x57AA 0x57B0 0x57C3 0x57C6 0x57D4 0x57D2 0x57D3 0x580A 0x57D6 0x57E3 0x580B 0x5819 0x581D 0x5872 0x5821 0x5862 0x584B 0x5870 0x6BC0 0x5852 0x583D 0x5879 0x5885 0x58B9 0x589F 0x58AB 0x58BA 0x58DE 0x58BB 0x58B8 0x58AE 0x58C5 0x58D3 0x58D1 0x58D7 0x58D9 0x58D8 0x58E5 0x58DC 0x58E4 0x58DF 0x58EF 0x58FA 0x58F9 0x58FB 0x58FC 0x58FD 0x5902 0x590A 0x5910 0x591B 0x68A6 0x5925 0x592C 0x592D 0x5932 0x5938 0x593E 0x7AD2 0x5955 0x5950 0x594E 0x595A 0x5958 0x5962 0x5960 0x5967 0x596C 0x5969 +0x5978 0x5981 0x599D 0x4F5E 0x4FAB 0x59A3 0x59B2 0x59C6 0x59E8 0x59DC 0x598D 0x59D9 0x59DA 0x5A25 0x5A1F 0x5A11 0x5A1C 0x5A09 0x5A1A 0x5A40 0x5A6C 0x5A49 0x5A35 0x5A36 0x5A62 0x5A6A 0x5A9A 0x5ABC 0x5ABE 0x5ACB 0x5AC2 0x5ABD 0x5AE3 0x5AD7 0x5AE6 0x5AE9 0x5AD6 0x5AFA 0x5AFB 0x5B0C 0x5B0B 0x5B16 0x5B32 0x5AD0 0x5B2A 0x5B36 0x5B3E 0x5B43 0x5B45 0x5B40 0x5B51 0x5B55 0x5B5A 0x5B5B 0x5B65 0x5B69 0x5B70 0x5B73 0x5B75 0x5B78 0x6588 0x5B7A 0x5B80 0x5B83 0x5BA6 0x5BB8 0x5BC3 0x5BC7 0x5BC9 0x5BD4 0x5BD0 0x5BE4 0x5BE6 0x5BE2 0x5BDE 0x5BE5 0x5BEB 0x5BF0 0x5BF6 0x5BF3 0x5C05 0x5C07 0x5C08 0x5C0D 0x5C13 0x5C20 0x5C22 0x5C28 0x5C38 0x5C39 0x5C41 0x5C46 0x5C4E 0x5C53 +0x5C50 0x5C4F 0x5B71 0x5C6C 0x5C6E 0x4E62 0x5C76 0x5C79 0x5C8C 0x5C91 0x5C94 0x599B 0x5CAB 0x5CBB 0x5CB6 0x5CBC 0x5CB7 0x5CC5 0x5CBE 0x5CC7 0x5CD9 0x5CE9 0x5CFD 0x5CFA 0x5CED 0x5D8C 0x5CEA 0x5D0B 0x5D15 0x5D17 0x5D5C 0x5D1F 0x5D1B 0x5D11 0x5D14 0x5D22 0x5D1A 0x5D19 0x5D18 0x5D4C 0x5D52 0x5D4E 0x5D4B 0x5D6C 0x5D73 0x5D76 0x5D87 0x5D84 0x5D82 0x5DA2 0x5D9D 0x5DAC 0x5DAE 0x5DBD 0x5D90 0x5DB7 0x5DBC 0x5DC9 0x5DCD 0x5DD3 0x5DD2 0x5DD6 0x5DDB 0x5DEB 0x5DF2 0x5DF5 0x5E0B 0x5E1A 0x5E19 0x5E11 0x5E1B 0x5E36 0x5E37 0x5E44 0x5E43 0x5E40 0x5E4E 0x5E57 0x5E54 0x5E5F 0x5E62 0x5E64 0x5E47 0x5E75 0x5E76 0x5E7A 0x9EBC 0x5E7F 0x5EA0 0x5EC1 0x5EC2 0x5EC8 0x5ED0 0x5ECF +0x5ED6 0x5EE3 0x5EDD 0x5EDA 0x5EDB 0x5EE2 0x5EE1 0x5EE8 0x5EE9 0x5EEC 0x5EF1 0x5EF3 0x5EF0 0x5EF4 0x5EF8 0x5EFE 0x5F03 0x5F09 0x5F5D 0x5F5C 0x5F0B 0x5F11 0x5F16 0x5F29 0x5F2D 0x5F38 0x5F41 0x5F48 0x5F4C 0x5F4E 0x5F2F 0x5F51 0x5F56 0x5F57 0x5F59 0x5F61 0x5F6D 0x5F73 0x5F77 0x5F83 0x5F82 0x5F7F 0x5F8A 0x5F88 0x5F91 0x5F87 0x5F9E 0x5F99 0x5F98 0x5FA0 0x5FA8 0x5FAD 0x5FBC 0x5FD6 0x5FFB 0x5FE4 0x5FF8 0x5FF1 0x5FDD 0x60B3 0x5FFF 0x6021 0x6060 0x6019 0x6010 0x6029 0x600E 0x6031 0x601B 0x6015 0x602B 0x6026 0x600F 0x603A 0x605A 0x6041 0x606A 0x6077 0x605F 0x604A 0x6046 0x604D 0x6063 0x6043 0x6064 0x6042 0x606C 0x606B 0x6059 0x6081 0x608D 0x60E7 0x6083 0x609A +0x6084 0x609B 0x6096 0x6097 0x6092 0x60A7 0x608B 0x60E1 0x60B8 0x60E0 0x60D3 0x60B4 0x5FF0 0x60BD 0x60C6 0x60B5 0x60D8 0x614D 0x6115 0x6106 0x60F6 0x60F7 0x6100 0x60F4 0x60FA 0x6103 0x6121 0x60FB 0x60F1 0x610D 0x610E 0x6147 0x613E 0x6128 0x6127 0x614A 0x613F 0x613C 0x612C 0x6134 0x613D 0x6142 0x6144 0x6173 0x6177 0x6158 0x6159 0x615A 0x616B 0x6174 0x616F 0x6165 0x6171 0x615F 0x615D 0x6153 0x6175 0x6199 0x6196 0x6187 0x61AC 0x6194 0x619A 0x618A 0x6191 0x61AB 0x61AE 0x61CC 0x61CA 0x61C9 0x61F7 0x61C8 0x61C3 0x61C6 0x61BA 0x61CB 0x7F79 0x61CD 0x61E6 0x61E3 0x61F6 0x61FA 0x61F4 0x61FF 0x61FD 0x61FC 0x61FE 0x6200 0x6208 0x6209 0x620D 0x620C 0x6214 0x621B +0x621E 0x6221 0x622A 0x622E 0x6230 0x6232 0x6233 0x6241 0x624E 0x625E 0x6263 0x625B 0x6260 0x6268 0x627C 0x6282 0x6289 0x627E 0x6292 0x6293 0x6296 0x62D4 0x6283 0x6294 0x62D7 0x62D1 0x62BB 0x62CF 0x62FF 0x62C6 0x64D4 0x62C8 0x62DC 0x62CC 0x62CA 0x62C2 0x62C7 0x629B 0x62C9 0x630C 0x62EE 0x62F1 0x6327 0x6302 0x6308 0x62EF 0x62F5 0x6350 0x633E 0x634D 0x641C 0x634F 0x6396 0x638E 0x6380 0x63AB 0x6376 0x63A3 0x638F 0x6389 0x639F 0x63B5 0x636B 0x6369 0x63BE 0x63E9 0x63C0 0x63C6 0x63E3 0x63C9 0x63D2 0x63F6 0x63C4 0x6416 0x6434 0x6406 0x6413 0x6426 0x6436 0x651D 0x6417 0x6428 0x640F 0x6467 0x646F 0x6476 0x644E 0x652A 0x6495 0x6493 0x64A5 0x64A9 0x6488 0x64BC +0x64DA 0x64D2 0x64C5 0x64C7 0x64BB 0x64D8 0x64C2 0x64F1 0x64E7 0x8209 0x64E0 0x64E1 0x62AC 0x64E3 0x64EF 0x652C 0x64F6 0x64F4 0x64F2 0x64FA 0x6500 0x64FD 0x6518 0x651C 0x6505 0x6524 0x6523 0x652B 0x6534 0x6535 0x6537 0x6536 0x6538 0x754B 0x6548 0x6556 0x6555 0x654D 0x6558 0x655E 0x655D 0x6572 0x6578 0x6582 0x6583 0x8B8A 0x659B 0x659F 0x65AB 0x65B7 0x65C3 0x65C6 0x65C1 0x65C4 0x65CC 0x65D2 0x65DB 0x65D9 0x65E0 0x65E1 0x65F1 0x6772 0x660A 0x6603 0x65FB 0x6773 0x6635 0x6636 0x6634 0x661C 0x664F 0x6644 0x6649 0x6641 0x665E 0x665D 0x6664 0x6667 0x6668 0x665F 0x6662 0x6670 0x6683 0x6688 0x668E 0x6689 0x6684 0x6698 0x669D 0x66C1 0x66B9 0x66C9 0x66BE 0x66BC +0x66C4 0x66B8 0x66D6 0x66DA 0x66E0 0x663F 0x66E6 0x66E9 0x66F0 0x66F5 0x66F7 0x670F 0x6716 0x671E 0x6726 0x6727 0x9738 0x672E 0x673F 0x6736 0x6741 0x6738 0x6737 0x6746 0x675E 0x6760 0x6759 0x6763 0x6764 0x6789 0x6770 0x67A9 0x677C 0x676A 0x678C 0x678B 0x67A6 0x67A1 0x6785 0x67B7 0x67EF 0x67B4 0x67EC 0x67B3 0x67E9 0x67B8 0x67E4 0x67DE 0x67DD 0x67E2 0x67EE 0x67B9 0x67CE 0x67C6 0x67E7 0x6A9C 0x681E 0x6846 0x6829 0x6840 0x684D 0x6832 0x684E 0x68B3 0x682B 0x6859 0x6863 0x6877 0x687F 0x689F 0x688F 0x68AD 0x6894 0x689D 0x689B 0x6883 0x6AAE 0x68B9 0x6874 0x68B5 0x68A0 0x68BA 0x690F 0x688D 0x687E 0x6901 0x68CA 0x6908 0x68D8 0x6922 0x6926 0x68E1 0x690C 0x68CD +0x68D4 0x68E7 0x68D5 0x6936 0x6912 0x6904 0x68D7 0x68E3 0x6925 0x68F9 0x68E0 0x68EF 0x6928 0x692A 0x691A 0x6923 0x6921 0x68C6 0x6979 0x6977 0x695C 0x6978 0x696B 0x6954 0x697E 0x696E 0x6939 0x6974 0x693D 0x6959 0x6930 0x6961 0x695E 0x695D 0x6981 0x696A 0x69B2 0x69AE 0x69D0 0x69BF 0x69C1 0x69D3 0x69BE 0x69CE 0x5BE8 0x69CA 0x69DD 0x69BB 0x69C3 0x69A7 0x6A2E 0x6991 0x69A0 0x699C 0x6995 0x69B4 0x69DE 0x69E8 0x6A02 0x6A1B 0x69FF 0x6B0A 0x69F9 0x69F2 0x69E7 0x6A05 0x69B1 0x6A1E 0x69ED 0x6A14 0x69EB 0x6A0A 0x6A12 0x6AC1 0x6A23 0x6A13 0x6A44 0x6A0C 0x6A72 0x6A36 0x6A78 0x6A47 0x6A62 0x6A59 0x6A66 0x6A48 0x6A38 0x6A22 0x6A90 0x6A8D 0x6AA0 0x6A84 0x6AA2 0x6AA3 +0x6A97 0x8617 0x6ABB 0x6AC3 0x6AC2 0x6AB8 0x6AB3 0x6AAC 0x6ADE 0x6AD1 0x6ADF 0x6AAA 0x6ADA 0x6AEA 0x6AFB 0x6B05 0x8616 0x6AFA 0x6B12 0x6B16 0x9B31 0x6B1F 0x6B38 0x6B37 0x76DC 0x6B39 0x98EE 0x6B47 0x6B43 0x6B49 0x6B50 0x6B59 0x6B54 0x6B5B 0x6B5F 0x6B61 0x6B78 0x6B79 0x6B7F 0x6B80 0x6B84 0x6B83 0x6B8D 0x6B98 0x6B95 0x6B9E 0x6BA4 0x6BAA 0x6BAB 0x6BAF 0x6BB2 0x6BB1 0x6BB3 0x6BB7 0x6BBC 0x6BC6 0x6BCB 0x6BD3 0x6BDF 0x6BEC 0x6BEB 0x6BF3 0x6BEF 0x9EBE 0x6C08 0x6C13 0x6C14 0x6C1B 0x6C24 0x6C23 0x6C5E 0x6C55 0x6C62 0x6C6A 0x6C82 0x6C8D 0x6C9A 0x6C81 0x6C9B 0x6C7E 0x6C68 0x6C73 0x6C92 0x6C90 0x6CC4 0x6CF1 0x6CD3 0x6CBD 0x6CD7 0x6CC5 0x6CDD 0x6CAE 0x6CB1 0x6CBE +0x6CBA 0x6CDB 0x6CEF 0x6CD9 0x6CEA 0x6D1F 0x884D 0x6D36 0x6D2B 0x6D3D 0x6D38 0x6D19 0x6D35 0x6D33 0x6D12 0x6D0C 0x6D63 0x6D93 0x6D64 0x6D5A 0x6D79 0x6D59 0x6D8E 0x6D95 0x6FE4 0x6D85 0x6DF9 0x6E15 0x6E0A 0x6DB5 0x6DC7 0x6DE6 0x6DB8 0x6DC6 0x6DEC 0x6DDE 0x6DCC 0x6DE8 0x6DD2 0x6DC5 0x6DFA 0x6DD9 0x6DE4 0x6DD5 0x6DEA 0x6DEE 0x6E2D 0x6E6E 0x6E2E 0x6E19 0x6E72 0x6E5F 0x6E3E 0x6E23 0x6E6B 0x6E2B 0x6E76 0x6E4D 0x6E1F 0x6E43 0x6E3A 0x6E4E 0x6E24 0x6EFF 0x6E1D 0x6E38 0x6E82 0x6EAA 0x6E98 0x6EC9 0x6EB7 0x6ED3 0x6EBD 0x6EAF 0x6EC4 0x6EB2 0x6ED4 0x6ED5 0x6E8F 0x6EA5 0x6EC2 0x6E9F 0x6F41 0x6F11 0x704C 0x6EEC 0x6EF8 0x6EFE 0x6F3F 0x6EF2 0x6F31 0x6EEF 0x6F32 0x6ECC +0x6F3E 0x6F13 0x6EF7 0x6F86 0x6F7A 0x6F78 0x6F81 0x6F80 0x6F6F 0x6F5B 0x6FF3 0x6F6D 0x6F82 0x6F7C 0x6F58 0x6F8E 0x6F91 0x6FC2 0x6F66 0x6FB3 0x6FA3 0x6FA1 0x6FA4 0x6FB9 0x6FC6 0x6FAA 0x6FDF 0x6FD5 0x6FEC 0x6FD4 0x6FD8 0x6FF1 0x6FEE 0x6FDB 0x7009 0x700B 0x6FFA 0x7011 0x7001 0x700F 0x6FFE 0x701B 0x701A 0x6F74 0x701D 0x7018 0x701F 0x7030 0x703E 0x7032 0x7051 0x7063 0x7099 0x7092 0x70AF 0x70F1 0x70AC 0x70B8 0x70B3 0x70AE 0x70DF 0x70CB 0x70DD 0x70D9 0x7109 0x70FD 0x711C 0x7119 0x7165 0x7155 0x7188 0x7166 0x7162 0x714C 0x7156 0x716C 0x718F 0x71FB 0x7184 0x7195 0x71A8 0x71AC 0x71D7 0x71B9 0x71BE 0x71D2 0x71C9 0x71D4 0x71CE 0x71E0 0x71EC 0x71E7 0x71F5 0x71FC +0x71F9 0x71FF 0x720D 0x7210 0x721B 0x7228 0x722D 0x722C 0x7230 0x7232 0x723B 0x723C 0x723F 0x7240 0x7246 0x724B 0x7258 0x7274 0x727E 0x7282 0x7281 0x7287 0x7292 0x7296 0x72A2 0x72A7 0x72B9 0x72B2 0x72C3 0x72C6 0x72C4 0x72CE 0x72D2 0x72E2 0x72E0 0x72E1 0x72F9 0x72F7 0x500F 0x7317 0x730A 0x731C 0x7316 0x731D 0x7334 0x732F 0x7329 0x7325 0x733E 0x734E 0x734F 0x9ED8 0x7357 0x736A 0x7368 0x7370 0x7378 0x7375 0x737B 0x737A 0x73C8 0x73B3 0x73CE 0x73BB 0x73C0 0x73E5 0x73EE 0x73DE 0x74A2 0x7405 0x746F 0x7425 0x73F8 0x7432 0x743A 0x7455 0x743F 0x745F 0x7459 0x7441 0x745C 0x7469 0x7470 0x7463 0x746A 0x7476 0x747E 0x748B 0x749E 0x74A7 0x74CA 0x74CF 0x74D4 0x73F1 +0x74E0 0x74E3 0x74E7 0x74E9 0x74EE 0x74F2 0x74F0 0x74F1 0x74F8 0x74F7 0x7504 0x7503 0x7505 0x750C 0x750E 0x750D 0x7515 0x7513 0x751E 0x7526 0x752C 0x753C 0x7544 0x754D 0x754A 0x7549 0x755B 0x7546 0x755A 0x7569 0x7564 0x7567 0x756B 0x756D 0x7578 0x7576 0x7586 0x7587 0x7574 0x758A 0x7589 0x7582 0x7594 0x759A 0x759D 0x75A5 0x75A3 0x75C2 0x75B3 0x75C3 0x75B5 0x75BD 0x75B8 0x75BC 0x75B1 0x75CD 0x75CA 0x75D2 0x75D9 0x75E3 0x75DE 0x75FE 0x75FF 0x75FC 0x7601 0x75F0 0x75FA 0x75F2 0x75F3 0x760B 0x760D 0x7609 0x761F 0x7627 0x7620 0x7621 0x7622 0x7624 0x7634 0x7630 0x763B 0x7647 0x7648 0x7646 0x765C 0x7658 0x7661 0x7662 0x7668 0x7669 0x766A 0x7667 0x766C 0x7670 +0x7672 0x7676 0x7678 0x767C 0x7680 0x7683 0x7688 0x768B 0x768E 0x7696 0x7693 0x7699 0x769A 0x76B0 0x76B4 0x76B8 0x76B9 0x76BA 0x76C2 0x76CD 0x76D6 0x76D2 0x76DE 0x76E1 0x76E5 0x76E7 0x76EA 0x862F 0x76FB 0x7708 0x7707 0x7704 0x7729 0x7724 0x771E 0x7725 0x7726 0x771B 0x7737 0x7738 0x7747 0x775A 0x7768 0x776B 0x775B 0x7765 0x777F 0x777E 0x7779 0x778E 0x778B 0x7791 0x77A0 0x779E 0x77B0 0x77B6 0x77B9 0x77BF 0x77BC 0x77BD 0x77BB 0x77C7 0x77CD 0x77D7 0x77DA 0x77DC 0x77E3 0x77EE 0x77FC 0x780C 0x7812 0x7926 0x7820 0x792A 0x7845 0x788E 0x7874 0x7886 0x787C 0x789A 0x788C 0x78A3 0x78B5 0x78AA 0x78AF 0x78D1 0x78C6 0x78CB 0x78D4 0x78BE 0x78BC 0x78C5 0x78CA 0x78EC +0x78E7 0x78DA 0x78FD 0x78F4 0x7907 0x7912 0x7911 0x7919 0x792C 0x792B 0x7940 0x7960 0x7957 0x795F 0x795A 0x7955 0x7953 0x797A 0x797F 0x798A 0x799D 0x79A7 0x9F4B 0x79AA 0x79AE 0x79B3 0x79B9 0x79BA 0x79C9 0x79D5 0x79E7 0x79EC 0x79E1 0x79E3 0x7A08 0x7A0D 0x7A18 0x7A19 0x7A20 0x7A1F 0x7980 0x7A31 0x7A3B 0x7A3E 0x7A37 0x7A43 0x7A57 0x7A49 0x7A61 0x7A62 0x7A69 0x9F9D 0x7A70 0x7A79 0x7A7D 0x7A88 0x7A97 0x7A95 0x7A98 0x7A96 0x7AA9 0x7AC8 0x7AB0 0x7AB6 0x7AC5 0x7AC4 0x7ABF 0x9083 0x7AC7 0x7ACA 0x7ACD 0x7ACF 0x7AD5 0x7AD3 0x7AD9 0x7ADA 0x7ADD 0x7AE1 0x7AE2 0x7AE6 0x7AED 0x7AF0 0x7B02 0x7B0F 0x7B0A 0x7B06 0x7B33 0x7B18 0x7B19 0x7B1E 0x7B35 0x7B28 0x7B36 0x7B50 +0x7B7A 0x7B04 0x7B4D 0x7B0B 0x7B4C 0x7B45 0x7B75 0x7B65 0x7B74 0x7B67 0x7B70 0x7B71 0x7B6C 0x7B6E 0x7B9D 0x7B98 0x7B9F 0x7B8D 0x7B9C 0x7B9A 0x7B8B 0x7B92 0x7B8F 0x7B5D 0x7B99 0x7BCB 0x7BC1 0x7BCC 0x7BCF 0x7BB4 0x7BC6 0x7BDD 0x7BE9 0x7C11 0x7C14 0x7BE6 0x7BE5 0x7C60 0x7C00 0x7C07 0x7C13 0x7BF3 0x7BF7 0x7C17 0x7C0D 0x7BF6 0x7C23 0x7C27 0x7C2A 0x7C1F 0x7C37 0x7C2B 0x7C3D 0x7C4C 0x7C43 0x7C54 0x7C4F 0x7C40 0x7C50 0x7C58 0x7C5F 0x7C64 0x7C56 0x7C65 0x7C6C 0x7C75 0x7C83 0x7C90 0x7CA4 0x7CAD 0x7CA2 0x7CAB 0x7CA1 0x7CA8 0x7CB3 0x7CB2 0x7CB1 0x7CAE 0x7CB9 0x7CBD 0x7CC0 0x7CC5 0x7CC2 0x7CD8 0x7CD2 0x7CDC 0x7CE2 0x9B3B 0x7CEF 0x7CF2 0x7CF4 0x7CF6 0x7CFA 0x7D06 +0x7D02 0x7D1C 0x7D15 0x7D0A 0x7D45 0x7D4B 0x7D2E 0x7D32 0x7D3F 0x7D35 0x7D46 0x7D73 0x7D56 0x7D4E 0x7D72 0x7D68 0x7D6E 0x7D4F 0x7D63 0x7D93 0x7D89 0x7D5B 0x7D8F 0x7D7D 0x7D9B 0x7DBA 0x7DAE 0x7DA3 0x7DB5 0x7DC7 0x7DBD 0x7DAB 0x7E3D 0x7DA2 0x7DAF 0x7DDC 0x7DB8 0x7D9F 0x7DB0 0x7DD8 0x7DDD 0x7DE4 0x7DDE 0x7DFB 0x7DF2 0x7DE1 0x7E05 0x7E0A 0x7E23 0x7E21 0x7E12 0x7E31 0x7E1F 0x7E09 0x7E0B 0x7E22 0x7E46 0x7E66 0x7E3B 0x7E35 0x7E39 0x7E43 0x7E37 0x7E32 0x7E3A 0x7E67 0x7E5D 0x7E56 0x7E5E 0x7E59 0x7E5A 0x7E79 0x7E6A 0x7E69 0x7E7C 0x7E7B 0x7E83 0x7DD5 0x7E7D 0x8FAE 0x7E7F 0x7E88 0x7E89 0x7E8C 0x7E92 0x7E90 0x7E93 0x7E94 0x7E96 0x7E8E 0x7E9B 0x7E9C 0x7F38 0x7F3A +0x7F45 0x7F4C 0x7F4D 0x7F4E 0x7F50 0x7F51 0x7F55 0x7F54 0x7F58 0x7F5F 0x7F60 0x7F68 0x7F69 0x7F67 0x7F78 0x7F82 0x7F86 0x7F83 0x7F88 0x7F87 0x7F8C 0x7F94 0x7F9E 0x7F9D 0x7F9A 0x7FA3 0x7FAF 0x7FB2 0x7FB9 0x7FAE 0x7FB6 0x7FB8 0x8B71 0x7FC5 0x7FC6 0x7FCA 0x7FD5 0x7FD4 0x7FE1 0x7FE6 0x7FE9 0x7FF3 0x7FF9 0x98DC 0x8006 0x8004 0x800B 0x8012 0x8018 0x8019 0x801C 0x8021 0x8028 0x803F 0x803B 0x804A 0x8046 0x8052 0x8058 0x805A 0x805F 0x8062 0x8068 0x8073 0x8072 0x8070 0x8076 0x8079 0x807D 0x807F 0x8084 0x8086 0x8085 0x809B 0x8093 0x809A 0x80AD 0x5190 0x80AC 0x80DB 0x80E5 0x80D9 0x80DD 0x80C4 0x80DA 0x80D6 0x8109 0x80EF 0x80F1 0x811B 0x8129 0x8123 0x812F 0x814B +0x968B 0x8146 0x813E 0x8153 0x8151 0x80FC 0x8171 0x816E 0x8165 0x8166 0x8174 0x8183 0x8188 0x818A 0x8180 0x8182 0x81A0 0x8195 0x81A4 0x81A3 0x815F 0x8193 0x81A9 0x81B0 0x81B5 0x81BE 0x81B8 0x81BD 0x81C0 0x81C2 0x81BA 0x81C9 0x81CD 0x81D1 0x81D9 0x81D8 0x81C8 0x81DA 0x81DF 0x81E0 0x81E7 0x81FA 0x81FB 0x81FE 0x8201 0x8202 0x8205 0x8207 0x820A 0x820D 0x8210 0x8216 0x8229 0x822B 0x8238 0x8233 0x8240 0x8259 0x8258 0x825D 0x825A 0x825F 0x8264 0x8262 0x8268 0x826A 0x826B 0x822E 0x8271 0x8277 0x8278 0x827E 0x828D 0x8292 0x82AB 0x829F 0x82BB 0x82AC 0x82E1 0x82E3 0x82DF 0x82D2 0x82F4 0x82F3 0x82FA 0x8393 0x8303 0x82FB 0x82F9 0x82DE 0x8306 0x82DC 0x8309 0x82D9 +0x8335 0x8334 0x8316 0x8332 0x8331 0x8340 0x8339 0x8350 0x8345 0x832F 0x832B 0x8317 0x8318 0x8385 0x839A 0x83AA 0x839F 0x83A2 0x8396 0x8323 0x838E 0x8387 0x838A 0x837C 0x83B5 0x8373 0x8375 0x83A0 0x8389 0x83A8 0x83F4 0x8413 0x83EB 0x83CE 0x83FD 0x8403 0x83D8 0x840B 0x83C1 0x83F7 0x8407 0x83E0 0x83F2 0x840D 0x8422 0x8420 0x83BD 0x8438 0x8506 0x83FB 0x846D 0x842A 0x843C 0x855A 0x8484 0x8477 0x846B 0x84AD 0x846E 0x8482 0x8469 0x8446 0x842C 0x846F 0x8479 0x8435 0x84CA 0x8462 0x84B9 0x84BF 0x849F 0x84D9 0x84CD 0x84BB 0x84DA 0x84D0 0x84C1 0x84C6 0x84D6 0x84A1 0x8521 0x84FF 0x84F4 0x8517 0x8518 0x852C 0x851F 0x8515 0x8514 0x84FC 0x8540 0x8563 0x8558 0x8548 +0x8541 0x8602 0x854B 0x8555 0x8580 0x85A4 0x8588 0x8591 0x858A 0x85A8 0x856D 0x8594 0x859B 0x85EA 0x8587 0x859C 0x8577 0x857E 0x8590 0x85C9 0x85BA 0x85CF 0x85B9 0x85D0 0x85D5 0x85DD 0x85E5 0x85DC 0x85F9 0x860A 0x8613 0x860B 0x85FE 0x85FA 0x8606 0x8622 0x861A 0x8630 0x863F 0x864D 0x4E55 0x8654 0x865F 0x8667 0x8671 0x8693 0x86A3 0x86A9 0x86AA 0x868B 0x868C 0x86B6 0x86AF 0x86C4 0x86C6 0x86B0 0x86C9 0x8823 0x86AB 0x86D4 0x86DE 0x86E9 0x86EC 0x86DF 0x86DB 0x86EF 0x8712 0x8706 0x8708 0x8700 0x8703 0x86FB 0x8711 0x8709 0x870D 0x86F9 0x870A 0x8734 0x873F 0x8737 0x873B 0x8725 0x8729 0x871A 0x8760 0x875F 0x8778 0x874C 0x874E 0x8774 0x8757 0x8768 0x876E 0x8759 +0x8753 0x8763 0x876A 0x8805 0x87A2 0x879F 0x8782 0x87AF 0x87CB 0x87BD 0x87C0 0x87D0 0x96D6 0x87AB 0x87C4 0x87B3 0x87C7 0x87C6 0x87BB 0x87EF 0x87F2 0x87E0 0x880F 0x880D 0x87FE 0x87F6 0x87F7 0x880E 0x87D2 0x8811 0x8816 0x8815 0x8822 0x8821 0x8831 0x8836 0x8839 0x8827 0x883B 0x8844 0x8842 0x8852 0x8859 0x885E 0x8862 0x886B 0x8881 0x887E 0x889E 0x8875 0x887D 0x88B5 0x8872 0x8882 0x8897 0x8892 0x88AE 0x8899 0x88A2 0x888D 0x88A4 0x88B0 0x88BF 0x88B1 0x88C3 0x88C4 0x88D4 0x88D8 0x88D9 0x88DD 0x88F9 0x8902 0x88FC 0x88F4 0x88E8 0x88F2 0x8904 0x890C 0x890A 0x8913 0x8943 0x891E 0x8925 0x892A 0x892B 0x8941 0x8944 0x893B 0x8936 0x8938 0x894C 0x891D 0x8960 0x895E +0x8966 0x8964 0x896D 0x896A 0x896F 0x8974 0x8977 0x897E 0x8983 0x8988 0x898A 0x8993 0x8998 0x89A1 0x89A9 0x89A6 0x89AC 0x89AF 0x89B2 0x89BA 0x89BD 0x89BF 0x89C0 0x89DA 0x89DC 0x89DD 0x89E7 0x89F4 0x89F8 0x8A03 0x8A16 0x8A10 0x8A0C 0x8A1B 0x8A1D 0x8A25 0x8A36 0x8A41 0x8A5B 0x8A52 0x8A46 0x8A48 0x8A7C 0x8A6D 0x8A6C 0x8A62 0x8A85 0x8A82 0x8A84 0x8AA8 0x8AA1 0x8A91 0x8AA5 0x8AA6 0x8A9A 0x8AA3 0x8AC4 0x8ACD 0x8AC2 0x8ADA 0x8AEB 0x8AF3 0x8AE7 0x8AE4 0x8AF1 0x8B14 0x8AE0 0x8AE2 0x8AF7 0x8ADE 0x8ADB 0x8B0C 0x8B07 0x8B1A 0x8AE1 0x8B16 0x8B10 0x8B17 0x8B20 0x8B33 0x97AB 0x8B26 0x8B2B 0x8B3E 0x8B28 0x8B41 0x8B4C 0x8B4F 0x8B4E 0x8B49 0x8B56 0x8B5B 0x8B5A 0x8B6B +0x8B5F 0x8B6C 0x8B6F 0x8B74 0x8B7D 0x8B80 0x8B8C 0x8B8E 0x8B92 0x8B93 0x8B96 0x8B99 0x8B9A 0x8C3A 0x8C41 0x8C3F 0x8C48 0x8C4C 0x8C4E 0x8C50 0x8C55 0x8C62 0x8C6C 0x8C78 0x8C7A 0x8C82 0x8C89 0x8C85 0x8C8A 0x8C8D 0x8C8E 0x8C94 0x8C7C 0x8C98 0x621D 0x8CAD 0x8CAA 0x8CBD 0x8CB2 0x8CB3 0x8CAE 0x8CB6 0x8CC8 0x8CC1 0x8CE4 0x8CE3 0x8CDA 0x8CFD 0x8CFA 0x8CFB 0x8D04 0x8D05 0x8D0A 0x8D07 0x8D0F 0x8D0D 0x8D10 0x9F4E 0x8D13 0x8CCD 0x8D14 0x8D16 0x8D67 0x8D6D 0x8D71 0x8D73 0x8D81 0x8D99 0x8DC2 0x8DBE 0x8DBA 0x8DCF 0x8DDA 0x8DD6 0x8DCC 0x8DDB 0x8DCB 0x8DEA 0x8DEB 0x8DDF 0x8DE3 0x8DFC 0x8E08 0x8E09 0x8DFF 0x8E1D 0x8E1E 0x8E10 0x8E1F 0x8E42 0x8E35 0x8E30 0x8E34 0x8E4A +0x8E47 0x8E49 0x8E4C 0x8E50 0x8E48 0x8E59 0x8E64 0x8E60 0x8E2A 0x8E63 0x8E55 0x8E76 0x8E72 0x8E7C 0x8E81 0x8E87 0x8E85 0x8E84 0x8E8B 0x8E8A 0x8E93 0x8E91 0x8E94 0x8E99 0x8EAA 0x8EA1 0x8EAC 0x8EB0 0x8EC6 0x8EB1 0x8EBE 0x8EC5 0x8EC8 0x8ECB 0x8EDB 0x8EE3 0x8EFC 0x8EFB 0x8EEB 0x8EFE 0x8F0A 0x8F05 0x8F15 0x8F12 0x8F19 0x8F13 0x8F1C 0x8F1F 0x8F1B 0x8F0C 0x8F26 0x8F33 0x8F3B 0x8F39 0x8F45 0x8F42 0x8F3E 0x8F4C 0x8F49 0x8F46 0x8F4E 0x8F57 0x8F5C 0x8F62 0x8F63 0x8F64 0x8F9C 0x8F9F 0x8FA3 0x8FAD 0x8FAF 0x8FB7 0x8FDA 0x8FE5 0x8FE2 0x8FEA 0x8FEF 0x9087 0x8FF4 0x9005 0x8FF9 0x8FFA 0x9011 0x9015 0x9021 0x900D 0x901E 0x9016 0x900B 0x9027 0x9036 0x9035 0x9039 0x8FF8 +0x904F 0x9050 0x9051 0x9052 0x900E 0x9049 0x903E 0x9056 0x9058 0x905E 0x9068 0x906F 0x9076 0x96A8 0x9072 0x9082 0x907D 0x9081 0x9080 0x908A 0x9089 0x908F 0x90A8 0x90AF 0x90B1 0x90B5 0x90E2 0x90E4 0x6248 0x90DB 0x9102 0x9112 0x9119 0x9132 0x9130 0x914A 0x9156 0x9158 0x9163 0x9165 0x9169 0x9173 0x9172 0x918B 0x9189 0x9182 0x91A2 0x91AB 0x91AF 0x91AA 0x91B5 0x91B4 0x91BA 0x91C0 0x91C1 0x91C9 0x91CB 0x91D0 0x91D6 0x91DF 0x91E1 0x91DB 0x91FC 0x91F5 0x91F6 0x921E 0x91FF 0x9214 0x922C 0x9215 0x9211 0x925E 0x9257 0x9245 0x9249 0x9264 0x9248 0x9295 0x923F 0x924B 0x9250 0x929C 0x9296 0x9293 0x929B 0x925A 0x92CF 0x92B9 0x92B7 0x92E9 0x930F 0x92FA 0x9344 0x932E +0x9319 0x9322 0x931A 0x9323 0x933A 0x9335 0x933B 0x935C 0x9360 0x937C 0x936E 0x9356 0x93B0 0x93AC 0x93AD 0x9394 0x93B9 0x93D6 0x93D7 0x93E8 0x93E5 0x93D8 0x93C3 0x93DD 0x93D0 0x93C8 0x93E4 0x941A 0x9414 0x9413 0x9403 0x9407 0x9410 0x9436 0x942B 0x9435 0x9421 0x943A 0x9441 0x9452 0x9444 0x945B 0x9460 0x9462 0x945E 0x946A 0x9229 0x9470 0x9475 0x9477 0x947D 0x945A 0x947C 0x947E 0x9481 0x947F 0x9582 0x9587 0x958A 0x9594 0x9596 0x9598 0x9599 0x95A0 0x95A8 0x95A7 0x95AD 0x95BC 0x95BB 0x95B9 0x95BE 0x95CA 0x6FF6 0x95C3 0x95CD 0x95CC 0x95D5 0x95D4 0x95D6 0x95DC 0x95E1 0x95E5 0x95E2 0x9621 0x9628 0x962E 0x962F 0x9642 0x964C 0x964F 0x964B 0x9677 0x965C 0x965E +0x965D 0x965F 0x9666 0x9672 0x966C 0x968D 0x9698 0x9695 0x9697 0x96AA 0x96A7 0x96B1 0x96B2 0x96B0 0x96B4 0x96B6 0x96B8 0x96B9 0x96CE 0x96CB 0x96C9 0x96CD 0x894D 0x96DC 0x970D 0x96D5 0x96F9 0x9704 0x9706 0x9708 0x9713 0x970E 0x9711 0x970F 0x9716 0x9719 0x9724 0x972A 0x9730 0x9739 0x973D 0x973E 0x9744 0x9746 0x9748 0x9742 0x9749 0x975C 0x9760 0x9764 0x9766 0x9768 0x52D2 0x976B 0x9771 0x9779 0x9785 0x977C 0x9781 0x977A 0x9786 0x978B 0x978F 0x9790 0x979C 0x97A8 0x97A6 0x97A3 0x97B3 0x97B4 0x97C3 0x97C6 0x97C8 0x97CB 0x97DC 0x97ED 0x9F4F 0x97F2 0x7ADF 0x97F6 0x97F5 0x980F 0x980C 0x9838 0x9824 0x9821 0x9837 0x983D 0x9846 0x984F 0x984B 0x986B 0x986F 0x9870 +0x9871 0x9874 0x9873 0x98AA 0x98AF 0x98B1 0x98B6 0x98C4 0x98C3 0x98C6 0x98E9 0x98EB 0x9903 0x9909 0x9912 0x9914 0x9918 0x9921 0x991D 0x991E 0x9924 0x9920 0x992C 0x992E 0x993D 0x993E 0x9942 0x9949 0x9945 0x9950 0x994B 0x9951 0x9952 0x994C 0x9955 0x9997 0x9998 0x99A5 0x99AD 0x99AE 0x99BC 0x99DF 0x99DB 0x99DD 0x99D8 0x99D1 0x99ED 0x99EE 0x99F1 0x99F2 0x99FB 0x99F8 0x9A01 0x9A0F 0x9A05 0x99E2 0x9A19 0x9A2B 0x9A37 0x9A45 0x9A42 0x9A40 0x9A43 0x9A3E 0x9A55 0x9A4D 0x9A5B 0x9A57 0x9A5F 0x9A62 0x9A65 0x9A64 0x9A69 0x9A6B 0x9A6A 0x9AAD 0x9AB0 0x9ABC 0x9AC0 0x9ACF 0x9AD1 0x9AD3 0x9AD4 0x9ADE 0x9ADF 0x9AE2 0x9AE3 0x9AE6 0x9AEF 0x9AEB 0x9AEE 0x9AF4 0x9AF1 0x9AF7 +0x9AFB 0x9B06 0x9B18 0x9B1A 0x9B1F 0x9B22 0x9B23 0x9B25 0x9B27 0x9B28 0x9B29 0x9B2A 0x9B2E 0x9B2F 0x9B32 0x9B44 0x9B43 0x9B4F 0x9B4D 0x9B4E 0x9B51 0x9B58 0x9B74 0x9B93 0x9B83 0x9B91 0x9B96 0x9B97 0x9B9F 0x9BA0 0x9BA8 0x9BB4 0x9BC0 0x9BCA 0x9BB9 0x9BC6 0x9BCF 0x9BD1 0x9BD2 0x9BE3 0x9BE2 0x9BE4 0x9BD4 0x9BE1 0x9C3A 0x9BF2 0x9BF1 0x9BF0 0x9C15 0x9C14 0x9C09 0x9C13 0x9C0C 0x9C06 0x9C08 0x9C12 0x9C0A 0x9C04 0x9C2E 0x9C1B 0x9C25 0x9C24 0x9C21 0x9C30 0x9C47 0x9C32 0x9C46 0x9C3E 0x9C5A 0x9C60 0x9C67 0x9C76 0x9C78 0x9CE7 0x9CEC 0x9CF0 0x9D09 0x9D08 0x9CEB 0x9D03 0x9D06 0x9D2A 0x9D26 0x9DAF 0x9D23 0x9D1F 0x9D44 0x9D15 0x9D12 0x9D41 0x9D3F 0x9D3E 0x9D46 0x9D48 +0x9D5D 0x9D5E 0x9D64 0x9D51 0x9D50 0x9D59 0x9D72 0x9D89 0x9D87 0x9DAB 0x9D6F 0x9D7A 0x9D9A 0x9DA4 0x9DA9 0x9DB2 0x9DC4 0x9DC1 0x9DBB 0x9DB8 0x9DBA 0x9DC6 0x9DCF 0x9DC2 0x9DD9 0x9DD3 0x9DF8 0x9DE6 0x9DED 0x9DEF 0x9DFD 0x9E1A 0x9E1B 0x9E1E 0x9E75 0x9E79 0x9E7D 0x9E81 0x9E88 0x9E8B 0x9E8C 0x9E92 0x9E95 0x9E91 0x9E9D 0x9EA5 0x9EA9 0x9EB8 0x9EAA 0x9EAD 0x9761 0x9ECC 0x9ECE 0x9ECF 0x9ED0 0x9ED4 0x9EDC 0x9EDE 0x9EDD 0x9EE0 0x9EE5 0x9EE8 0x9EEF 0x9EF4 0x9EF6 0x9EF7 0x9EF9 0x9EFB 0x9EFC 0x9EFD 0x9F07 0x9F08 0x76B7 0x9F15 0x9F21 0x9F2C 0x9F3E 0x9F4A 0x9F52 0x9F54 0x9F63 0x9F5F 0x9F60 0x9F61 0x9F66 0x9F67 0x9F6C 0x9F6A 0x9F77 0x9F72 0x9F76 0x9F95 0x9F9C 0x9FA0 +0x582F 0x69C7 0x9059 0x7464 0x51DC 0x7199 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F 0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F 0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F 0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F 0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F 0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E +0x00A0 0x00A1 0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00B0 0x00B1 0x00B2 0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00BA 0x00BB 0x00BC 0x00BD 0x00BF 0x00C0 0x00C1 0x00C2 0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0102 0x0103 0x0104 +0x0105 0x0106 0x0107 0x0118 0x0119 0x0141 0x0142 0x0143 0x0144 0x0151 0x015A 0x015B 0x0179 0x017A 0x017B 0x017C 0x015E 0x015F 0x0162 0x0163 0x0171 0x0192 0x0218 0x0219 0x021A 0x021B 0x2022 0x203C 0x207F 0x20A7 0x20AC 0x2122 0x2194 0x2195 0x21A8 0x2219 0x221A 0x221E 0x221F 0x2229 0x2248 0x2261 0x2264 0x2265 0x2302 0x2310 0x2320 0x2321 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x2580 0x2584 0x2588 0x258C 0x2590 0x2591 0x2592 0x2593 0x25A0 0x25A1 0x25AC 0x25B2 0x25B3 0x25BA 0x25BC 0x25BD 0x25C4 +0x25C6 0x25C7 0x25CB 0x25CE 0x25CF 0x25D8 0x25D9 0x2605 0x263A 0x263B 0x263C 0x2640 0x2642 0x2660 0x2663 0x2665 0x2666 0x266A 0x266B 0x7B80 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE079 0xE07A 0xE07B 0xE07C 0xE07D 0xE07E 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0386 0x0388 0x0389 0x038A 0x038C 0x038E 0x038F 0x0390 0x03AA 0x03AB 0x03AC 0x03AD 0x03AE 0x03AF 0x03B0 0x03C2 0x03CA 0x03CB 0x03CC 0x03CD 0x03CE 0x0406 0x0407 0x0456 0x0457 0x0490 0x0491 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x65E5 0x672C 0x8A9E 0x7409 0x7403 0x8AF8 0x4E2D 0x6587 0x7B80 0x4F53 0x7E41 0x9AD4 0xD55C 0xAD6D 0xC5B4 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 \ No newline at end of file diff --git a/resources/fonts/font_misaki_gothic_8x8.frf b/resources/fonts/font_misaki_gothic_8x8.frf deleted file mode 100644 index 2ec473ced..000000000 Binary files a/resources/fonts/font_misaki_gothic_8x8.frf and /dev/null differ diff --git a/resources/fonts/font_misaki_gothic_8x8.pbm b/resources/fonts/font_misaki_gothic_8x8.pbm deleted file mode 100644 index bb5f28d75..000000000 Binary files a/resources/fonts/font_misaki_gothic_8x8.pbm and /dev/null differ diff --git a/resources/fonts/fusion/font_fusion_hans_8x8.frf b/resources/fonts/fusion/font_fusion_hans_8x8.frf new file mode 100644 index 000000000..16e0c2fe2 Binary files /dev/null and b/resources/fonts/fusion/font_fusion_hans_8x8.frf differ diff --git a/resources/fonts/fusion/font_fusion_hans_8x8.pbm b/resources/fonts/fusion/font_fusion_hans_8x8.pbm new file mode 100644 index 000000000..11da9708d Binary files /dev/null and b/resources/fonts/fusion/font_fusion_hans_8x8.pbm differ diff --git a/resources/fonts/fusion/font_fusion_hans_8x8.txt b/resources/fonts/fusion/font_fusion_hans_8x8.txt new file mode 100644 index 000000000..cd88777dd --- /dev/null +++ b/resources/fonts/fusion/font_fusion_hans_8x8.txt @@ -0,0 +1,1379 @@ +0x0020 0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F +0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F +0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F +0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F +0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F +0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E 0x00A1 +0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00AF 0x00B0 0x00B1 0x00B2 +0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00B8 0x00B9 0x00BA 0x00BB 0x00BC 0x00BD 0x00BE 0x00BF 0x00C0 0x00C1 0x00C2 +0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 +0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 +0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 +0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0100 0x0101 0x0102 +0x0103 0x0104 0x0105 0x0106 0x0107 0x0108 0x0109 0x010A 0x010B 0x010C 0x010D 0x010E 0x010F 0x0110 0x0111 0x0112 +0x0113 0x0114 0x0115 0x0116 0x0117 0x0118 0x0119 0x011A 0x011B 0x011C 0x011D 0x011E 0x011F 0x0120 0x0121 0x0122 +0x0123 0x0124 0x0125 0x0126 0x0127 0x0128 0x0129 0x012A 0x012B 0x012C 0x012D 0x012E 0x012F 0x0130 0x0131 0x0132 +0x0133 0x0134 0x0135 0x0136 0x0137 0x0138 0x0139 0x013A 0x013B 0x013C 0x013D 0x013E 0x013F 0x0140 0x0141 0x0142 +0x0143 0x0144 0x0145 0x0146 0x0147 0x0148 0x0149 0x014A 0x014B 0x014C 0x014D 0x014E 0x014F 0x0150 0x0151 0x0152 +0x0153 0x0154 0x0155 0x0156 0x0157 0x0158 0x0159 0x015A 0x015B 0x015C 0x015D 0x015E 0x015F 0x0160 0x0161 0x0162 +0x0163 0x0164 0x0165 0x0166 0x0167 0x0168 0x0169 0x016A 0x016B 0x016C 0x016D 0x016E 0x016F 0x0170 0x0171 0x0172 +0x0173 0x0174 0x0175 0x0176 0x0177 0x0178 0x0179 0x017A 0x017B 0x017C 0x017D 0x017E 0x017F 0x0192 0x0197 0x01A0 +0x01A1 0x01AC 0x01AF 0x01B0 0x01C0 0x01C1 0x01C2 0x01C3 0x01CD 0x01CE 0x01CF 0x01D0 0x01D1 0x01D2 0x01D3 0x01D4 +0x01D5 0x01D6 0x01D7 0x01D8 0x01D9 0x01DA 0x01DB 0x01DC 0x01DE 0x01DF 0x01E0 0x01E1 0x01E2 0x01E3 0x01E6 0x01E7 +0x01E8 0x01E9 0x01EA 0x01EB 0x01EC 0x01ED 0x01F0 0x01F4 0x01F5 0x01F8 0x01F9 0x01FA 0x01FB 0x01FC 0x01FD 0x01FE +0x01FF 0x0218 0x0219 0x021A 0x021B 0x021E 0x021F 0x0221 0x0226 0x0227 0x0228 0x0229 0x022A 0x022B 0x022C 0x022D +0x022E 0x022F 0x0230 0x0231 0x0232 0x0233 0x0235 0x0236 0x0237 0x0244 0x2010 0x2011 0x2012 0x2013 0x2014 0x2015 +0x2016 0x2017 0x2018 0x2019 0x201A 0x201C 0x201D 0x201E 0x2020 0x2021 0x2022 0x2023 0x2025 0x2026 0x2027 0x2030 +0x2031 0x2032 0x2033 0x2034 0x2035 0x2037 0x2038 0x2039 0x203A 0x203B 0x203C 0x203E 0x203F 0x2044 0x2103 0x2109 +0x2160 0x2161 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 0x216A 0x216B 0x2170 0x2171 0x2172 0x2173 +0x2174 0x2175 0x2176 0x2177 0x2178 0x2179 0x2181 0x2182 0x2190 0x2191 0x2192 0x2193 0x2194 0x2195 0x2196 0x2197 +0x2198 0x2199 0x219A 0x219B 0x21BA 0x21BB 0x21D0 0x21D1 0x21D2 0x21D3 0x21D4 0x21D5 0x21D6 0x21D7 0x21D8 0x21D9 +0x21DA 0x21DB 0x21E0 0x21E1 0x21E2 0x21E3 0x21E4 0x21E5 0x21E6 0x21E7 0x21E8 0x21E9 0x21EA 0x21EB 0x21EC 0x21ED +0x21EE 0x21EF 0x21F0 0x21F1 0x21F2 0x21F3 0x21FD 0x21FE 0x21FF 0x2200 0x2202 0x2203 0x2207 0x2208 0x220B 0x2211 +0x2212 0x221A 0x221D 0x221E 0x221F 0x2220 0x2225 0x2227 0x2228 0x2229 0x222A 0x222B 0x222C 0x222E 0x2234 0x2235 +0x223D 0x2252 0x2260 0x2261 0x2266 0x2267 0x226A 0x226B 0x2282 0x2283 0x2286 0x2287 0x22A5 0x22BF 0x2460 0x2461 +0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 0x246A 0x246B 0x246C 0x246D 0x246E 0x246F 0x2470 0x2471 +0x2472 0x2473 0x2500 0x2501 0x2502 0x2503 0x2504 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C 0x250D +0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C 0x251D +0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C 0x252D +0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C 0x253D +0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0x254C 0x254D +0x254E 0x254F 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D +0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x256D +0x256E 0x256F 0x2570 0x2571 0x2572 0x2573 0x2574 0x2575 0x2576 0x2577 0x2578 0x2579 0x257A 0x257B 0x257C 0x257D +0x257E 0x257F 0x2580 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 0x2589 0x258A 0x258B 0x258C 0x258D +0x258E 0x258F 0x2590 0x2591 0x2592 0x2593 0x2594 0x2595 0x2596 0x2597 0x2598 0x2599 0x259A 0x259B 0x259C 0x259D +0x259E 0x259F 0x25A0 0x25A1 0x25A2 0x25A3 0x25A4 0x25A5 0x25A6 0x25A7 0x25A8 0x25A9 0x25AA 0x25AB 0x25AC 0x25AD +0x25AE 0x25AF 0x25B0 0x25B1 0x25B2 0x25B3 0x25B4 0x25B5 0x25B6 0x25B7 0x25B8 0x25B9 0x25BA 0x25BB 0x25BC 0x25BD +0x25BE 0x25BF 0x25C0 0x25C1 0x25C2 0x25C3 0x25C4 0x25C5 0x25C6 0x25C7 0x25C8 0x25C9 0x25CA 0x25CB 0x25CC 0x25CD +0x25CE 0x25CF 0x25D0 0x25D1 0x25D2 0x25D3 0x25D4 0x25D5 0x25D6 0x25D7 0x25D8 0x25D9 0x25DA 0x25DB 0x25DC 0x25DD +0x25DE 0x25DF 0x25E0 0x25E1 0x25E2 0x25E3 0x25E4 0x25E5 0x25E6 0x25E7 0x25E8 0x25E9 0x25EA 0x25EB 0x25EC 0x25ED +0x25EE 0x25EF 0x25F0 0x25F1 0x25F2 0x25F3 0x25F4 0x25F5 0x25F6 0x25F7 0x25F8 0x25F9 0x25FA 0x25FB 0x25FC 0x25FD +0x25FE 0x25FF 0x2600 0x2602 0x2604 0x2605 0x2606 0x2609 0x260A 0x260B 0x260C 0x260D 0x260E 0x260F 0x2616 0x2617 +0x262D 0x262E 0x262F 0x2630 0x2631 0x2632 0x2633 0x2634 0x2635 0x2636 0x2637 0x2639 0x263A 0x263B 0x263C 0x263D +0x263E 0x2640 0x2641 0x2642 0x2660 0x2661 0x2662 0x2663 0x2664 0x2665 0x2666 0x2667 0x2668 0x2669 0x266A 0x266B +0x266C 0x266D 0x266E 0x266F 0x2680 0x2681 0x2682 0x2683 0x2684 0x2685 0x2686 0x2687 0x2688 0x2689 0x268A 0x268B +0x268C 0x268D 0x268E 0x268F 0x2694 0x2698 0x2699 0x26AA 0x26AB 0x26AC 0x26C9 0x26CA 0x26F6 0x2800 0x2801 0x2802 +0x2803 0x2804 0x2805 0x2806 0x2807 0x2808 0x2809 0x280A 0x280B 0x280C 0x280D 0x280E 0x280F 0x2810 0x2811 0x2812 +0x2813 0x2814 0x2815 0x2816 0x2817 0x2818 0x2819 0x281A 0x281B 0x281C 0x281D 0x281E 0x281F 0x2820 0x2821 0x2822 +0x2823 0x2824 0x2825 0x2826 0x2827 0x2828 0x2829 0x282A 0x282B 0x282C 0x282D 0x282E 0x282F 0x2830 0x2831 0x2832 +0x2833 0x2834 0x2835 0x2836 0x2837 0x2838 0x2839 0x283A 0x283B 0x283C 0x283D 0x283E 0x283F 0x2840 0x2841 0x2842 +0x2843 0x2844 0x2845 0x2846 0x2847 0x2848 0x2849 0x284A 0x284B 0x284C 0x284D 0x284E 0x284F 0x2850 0x2851 0x2852 +0x2853 0x2854 0x2855 0x2856 0x2857 0x2858 0x2859 0x285A 0x285B 0x285C 0x285D 0x285E 0x285F 0x2860 0x2861 0x2862 +0x2863 0x2864 0x2865 0x2866 0x2867 0x2868 0x2869 0x286A 0x286B 0x286C 0x286D 0x286E 0x286F 0x2870 0x2871 0x2872 +0x2873 0x2874 0x2875 0x2876 0x2877 0x2878 0x2879 0x287A 0x287B 0x287C 0x287D 0x287E 0x287F 0x2880 0x2881 0x2882 +0x2883 0x2884 0x2885 0x2886 0x2887 0x2888 0x2889 0x288A 0x288B 0x288C 0x288D 0x288E 0x288F 0x2890 0x2891 0x2892 +0x2893 0x2894 0x2895 0x2896 0x2897 0x2898 0x2899 0x289A 0x289B 0x289C 0x289D 0x289E 0x289F 0x28A0 0x28A1 0x28A2 +0x28A3 0x28A4 0x28A5 0x28A6 0x28A7 0x28A8 0x28A9 0x28AA 0x28AB 0x28AC 0x28AD 0x28AE 0x28AF 0x28B0 0x28B1 0x28B2 +0x28B3 0x28B4 0x28B5 0x28B6 0x28B7 0x28B8 0x28B9 0x28BA 0x28BB 0x28BC 0x28BD 0x28BE 0x28BF 0x28C0 0x28C1 0x28C2 +0x28C3 0x28C4 0x28C5 0x28C6 0x28C7 0x28C8 0x28C9 0x28CA 0x28CB 0x28CC 0x28CD 0x28CE 0x28CF 0x28D0 0x28D1 0x28D2 +0x28D3 0x28D4 0x28D5 0x28D6 0x28D7 0x28D8 0x28D9 0x28DA 0x28DB 0x28DC 0x28DD 0x28DE 0x28DF 0x28E0 0x28E1 0x28E2 +0x28E3 0x28E4 0x28E5 0x28E6 0x28E7 0x28E8 0x28E9 0x28EA 0x28EB 0x28EC 0x28ED 0x28EE 0x28EF 0x28F0 0x28F1 0x28F2 +0x28F3 0x28F4 0x28F5 0x28F6 0x28F7 0x28F8 0x28F9 0x28FA 0x28FB 0x28FC 0x28FD 0x28FE 0x28FF 0x3000 0x3001 0x3002 +0x3003 0x3004 0x3005 0x3006 0x3007 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0x3012 +0x3013 0x3014 0x3015 0x3016 0x3017 0x3018 0x3019 0x301A 0x301B 0x301C 0x301D 0x301E 0x301F 0x3020 0x3021 0x3022 +0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 0x3029 0x3036 0x3037 0x3038 0x3039 0x303A 0x303C 0x303E 0x303F 0x3041 +0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 +0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 +0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 +0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 +0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 +0x3092 0x3093 0x309B 0x309C 0x309D 0x309E 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA +0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA +0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA +0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA +0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA +0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x30FB 0x30FC 0x30FD 0x30FE +0x3105 0x3106 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 +0x3115 0x3116 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 +0x3125 0x3126 0x3127 0x3128 0x3129 0x312A 0x312B 0x312C 0x312D 0x312E 0x312F 0x3131 0x3132 0x3133 0x3134 0x3135 +0x3136 0x3137 0x3138 0x3139 0x313A 0x313B 0x313C 0x313D 0x313E 0x313F 0x3140 0x3141 0x3142 0x3143 0x3144 0x3145 +0x3146 0x3147 0x3148 0x3149 0x314A 0x314B 0x314C 0x314D 0x314E 0x314F 0x3150 0x3151 0x3152 0x3153 0x3154 0x3155 +0x3156 0x3157 0x3158 0x3159 0x315A 0x315B 0x315C 0x315D 0x315E 0x315F 0x3160 0x3161 0x3162 0x3163 0x3164 0x3220 +0x3221 0x3222 0x3223 0x3224 0x3225 0x3226 0x3227 0x3228 0x3229 0x3231 0x3232 0x3239 0x3268 0x3280 0x3281 0x3282 +0x3283 0x3284 0x3285 0x3286 0x3287 0x3288 0x3289 0x32A3 0x32A4 0x32A5 0x32A6 0x32A7 0x32A8 0x32FF 0x4E00 0x4E01 +0x4E02 0x4E03 0x4E04 0x4E05 0x4E06 0x4E07 0x4E08 0x4E09 0x4E0A 0x4E0B 0x4E0C 0x4E0D 0x4E0E 0x4E0F 0x4E10 0x4E11 +0x4E12 0x4E13 0x4E14 0x4E15 0x4E16 0x4E17 0x4E18 0x4E19 0x4E1A 0x4E1B 0x4E1C 0x4E1D 0x4E1E 0x4E1F 0x4E20 0x4E21 +0x4E22 0x4E23 0x4E24 0x4E25 0x4E26 0x4E27 0x4E28 0x4E29 0x4E2A 0x4E2B 0x4E2C 0x4E2D 0x4E2E 0x4E2F 0x4E30 0x4E31 +0x4E32 0x4E33 0x4E34 0x4E35 0x4E36 0x4E37 0x4E38 0x4E39 0x4E3A 0x4E3B 0x4E3C 0x4E3D 0x4E3E 0x4E3F 0x4E40 0x4E41 +0x4E42 0x4E43 0x4E44 0x4E45 0x4E46 0x4E47 0x4E48 0x4E49 0x4E4A 0x4E4B 0x4E4C 0x4E4D 0x4E4E 0x4E4F 0x4E50 0x4E51 +0x4E52 0x4E53 0x4E54 0x4E55 0x4E56 0x4E57 0x4E58 0x4E59 0x4E5A 0x4E5B 0x4E5C 0x4E5D 0x4E5E 0x4E5F 0x4E60 0x4E61 +0x4E62 0x4E63 0x4E64 0x4E65 0x4E66 0x4E67 0x4E68 0x4E69 0x4E6A 0x4E6B 0x4E6C 0x4E6D 0x4E6E 0x4E6F 0x4E70 0x4E71 +0x4E72 0x4E73 0x4E74 0x4E75 0x4E76 0x4E77 0x4E78 0x4E79 0x4E7A 0x4E7B 0x4E7C 0x4E7D 0x4E7E 0x4E7F 0x4E80 0x4E81 +0x4E82 0x4E83 0x4E84 0x4E85 0x4E86 0x4E87 0x4E88 0x4E89 0x4E8A 0x4E8B 0x4E8C 0x4E8D 0x4E8E 0x4E8F 0x4E90 0x4E91 +0x4E92 0x4E93 0x4E94 0x4E95 0x4E96 0x4E97 0x4E98 0x4E99 0x4E9A 0x4E9B 0x4E9C 0x4E9D 0x4E9E 0x4E9F 0x4EA0 0x4EA1 +0x4EA2 0x4EA3 0x4EA4 0x4EA5 0x4EA6 0x4EA7 0x4EA8 0x4EA9 0x4EAA 0x4EAB 0x4EAC 0x4EAD 0x4EAE 0x4EAF 0x4EB0 0x4EB1 +0x4EB2 0x4EB3 0x4EB4 0x4EB5 0x4EB6 0x4EB7 0x4EB8 0x4EB9 0x4EBA 0x4EBB 0x4EBC 0x4EBD 0x4EBE 0x4EBF 0x4EC0 0x4EC1 +0x4EC2 0x4EC3 0x4EC4 0x4EC5 0x4EC6 0x4EC7 0x4EC8 0x4EC9 0x4ECA 0x4ECB 0x4ECC 0x4ECD 0x4ECE 0x4ECF 0x4ED0 0x4ED1 +0x4ED2 0x4ED3 0x4ED4 0x4ED5 0x4ED6 0x4ED7 0x4ED8 0x4ED9 0x4EDA 0x4EDB 0x4EDC 0x4EDD 0x4EDE 0x4EDF 0x4EE0 0x4EE1 +0x4EE2 0x4EE3 0x4EE4 0x4EE5 0x4EE6 0x4EE7 0x4EE8 0x4EE9 0x4EEA 0x4EEB 0x4EEC 0x4EED 0x4EEE 0x4EEF 0x4EF0 0x4EF1 +0x4EF2 0x4EF3 0x4EF4 0x4EF5 0x4EF6 0x4EF7 0x4EF8 0x4EF9 0x4EFA 0x4EFB 0x4EFC 0x4EFD 0x4EFE 0x4EFF 0x4F00 0x4F01 +0x4F02 0x4F03 0x4F04 0x4F05 0x4F06 0x4F07 0x4F08 0x4F09 0x4F0A 0x4F0B 0x4F0C 0x4F0D 0x4F0E 0x4F0F 0x4F10 0x4F11 +0x4F12 0x4F13 0x4F14 0x4F15 0x4F16 0x4F17 0x4F18 0x4F19 0x4F1A 0x4F1B 0x4F1C 0x4F1D 0x4F1E 0x4F1F 0x4F20 0x4F21 +0x4F22 0x4F23 0x4F24 0x4F25 0x4F26 0x4F27 0x4F28 0x4F29 0x4F2A 0x4F2B 0x4F2C 0x4F2D 0x4F2E 0x4F2F 0x4F30 0x4F31 +0x4F32 0x4F33 0x4F34 0x4F35 0x4F36 0x4F37 0x4F38 0x4F39 0x4F3A 0x4F3B 0x4F3C 0x4F3D 0x4F3E 0x4F3F 0x4F40 0x4F41 +0x4F42 0x4F43 0x4F44 0x4F45 0x4F46 0x4F47 0x4F48 0x4F49 0x4F4A 0x4F4B 0x4F4C 0x4F4D 0x4F4E 0x4F4F 0x4F50 0x4F51 +0x4F52 0x4F53 0x4F54 0x4F55 0x4F56 0x4F57 0x4F58 0x4F59 0x4F5A 0x4F5B 0x4F5C 0x4F5D 0x4F5E 0x4F5F 0x4F60 0x4F61 +0x4F62 0x4F63 0x4F64 0x4F65 0x4F66 0x4F67 0x4F68 0x4F69 0x4F6A 0x4F6B 0x4F6C 0x4F6D 0x4F6E 0x4F6F 0x4F70 0x4F71 +0x4F72 0x4F73 0x4F74 0x4F75 0x4F76 0x4F77 0x4F78 0x4F79 0x4F7A 0x4F7B 0x4F7C 0x4F7D 0x4F7E 0x4F7F 0x4F80 0x4F81 +0x4F82 0x4F83 0x4F84 0x4F85 0x4F86 0x4F87 0x4F88 0x4F89 0x4F8A 0x4F8B 0x4F8C 0x4F8D 0x4F8E 0x4F8F 0x4F90 0x4F91 +0x4F92 0x4F93 0x4F94 0x4F95 0x4F96 0x4F97 0x4F98 0x4F99 0x4F9A 0x4F9B 0x4F9C 0x4F9D 0x4F9E 0x4F9F 0x4FA0 0x4FA1 +0x4FA2 0x4FA3 0x4FA4 0x4FA5 0x4FA6 0x4FA7 0x4FA8 0x4FA9 0x4FAA 0x4FAB 0x4FAC 0x4FAD 0x4FAE 0x4FAF 0x4FB0 0x4FB1 +0x4FB2 0x4FB3 0x4FB4 0x4FB5 0x4FB6 0x4FB7 0x4FB8 0x4FB9 0x4FBA 0x4FBB 0x4FBC 0x4FBD 0x4FBE 0x4FBF 0x4FC0 0x4FC1 +0x4FC2 0x4FC3 0x4FC4 0x4FC5 0x4FC6 0x4FC7 0x4FC8 0x4FC9 0x4FCA 0x4FCB 0x4FCC 0x4FCD 0x4FCE 0x4FCF 0x4FD0 0x4FD1 +0x4FD2 0x4FD3 0x4FD4 0x4FD5 0x4FD6 0x4FD7 0x4FD8 0x4FD9 0x4FDA 0x4FDB 0x4FDC 0x4FDD 0x4FDE 0x4FDF 0x4FE0 0x4FE1 +0x4FE2 0x4FE3 0x4FE4 0x4FE5 0x4FE6 0x4FE7 0x4FE8 0x4FE9 0x4FEA 0x4FEB 0x4FEC 0x4FED 0x4FEE 0x4FEF 0x4FF0 0x4FF1 +0x4FF2 0x4FF3 0x4FF4 0x4FF5 0x4FF6 0x4FF7 0x4FF8 0x4FF9 0x4FFA 0x4FFB 0x4FFC 0x4FFD 0x4FFE 0x4FFF 0x5000 0x5001 +0x5002 0x5003 0x5004 0x5005 0x5006 0x5007 0x5008 0x5009 0x500A 0x500B 0x500C 0x500D 0x500E 0x500F 0x5010 0x5011 +0x5012 0x5013 0x5014 0x5015 0x5016 0x5017 0x5018 0x5019 0x501A 0x501B 0x501C 0x501D 0x501E 0x501F 0x5020 0x5021 +0x5022 0x5023 0x5024 0x5025 0x5026 0x5027 0x5028 0x5029 0x502A 0x502B 0x502C 0x502D 0x502E 0x502F 0x5030 0x5031 +0x5033 0x5034 0x5035 0x5036 0x5037 0x5039 0x503A 0x503B 0x503C 0x503E 0x5040 0x5041 0x5043 0x5045 0x5046 0x5047 +0x5048 0x5049 0x504A 0x504B 0x504C 0x504D 0x504E 0x504F 0x5050 0x5051 0x5053 0x5055 0x5056 0x5057 0x505A 0x505B +0x505C 0x505D 0x505E 0x505F 0x5060 0x5061 0x5062 0x5063 0x5064 0x5065 0x5068 0x5069 0x506A 0x506B 0x506C 0x506D +0x506E 0x506F 0x5070 0x5072 0x5073 0x5074 0x5075 0x5076 0x5077 0x5078 0x507A 0x507B 0x507D 0x507E 0x507F 0x5080 +0x5082 0x5083 0x5085 0x5087 0x5088 0x5089 0x508B 0x508C 0x508D 0x508E 0x5091 0x5092 0x5094 0x5095 0x5096 0x5098 +0x5099 0x509A 0x509B 0x509C 0x509D 0x509E 0x50A2 0x50A3 0x50A4 0x50A5 0x50A7 0x50A8 0x50A9 0x50AC 0x50AD 0x50AE +0x50AF 0x50B0 0x50B1 0x50B2 0x50B3 0x50B4 0x50B5 0x50B6 0x50B7 0x50B8 0x50BA 0x50BB 0x50BD 0x50BE 0x50BF 0x50C1 +0x50C2 0x50C4 0x50C5 0x50C6 0x50C7 0x50C8 0x50C9 0x50CA 0x50CB 0x50CD 0x50CE 0x50CF 0x50D1 0x50D3 0x50D4 0x50D5 +0x50D6 0x50D7 0x50D9 0x50DA 0x50DB 0x50DC 0x50DD 0x50DE 0x50E0 0x50E3 0x50E4 0x50E5 0x50E6 0x50E7 0x50E8 0x50E9 +0x50EA 0x50EB 0x50EC 0x50ED 0x50EE 0x50EF 0x50F0 0x50F1 0x50F3 0x50F5 0x50F6 0x50F8 0x50F9 0x50FB 0x50FD 0x50FE +0x50FF 0x5100 0x5101 0x5102 0x5103 0x5104 0x5105 0x5106 0x5107 0x5108 0x5109 0x510A 0x510B 0x510C 0x510D 0x510E +0x5110 0x5111 0x5112 0x5113 0x5114 0x5115 0x5116 0x5117 0x5118 0x511A 0x511C 0x511F 0x5120 0x5121 0x5122 0x5124 +0x5125 0x5126 0x5129 0x512A 0x512D 0x512E 0x5130 0x5131 0x5132 0x5133 0x5134 0x5135 0x5137 0x5138 0x5139 0x513A +0x513B 0x513C 0x513D 0x513F 0x5140 0x5141 0x5142 0x5143 0x5144 0x5145 0x5146 0x5147 0x5148 0x5149 0x514A 0x514B +0x514C 0x514D 0x514E 0x514F 0x5150 0x5151 0x5152 0x5153 0x5154 0x5155 0x5156 0x5157 0x5159 0x515A 0x515B 0x515C +0x515D 0x515E 0x515F 0x5161 0x5162 0x5163 0x5165 0x5166 0x5167 0x5168 0x5169 0x516A 0x516B 0x516C 0x516D 0x516E +0x516F 0x5170 0x5171 0x5172 0x5173 0x5174 0x5175 0x5176 0x5177 0x5178 0x5179 0x517B 0x517C 0x517D 0x5180 0x5181 +0x5182 0x5183 0x5184 0x5185 0x5186 0x5187 0x5188 0x5189 0x518A 0x518B 0x518C 0x518D 0x518E 0x518F 0x5190 0x5191 +0x5192 0x5193 0x5194 0x5195 0x5196 0x5197 0x5198 0x5199 0x519A 0x519B 0x519C 0x519D 0x519E 0x51A0 0x51A2 0x51A4 +0x51A5 0x51A6 0x51A7 0x51A8 0x51A9 0x51AA 0x51AB 0x51AC 0x51AD 0x51AE 0x51AF 0x51B0 0x51B1 0x51B2 0x51B3 0x51B4 +0x51B5 0x51B6 0x51B7 0x51B9 0x51BB 0x51BC 0x51BD 0x51BE 0x51C0 0x51C3 0x51C4 0x51C5 0x51C6 0x51C7 0x51C8 0x51C9 +0x51CA 0x51CB 0x51CC 0x51CD 0x51CE 0x51CF 0x51D0 0x51D1 0x51D3 0x51D4 0x51D6 0x51D7 0x51D8 0x51D9 0x51DB 0x51DC +0x51DD 0x51DE 0x51E0 0x51E1 0x51E2 0x51E4 0x51E5 0x51E6 0x51E7 0x51E9 0x51EA 0x51EB 0x51ED 0x51EE 0x51EF 0x51F0 +0x51F1 0x51F3 0x51F4 0x51F5 0x51F6 0x51F7 0x51F8 0x51F9 0x51FA 0x51FB 0x51FC 0x51FD 0x51FE 0x51FF 0x5200 0x5201 +0x5202 0x5203 0x5204 0x5205 0x5206 0x5207 0x5208 0x5209 0x520A 0x520B 0x520C 0x520D 0x520E 0x5210 0x5211 0x5212 +0x5213 0x5214 0x5215 0x5216 0x5217 0x5218 0x5219 0x521A 0x521B 0x521C 0x521D 0x521E 0x5220 0x5221 0x5223 0x5224 +0x5225 0x5227 0x5228 0x5229 0x522A 0x522B 0x522C 0x522D 0x522E 0x5230 0x5231 0x5232 0x5233 0x5235 0x5236 0x5237 +0x5238 0x5239 0x523A 0x523B 0x523D 0x523F 0x5240 0x5241 0x5242 0x5243 0x5244 0x5245 0x5246 0x5247 0x5249 0x524A +0x524B 0x524C 0x524D 0x524E 0x524F 0x5250 0x5251 0x5252 0x5254 0x5255 0x5256 0x5257 0x525A 0x525B 0x525C 0x525D +0x525E 0x525F 0x5261 0x5262 0x5263 0x5264 0x5265 0x5267 0x5269 0x526A 0x526B 0x526C 0x526D 0x526E 0x526F 0x5270 +0x5271 0x5272 0x5273 0x5274 0x5275 0x5277 0x5278 0x527A 0x527B 0x527C 0x527D 0x527E 0x527F 0x5280 0x5281 0x5282 +0x5283 0x5284 0x5287 0x5288 0x5289 0x528A 0x528B 0x528C 0x528D 0x528F 0x5290 0x5291 0x5292 0x5293 0x5294 0x5296 +0x5297 0x5298 0x5299 0x529B 0x529C 0x529D 0x529E 0x529F 0x52A0 0x52A1 0x52A2 0x52A3 0x52A4 0x52A6 0x52A8 0x52A9 +0x52AA 0x52AB 0x52AC 0x52AD 0x52AE 0x52B1 0x52B2 0x52B3 0x52B4 0x52B5 0x52B9 0x52BB 0x52BC 0x52BE 0x52BF 0x52C0 +0x52C1 0x52C2 0x52C3 0x52C5 0x52C7 0x52C9 0x52CB 0x52CD 0x52D0 0x52D2 0x52D3 0x52D4 0x52D5 0x52D6 0x52D7 0x52D8 +0x52D9 0x52DA 0x52DB 0x52DD 0x52DE 0x52DF 0x52E0 0x52E2 0x52E3 0x52E4 0x52E5 0x52E6 0x52E7 0x52E9 0x52EB 0x52EF +0x52F0 0x52F1 0x52F2 0x52F3 0x52F4 0x52F5 0x52F7 0x52F8 0x52F9 0x52FA 0x52FB 0x52FC 0x52FD 0x52FE 0x52FF 0x5300 +0x5301 0x5302 0x5303 0x5304 0x5305 0x5306 0x5308 0x5309 0x530A 0x530B 0x530D 0x530E 0x530F 0x5310 0x5311 0x5312 +0x5315 0x5316 0x5317 0x5318 0x5319 0x531A 0x531B 0x531C 0x531D 0x531E 0x531F 0x5320 0x5321 0x5322 0x5323 0x5326 +0x5327 0x532A 0x532D 0x532E 0x532F 0x5330 0x5331 0x5333 0x5334 0x5337 0x5338 0x5339 0x533A 0x533B 0x533C 0x533D +0x533E 0x533F 0x5340 0x5341 0x5342 0x5343 0x5344 0x5345 0x5346 0x5347 0x5348 0x5349 0x534A 0x534B 0x534C 0x534D +0x534E 0x534F 0x5350 0x5351 0x5352 0x5353 0x5354 0x5355 0x5356 0x5357 0x5358 0x535A 0x535C 0x535D 0x535E 0x535F +0x5360 0x5361 0x5362 0x5363 0x5364 0x5365 0x5366 0x5367 0x5368 0x5369 0x536A 0x536B 0x536C 0x536D 0x536E 0x536F +0x5370 0x5371 0x5372 0x5373 0x5374 0x5375 0x5377 0x5378 0x5379 0x537A 0x537B 0x537C 0x537D 0x537F 0x5382 0x5383 +0x5384 0x5385 0x5386 0x5389 0x538A 0x538B 0x538C 0x538D 0x538E 0x538F 0x5390 0x5392 0x5393 0x5394 0x5395 0x5396 +0x5397 0x5398 0x5399 0x539A 0x539C 0x539D 0x539E 0x539F 0x53A0 0x53A2 0x53A3 0x53A4 0x53A5 0x53A6 0x53A7 0x53A8 +0x53A9 0x53AC 0x53AD 0x53AE 0x53B0 0x53B2 0x53B3 0x53B4 0x53B6 0x53B7 0x53B9 0x53BB 0x53BE 0x53BF 0x53C1 0x53C2 +0x53C3 0x53C4 0x53C6 0x53C7 0x53C8 0x53C9 0x53CA 0x53CB 0x53CC 0x53CD 0x53CE 0x53D1 0x53D2 0x53D4 0x53D5 0x53D6 +0x53D7 0x53D8 0x53D9 0x53DA 0x53DB 0x53DF 0x53E0 0x53E1 0x53E2 0x53E3 0x53E4 0x53E5 0x53E6 0x53E8 0x53E9 0x53EA +0x53EB 0x53EC 0x53ED 0x53EE 0x53EF 0x53F0 0x53F1 0x53F2 0x53F3 0x53F5 0x53F6 0x53F7 0x53F8 0x53F9 0x53FA 0x53FB +0x53FC 0x53FD 0x53FE 0x5401 0x5403 0x5404 0x5406 0x5407 0x5408 0x5409 0x540A 0x540B 0x540C 0x540D 0x540E 0x540F +0x5410 0x5411 0x5412 0x5413 0x5414 0x5415 0x5416 0x5417 0x5418 0x5419 0x541B 0x541C 0x541D 0x541E 0x541F 0x5420 +0x5421 0x5423 0x5424 0x5425 0x5426 0x5427 0x5428 0x5429 0x542A 0x542B 0x542C 0x542D 0x542E 0x542F 0x5430 0x5431 +0x5432 0x5433 0x5434 0x5435 0x5436 0x5437 0x5438 0x5439 0x543B 0x543C 0x543D 0x543E 0x543F 0x5440 0x5441 0x5442 +0x5443 0x5445 0x5446 0x5447 0x5448 0x5449 0x544A 0x544B 0x544E 0x544F 0x5450 0x5451 0x5452 0x5453 0x5454 0x5455 +0x5456 0x5457 0x5458 0x5459 0x545B 0x545C 0x545D 0x545F 0x5460 0x5461 0x5462 0x5463 0x5464 0x5465 0x5466 0x5467 +0x5468 0x546A 0x546B 0x546C 0x546F 0x5470 0x5471 0x5472 0x5473 0x5474 0x5475 0x5476 0x5477 0x5478 0x547A 0x547B +0x547C 0x547D 0x547E 0x547F 0x5480 0x5481 0x5482 0x5484 0x5486 0x5487 0x5488 0x5489 0x548B 0x548C 0x548D 0x548E +0x548F 0x5490 0x5491 0x5492 0x5493 0x5494 0x5495 0x5496 0x5497 0x5498 0x5499 0x549A 0x549B 0x549D 0x54A0 0x54A1 +0x54A2 0x54A3 0x54A4 0x54A5 0x54A6 0x54A7 0x54A8 0x54A9 0x54AA 0x54AB 0x54AC 0x54AD 0x54AE 0x54AF 0x54B0 0x54B1 +0x54B2 0x54B3 0x54B4 0x54B5 0x54B6 0x54B7 0x54B8 0x54B9 0x54BA 0x54BB 0x54BC 0x54BD 0x54BE 0x54BF 0x54C0 0x54C1 +0x54C2 0x54C3 0x54C4 0x54C5 0x54C6 0x54C7 0x54C8 0x54C9 0x54CA 0x54CB 0x54CC 0x54CD 0x54CE 0x54CF 0x54D0 0x54D1 +0x54D2 0x54D3 0x54D4 0x54D5 0x54D6 0x54D7 0x54D8 0x54D9 0x54DA 0x54DC 0x54DD 0x54DE 0x54DF 0x54E0 0x54E1 0x54E2 +0x54E4 0x54E5 0x54E6 0x54E7 0x54E8 0x54E9 0x54EA 0x54EB 0x54ED 0x54EE 0x54F1 0x54F2 0x54F3 0x54F7 0x54F8 0x54FA +0x54FB 0x54FC 0x54FD 0x54FF 0x5501 0x5503 0x5504 0x5505 0x5506 0x5507 0x5508 0x5509 0x550A 0x550B 0x550C 0x550E +0x550F 0x5510 0x5511 0x5512 0x5513 0x5514 0x5516 0x5517 0x551A 0x551B 0x551C 0x551D 0x551E 0x5520 0x5521 0x5522 +0x5523 0x5524 0x5525 0x5526 0x5527 0x552A 0x552C 0x552D 0x552E 0x552F 0x5530 0x5531 0x5532 0x5533 0x5534 0x5535 +0x5536 0x5537 0x5538 0x5539 0x553B 0x553C 0x553E 0x553F 0x5540 0x5541 0x5543 0x5544 0x5545 0x5546 0x5548 0x5549 +0x554A 0x554B 0x554C 0x554D 0x554E 0x554F 0x5550 0x5551 0x5552 0x5553 0x5555 0x5556 0x5557 0x5559 0x555B 0x555C +0x555D 0x555E 0x555F 0x5561 0x5562 0x5563 0x5564 0x5565 0x5566 0x5567 0x5569 0x556A 0x556B 0x556C 0x556D 0x556E +0x556F 0x5570 0x5571 0x5572 0x5574 0x5575 0x5576 0x5577 0x5578 0x5579 0x557B 0x557C 0x557D 0x557E 0x557F 0x5580 +0x5581 0x5582 0x5583 0x5584 0x5586 0x5587 0x5588 0x5589 0x558A 0x558B 0x558C 0x558D 0x558E 0x558F 0x5591 0x5592 +0x5593 0x5594 0x5595 0x5598 0x5599 0x559A 0x559C 0x559D 0x559E 0x559F 0x55A1 0x55A2 0x55A3 0x55A4 0x55A5 0x55A6 +0x55A7 0x55A8 0x55A9 0x55AA 0x55AB 0x55AC 0x55AD 0x55AE 0x55B0 0x55B1 0x55B2 0x55B3 0x55B5 0x55B6 0x55B7 0x55B9 +0x55BA 0x55BB 0x55BC 0x55BD 0x55BE 0x55BF 0x55C0 0x55C2 0x55C3 0x55C4 0x55C5 0x55C6 0x55C7 0x55C8 0x55C9 0x55CA +0x55CB 0x55CC 0x55CD 0x55CE 0x55CF 0x55D0 0x55D1 0x55D2 0x55D3 0x55D4 0x55D5 0x55D6 0x55D7 0x55D9 0x55DA 0x55DB +0x55DC 0x55DD 0x55DE 0x55DF 0x55E1 0x55E2 0x55E3 0x55E4 0x55E5 0x55E6 0x55E7 0x55E8 0x55E9 0x55EA 0x55EB 0x55EC +0x55EE 0x55EF 0x55F0 0x55F1 0x55F2 0x55F3 0x55F5 0x55F6 0x55F7 0x55F9 0x55FA 0x55FB 0x55FC 0x55FD 0x55FE 0x55FF +0x5600 0x5601 0x5602 0x5604 0x5605 0x5606 0x5608 0x5609 0x560C 0x560D 0x560E 0x560F 0x5610 0x5611 0x5612 0x5613 +0x5614 0x5615 0x5616 0x5617 0x5618 0x561A 0x561B 0x561C 0x561D 0x561E 0x561F 0x5621 0x5622 0x5623 0x5624 0x5625 +0x5627 0x5629 0x562A 0x562B 0x562C 0x562D 0x562E 0x562F 0x5630 0x5631 0x5632 0x5633 0x5634 0x5635 0x5636 0x5638 +0x5639 0x563A 0x563B 0x563D 0x563E 0x563F 0x5640 0x5641 0x5642 0x5643 0x5645 0x5646 0x5647 0x5648 0x5649 0x564A +0x564C 0x564D 0x564E 0x564F 0x5650 0x5652 0x5653 0x5654 0x5657 0x5658 0x5659 0x565A 0x565B 0x565C 0x565D 0x565E +0x5660 0x5662 0x5663 0x5664 0x5665 0x5666 0x5668 0x5669 0x566A 0x566B 0x566C 0x566D 0x566E 0x566F 0x5670 0x5671 +0x5672 0x5673 0x5674 0x5676 0x5677 0x5678 0x5679 0x567A 0x567B 0x567C 0x567E 0x567F 0x5680 0x5681 0x5682 0x5683 +0x5684 0x5685 0x5686 0x5687 0x5689 0x568A 0x568C 0x568D 0x568E 0x568F 0x5690 0x5692 0x5693 0x5694 0x5695 0x5697 +0x5698 0x5699 0x569A 0x569B 0x569C 0x569D 0x569F 0x56A0 0x56A1 0x56A2 0x56A3 0x56A4 0x56A5 0x56A6 0x56A7 0x56A8 +0x56AA 0x56AB 0x56AC 0x56AD 0x56AE 0x56AF 0x56B1 0x56B2 0x56B3 0x56B4 0x56B5 0x56B6 0x56B7 0x56B9 0x56BC 0x56BD +0x56BE 0x56BF 0x56C0 0x56C1 0x56C2 0x56C3 0x56C5 0x56C6 0x56C8 0x56C9 0x56CA 0x56CB 0x56CC 0x56CD 0x56CE 0x56D1 +0x56D2 0x56D3 0x56D4 0x56D6 0x56D7 0x56D8 0x56D9 0x56DA 0x56DB 0x56DC 0x56DD 0x56DE 0x56DF 0x56E0 0x56E1 0x56E2 +0x56E3 0x56E4 0x56E5 0x56E6 0x56E7 0x56E8 0x56E9 0x56EA 0x56EB 0x56EC 0x56ED 0x56EE 0x56EF 0x56F0 0x56F1 0x56F2 +0x56F3 0x56F4 0x56F5 0x56F6 0x56F7 0x56F8 0x56F9 0x56FA 0x56FB 0x56FC 0x56FD 0x56FE 0x56FF 0x5700 0x5701 0x5702 +0x5703 0x5704 0x5705 0x5706 0x5707 0x5708 0x5709 0x570A 0x570B 0x570C 0x570D 0x570E 0x570F 0x5710 0x5711 0x5712 +0x5713 0x5714 0x5715 0x5716 0x5717 0x5718 0x5719 0x571A 0x571B 0x571C 0x571D 0x571E 0x571F 0x5720 0x5721 0x5722 +0x5723 0x5724 0x5726 0x5727 0x5728 0x5729 0x572A 0x572B 0x572C 0x572D 0x572E 0x572F 0x5730 0x5732 0x5733 0x5734 +0x5737 0x5738 0x5739 0x573A 0x573B 0x573E 0x5740 0x5741 0x5742 0x5745 0x5747 0x5749 0x574A 0x574B 0x574C 0x574D +0x574E 0x574F 0x5750 0x5751 0x5752 0x5754 0x5757 0x575A 0x575B 0x575C 0x575D 0x575E 0x575F 0x5760 0x5761 0x5762 +0x5764 0x5765 0x5766 0x5768 0x5769 0x576A 0x576B 0x576C 0x576D 0x576E 0x576F 0x5770 0x5771 0x5772 0x5773 0x5774 +0x5775 0x5776 0x5777 0x577B 0x577C 0x577D 0x577F 0x5780 0x5782 0x5783 0x5784 0x5785 0x5786 0x5787 0x5788 0x5789 +0x578B 0x578C 0x578D 0x578E 0x578F 0x5792 0x5793 0x5794 0x5795 0x5797 0x5798 0x5799 0x579A 0x579B 0x579D 0x579E +0x579F 0x57A0 0x57A1 0x57A2 0x57A3 0x57A4 0x57A5 0x57A6 0x57A7 0x57A8 0x57A9 0x57AA 0x57AB 0x57AD 0x57AE 0x57AF +0x57B0 0x57B1 0x57B2 0x57B3 0x57B4 0x57B5 0x57B6 0x57B8 0x57B9 0x57BA 0x57BB 0x57BC 0x57BD 0x57BE 0x57BF 0x57C0 +0x57C1 0x57C2 0x57C3 0x57C6 0x57C7 0x57C8 0x57CB 0x57CC 0x57CE 0x57CF 0x57D0 0x57D2 0x57D3 0x57D4 0x57D5 0x57D6 +0x57D7 0x57D8 0x57D9 0x57DA 0x57DC 0x57DD 0x57DE 0x57DF 0x57E0 0x57E1 0x57E2 0x57E3 0x57E4 0x57E5 0x57E7 0x57E8 +0x57E9 0x57EA 0x57EB 0x57EC 0x57ED 0x57EE 0x57EF 0x57F0 0x57F1 0x57F2 0x57F3 0x57F4 0x57F5 0x57F6 0x57F7 0x57F8 +0x57F9 0x57FA 0x57FB 0x57FC 0x57FD 0x5800 0x5801 0x5802 0x5803 0x5804 0x5805 0x5806 0x5807 0x5808 0x5809 0x580A +0x580B 0x580C 0x580D 0x580E 0x5810 0x5811 0x5814 0x5815 0x5816 0x5817 0x5819 0x581B 0x581C 0x581D 0x581E 0x5820 +0x5821 0x5823 0x5824 0x5825 0x5827 0x5828 0x5829 0x582A 0x582C 0x582D 0x582E 0x582F 0x5830 0x5831 0x5832 0x5833 +0x5834 0x5835 0x5836 0x5837 0x5838 0x5839 0x583A 0x583B 0x583C 0x583D 0x583E 0x583F 0x5840 0x5841 0x5842 0x5843 +0x5844 0x5845 0x5846 0x5848 0x5849 0x584A 0x584B 0x584C 0x584D 0x584E 0x584F 0x5851 0x5852 0x5853 0x5854 0x5855 +0x5857 0x5858 0x5859 0x585A 0x585B 0x585D 0x585E 0x5861 0x5862 0x5863 0x5864 0x5865 0x5868 0x5869 0x586B 0x586C +0x586D 0x586E 0x586F 0x5870 0x5871 0x5872 0x5873 0x5874 0x5875 0x5876 0x5878 0x5879 0x587A 0x587B 0x587C 0x587D +0x587E 0x587F 0x5880 0x5881 0x5882 0x5883 0x5884 0x5885 0x5886 0x5887 0x5888 0x5889 0x588A 0x588B 0x588E 0x588F +0x5890 0x5891 0x5892 0x5893 0x5894 0x5895 0x5897 0x5898 0x5899 0x589A 0x589C 0x589D 0x589E 0x589F 0x58A0 0x58A1 +0x58A3 0x58A5 0x58A6 0x58A8 0x58A9 0x58AB 0x58AC 0x58AE 0x58AF 0x58B1 0x58B3 0x58B6 0x58B8 0x58B9 0x58BA 0x58BB +0x58BC 0x58BD 0x58BE 0x58BF 0x58C1 0x58C2 0x58C5 0x58C6 0x58C7 0x58C8 0x58C9 0x58CA 0x58CB 0x58CC 0x58CE 0x58CF +0x58D1 0x58D2 0x58D3 0x58D4 0x58D5 0x58D6 0x58D7 0x58D8 0x58D9 0x58DA 0x58DB 0x58DC 0x58DD 0x58DE 0x58DF 0x58E0 +0x58E2 0x58E3 0x58E4 0x58E5 0x58E7 0x58E8 0x58E9 0x58EA 0x58EB 0x58EC 0x58EE 0x58EF 0x58F0 0x58F1 0x58F2 0x58F3 +0x58F4 0x58F6 0x58F7 0x58F8 0x58F9 0x58FA 0x58FB 0x58FC 0x58FD 0x58FE 0x58FF 0x5902 0x5903 0x5904 0x5906 0x5907 +0x5909 0x590A 0x590B 0x590C 0x590D 0x590E 0x590F 0x5910 0x5912 0x5913 0x5914 0x5915 0x5916 0x5917 0x5918 0x5919 +0x591A 0x591B 0x591C 0x591F 0x5920 0x5922 0x5924 0x5925 0x5927 0x5928 0x5929 0x592A 0x592B 0x592C 0x592D 0x592E +0x592F 0x5930 0x5931 0x5932 0x5933 0x5934 0x5937 0x5938 0x5939 0x593A 0x593C 0x593D 0x593E 0x593F 0x5940 0x5941 +0x5942 0x5944 0x5945 0x5947 0x5948 0x5949 0x594A 0x594B 0x594C 0x594E 0x594F 0x5950 0x5951 0x5953 0x5954 0x5955 +0x5956 0x5957 0x5958 0x595A 0x595C 0x5960 0x5961 0x5962 0x5964 0x5965 0x5967 0x5968 0x5969 0x596A 0x596B 0x596C +0x596D 0x596E 0x5970 0x5971 0x5972 0x5973 0x5974 0x5976 0x5977 0x5978 0x5979 0x597B 0x597C 0x597D 0x597E 0x597F +0x5980 0x5981 0x5982 0x5983 0x5984 0x5985 0x5986 0x5987 0x5988 0x5989 0x598A 0x598D 0x598E 0x598F 0x5990 0x5992 +0x5993 0x5996 0x5997 0x5998 0x5999 0x599B 0x599D 0x599E 0x59A0 0x59A1 0x59A2 0x59A3 0x59A4 0x59A5 0x59A6 0x59A7 +0x59A8 0x59A9 0x59AA 0x59AB 0x59AC 0x59AD 0x59AE 0x59AF 0x59B1 0x59B2 0x59B3 0x59B4 0x59B5 0x59B6 0x59B8 0x59B9 +0x59BA 0x59BB 0x59BC 0x59BD 0x59BE 0x59C0 0x59C1 0x59C3 0x59C5 0x59C6 0x59C7 0x59C8 0x59C9 0x59CA 0x59CB 0x59CC +0x59CD 0x59CE 0x59CF 0x59D0 0x59D1 0x59D2 0x59D3 0x59D4 0x59D6 0x59D7 0x59D8 0x59D9 0x59DA 0x59DB 0x59DC 0x59DD +0x59DE 0x59E0 0x59E1 0x59E3 0x59E4 0x59E5 0x59E6 0x59E8 0x59E9 0x59EA 0x59EB 0x59EC 0x59ED 0x59EE 0x59F1 0x59F2 +0x59F3 0x59F4 0x59F5 0x59F6 0x59F7 0x59F8 0x59F9 0x59FA 0x59FB 0x59FC 0x59FD 0x59FE 0x59FF 0x5A00 0x5A01 0x5A03 +0x5A04 0x5A05 0x5A06 0x5A07 0x5A08 0x5A09 0x5A0A 0x5A0C 0x5A0D 0x5A0F 0x5A11 0x5A12 0x5A13 0x5A15 0x5A16 0x5A17 +0x5A18 0x5A19 0x5A1A 0x5A1B 0x5A1C 0x5A1E 0x5A1F 0x5A20 0x5A23 0x5A25 0x5A29 0x5A2B 0x5A2D 0x5A2E 0x5A2F 0x5A31 +0x5A32 0x5A33 0x5A34 0x5A35 0x5A36 0x5A37 0x5A38 0x5A39 0x5A3C 0x5A3E 0x5A3F 0x5A40 0x5A41 0x5A42 0x5A43 0x5A44 +0x5A46 0x5A47 0x5A48 0x5A49 0x5A4A 0x5A4B 0x5A4C 0x5A4D 0x5A50 0x5A51 0x5A52 0x5A53 0x5A55 0x5A56 0x5A57 0x5A58 +0x5A5A 0x5A5B 0x5A5C 0x5A5D 0x5A5E 0x5A5F 0x5A60 0x5A62 0x5A64 0x5A65 0x5A66 0x5A67 0x5A69 0x5A6A 0x5A6B 0x5A6C +0x5A6D 0x5A70 0x5A73 0x5A74 0x5A75 0x5A76 0x5A77 0x5A78 0x5A7A 0x5A7B 0x5A7C 0x5A7D 0x5A7F 0x5A82 0x5A83 0x5A84 +0x5A86 0x5A8A 0x5A8B 0x5A8C 0x5A8E 0x5A8F 0x5A90 0x5A92 0x5A93 0x5A94 0x5A95 0x5A96 0x5A97 0x5A9A 0x5A9B 0x5A9C +0x5A9D 0x5A9E 0x5A9F 0x5AA0 0x5AA2 0x5AA4 0x5AA5 0x5AA6 0x5AA7 0x5AA9 0x5AAA 0x5AAC 0x5AAD 0x5AAE 0x5AAF 0x5AB0 +0x5AB1 0x5AB2 0x5AB3 0x5AB4 0x5AB5 0x5AB6 0x5AB7 0x5AB8 0x5AB9 0x5ABA 0x5ABB 0x5ABC 0x5ABD 0x5ABE 0x5ABF 0x5AC0 +0x5AC1 0x5AC2 0x5AC4 0x5AC6 0x5AC7 0x5AC8 0x5AC9 0x5ACA 0x5ACB 0x5ACC 0x5ACD 0x5ACF 0x5AD0 0x5AD2 0x5AD4 0x5AD5 +0x5AD6 0x5AD7 0x5AD8 0x5AD9 0x5ADA 0x5ADB 0x5ADC 0x5ADD 0x5ADE 0x5ADF 0x5AE0 0x5AE1 0x5AE2 0x5AE3 0x5AE4 0x5AE5 +0x5AE6 0x5AE8 0x5AE9 0x5AEA 0x5AEB 0x5AEC 0x5AED 0x5AEE 0x5AF1 0x5AF2 0x5AF3 0x5AF4 0x5AF5 0x5AF6 0x5AF7 0x5AF8 +0x5AF9 0x5AFA 0x5AFB 0x5AFD 0x5AFF 0x5B00 0x5B01 0x5B02 0x5B03 0x5B05 0x5B07 0x5B08 0x5B09 0x5B0B 0x5B0C 0x5B0F +0x5B10 0x5B13 0x5B14 0x5B16 0x5B17 0x5B19 0x5B1A 0x5B1B 0x5B1D 0x5B1E 0x5B20 0x5B21 0x5B22 0x5B23 0x5B24 0x5B25 +0x5B26 0x5B27 0x5B28 0x5B2A 0x5B2C 0x5B2D 0x5B2E 0x5B2F 0x5B30 0x5B32 0x5B34 0x5B36 0x5B37 0x5B38 0x5B3C 0x5B3D +0x5B3E 0x5B3F 0x5B40 0x5B43 0x5B45 0x5B47 0x5B48 0x5B4B 0x5B4C 0x5B4D 0x5B4E 0x5B50 0x5B51 0x5B52 0x5B53 0x5B54 +0x5B55 0x5B56 0x5B57 0x5B58 0x5B59 0x5B5A 0x5B5B 0x5B5C 0x5B5D 0x5B5E 0x5B5F 0x5B62 0x5B63 0x5B64 0x5B65 0x5B66 +0x5B69 0x5B6A 0x5B6B 0x5B6C 0x5B6D 0x5B6E 0x5B70 0x5B71 0x5B72 0x5B73 0x5B75 0x5B77 0x5B78 0x5B7A 0x5B7B 0x5B7C +0x5B7D 0x5B7F 0x5B80 0x5B81 0x5B82 0x5B83 0x5B84 0x5B85 0x5B87 0x5B88 0x5B89 0x5B8B 0x5B8C 0x5B8D 0x5B8E 0x5B8F +0x5B90 0x5B92 0x5B93 0x5B95 0x5B96 0x5B97 0x5B98 0x5B99 0x5B9A 0x5B9B 0x5B9C 0x5B9D 0x5B9E 0x5B9F 0x5BA0 0x5BA1 +0x5BA2 0x5BA3 0x5BA4 0x5BA5 0x5BA6 0x5BA7 0x5BA8 0x5BAA 0x5BAB 0x5BAC 0x5BAD 0x5BAE 0x5BB0 0x5BB3 0x5BB4 0x5BB5 +0x5BB6 0x5BB8 0x5BB9 0x5BBD 0x5BBE 0x5BBF 0x5BC0 0x5BC1 0x5BC2 0x5BC3 0x5BC4 0x5BC5 0x5BC6 0x5BC7 0x5BC9 0x5BCA +0x5BCB 0x5BCC 0x5BCD 0x5BCE 0x5BD0 0x5BD1 0x5BD2 0x5BD3 0x5BD4 0x5BD6 0x5BD7 0x5BD8 0x5BD9 0x5BDB 0x5BDD 0x5BDE +0x5BDF 0x5BE0 0x5BE1 0x5BE2 0x5BE3 0x5BE4 0x5BE5 0x5BE6 0x5BE7 0x5BE8 0x5BE9 0x5BEA 0x5BEB 0x5BEC 0x5BEE 0x5BEF +0x5BF0 0x5BF1 0x5BF2 0x5BF3 0x5BF5 0x5BF6 0x5BF8 0x5BF9 0x5BFA 0x5BFB 0x5BFC 0x5BFE 0x5BFF 0x5C01 0x5C02 0x5C03 +0x5C04 0x5C05 0x5C06 0x5C07 0x5C08 0x5C09 0x5C0A 0x5C0B 0x5C0C 0x5C0D 0x5C0E 0x5C0F 0x5C10 0x5C11 0x5C12 0x5C13 +0x5C14 0x5C15 0x5C16 0x5C17 0x5C18 0x5C19 0x5C1A 0x5C1B 0x5C1C 0x5C1D 0x5C1F 0x5C20 0x5C22 0x5C23 0x5C24 0x5C25 +0x5C27 0x5C28 0x5C2A 0x5C2C 0x5C2D 0x5C30 0x5C31 0x5C33 0x5C34 0x5C35 0x5C36 0x5C37 0x5C38 0x5C39 0x5C3A 0x5C3B +0x5C3C 0x5C3D 0x5C3E 0x5C3F 0x5C40 0x5C41 0x5C42 0x5C43 0x5C44 0x5C45 0x5C46 0x5C47 0x5C48 0x5C49 0x5C4A 0x5C4B +0x5C4C 0x5C4D 0x5C4E 0x5C4F 0x5C50 0x5C51 0x5C53 0x5C54 0x5C55 0x5C56 0x5C58 0x5C59 0x5C5B 0x5C5C 0x5C5D 0x5C5E +0x5C60 0x5C61 0x5C62 0x5C63 0x5C64 0x5C65 0x5C66 0x5C67 0x5C68 0x5C69 0x5C6A 0x5C6C 0x5C6D 0x5C6E 0x5C6F 0x5C70 +0x5C71 0x5C72 0x5C73 0x5C74 0x5C75 0x5C76 0x5C79 0x5C7A 0x5C7B 0x5C7C 0x5C7E 0x5C7F 0x5C81 0x5C82 0x5C83 0x5C86 +0x5C88 0x5C89 0x5C8A 0x5C8B 0x5C8C 0x5C8D 0x5C8F 0x5C90 0x5C91 0x5C92 0x5C93 0x5C94 0x5C95 0x5C96 0x5C97 0x5C98 +0x5C99 0x5C9A 0x5C9B 0x5C9C 0x5C9D 0x5C9E 0x5C9F 0x5CA0 0x5CA1 0x5CA2 0x5CA3 0x5CA4 0x5CA5 0x5CA6 0x5CA7 0x5CA8 +0x5CA9 0x5CAA 0x5CAB 0x5CAC 0x5CAD 0x5CAE 0x5CAF 0x5CB0 0x5CB1 0x5CB3 0x5CB5 0x5CB6 0x5CB7 0x5CB8 0x5CBA 0x5CBB +0x5CBC 0x5CBD 0x5CBE 0x5CBF 0x5CC0 0x5CC1 0x5CC2 0x5CC3 0x5CC4 0x5CC5 0x5CC6 0x5CC7 0x5CC8 0x5CC9 0x5CCA 0x5CCB +0x5CCC 0x5CCE 0x5CCF 0x5CD0 0x5CD2 0x5CD3 0x5CD4 0x5CD6 0x5CD7 0x5CD8 0x5CD9 0x5CDA 0x5CDB 0x5CDE 0x5CDF 0x5CE0 +0x5CE1 0x5CE3 0x5CE4 0x5CE5 0x5CE6 0x5CE7 0x5CE8 0x5CE9 0x5CEA 0x5CEC 0x5CED 0x5CEE 0x5CEF 0x5CF0 0x5CF1 0x5CF4 +0x5CF6 0x5CF7 0x5CF8 0x5CF9 0x5CFA 0x5CFB 0x5CFD 0x5CFF 0x5D00 0x5D01 0x5D02 0x5D03 0x5D04 0x5D05 0x5D06 0x5D07 +0x5D0B 0x5D0C 0x5D0D 0x5D0E 0x5D0F 0x5D10 0x5D11 0x5D12 0x5D14 0x5D15 0x5D16 0x5D17 0x5D18 0x5D19 0x5D1A 0x5D1B +0x5D1D 0x5D1E 0x5D1F 0x5D20 0x5D21 0x5D22 0x5D23 0x5D24 0x5D25 0x5D26 0x5D27 0x5D28 0x5D29 0x5D2C 0x5D2D 0x5D2E +0x5D30 0x5D31 0x5D32 0x5D33 0x5D34 0x5D35 0x5D36 0x5D37 0x5D38 0x5D39 0x5D3A 0x5D3C 0x5D3D 0x5D3E 0x5D3F 0x5D40 +0x5D41 0x5D42 0x5D43 0x5D44 0x5D45 0x5D47 0x5D49 0x5D4A 0x5D4B 0x5D4C 0x5D4E 0x5D50 0x5D51 0x5D52 0x5D55 0x5D56 +0x5D58 0x5D59 0x5D5A 0x5D5B 0x5D5C 0x5D5D 0x5D5E 0x5D62 0x5D63 0x5D65 0x5D67 0x5D68 0x5D69 0x5D6B 0x5D6C 0x5D6F +0x5D71 0x5D72 0x5D73 0x5D74 0x5D76 0x5D77 0x5D79 0x5D7A 0x5D7C 0x5D7D 0x5D7E 0x5D7F 0x5D80 0x5D81 0x5D82 0x5D84 +0x5D85 0x5D86 0x5D87 0x5D88 0x5D89 0x5D8A 0x5D8B 0x5D8C 0x5D8D 0x5D90 0x5D92 0x5D93 0x5D94 0x5D95 0x5D97 0x5D99 +0x5D9A 0x5D9C 0x5D9D 0x5D9E 0x5D9F 0x5DA0 0x5DA1 0x5DA2 0x5DA6 0x5DA7 0x5DA8 0x5DA9 0x5DAA 0x5DAC 0x5DAD 0x5DAE +0x5DAF 0x5DB0 0x5DB1 0x5DB2 0x5DB4 0x5DB5 0x5DB7 0x5DB8 0x5DBA 0x5DBC 0x5DBD 0x5DC0 0x5DC2 0x5DC3 0x5DC5 0x5DC6 +0x5DC7 0x5DC9 0x5DCB 0x5DCC 0x5DCD 0x5DCF 0x5DD1 0x5DD2 0x5DD3 0x5DD4 0x5DD5 0x5DD6 0x5DD8 0x5DDB 0x5DDD 0x5DDE +0x5DDF 0x5DE0 0x5DE1 0x5DE2 0x5DE3 0x5DE4 0x5DE5 0x5DE6 0x5DE7 0x5DE8 0x5DE9 0x5DEA 0x5DEB 0x5DED 0x5DEE 0x5DEF +0x5DF0 0x5DF1 0x5DF2 0x5DF3 0x5DF4 0x5DF5 0x5DF7 0x5DF8 0x5DF9 0x5DFB 0x5DFD 0x5DFE 0x5DFF 0x5E00 0x5E01 0x5E02 +0x5E03 0x5E04 0x5E05 0x5E06 0x5E08 0x5E0A 0x5E0B 0x5E0C 0x5E0E 0x5E0F 0x5E10 0x5E11 0x5E14 0x5E15 0x5E16 0x5E17 +0x5E18 0x5E19 0x5E1A 0x5E1B 0x5E1C 0x5E1D 0x5E1F 0x5E20 0x5E21 0x5E22 0x5E23 0x5E24 0x5E25 0x5E26 0x5E27 0x5E28 +0x5E29 0x5E2B 0x5E2D 0x5E2E 0x5E2F 0x5E30 0x5E31 0x5E33 0x5E34 0x5E35 0x5E36 0x5E37 0x5E38 0x5E3B 0x5E3C 0x5E3D +0x5E3E 0x5E3F 0x5E40 0x5E41 0x5E42 0x5E43 0x5E44 0x5E45 0x5E47 0x5E48 0x5E4A 0x5E4B 0x5E4C 0x5E4D 0x5E4E 0x5E4F +0x5E53 0x5E54 0x5E55 0x5E56 0x5E57 0x5E58 0x5E59 0x5E5B 0x5E5C 0x5E5D 0x5E5E 0x5E5F 0x5E60 0x5E61 0x5E62 0x5E63 +0x5E64 0x5E66 0x5E67 0x5E68 0x5E69 0x5E6A 0x5E6B 0x5E6C 0x5E6D 0x5E6E 0x5E6F 0x5E70 0x5E72 0x5E73 0x5E74 0x5E75 +0x5E76 0x5E77 0x5E78 0x5E79 0x5E7A 0x5E7B 0x5E7C 0x5E7D 0x5E7E 0x5E7F 0x5E80 0x5E81 0x5E82 0x5E83 0x5E84 0x5E85 +0x5E86 0x5E87 0x5E88 0x5E89 0x5E8A 0x5E8B 0x5E8C 0x5E8D 0x5E8F 0x5E90 0x5E91 0x5E93 0x5E94 0x5E95 0x5E96 0x5E97 +0x5E99 0x5E9A 0x5E9B 0x5E9C 0x5E9D 0x5E9E 0x5E9F 0x5EA0 0x5EA2 0x5EA3 0x5EA4 0x5EA5 0x5EA6 0x5EA7 0x5EA8 0x5EAA +0x5EAB 0x5EAC 0x5EAD 0x5EAE 0x5EB0 0x5EB1 0x5EB2 0x5EB3 0x5EB4 0x5EB5 0x5EB6 0x5EB7 0x5EB8 0x5EB9 0x5EBC 0x5EBE +0x5EC1 0x5EC2 0x5EC3 0x5EC4 0x5EC5 0x5EC6 0x5EC7 0x5EC8 0x5EC9 0x5ECA 0x5ECB 0x5ECC 0x5ECD 0x5ECE 0x5ECF 0x5ED0 +0x5ED1 0x5ED2 0x5ED3 0x5ED4 0x5ED5 0x5ED6 0x5ED7 0x5ED8 0x5ED9 0x5EDA 0x5EDB 0x5EDC 0x5EDD 0x5EDE 0x5EDF 0x5EE0 +0x5EE1 0x5EE2 0x5EE3 0x5EE5 0x5EE6 0x5EE7 0x5EE8 0x5EE9 0x5EEA 0x5EEC 0x5EEE 0x5EEF 0x5EF0 0x5EF1 0x5EF2 0x5EF3 +0x5EF4 0x5EF6 0x5EF7 0x5EF8 0x5EFA 0x5EFB 0x5EFC 0x5EFE 0x5EFF 0x5F00 0x5F01 0x5F02 0x5F03 0x5F04 0x5F05 0x5F06 +0x5F07 0x5F08 0x5F09 0x5F0A 0x5F0B 0x5F0C 0x5F0D 0x5F0E 0x5F0F 0x5F10 0x5F11 0x5F12 0x5F13 0x5F14 0x5F15 0x5F16 +0x5F17 0x5F18 0x5F1A 0x5F1B 0x5F1C 0x5F1D 0x5F1F 0x5F20 0x5F22 0x5F23 0x5F24 0x5F25 0x5F26 0x5F27 0x5F28 0x5F29 +0x5F2A 0x5F2D 0x5F2E 0x5F2F 0x5F30 0x5F31 0x5F33 0x5F34 0x5F35 0x5F36 0x5F37 0x5F38 0x5F39 0x5F3A 0x5F3C 0x5F3E +0x5F40 0x5F41 0x5F43 0x5F44 0x5F45 0x5F46 0x5F48 0x5F49 0x5F4A 0x5F4B 0x5F4C 0x5F4E 0x5F4F 0x5F50 0x5F51 0x5F52 +0x5F53 0x5F54 0x5F55 0x5F56 0x5F57 0x5F58 0x5F59 0x5F5B 0x5F5C 0x5F5D 0x5F5E 0x5F5F 0x5F60 0x5F61 0x5F62 0x5F63 +0x5F64 0x5F65 0x5F66 0x5F67 0x5F68 0x5F69 0x5F6A 0x5F6B 0x5F6C 0x5F6D 0x5F6E 0x5F6F 0x5F70 0x5F71 0x5F72 0x5F73 +0x5F74 0x5F76 0x5F77 0x5F78 0x5F79 0x5F7B 0x5F7C 0x5F7D 0x5F7E 0x5F7F 0x5F80 0x5F81 0x5F82 0x5F83 0x5F84 0x5F85 +0x5F86 0x5F87 0x5F88 0x5F89 0x5F8A 0x5F8B 0x5F8C 0x5F90 0x5F91 0x5F92 0x5F93 0x5F95 0x5F96 0x5F97 0x5F98 0x5F99 +0x5F9B 0x5F9C 0x5F9E 0x5F9F 0x5FA0 0x5FA1 0x5FA5 0x5FA6 0x5FA7 0x5FA8 0x5FA9 0x5FAA 0x5FAB 0x5FAC 0x5FAD 0x5FAE +0x5FAF 0x5FB3 0x5FB4 0x5FB5 0x5FB7 0x5FB9 0x5FBC 0x5FBD 0x5FC3 0x5FC4 0x5FC5 0x5FC6 0x5FC9 0x5FCC 0x5FCD 0x5FCF +0x5FD0 0x5FD1 0x5FD2 0x5FD3 0x5FD6 0x5FD7 0x5FD8 0x5FD9 0x5FDC 0x5FDD 0x5FDE 0x5FDF 0x5FE0 0x5FE1 0x5FE3 0x5FE4 +0x5FE7 0x5FE8 0x5FEA 0x5FEB 0x5FED 0x5FEE 0x5FF0 0x5FF1 0x5FF3 0x5FF5 0x5FF8 0x5FFA 0x5FFB 0x5FFC 0x5FFD 0x5FFE +0x5FFF 0x6000 0x6001 0x6002 0x6003 0x6004 0x6005 0x6006 0x600A 0x600D 0x600E 0x600F 0x6010 0x6012 0x6014 0x6015 +0x6016 0x6017 0x6019 0x601B 0x601C 0x601D 0x6020 0x6021 0x6025 0x6026 0x6027 0x6028 0x6029 0x602A 0x602B 0x602F +0x6031 0x6033 0x6035 0x6039 0x603A 0x603B 0x603C 0x603F 0x6041 0x6042 0x6043 0x6046 0x6047 0x604A 0x604B 0x604D +0x604F 0x6050 0x6052 0x6053 0x6054 0x6055 0x6059 0x605A 0x605D 0x605F 0x6060 0x6062 0x6063 0x6064 0x6065 0x6067 +0x6068 0x6069 0x606A 0x606B 0x606C 0x606D 0x606F 0x6070 0x6073 0x6075 0x6076 0x6077 0x6078 0x6079 0x607A 0x607B +0x607C 0x607D 0x607F 0x6081 0x6083 0x6084 0x6085 0x6086 0x6088 0x6089 0x608B 0x608C 0x608D 0x6092 0x6094 0x6095 +0x6096 0x6097 0x609A 0x609B 0x609D 0x609E 0x609F 0x60A0 0x60A2 0x60A3 0x60A4 0x60A6 0x60A7 0x60A8 0x60A9 0x60AA +0x60AB 0x60AC 0x60AD 0x60AE 0x60AF 0x60B0 0x60B1 0x60B2 0x60B3 0x60B4 0x60B5 0x60B6 0x60B8 0x60BB 0x60BC 0x60BD +0x60BE 0x60C5 0x60C6 0x60C7 0x60CA 0x60CB 0x60CE 0x60D1 0x60D3 0x60D4 0x60D5 0x60D7 0x60D8 0x60D9 0x60DA 0x60DB +0x60DC 0x60DD 0x60DF 0x60E0 0x60E1 0x60E2 0x60E3 0x60E6 0x60E7 0x60E8 0x60E9 0x60EB 0x60EC 0x60ED 0x60EE 0x60EF +0x60F0 0x60F1 0x60F2 0x60F3 0x60F4 0x60F6 0x60F7 0x60F9 0x60FA 0x60FB 0x60FC 0x6100 0x6101 0x6103 0x6106 0x6108 +0x6109 0x610A 0x610D 0x610E 0x610F 0x6110 0x6112 0x6113 0x6114 0x6115 0x6116 0x611A 0x611B 0x611C 0x611F 0x6120 +0x6121 0x6123 0x6124 0x6126 0x6127 0x6128 0x612B 0x612C 0x612D 0x6130 0x6134 0x6137 0x613C 0x613D 0x613E 0x613F +0x6142 0x6144 0x6146 0x6147 0x6148 0x614A 0x614B 0x614C 0x614D 0x614E 0x6151 0x6153 0x6155 0x6158 0x6159 0x615A +0x615C 0x615D 0x615F 0x6160 0x6162 0x6163 0x6164 0x6165 0x6167 0x6168 0x616A 0x616B 0x616C 0x616D 0x616E 0x616F +0x6170 0x6171 0x6173 0x6174 0x6175 0x6176 0x6177 0x617C 0x617D 0x617E 0x6181 0x6182 0x6183 0x6187 0x618A 0x618B +0x618D 0x618E 0x618F 0x6190 0x6191 0x6192 0x6193 0x6194 0x6195 0x6196 0x6198 0x6199 0x619A 0x619D 0x61A4 0x61A7 +0x61A8 0x61A9 0x61AB 0x61AC 0x61AD 0x61AE 0x61AF 0x61B1 0x61B2 0x61B6 0x61B7 0x61B9 0x61BA 0x61BE 0x61C1 0x61C2 +0x61C3 0x61C6 0x61C7 0x61C8 0x61C9 0x61CA 0x61CB 0x61CC 0x61CD 0x61D0 0x61D1 0x61D2 0x61D4 0x61DE 0x61DF 0x61E3 +0x61E6 0x61E8 0x61F2 0x61F4 0x61F5 0x61F6 0x61F7 0x61F8 0x61FA 0x61FC 0x61FD 0x61FE 0x61FF 0x6200 0x6206 0x6207 +0x6208 0x6209 0x620A 0x620B 0x620C 0x620D 0x620E 0x620F 0x6210 0x6211 0x6212 0x6213 0x6214 0x6215 0x6216 0x6217 +0x6218 0x6219 0x621A 0x621B 0x621D 0x621E 0x621F 0x6221 0x6222 0x6223 0x6224 0x6225 0x6226 0x6227 0x6229 0x622A +0x622C 0x622D 0x622E 0x622F 0x6230 0x6231 0x6232 0x6233 0x6234 0x6236 0x6237 0x6238 0x623A 0x623B 0x623D 0x623E +0x623F 0x6240 0x6241 0x6242 0x6243 0x6245 0x6246 0x6247 0x6248 0x6249 0x624A 0x624B 0x624C 0x624D 0x624E 0x6250 +0x6251 0x6252 0x6253 0x6254 0x6255 0x6258 0x6259 0x625A 0x625B 0x625E 0x6260 0x6261 0x6263 0x6264 0x6265 0x6266 +0x6267 0x6268 0x6269 0x626A 0x626B 0x626C 0x626D 0x626E 0x626F 0x6270 0x6271 0x6273 0x6276 0x6279 0x627A 0x627C +0x627D 0x627E 0x627F 0x6280 0x6282 0x6283 0x6284 0x6286 0x6288 0x6289 0x628A 0x628C 0x628F 0x6291 0x6292 0x6293 +0x6294 0x6295 0x6296 0x6297 0x6298 0x629A 0x629B 0x629C 0x629E 0x629F 0x62A0 0x62A1 0x62A2 0x62A4 0x62A5 0x62A6 +0x62A8 0x62AB 0x62AC 0x62AE 0x62B1 0x62B5 0x62B6 0x62B9 0x62BA 0x62BB 0x62BC 0x62BD 0x62BF 0x62C2 0x62C3 0x62C4 +0x62C5 0x62C6 0x62C7 0x62C8 0x62C9 0x62CA 0x62CB 0x62CC 0x62CD 0x62CE 0x62CF 0x62D0 0x62D1 0x62D2 0x62D3 0x62D4 +0x62D6 0x62D7 0x62D8 0x62D9 0x62DA 0x62DB 0x62DC 0x62DD 0x62DF 0x62E0 0x62E1 0x62E2 0x62E3 0x62E4 0x62E5 0x62E6 +0x62E7 0x62E8 0x62E9 0x62EC 0x62ED 0x62EE 0x62EF 0x62F1 0x62F3 0x62F4 0x62F5 0x62F6 0x62F7 0x62FC 0x62FD 0x62FE +0x62FF 0x6301 0x6302 0x6307 0x6308 0x6309 0x630C 0x630E 0x6311 0x6313 0x6316 0x6319 0x631A 0x631B 0x631C 0x631D +0x631E 0x631F 0x6320 0x6321 0x6322 0x6323 0x6324 0x6325 0x6326 0x6327 0x6328 0x632A 0x632B 0x632F 0x6332 0x6335 +0x6339 0x633A 0x633B 0x633C 0x633D 0x633E 0x633F 0x6342 0x6343 0x6345 0x6346 0x6349 0x634B 0x634C 0x634D 0x634E +0x634F 0x6350 0x6355 0x6357 0x6358 0x635C 0x635E 0x635F 0x6361 0x6362 0x6363 0x6367 0x6368 0x6369 0x636B 0x636D +0x636E 0x636F 0x6371 0x6372 0x6376 0x6377 0x637A 0x637B 0x637D 0x637F 0x6380 0x6382 0x6383 0x6384 0x6387 0x6388 +0x6389 0x638A 0x638C 0x638E 0x638F 0x6390 0x6392 0x6396 0x6397 0x6398 0x6399 0x639B 0x639E 0x639F 0x63A0 0x63A1 +0x63A2 0x63A3 0x63A5 0x63A7 0x63A8 0x63A9 0x63AA 0x63AB 0x63AC 0x63AD 0x63AE 0x63AF 0x63B0 0x63B1 0x63B2 0x63B3 +0x63B4 0x63B5 0x63B7 0x63B8 0x63B9 0x63BA 0x63BB 0x63BC 0x63BE 0x63C0 0x63C3 0x63C4 0x63C5 0x63C6 0x63C8 0x63C9 +0x63CC 0x63CD 0x63CE 0x63CF 0x63D0 0x63D2 0x63D5 0x63D6 0x63DA 0x63DB 0x63DE 0x63E0 0x63E1 0x63E2 0x63E3 0x63E4 +0x63E6 0x63E9 0x63EA 0x63EC 0x63ED 0x63EE 0x63F2 0x63F3 0x63F4 0x63F6 0x63F7 0x63F8 0x63F9 0x63FA 0x63FB 0x63FC +0x63FD 0x63FE 0x63FF 0x6400 0x6401 0x6402 0x6405 0x6406 0x6407 0x640A 0x640B 0x640C 0x640D 0x640F 0x6410 0x6412 +0x6413 0x6414 0x6415 0x6416 0x6417 0x6419 0x641B 0x641C 0x641D 0x641E 0x6420 0x6421 0x6422 0x6423 0x6425 0x6426 +0x6427 0x6428 0x642A 0x642C 0x642D 0x6430 0x6432 0x6434 0x6435 0x6436 0x643A 0x643D 0x643E 0x643F 0x6440 0x6441 +0x6442 0x6443 0x6444 0x6445 0x6446 0x6447 0x6448 0x644A 0x644B 0x644E 0x644F 0x6451 0x6452 0x6454 0x6458 0x6459 +0x645B 0x645C 0x645E 0x645F 0x6460 0x6467 0x6469 0x646D 0x646F 0x6470 0x6471 0x6473 0x6474 0x6475 0x6476 0x6477 +0x6478 0x6479 0x647A 0x647B 0x647D 0x6482 0x6483 0x6484 0x6485 0x6487 0x6488 0x648D 0x648F 0x6490 0x6491 0x6492 +0x6493 0x6495 0x6496 0x6498 0x6499 0x649A 0x649D 0x649E 0x649F 0x64A2 0x64A3 0x64A4 0x64A5 0x64A9 0x64AB 0x64AC +0x64AD 0x64AE 0x64B0 0x64B2 0x64B3 0x64B4 0x64B5 0x64B7 0x64B8 0x64B9 0x64BA 0x64BB 0x64BC 0x64BE 0x64BF 0x64C0 +0x64C1 0x64C2 0x64C4 0x64C5 0x64C7 0x64CA 0x64CB 0x64CD 0x64CE 0x64D0 0x64D2 0x64D3 0x64D4 0x64D6 0x64D7 0x64D8 +0x64DA 0x64DD 0x64DE 0x64E0 0x64E1 0x64E2 0x64E3 0x64E4 0x64E5 0x64E6 0x64E7 0x64E9 0x64EC 0x64ED 0x64EF 0x64F0 +0x64F1 0x64F2 0x64F4 0x64F6 0x64F7 0x64F8 0x64FA 0x64FB 0x64FC 0x64FD 0x64FE 0x64FF 0x6500 0x6504 0x6505 0x6506 +0x6509 0x650F 0x6511 0x6512 0x6514 0x6516 0x6518 0x6519 0x651B 0x651C 0x651D 0x651E 0x6522 0x6523 0x6524 0x6525 +0x652A 0x652B 0x652C 0x652E 0x652F 0x6530 0x6534 0x6535 0x6536 0x6537 0x6538 0x6539 0x653A 0x653B 0x653D 0x653E +0x653F 0x6541 0x6543 0x6545 0x6548 0x6549 0x654C 0x654D 0x654E 0x654F 0x6551 0x6554 0x6555 0x6556 0x6557 0x6558 +0x6559 0x655B 0x655C 0x655D 0x655E 0x6560 0x6562 0x6563 0x6566 0x6569 0x656B 0x656C 0x656D 0x6570 0x6572 0x6574 +0x6575 0x6577 0x6578 0x6579 0x657E 0x6582 0x6583 0x6585 0x6586 0x6587 0x6588 0x6589 0x658B 0x658C 0x658E 0x658F +0x6590 0x6591 0x6593 0x6595 0x6597 0x6599 0x659B 0x659C 0x659D 0x659E 0x659F 0x65A0 0x65A1 0x65A2 0x65A4 0x65A5 +0x65A7 0x65A8 0x65A9 0x65AB 0x65AC 0x65AD 0x65AF 0x65B0 0x65B2 0x65B6 0x65B7 0x65B8 0x65B9 0x65BC 0x65BD 0x65C1 +0x65C2 0x65C3 0x65C4 0x65C5 0x65C6 0x65CB 0x65CC 0x65CE 0x65CF 0x65D0 0x65D2 0x65D6 0x65D7 0x65D9 0x65DB 0x65DE +0x65E0 0x65E1 0x65E2 0x65E3 0x65E5 0x65E6 0x65E7 0x65E8 0x65E9 0x65EC 0x65ED 0x65EE 0x65EF 0x65F0 0x65F1 0x65F2 +0x65F3 0x65F4 0x65F5 0x65F6 0x65F7 0x65F8 0x65FA 0x65FB 0x65FC 0x65FD 0x65FF 0x6600 0x6602 0x6603 0x6604 0x6605 +0x6606 0x6607 0x6608 0x6609 0x660A 0x660B 0x660C 0x660D 0x660E 0x660F 0x6610 0x6611 0x6612 0x6613 0x6614 0x6615 +0x6619 0x661A 0x661C 0x661D 0x661E 0x661F 0x6620 0x6621 0x6622 0x6623 0x6624 0x6625 0x6626 0x6627 0x6628 0x662A +0x662B 0x662D 0x662E 0x662F 0x6630 0x6631 0x6632 0x6633 0x6634 0x6635 0x6636 0x663A 0x663B 0x663C 0x663D 0x663E +0x663F 0x6641 0x6642 0x6643 0x6644 0x6645 0x6649 0x664A 0x664B 0x664C 0x664F 0x6650 0x6652 0x6653 0x6654 0x6655 +0x6656 0x6657 0x6659 0x665A 0x665B 0x665D 0x665E 0x665F 0x6661 0x6662 0x6664 0x6665 0x6666 0x6667 0x6668 0x6669 +0x666A 0x666B 0x666C 0x666E 0x666F 0x6670 0x6671 0x6673 0x6674 0x6676 0x6677 0x6678 0x6679 0x667A 0x667B 0x667E +0x6681 0x6682 0x6683 0x6684 0x6685 0x6687 0x6688 0x6689 0x668B 0x668C 0x668D 0x668E 0x6690 0x6691 0x6692 0x6695 +0x6696 0x6697 0x6698 0x669D 0x66A0 0x66A2 0x66A3 0x66A6 0x66A7 0x66A8 0x66AA 0x66AB 0x66AE 0x66B1 0x66B2 0x66B3 +0x66B4 0x66B5 0x66B6 0x66B8 0x66B9 0x66BB 0x66BC 0x66BE 0x66BF 0x66C1 0x66C4 0x66C6 0x66C7 0x66C8 0x66C9 0x66CC +0x66D6 0x66D9 0x66DA 0x66DB 0x66DC 0x66DD 0x66E0 0x66E3 0x66E6 0x66E8 0x66E9 0x66EC 0x66EF 0x66F0 0x66F1 0x66F2 +0x66F3 0x66F4 0x66F5 0x66F7 0x66F8 0x66F9 0x66FA 0x66FC 0x66FD 0x66FE 0x66FF 0x6700 0x6701 0x6703 0x6706 0x6708 +0x6709 0x670A 0x670B 0x670D 0x670F 0x6710 0x6711 0x6712 0x6713 0x6714 0x6715 0x6716 0x6717 0x6718 0x671B 0x671D +0x671E 0x671F 0x6723 0x6725 0x6726 0x6727 0x6728 0x6729 0x672A 0x672B 0x672C 0x672D 0x672E 0x672F 0x6730 0x6731 +0x6732 0x6733 0x6734 0x6735 0x6736 0x6737 0x6738 0x673A 0x673D 0x673F 0x6740 0x6741 0x6742 0x6743 0x6744 0x6745 +0x6746 0x6748 0x6749 0x674B 0x674C 0x674E 0x674F 0x6750 0x6751 0x6753 0x6755 0x6756 0x6757 0x6759 0x675C 0x675E +0x675F 0x6760 0x6761 0x6762 0x6763 0x6764 0x6765 0x6767 0x6768 0x6769 0x676A 0x676D 0x676E 0x676F 0x6770 0x6771 +0x6772 0x6773 0x6774 0x6775 0x6777 0x677A 0x677B 0x677C 0x677E 0x677F 0x6781 0x6784 0x6785 0x6787 0x6789 0x678B +0x678C 0x678D 0x678F 0x6790 0x6791 0x6792 0x6793 0x6795 0x6797 0x6798 0x6799 0x679A 0x679C 0x679D 0x679E 0x679F +0x67A0 0x67A1 0x67A2 0x67A3 0x67A5 0x67A6 0x67A7 0x67A8 0x67A9 0x67AA 0x67AB 0x67AD 0x67AF 0x67B0 0x67B1 0x67B2 +0x67B3 0x67B4 0x67B5 0x67B6 0x67B7 0x67B8 0x67B9 0x67BE 0x67C1 0x67C3 0x67C4 0x67C6 0x67C8 0x67CA 0x67CE 0x67CF +0x67D0 0x67D1 0x67D2 0x67D3 0x67D4 0x67D6 0x67D8 0x67D9 0x67DA 0x67DC 0x67DD 0x67DE 0x67E0 0x67E2 0x67E4 0x67E5 +0x67E7 0x67E9 0x67EC 0x67EE 0x67EF 0x67F0 0x67F1 0x67F3 0x67F4 0x67F5 0x67F6 0x67F7 0x67FA 0x67FB 0x67FD 0x67FE +0x67FF 0x6800 0x6802 0x6803 0x6804 0x6805 0x6807 0x6808 0x6809 0x680A 0x680B 0x680C 0x680E 0x680F 0x6810 0x6811 +0x6812 0x6813 0x6814 0x6816 0x6817 0x6818 0x681D 0x681E 0x681F 0x6821 0x6822 0x6829 0x682A 0x682B 0x682F 0x6832 +0x6833 0x6834 0x6837 0x6838 0x6839 0x683B 0x683C 0x683D 0x683E 0x683F 0x6840 0x6841 0x6842 0x6843 0x6844 0x6845 +0x6846 0x6848 0x6849 0x684A 0x684B 0x684C 0x684D 0x684E 0x6850 0x6851 0x6853 0x6854 0x6855 0x6859 0x685C 0x685D +0x685F 0x6860 0x6861 0x6862 0x6863 0x6864 0x6865 0x6866 0x6867 0x6868 0x6869 0x686A 0x686B 0x686C 0x686D 0x686F +0x6872 0x6874 0x6876 0x6877 0x6879 0x687E 0x687F 0x6881 0x6882 0x6883 0x6885 0x6886 0x6887 0x688C 0x688D 0x688F +0x6890 0x6893 0x6894 0x6897 0x6898 0x689B 0x689C 0x689D 0x689F 0x68A0 0x68A1 0x68A2 0x68A3 0x68A6 0x68A7 0x68A8 +0x68AD 0x68AF 0x68B0 0x68B1 0x68B2 0x68B3 0x68B4 0x68B5 0x68B6 0x68B9 0x68BA 0x68BC 0x68BD 0x68BE 0x68BF 0x68C0 +0x68C1 0x68C2 0x68C4 0x68C5 0x68C6 0x68C9 0x68CA 0x68CB 0x68CD 0x68D0 0x68D1 0x68D2 0x68D3 0x68D4 0x68D5 0x68D6 +0x68D7 0x68D8 0x68DA 0x68DF 0x68E0 0x68E1 0x68E3 0x68E4 0x68E7 0x68E8 0x68EA 0x68EB 0x68EC 0x68EE 0x68EF 0x68F0 +0x68F1 0x68F2 0x68F5 0x68F6 0x68F8 0x68F9 0x68FA 0x68FB 0x68FC 0x68FD 0x6900 0x6901 0x6904 0x6905 0x6906 0x6907 +0x6908 0x690B 0x690C 0x690D 0x690E 0x690F 0x6910 0x6911 0x6912 0x6913 0x6919 0x691A 0x691B 0x691C 0x691D 0x691F +0x6920 0x6921 0x6922 0x6923 0x6924 0x6925 0x6926 0x6927 0x6928 0x692A 0x692B 0x692D 0x6930 0x6934 0x6935 0x6936 +0x6938 0x6939 0x693D 0x693F 0x6940 0x6942 0x694A 0x6952 0x6953 0x6954 0x6955 0x6957 0x6959 0x695A 0x695B 0x695C +0x695D 0x695E 0x695F 0x6960 0x6961 0x6962 0x6963 0x6966 0x6968 0x6969 0x696A 0x696B 0x696C 0x696D 0x696E 0x696F +0x6971 0x6973 0x6974 0x6975 0x6977 0x6978 0x6979 0x697C 0x697D 0x697E 0x6980 0x6981 0x6982 0x6983 0x6984 0x6985 +0x6986 0x6987 0x6988 0x6989 0x698A 0x698D 0x698E 0x6991 0x6994 0x6995 0x6996 0x6998 0x699B 0x699C 0x69A0 0x69A3 +0x69A5 0x69A6 0x69A7 0x69A8 0x69AA 0x69AB 0x69AD 0x69AE 0x69B0 0x69B1 0x69B2 0x69B4 0x69B7 0x69BB 0x69BC 0x69BE +0x69BF 0x69C1 0x69C3 0x69C5 0x69C7 0x69CA 0x69CB 0x69CC 0x69CD 0x69CE 0x69CF 0x69D0 0x69D1 0x69D3 0x69D4 0x69D8 +0x69D9 0x69DA 0x69DB 0x69DC 0x69DD 0x69DE 0x69DF 0x69E0 0x69E4 0x69E5 0x69E7 0x69E8 0x69EA 0x69EB 0x69ED 0x69F1 +0x69F2 0x69F3 0x69F9 0x69FA 0x69FB 0x69FC 0x69FD 0x69FE 0x69FF 0x6A01 0x6A02 0x6A05 0x6A0A 0x6A0B 0x6A0C 0x6A11 +0x6A12 0x6A13 0x6A14 0x6A17 0x6A18 0x6A19 0x6A1B 0x6A1E 0x6A1F 0x6A21 0x6A22 0x6A23 0x6A28 0x6A29 0x6A2A 0x6A2B +0x6A2E 0x6A2F 0x6A31 0x6A33 0x6A35 0x6A36 0x6A38 0x6A39 0x6A3A 0x6A3D 0x6A3E 0x6A3F 0x6A44 0x6A47 0x6A48 0x6A4B +0x6A50 0x6A51 0x6A52 0x6A53 0x6A58 0x6A59 0x6A5A 0x6A5B 0x6A5E 0x6A5F 0x6A61 0x6A62 0x6A65 0x6A66 0x6A6B 0x6A71 +0x6A72 0x6A74 0x6A78 0x6A79 0x6A7C 0x6A7D 0x6A7E 0x6A7F 0x6A80 0x6A81 0x6A84 0x6A87 0x6A89 0x6A8D 0x6A8E 0x6A90 +0x6A91 0x6A94 0x6A96 0x6A97 0x6A9C 0x6A9E 0x6A9F 0x6AA0 0x6AA2 0x6AA3 0x6AA8 0x6AA9 0x6AAA 0x6AAB 0x6AAC 0x6AAE +0x6AAF 0x6AB3 0x6AB4 0x6AB5 0x6AB8 0x6ABB 0x6AC1 0x6AC2 0x6AC3 0x6AC6 0x6AC8 0x6ACD 0x6AD1 0x6AD3 0x6ADA 0x6ADB +0x6ADD 0x6ADE 0x6ADF 0x6AE5 0x6AE7 0x6AE8 0x6AEA 0x6AEB 0x6AEC 0x6AF1 0x6AF3 0x6AF6 0x6AF8 0x6AFA 0x6AFB 0x6AFC +0x6B02 0x6B04 0x6B05 0x6B09 0x6B0A 0x6B0C 0x6B0F 0x6B10 0x6B12 0x6B13 0x6B16 0x6B17 0x6B1D 0x6B1E 0x6B1F 0x6B20 +0x6B21 0x6B22 0x6B23 0x6B24 0x6B27 0x6B2C 0x6B32 0x6B37 0x6B38 0x6B39 0x6B3A 0x6B3B 0x6B3D 0x6B3E 0x6B3F 0x6B43 +0x6B45 0x6B46 0x6B47 0x6B49 0x6B4C 0x6B4E 0x6B50 0x6B53 0x6B54 0x6B58 0x6B59 0x6B5B 0x6B5C 0x6B5F 0x6B61 0x6B62 +0x6B63 0x6B64 0x6B65 0x6B66 0x6B67 0x6B69 0x6B6A 0x6B6C 0x6B6F 0x6B72 0x6B73 0x6B74 0x6B77 0x6B78 0x6B79 0x6B7A +0x6B7B 0x6B7C 0x6B7F 0x6B80 0x6B81 0x6B82 0x6B83 0x6B84 0x6B86 0x6B87 0x6B89 0x6B8A 0x6B8B 0x6B8D 0x6B92 0x6B93 +0x6B95 0x6B96 0x6B98 0x6B9A 0x6B9B 0x6B9E 0x6BA1 0x6BA2 0x6BA3 0x6BA4 0x6BAA 0x6BAB 0x6BAD 0x6BAE 0x6BAF 0x6BB1 +0x6BB2 0x6BB3 0x6BB4 0x6BB5 0x6BB7 0x6BBA 0x6BBB 0x6BBC 0x6BBD 0x6BBF 0x6BC0 0x6BC1 0x6BC2 0x6BC5 0x6BC6 0x6BCB +0x6BCC 0x6BCD 0x6BCE 0x6BCF 0x6BD0 0x6BD1 0x6BD2 0x6BD3 0x6BD4 0x6BD5 0x6BD6 0x6BD7 0x6BD8 0x6BD9 0x6BDA 0x6BDB +0x6BDF 0x6BE1 0x6BEA 0x6BEB 0x6BEC 0x6BEF 0x6BF3 0x6BF4 0x6BF5 0x6BF7 0x6BF9 0x6BFD 0x6BFF 0x6C02 0x6C05 0x6C06 +0x6C07 0x6C08 0x6C09 0x6C0A 0x6C0C 0x6C0D 0x6C0F 0x6C10 0x6C11 0x6C13 0x6C14 0x6C15 0x6C16 0x6C17 0x6C18 0x6C19 +0x6C1A 0x6C1B 0x6C1C 0x6C1D 0x6C1E 0x6C1F 0x6C20 0x6C21 0x6C22 0x6C23 0x6C24 0x6C25 0x6C26 0x6C27 0x6C28 0x6C29 +0x6C2A 0x6C2B 0x6C2C 0x6C2D 0x6C2E 0x6C2F 0x6C30 0x6C31 0x6C32 0x6C33 0x6C34 0x6C35 0x6C36 0x6C37 0x6C38 0x6C39 +0x6C3A 0x6C3B 0x6C3C 0x6C3D 0x6C3E 0x6C3F 0x6C40 0x6C41 0x6C42 0x6C43 0x6C46 0x6C47 0x6C48 0x6C49 0x6C4A 0x6C4B +0x6C4D 0x6C4E 0x6C4F 0x6C50 0x6C54 0x6C55 0x6C57 0x6C59 0x6C5A 0x6C5B 0x6C5C 0x6C5D 0x6C5E 0x6C5F 0x6C60 0x6C61 +0x6C62 0x6C64 0x6C67 0x6C68 0x6C69 0x6C6A 0x6C6B 0x6C6D 0x6C70 0x6C72 0x6C73 0x6C74 0x6C76 0x6C78 0x6C79 0x6C7A +0x6C7D 0x6C7E 0x6C81 0x6C82 0x6C83 0x6C84 0x6C85 0x6C86 0x6C87 0x6C88 0x6C89 0x6C8C 0x6C8D 0x6C8F 0x6C90 0x6C92 +0x6C93 0x6C94 0x6C95 0x6C96 0x6C98 0x6C99 0x6C9A 0x6C9B 0x6C9C 0x6C9F 0x6CA1 0x6CA2 0x6CA3 0x6CA4 0x6CA5 0x6CA6 +0x6CA7 0x6CA8 0x6CA9 0x6CAA 0x6CAB 0x6CAC 0x6CAD 0x6CAE 0x6CB1 0x6CB2 0x6CB3 0x6CB5 0x6CB8 0x6CB9 0x6CBA 0x6CBB +0x6CBC 0x6CBD 0x6CBE 0x6CBF 0x6CC1 0x6CC2 0x6CC3 0x6CC4 0x6CC5 0x6CC6 0x6CC7 0x6CC9 0x6CCA 0x6CCC 0x6CD0 0x6CD3 +0x6CD4 0x6CD5 0x6CD6 0x6CD7 0x6CD9 0x6CDA 0x6CDB 0x6CDC 0x6CDD 0x6CDE 0x6CE0 0x6CE1 0x6CE2 0x6CE3 0x6CE5 0x6CE8 +0x6CEA 0x6CEB 0x6CEE 0x6CEF 0x6CF0 0x6CF1 0x6CF3 0x6CF5 0x6CF6 0x6CF7 0x6CF8 0x6CFA 0x6CFB 0x6CFC 0x6CFD 0x6CFE +0x6D01 0x6D04 0x6D05 0x6D07 0x6D08 0x6D0B 0x6D0C 0x6D0D 0x6D0E 0x6D10 0x6D11 0x6D12 0x6D13 0x6D16 0x6D17 0x6D18 +0x6D19 0x6D1A 0x6D1B 0x6D1E 0x6D1F 0x6D22 0x6D23 0x6D25 0x6D27 0x6D28 0x6D29 0x6D2A 0x6D2B 0x6D2D 0x6D2E 0x6D31 +0x6D32 0x6D33 0x6D34 0x6D35 0x6D36 0x6D38 0x6D39 0x6D3A 0x6D3B 0x6D3C 0x6D3D 0x6D3E 0x6D3F 0x6D41 0x6D43 0x6D44 +0x6D45 0x6D46 0x6D47 0x6D48 0x6D49 0x6D4A 0x6D4B 0x6D4D 0x6D4E 0x6D4F 0x6D50 0x6D51 0x6D52 0x6D53 0x6D54 0x6D55 +0x6D59 0x6D5A 0x6D5B 0x6D5C 0x6D5E 0x6D5F 0x6D60 0x6D61 0x6D63 0x6D64 0x6D65 0x6D66 0x6D69 0x6D6A 0x6D6C 0x6D6D +0x6D6E 0x6D6F 0x6D70 0x6D72 0x6D74 0x6D77 0x6D78 0x6D79 0x6D7B 0x6D7C 0x6D7F 0x6D82 0x6D84 0x6D85 0x6D87 0x6D88 +0x6D89 0x6D8A 0x6D8C 0x6D8D 0x6D8E 0x6D8F 0x6D90 0x6D91 0x6D93 0x6D94 0x6D95 0x6D97 0x6D98 0x6D99 0x6D9A 0x6D9B +0x6D9C 0x6D9D 0x6D9E 0x6D9F 0x6DA0 0x6DA1 0x6DA2 0x6DA3 0x6DA4 0x6DA6 0x6DA7 0x6DA8 0x6DA9 0x6DAA 0x6DAB 0x6DAD +0x6DAE 0x6DAF 0x6DB2 0x6DB4 0x6DB5 0x6DB7 0x6DB8 0x6DBC 0x6DBF 0x6DC0 0x6DC3 0x6DC4 0x6DC5 0x6DC6 0x6DC7 0x6DCB +0x6DCC 0x6DCD 0x6DCF 0x6DD1 0x6DD2 0x6DD5 0x6DD6 0x6DD8 0x6DD9 0x6DDA 0x6DDC 0x6DDD 0x6DDE 0x6DDF 0x6DE0 0x6DE1 +0x6DE4 0x6DE5 0x6DE6 0x6DE8 0x6DE9 0x6DEA 0x6DEB 0x6DEC 0x6DEE 0x6DEF 0x6DF1 0x6DF3 0x6DF4 0x6DF5 0x6DF6 0x6DF7 +0x6DF8 0x6DF9 0x6DFA 0x6DFB 0x6DFC 0x6DFD 0x6E05 0x6E07 0x6E08 0x6E09 0x6E0A 0x6E0B 0x6E0C 0x6E0D 0x6E0E 0x6E10 +0x6E11 0x6E13 0x6E14 0x6E15 0x6E16 0x6E17 0x6E19 0x6E1A 0x6E1B 0x6E1D 0x6E1F 0x6E20 0x6E21 0x6E22 0x6E23 0x6E24 +0x6E25 0x6E26 0x6E29 0x6E2B 0x6E2C 0x6E2D 0x6E2E 0x6E2F 0x6E30 0x6E32 0x6E34 0x6E36 0x6E38 0x6E3A 0x6E3C 0x6E3D +0x6E3E 0x6E43 0x6E44 0x6E49 0x6E4A 0x6E4B 0x6E4D 0x6E4E 0x6E51 0x6E53 0x6E54 0x6E56 0x6E58 0x6E5B 0x6E5C 0x6E5D +0x6E5E 0x6E5F 0x6E61 0x6E62 0x6E63 0x6E66 0x6E67 0x6E68 0x6E69 0x6E6A 0x6E6B 0x6E6E 0x6E6F 0x6E72 0x6E73 0x6E74 +0x6E76 0x6E7A 0x6E7B 0x6E7E 0x6E7F 0x6E80 0x6E81 0x6E82 0x6E83 0x6E85 0x6E86 0x6E87 0x6E88 0x6E89 0x6E8C 0x6E8D +0x6E8E 0x6E8F 0x6E90 0x6E96 0x6E98 0x6E9A 0x6E9C 0x6E9D 0x6E9E 0x6E9F 0x6EA0 0x6EA2 0x6EA5 0x6EA6 0x6EA7 0x6EAA +0x6EAB 0x6EAE 0x6EAF 0x6EB1 0x6EB2 0x6EB3 0x6EB4 0x6EB5 0x6EB6 0x6EB7 0x6EB9 0x6EBA 0x6EBB 0x6EBC 0x6EBD 0x6EC1 +0x6EC2 0x6EC3 0x6EC4 0x6EC5 0x6EC6 0x6EC7 0x6EC8 0x6EC9 0x6ECB 0x6ECC 0x6ECD 0x6ECE 0x6ECF 0x6ED1 0x6ED3 0x6ED4 +0x6ED5 0x6ED7 0x6ED8 0x6ED9 0x6EDA 0x6EDD 0x6EDE 0x6EDF 0x6EE0 0x6EE1 0x6EE2 0x6EE4 0x6EE5 0x6EE6 0x6EE7 0x6EE8 +0x6EE9 0x6EEA 0x6EEB 0x6EEC 0x6EEE 0x6EEF 0x6EF2 0x6EF4 0x6EF7 0x6EF8 0x6EF9 0x6EFB 0x6EFE 0x6EFF 0x6F01 0x6F02 +0x6F06 0x6F08 0x6F09 0x6F0A 0x6F0B 0x6F0C 0x6F0D 0x6F0F 0x6F11 0x6F13 0x6F14 0x6F15 0x6F16 0x6F1A 0x6F20 0x6F22 +0x6F23 0x6F24 0x6F25 0x6F26 0x6F27 0x6F29 0x6F2A 0x6F2B 0x6F2C 0x6F2D 0x6F2F 0x6F30 0x6F31 0x6F32 0x6F33 0x6F34 +0x6F35 0x6F36 0x6F37 0x6F38 0x6F39 0x6F3B 0x6F3C 0x6F3E 0x6F3F 0x6F41 0x6F45 0x6F46 0x6F47 0x6F4A 0x6F4B 0x6F4D +0x6F4F 0x6F51 0x6F54 0x6F55 0x6F56 0x6F57 0x6F58 0x6F59 0x6F5A 0x6F5B 0x6F5C 0x6F5E 0x6F5F 0x6F60 0x6F62 0x6F63 +0x6F64 0x6F66 0x6F69 0x6F6D 0x6F6E 0x6F6F 0x6F70 0x6F72 0x6F74 0x6F75 0x6F76 0x6F77 0x6F78 0x6F7A 0x6F7C 0x6F7D +0x6F7E 0x6F7F 0x6F80 0x6F81 0x6F82 0x6F84 0x6F86 0x6F87 0x6F88 0x6F89 0x6F8C 0x6F8D 0x6F8E 0x6F90 0x6F91 0x6F92 +0x6F94 0x6F97 0x6F9B 0x6F9C 0x6FA0 0x6FA1 0x6FA3 0x6FA4 0x6FA5 0x6FA6 0x6FA7 0x6FA8 0x6FA9 0x6FAA 0x6FAB 0x6FAD +0x6FAE 0x6FAF 0x6FB1 0x6FB3 0x6FB4 0x6FB6 0x6FB9 0x6FBC 0x6FBD 0x6FBE 0x6FC0 0x6FC1 0x6FC2 0x6FC3 0x6FC6 0x6FC7 +0x6FC9 0x6FCA 0x6FCB 0x6FD1 0x6FD2 0x6FD4 0x6FD5 0x6FD8 0x6FDA 0x6FDB 0x6FDC 0x6FDE 0x6FDF 0x6FE0 0x6FE1 0x6FE4 +0x6FE8 0x6FE9 0x6FEB 0x6FEC 0x6FEE 0x6FEF 0x6FF0 0x6FF1 0x6FF3 0x6FF6 0x6FFA 0x6FFC 0x6FFE 0x7001 0x7002 0x7005 +0x7006 0x7009 0x700B 0x700C 0x700D 0x700F 0x7011 0x7014 0x7015 0x7018 0x701A 0x701B 0x701C 0x701D 0x701E 0x701F +0x7020 0x7021 0x7023 0x7026 0x7027 0x7028 0x702C 0x702F 0x7030 0x7031 0x7032 0x7035 0x7037 0x7039 0x703C 0x703E +0x7043 0x7044 0x7048 0x704C 0x704F 0x7050 0x7051 0x7054 0x7055 0x7058 0x705D 0x705E 0x7060 0x7063 0x7064 0x7065 +0x7067 0x7069 0x706B 0x706C 0x706D 0x706F 0x7070 0x7074 0x7075 0x7076 0x7078 0x707A 0x707C 0x707D 0x707E 0x707F +0x7080 0x7081 0x7085 0x7086 0x7089 0x708A 0x708C 0x708E 0x7092 0x7094 0x7095 0x7096 0x7098 0x7099 0x709A 0x709C +0x709D 0x709E 0x709F 0x70A1 0x70A3 0x70A4 0x70A9 0x70AB 0x70AC 0x70AD 0x70AE 0x70AF 0x70B0 0x70B1 0x70B3 0x70B5 +0x70B7 0x70B8 0x70B9 0x70BA 0x70BB 0x70BC 0x70BD 0x70C0 0x70C1 0x70C2 0x70C3 0x70C7 0x70C8 0x70CA 0x70CB 0x70CE +0x70CF 0x70D3 0x70D4 0x70D8 0x70D9 0x70DA 0x70DB 0x70DC 0x70DD 0x70DF 0x70E0 0x70E4 0x70E6 0x70E7 0x70E8 0x70E9 +0x70EB 0x70EC 0x70ED 0x70EF 0x70F1 0x70F4 0x70F6 0x70F7 0x70F9 0x70FA 0x70FB 0x70FD 0x7104 0x7106 0x7109 0x710A +0x710C 0x7110 0x7113 0x7114 0x7115 0x7116 0x7117 0x7118 0x7119 0x711A 0x711C 0x711E 0x7120 0x7121 0x7122 0x7126 +0x712E 0x712F 0x7130 0x7131 0x7136 0x713A 0x713C 0x713F 0x7140 0x7141 0x7143 0x7145 0x7146 0x7147 0x7149 0x714A +0x714B 0x714C 0x714E 0x714F 0x7150 0x7151 0x7152 0x7153 0x7155 0x7156 0x7159 0x715A 0x715C 0x715E 0x715F 0x7162 +0x7163 0x7164 0x7165 0x7166 0x7167 0x7168 0x7169 0x716C 0x716E 0x7172 0x7173 0x7174 0x7178 0x717A 0x717D 0x717F +0x7180 0x7184 0x7185 0x7187 0x7188 0x7189 0x718A 0x718F 0x7190 0x7192 0x7194 0x7195 0x7197 0x7198 0x7199 0x719B +0x719C 0x719F 0x71A0 0x71A2 0x71A5 0x71A8 0x71AC 0x71AF 0x71B0 0x71B1 0x71B2 0x71B3 0x71B5 0x71B9 0x71BA 0x71BB +0x71BE 0x71C0 0x71C1 0x71C3 0x71C4 0x71C8 0x71C9 0x71CA 0x71CB 0x71CE 0x71CF 0x71D0 0x71D2 0x71D4 0x71D5 0x71D6 +0x71D7 0x71D9 0x71DA 0x71DC 0x71DF 0x71E0 0x71E1 0x71E5 0x71E6 0x71E7 0x71EC 0x71ED 0x71EE 0x71F4 0x71F5 0x71F6 +0x71F8 0x71F9 0x71FB 0x71FC 0x71FE 0x71FF 0x7200 0x7201 0x7206 0x7207 0x720C 0x720D 0x7210 0x7213 0x7214 0x7215 +0x721A 0x721B 0x721D 0x721F 0x7228 0x722A 0x722B 0x722C 0x722D 0x7230 0x7231 0x7232 0x7235 0x7236 0x7237 0x7238 +0x7239 0x723A 0x723B 0x723C 0x723D 0x723E 0x723F 0x7240 0x7241 0x7242 0x7246 0x7247 0x7248 0x724B 0x724C 0x724D +0x7252 0x7256 0x7258 0x7259 0x725A 0x725B 0x725D 0x725E 0x725F 0x7260 0x7261 0x7262 0x7263 0x7264 0x7265 0x7266 +0x7267 0x7269 0x726E 0x726F 0x7272 0x7274 0x7275 0x7277 0x7278 0x7279 0x727A 0x727B 0x727D 0x727E 0x727F 0x7280 +0x7281 0x7282 0x7284 0x7287 0x728A 0x728B 0x728D 0x728F 0x7292 0x7296 0x7297 0x729B 0x729F 0x72A0 0x72A1 0x72A2 +0x72A7 0x72A8 0x72AC 0x72AD 0x72AE 0x72AF 0x72B0 0x72B2 0x72B4 0x72B6 0x72B7 0x72B8 0x72B9 0x72BC 0x72C0 0x72C1 +0x72C2 0x72C3 0x72C4 0x72C6 0x72C8 0x72C9 0x72CD 0x72CE 0x72D0 0x72D2 0x72D3 0x72D7 0x72D9 0x72DB 0x72DD 0x72DE +0x72DF 0x72E0 0x72E1 0x72E2 0x72E8 0x72E9 0x72EC 0x72ED 0x72EE 0x72EF 0x72F0 0x72F1 0x72F2 0x72F3 0x72F4 0x72F7 +0x72F8 0x72F9 0x72FA 0x72FB 0x72FC 0x72FD 0x7301 0x7303 0x7304 0x7306 0x7307 0x730A 0x730B 0x730E 0x7313 0x7314 +0x7315 0x7316 0x7317 0x7319 0x731B 0x731C 0x731D 0x731E 0x731F 0x7321 0x7322 0x7325 0x7329 0x732A 0x732B 0x732C +0x732E 0x732F 0x7330 0x7331 0x7334 0x7336 0x7337 0x7338 0x7339 0x733A 0x733B 0x733E 0x733F 0x7341 0x7343 0x7344 +0x7345 0x7347 0x734D 0x734E 0x734F 0x7350 0x7352 0x7355 0x7357 0x735A 0x735B 0x7360 0x7362 0x7363 0x7364 0x7368 +0x736A 0x736B 0x736C 0x736D 0x736E 0x736F 0x7370 0x7372 0x7374 0x7375 0x7377 0x7378 0x737A 0x737B 0x737C 0x737E +0x7380 0x7381 0x7383 0x7384 0x7386 0x7387 0x7389 0x738A 0x738B 0x738E 0x738F 0x7391 0x7392 0x7393 0x7394 0x7395 +0x7396 0x7397 0x7398 0x7399 0x739A 0x739B 0x739E 0x739F 0x73A0 0x73A1 0x73A2 0x73A4 0x73A5 0x73A6 0x73A7 0x73A8 +0x73A9 0x73AB 0x73AD 0x73AE 0x73AF 0x73B0 0x73B1 0x73B2 0x73B3 0x73B5 0x73B6 0x73B7 0x73B9 0x73BA 0x73BB 0x73BC +0x73BD 0x73BF 0x73C0 0x73C2 0x73C3 0x73C4 0x73C5 0x73C7 0x73C8 0x73C9 0x73CA 0x73CB 0x73CC 0x73CD 0x73CE 0x73CF +0x73D0 0x73D1 0x73D2 0x73D5 0x73D6 0x73D7 0x73D9 0x73DB 0x73DD 0x73DE 0x73E0 0x73E1 0x73E2 0x73E3 0x73E4 0x73E5 +0x73E6 0x73E7 0x73E8 0x73E9 0x73EA 0x73EB 0x73ED 0x73EE 0x73F0 0x73F1 0x73F2 0x73F5 0x73F6 0x73F7 0x73F8 0x73F9 +0x73FA 0x73FD 0x73FE 0x7400 0x7401 0x7402 0x7403 0x7404 0x7405 0x7406 0x7407 0x7408 0x7409 0x740A 0x740D 0x740E +0x740F 0x7410 0x7413 0x7414 0x7415 0x741A 0x741B 0x741E 0x741F 0x7420 0x7421 0x7422 0x7424 0x7425 0x7426 0x7428 +0x742A 0x742B 0x742C 0x742D 0x742E 0x742F 0x7430 0x7431 0x7432 0x7433 0x7434 0x7435 0x7436 0x7437 0x7438 0x743A +0x743C 0x743F 0x7440 0x7441 0x7442 0x7443 0x7444 0x7445 0x7446 0x744A 0x744B 0x744C 0x7451 0x7452 0x7453 0x7454 +0x7455 0x7456 0x7457 0x7459 0x745A 0x745B 0x745C 0x745D 0x745E 0x745F 0x7460 0x7462 0x7463 0x7464 0x7465 0x7467 +0x7468 0x7469 0x746A 0x746C 0x746D 0x746F 0x7470 0x7471 0x7472 0x7473 0x7476 0x7477 0x7478 0x747D 0x747E 0x7480 +0x7481 0x7482 0x7483 0x7486 0x7487 0x7488 0x7489 0x748A 0x748B 0x748E 0x748F 0x7490 0x7492 0x7495 0x7497 0x7498 +0x749C 0x749E 0x749F 0x74A0 0x74A1 0x74A2 0x74A3 0x74A4 0x74A5 0x74A6 0x74A7 0x74A8 0x74A9 0x74AA 0x74AB 0x74AC +0x74AE 0x74B0 0x74B1 0x74B2 0x74B5 0x74B8 0x74B9 0x74BA 0x74BD 0x74BF 0x74C0 0x74C5 0x74C6 0x74C8 0x74CA 0x74CC +0x74CF 0x74D2 0x74D3 0x74D4 0x74D6 0x74D8 0x74DA 0x74DB 0x74DC 0x74DE 0x74E0 0x74E2 0x74E3 0x74E4 0x74E6 0x74E7 +0x74E9 0x74EE 0x74EF 0x74F0 0x74F1 0x74F2 0x74F4 0x74F6 0x74F7 0x74F8 0x74FB 0x74FF 0x7501 0x7503 0x7504 0x7505 +0x7507 0x750C 0x750D 0x750E 0x750F 0x7511 0x7513 0x7515 0x7516 0x7517 0x7518 0x7519 0x751A 0x751B 0x751C 0x751D +0x751E 0x751F 0x7521 0x7522 0x7523 0x7525 0x7526 0x7528 0x7529 0x752A 0x752B 0x752C 0x752D 0x752E 0x752F 0x7530 +0x7531 0x7532 0x7533 0x7534 0x7535 0x7537 0x7538 0x7539 0x753A 0x753B 0x753C 0x753D 0x753E 0x753F 0x7540 0x7544 +0x7545 0x7546 0x7547 0x7548 0x7549 0x754A 0x754B 0x754C 0x754D 0x754E 0x754F 0x7551 0x7553 0x7554 0x7556 0x7559 +0x755A 0x755B 0x755C 0x755D 0x755F 0x7560 0x7562 0x7563 0x7564 0x7565 0x7566 0x7567 0x7569 0x756A 0x756B 0x756C +0x756D 0x756F 0x7570 0x7572 0x7573 0x7574 0x7575 0x7576 0x7577 0x7578 0x7579 0x757A 0x757D 0x757E 0x757F 0x7580 +0x7581 0x7582 0x7583 0x7584 0x7586 0x7587 0x7589 0x758A 0x758B 0x758C 0x758D 0x758E 0x758F 0x7590 0x7591 0x7592 +0x7594 0x7595 0x7596 0x7597 0x7598 0x7599 0x759A 0x759D 0x759F 0x75A0 0x75A1 0x75A2 0x75A3 0x75A4 0x75A5 0x75A7 +0x75AA 0x75AB 0x75AC 0x75AD 0x75AE 0x75AF 0x75B0 0x75B1 0x75B2 0x75B3 0x75B4 0x75B5 0x75B6 0x75B8 0x75B9 0x75BA +0x75BB 0x75BC 0x75BD 0x75BE 0x75BF 0x75C0 0x75C1 0x75C2 0x75C3 0x75C4 0x75C5 0x75C7 0x75C8 0x75C9 0x75CA 0x75CB +0x75CC 0x75CD 0x75CE 0x75CF 0x75D0 0x75D1 0x75D2 0x75D3 0x75D4 0x75D5 0x75D6 0x75D7 0x75D8 0x75D9 0x75DA 0x75DB +0x75DD 0x75DE 0x75DF 0x75E0 0x75E1 0x75E2 0x75E3 0x75E4 0x75E6 0x75E7 0x75E8 0x75E9 0x75EA 0x75EB 0x75ED 0x75EF +0x75F0 0x75F1 0x75F2 0x75F3 0x75F4 0x75F5 0x75F6 0x75F7 0x75F8 0x75F9 0x75FA 0x75FB 0x75FC 0x75FD 0x75FE 0x75FF +0x7600 0x7601 0x7602 0x7603 0x7604 0x7605 0x7606 0x7608 0x7609 0x760A 0x760B 0x760C 0x760D 0x760F 0x7610 0x7611 +0x7613 0x7614 0x7615 0x7616 0x7617 0x7618 0x7619 0x761A 0x761B 0x761C 0x761D 0x761E 0x761F 0x7620 0x7621 0x7622 +0x7623 0x7624 0x7625 0x7626 0x7627 0x7628 0x7629 0x762A 0x762B 0x762D 0x762E 0x762F 0x7630 0x7631 0x7632 0x7633 +0x7634 0x7635 0x7638 0x763A 0x763B 0x763C 0x763D 0x763E 0x763F 0x7640 0x7642 0x7643 0x7646 0x7647 0x7648 0x7649 +0x764C 0x764D 0x764E 0x7650 0x7652 0x7653 0x7654 0x7656 0x7657 0x7658 0x7659 0x765A 0x765C 0x765E 0x765F 0x7660 +0x7661 0x7662 0x7663 0x7664 0x7665 0x7666 0x7667 0x7668 0x7669 0x766A 0x766B 0x766C 0x766D 0x766E 0x766F 0x7670 +0x7671 0x7672 0x7675 0x7676 0x7678 0x7679 0x767A 0x767B 0x767C 0x767D 0x767E 0x767F 0x7680 0x7681 0x7682 0x7683 +0x7684 0x7686 0x7687 0x7688 0x7689 0x768A 0x768B 0x768E 0x768F 0x7690 0x7691 0x7692 0x7693 0x7695 0x7696 0x7699 +0x769A 0x769B 0x769C 0x769D 0x769E 0x76A4 0x76A6 0x76AA 0x76AB 0x76AD 0x76AE 0x76AF 0x76B0 0x76B1 0x76B2 0x76B4 +0x76B5 0x76B6 0x76B7 0x76B8 0x76B9 0x76BA 0x76BB 0x76BD 0x76BE 0x76BF 0x76C2 0x76C3 0x76C4 0x76C5 0x76C6 0x76C8 +0x76C9 0x76CA 0x76CC 0x76CD 0x76CE 0x76CF 0x76D0 0x76D1 0x76D2 0x76D3 0x76D4 0x76D6 0x76D7 0x76D8 0x76DA 0x76DB +0x76DC 0x76DD 0x76DE 0x76DF 0x76E1 0x76E3 0x76E4 0x76E5 0x76E6 0x76E7 0x76E8 0x76E9 0x76EA 0x76EC 0x76ED 0x76EE +0x76EF 0x76F0 0x76F1 0x76F2 0x76F3 0x76F4 0x76F5 0x76F7 0x76F8 0x76F9 0x76FA 0x76FB 0x76FC 0x76FE 0x7701 0x7704 +0x7707 0x7708 0x7709 0x770A 0x770B 0x770C 0x770D 0x7712 0x7715 0x7719 0x771A 0x771B 0x771C 0x771E 0x771F 0x7720 +0x7722 0x7724 0x7725 0x7726 0x7728 0x7729 0x772C 0x772D 0x772F 0x7735 0x7736 0x7737 0x7738 0x773A 0x773C 0x773D +0x773E 0x7740 0x7741 0x7743 0x7744 0x7746 0x7747 0x774D 0x774E 0x774F 0x7750 0x7751 0x7752 0x775A 0x775B 0x775C +0x775E 0x7761 0x7762 0x7763 0x7765 0x7766 0x7768 0x7769 0x776A 0x776B 0x776C 0x7779 0x777A 0x777D 0x777E 0x777F +0x7780 0x7784 0x7785 0x7786 0x7787 0x778B 0x778C 0x778D 0x778E 0x778F 0x7791 0x7792 0x7793 0x7798 0x779A 0x779C +0x779E 0x779F 0x77A0 0x77A2 0x77A4 0x77A5 0x77A7 0x77A9 0x77AA 0x77AB 0x77AC 0x77AD 0x77B0 0x77B3 0x77B5 0x77B6 +0x77B7 0x77B9 0x77BB 0x77BC 0x77BD 0x77BF 0x77C7 0x77CB 0x77CD 0x77CE 0x77D3 0x77D7 0x77DA 0x77DB 0x77DC 0x77DE +0x77E2 0x77E3 0x77E5 0x77E7 0x77E9 0x77EB 0x77EC 0x77ED 0x77EE 0x77EF 0x77F0 0x77F3 0x77F4 0x77F6 0x77F7 0x77F8 +0x77F9 0x77FA 0x77FB 0x77FC 0x77FD 0x77FE 0x77FF 0x7800 0x7801 0x7802 0x7803 0x7804 0x7805 0x7806 0x7807 0x7808 +0x7809 0x780C 0x780D 0x780E 0x780F 0x7810 0x7811 0x7812 0x7813 0x7814 0x7815 0x7816 0x7817 0x7818 0x781A 0x781C +0x781D 0x781F 0x7820 0x7821 0x7822 0x7823 0x7825 0x7826 0x7827 0x7828 0x7829 0x782A 0x782B 0x782C 0x782D 0x782E +0x782F 0x7830 0x7831 0x7832 0x7833 0x7834 0x7835 0x7837 0x7838 0x7839 0x783A 0x783B 0x783C 0x783E 0x783F 0x7840 +0x7841 0x7843 0x7845 0x7847 0x7848 0x7849 0x784A 0x784B 0x784C 0x784D 0x784E 0x784F 0x7850 0x7852 0x7853 0x7854 +0x7855 0x7856 0x7857 0x7859 0x785A 0x785C 0x785D 0x785E 0x7860 0x7862 0x7864 0x7865 0x7866 0x7868 0x7869 0x786A +0x786B 0x786C 0x786D 0x786E 0x786F 0x7870 0x7871 0x7872 0x7874 0x7875 0x7877 0x7879 0x787B 0x787C 0x787E 0x787F +0x7880 0x7881 0x7883 0x7884 0x7885 0x7886 0x7887 0x7888 0x7889 0x788C 0x788D 0x788E 0x788F 0x7891 0x7893 0x7894 +0x7895 0x7896 0x7897 0x7898 0x789A 0x789B 0x789C 0x789F 0x78A1 0x78A3 0x78A5 0x78A7 0x78A8 0x78A9 0x78AA 0x78AD +0x78AF 0x78B0 0x78B1 0x78B2 0x78B3 0x78B4 0x78B5 0x78B6 0x78B8 0x78B9 0x78BA 0x78BB 0x78BC 0x78BE 0x78C1 0x78C5 +0x78C6 0x78C8 0x78C9 0x78CA 0x78CB 0x78CE 0x78CF 0x78D0 0x78D1 0x78D4 0x78D5 0x78D8 0x78D9 0x78DA 0x78DC 0x78E0 +0x78E1 0x78E2 0x78E3 0x78E7 0x78E8 0x78EC 0x78EF 0x78F2 0x78F4 0x78F5 0x78F7 0x78F9 0x78FA 0x78FB 0x78FD 0x78FE +0x7901 0x7903 0x7904 0x7905 0x7906 0x7907 0x790C 0x790E 0x7910 0x7911 0x7912 0x7913 0x7916 0x7919 0x791E 0x7921 +0x7924 0x7926 0x792A 0x792B 0x792C 0x7931 0x7933 0x7934 0x7935 0x793A 0x793B 0x793C 0x793D 0x793E 0x7940 0x7941 +0x7942 0x7943 0x7945 0x7946 0x7947 0x7948 0x7949 0x794A 0x794B 0x794E 0x794F 0x7950 0x7953 0x7955 0x7956 0x7957 +0x795A 0x795B 0x795C 0x795D 0x795E 0x795F 0x7960 0x7962 0x7965 0x7967 0x7968 0x7969 0x796B 0x796D 0x796F 0x7972 +0x7977 0x7978 0x797A 0x797C 0x797E 0x797F 0x7980 0x7981 0x7984 0x7985 0x798A 0x798B 0x798D 0x798E 0x798F 0x7991 +0x7992 0x7994 0x7995 0x7998 0x799A 0x799B 0x799D 0x799F 0x79A0 0x79A1 0x79A4 0x79A5 0x79A6 0x79A7 0x79A9 0x79AA +0x79AE 0x79B0 0x79B1 0x79B3 0x79B8 0x79B9 0x79BA 0x79BB 0x79BD 0x79BE 0x79BF 0x79C0 0x79C1 0x79C2 0x79C3 0x79C6 +0x79C8 0x79C9 0x79CA 0x79CB 0x79CD 0x79CF 0x79D1 0x79D2 0x79D5 0x79D8 0x79DD 0x79DE 0x79DF 0x79E1 0x79E3 0x79E4 +0x79E6 0x79E7 0x79E9 0x79EB 0x79EC 0x79ED 0x79EF 0x79F0 0x79F8 0x79FB 0x79FD 0x79FE 0x7A00 0x7A02 0x7A03 0x7A04 +0x7A05 0x7A06 0x7A08 0x7A09 0x7A0B 0x7A0C 0x7A0D 0x7A0E 0x7A11 0x7A14 0x7A16 0x7A17 0x7A18 0x7A19 0x7A1A 0x7A1C +0x7A1E 0x7A1F 0x7A20 0x7A23 0x7A26 0x7A2E 0x7A31 0x7A32 0x7A33 0x7A36 0x7A37 0x7A39 0x7A3B 0x7A3C 0x7A3D 0x7A3E +0x7A3F 0x7A40 0x7A42 0x7A43 0x7A44 0x7A46 0x7A47 0x7A49 0x7A4B 0x7A4C 0x7A4D 0x7A4E 0x7A4F 0x7A50 0x7A51 0x7A57 +0x7A59 0x7A5C 0x7A5E 0x7A5F 0x7A60 0x7A61 0x7A62 0x7A63 0x7A66 0x7A68 0x7A69 0x7A6B 0x7A6D 0x7A70 0x7A74 0x7A75 +0x7A76 0x7A77 0x7A78 0x7A79 0x7A7A 0x7A7D 0x7A7F 0x7A80 0x7A81 0x7A83 0x7A84 0x7A85 0x7A86 0x7A88 0x7A8A 0x7A8D +0x7A8E 0x7A91 0x7A92 0x7A93 0x7A95 0x7A96 0x7A97 0x7A98 0x7A9C 0x7A9D 0x7A9F 0x7AA0 0x7AA3 0x7AA5 0x7AA6 0x7AA8 +0x7AA9 0x7AAA 0x7AAC 0x7AAD 0x7AAE 0x7AAF 0x7AB0 0x7AB3 0x7AB5 0x7AB6 0x7AB8 0x7ABA 0x7ABE 0x7ABF 0x7AC3 0x7AC4 +0x7AC5 0x7AC7 0x7AC8 0x7ACA 0x7ACB 0x7ACD 0x7ACF 0x7AD1 0x7AD2 0x7AD3 0x7AD5 0x7AD6 0x7AD7 0x7AD8 0x7AD9 0x7ADA +0x7ADC 0x7ADD 0x7ADE 0x7ADF 0x7AE0 0x7AE1 0x7AE2 0x7AE3 0x7AE5 0x7AE6 0x7AEA 0x7AEB 0x7AED 0x7AEF 0x7AF0 0x7AF6 +0x7AF7 0x7AF8 0x7AF9 0x7AFA 0x7AFD 0x7AFF 0x7B02 0x7B03 0x7B04 0x7B06 0x7B08 0x7B0A 0x7B0B 0x7B0F 0x7B11 0x7B14 +0x7B15 0x7B18 0x7B19 0x7B1B 0x7B1E 0x7B20 0x7B24 0x7B25 0x7B26 0x7B28 0x7B2A 0x7B2B 0x7B2C 0x7B2D 0x7B2E 0x7B2F +0x7B31 0x7B33 0x7B35 0x7B36 0x7B38 0x7B39 0x7B3A 0x7B3C 0x7B3E 0x7B40 0x7B45 0x7B46 0x7B47 0x7B48 0x7B49 0x7B4A +0x7B4B 0x7B4C 0x7B4D 0x7B4E 0x7B4F 0x7B50 0x7B51 0x7B52 0x7B54 0x7B56 0x7B58 0x7B5A 0x7B5B 0x7B5C 0x7B5D 0x7B60 +0x7B62 0x7B64 0x7B65 0x7B66 0x7B67 0x7B69 0x7B6C 0x7B6E 0x7B6F 0x7B70 0x7B71 0x7B72 0x7B74 0x7B75 0x7B76 0x7B77 +0x7B79 0x7B7A 0x7B7B 0x7B7C 0x7B7D 0x7B7E 0x7B7F 0x7B80 0x7B84 0x7B85 0x7B86 0x7B87 0x7B8B 0x7B8D 0x7B8E 0x7B8F +0x7B90 0x7B92 0x7B93 0x7B94 0x7B95 0x7B96 0x7B97 0x7B98 0x7B99 0x7B9A 0x7B9C 0x7B9D 0x7B9F 0x7BA0 0x7BA1 0x7BA2 +0x7BA3 0x7BA6 0x7BA7 0x7BA8 0x7BA9 0x7BAA 0x7BAB 0x7BAC 0x7BAD 0x7BB1 0x7BB4 0x7BB8 0x7BC0 0x7BC1 0x7BC4 0x7BC6 +0x7BC7 0x7BC9 0x7BCB 0x7BCC 0x7BCF 0x7BD1 0x7BD2 0x7BD3 0x7BD4 0x7BD9 0x7BDA 0x7BDB 0x7BDD 0x7BE0 0x7BE1 0x7BE2 +0x7BE4 0x7BE5 0x7BE6 0x7BE9 0x7BEA 0x7BED 0x7BEE 0x7BEF 0x7BF0 0x7BF1 0x7BF2 0x7BF3 0x7BF6 0x7BF7 0x7BFC 0x7BFE +0x7C00 0x7C03 0x7C07 0x7C09 0x7C0B 0x7C0C 0x7C0D 0x7C0F 0x7C11 0x7C12 0x7C13 0x7C14 0x7C15 0x7C16 0x7C17 0x7C1D +0x7C1E 0x7C1F 0x7C20 0x7C21 0x7C23 0x7C26 0x7C27 0x7C29 0x7C2A 0x7C2B 0x7C30 0x7C37 0x7C38 0x7C39 0x7C3D 0x7C3E +0x7C3F 0x7C40 0x7C41 0x7C43 0x7C4C 0x7C4D 0x7C4F 0x7C50 0x7C53 0x7C54 0x7C56 0x7C57 0x7C58 0x7C59 0x7C5B 0x7C5C +0x7C5D 0x7C5F 0x7C60 0x7C63 0x7C64 0x7C65 0x7C69 0x7C6A 0x7C6C 0x7C6E 0x7C72 0x7C73 0x7C74 0x7C75 0x7C78 0x7C79 +0x7C7B 0x7C7C 0x7C7D 0x7C7E 0x7C81 0x7C82 0x7C83 0x7C84 0x7C89 0x7C8B 0x7C8D 0x7C90 0x7C91 0x7C92 0x7C95 0x7C97 +0x7C98 0x7C9B 0x7C9C 0x7C9D 0x7C9E 0x7C9F 0x7CA1 0x7CA2 0x7CA4 0x7CA5 0x7CA6 0x7CA7 0x7CA8 0x7CAA 0x7CAB 0x7CAC +0x7CAD 0x7CAE 0x7CB1 0x7CB2 0x7CB3 0x7CB5 0x7CB9 0x7CBA 0x7CBC 0x7CBD 0x7CBE 0x7CBF 0x7CC0 0x7CC1 0x7CC2 0x7CC4 +0x7CC5 0x7CC7 0x7CC8 0x7CC9 0x7CCA 0x7CCC 0x7CCD 0x7CCE 0x7CD2 0x7CD5 0x7CD6 0x7CD7 0x7CD8 0x7CD9 0x7CDC 0x7CDD +0x7CDE 0x7CDF 0x7CE0 0x7CE2 0x7CE7 0x7CE8 0x7CEC 0x7CED 0x7CEF 0x7CF0 0x7CF2 0x7CF4 0x7CF5 0x7CF6 0x7CF8 0x7CF9 +0x7CFA 0x7CFB 0x7CFE 0x7D00 0x7D02 0x7D03 0x7D04 0x7D05 0x7D06 0x7D07 0x7D08 0x7D09 0x7D0A 0x7D0B 0x7D0D 0x7D10 +0x7D11 0x7D13 0x7D14 0x7D15 0x7D16 0x7D17 0x7D18 0x7D19 0x7D1A 0x7D1B 0x7D1C 0x7D1D 0x7D1E 0x7D20 0x7D21 0x7D22 +0x7D27 0x7D2B 0x7D2C 0x7D2E 0x7D2F 0x7D30 0x7D31 0x7D32 0x7D33 0x7D35 0x7D39 0x7D3A 0x7D3C 0x7D3F 0x7D40 0x7D42 +0x7D43 0x7D44 0x7D45 0x7D46 0x7D4B 0x7D4C 0x7D4E 0x7D4F 0x7D50 0x7D53 0x7D55 0x7D56 0x7D5A 0x7D5B 0x7D5C 0x7D5D +0x7D5E 0x7D61 0x7D62 0x7D63 0x7D66 0x7D68 0x7D6A 0x7D6E 0x7D70 0x7D71 0x7D72 0x7D73 0x7D75 0x7D76 0x7D77 0x7D79 +0x7D7A 0x7D7D 0x7D7F 0x7D81 0x7D83 0x7D84 0x7D86 0x7D88 0x7D89 0x7D8C 0x7D8E 0x7D8F 0x7D91 0x7D93 0x7D96 0x7D99 +0x7D9A 0x7D9B 0x7D9C 0x7D9D 0x7D9E 0x7D9F 0x7DA0 0x7DA1 0x7DA2 0x7DA3 0x7DA6 0x7DA7 0x7DAA 0x7DAB 0x7DAC 0x7DAD +0x7DAE 0x7DAF 0x7DB0 0x7DB1 0x7DB2 0x7DB3 0x7DB4 0x7DB5 0x7DB7 0x7DB8 0x7DB9 0x7DBA 0x7DBB 0x7DBD 0x7DBE 0x7DBF +0x7DC1 0x7DC4 0x7DC7 0x7DC8 0x7DCA 0x7DCB 0x7DCC 0x7DCF 0x7DD1 0x7DD2 0x7DD3 0x7DD4 0x7DD5 0x7DD6 0x7DD7 0x7DD8 +0x7DD9 0x7DDA 0x7DDC 0x7DDD 0x7DDE 0x7DE0 0x7DE1 0x7DE3 0x7DE4 0x7DE6 0x7DE8 0x7DE9 0x7DEA 0x7DEC 0x7DEF 0x7DF1 +0x7DF2 0x7DF4 0x7DF6 0x7DF9 0x7DFB 0x7DFC 0x7E01 0x7E04 0x7E05 0x7E08 0x7E09 0x7E0A 0x7E0B 0x7E10 0x7E11 0x7E12 +0x7E15 0x7E17 0x7E1B 0x7E1D 0x7E1E 0x7E1F 0x7E20 0x7E21 0x7E22 0x7E23 0x7E26 0x7E27 0x7E29 0x7E2B 0x7E2D 0x7E2E +0x7E2F 0x7E31 0x7E32 0x7E33 0x7E34 0x7E35 0x7E36 0x7E37 0x7E39 0x7E3A 0x7E3B 0x7E3D 0x7E3E 0x7E3F 0x7E41 0x7E43 +0x7E44 0x7E45 0x7E46 0x7E47 0x7E48 0x7E4A 0x7E4B 0x7E4D 0x7E4E 0x7E51 0x7E52 0x7E54 0x7E55 0x7E56 0x7E59 0x7E5A +0x7E5D 0x7E5E 0x7E61 0x7E62 0x7E66 0x7E67 0x7E69 0x7E6A 0x7E6B 0x7E6D 0x7E6E 0x7E6F 0x7E70 0x7E73 0x7E76 0x7E79 +0x7E7B 0x7E7C 0x7E7D 0x7E7E 0x7E7F 0x7E81 0x7E82 0x7E83 0x7E86 0x7E87 0x7E88 0x7E89 0x7E8A 0x7E8C 0x7E8D 0x7E8E +0x7E8F 0x7E90 0x7E92 0x7E93 0x7E94 0x7E95 0x7E96 0x7E98 0x7E9A 0x7E9B 0x7E9C 0x7E9F 0x7EA0 0x7EA1 0x7EA2 0x7EA3 +0x7EA4 0x7EA5 0x7EA6 0x7EA7 0x7EA8 0x7EA9 0x7EAA 0x7EAB 0x7EAC 0x7EAD 0x7EAE 0x7EAF 0x7EB0 0x7EB1 0x7EB2 0x7EB3 +0x7EB4 0x7EB5 0x7EB6 0x7EB7 0x7EB8 0x7EB9 0x7EBA 0x7EBB 0x7EBC 0x7EBD 0x7EBE 0x7EBF 0x7EC0 0x7EC1 0x7EC2 0x7EC3 +0x7EC4 0x7EC5 0x7EC6 0x7EC7 0x7EC8 0x7EC9 0x7ECA 0x7ECB 0x7ECC 0x7ECD 0x7ECE 0x7ECF 0x7ED0 0x7ED1 0x7ED2 0x7ED3 +0x7ED4 0x7ED5 0x7ED6 0x7ED7 0x7ED8 0x7ED9 0x7EDA 0x7EDB 0x7EDC 0x7EDD 0x7EDE 0x7EDF 0x7EE0 0x7EE1 0x7EE2 0x7EE3 +0x7EE4 0x7EE5 0x7EE6 0x7EE7 0x7EE8 0x7EE9 0x7EEA 0x7EEB 0x7EEC 0x7EED 0x7EEE 0x7EEF 0x7EF0 0x7EF1 0x7EF2 0x7EF3 +0x7EF4 0x7EF5 0x7EF6 0x7EF7 0x7EF8 0x7EF9 0x7EFA 0x7EFB 0x7EFC 0x7EFD 0x7EFE 0x7EFF 0x7F00 0x7F01 0x7F02 0x7F03 +0x7F04 0x7F05 0x7F06 0x7F07 0x7F08 0x7F09 0x7F0A 0x7F0B 0x7F0C 0x7F0D 0x7F0E 0x7F0F 0x7F10 0x7F11 0x7F12 0x7F13 +0x7F14 0x7F15 0x7F16 0x7F17 0x7F18 0x7F19 0x7F1A 0x7F1B 0x7F1C 0x7F1D 0x7F1E 0x7F1F 0x7F20 0x7F21 0x7F22 0x7F23 +0x7F24 0x7F25 0x7F26 0x7F27 0x7F28 0x7F29 0x7F2A 0x7F2B 0x7F2C 0x7F2D 0x7F2E 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 +0x7F34 0x7F35 0x7F36 0x7F38 0x7F39 0x7F3A 0x7F3D 0x7F42 0x7F43 0x7F44 0x7F45 0x7F48 0x7F49 0x7F4C 0x7F4D 0x7F4E +0x7F4F 0x7F50 0x7F51 0x7F52 0x7F53 0x7F54 0x7F55 0x7F57 0x7F58 0x7F5A 0x7F5B 0x7F5C 0x7F5D 0x7F5E 0x7F5F 0x7F60 +0x7F61 0x7F62 0x7F63 0x7F65 0x7F66 0x7F67 0x7F68 0x7F69 0x7F6A 0x7F6B 0x7F6C 0x7F6D 0x7F6E 0x7F70 0x7F71 0x7F72 +0x7F73 0x7F74 0x7F75 0x7F76 0x7F77 0x7F78 0x7F79 0x7F7D 0x7F7E 0x7F81 0x7F82 0x7F83 0x7F85 0x7F86 0x7F87 0x7F88 +0x7F8A 0x7F8B 0x7F8C 0x7F8E 0x7F91 0x7F93 0x7F94 0x7F95 0x7F96 0x7F97 0x7F9A 0x7F9D 0x7F9E 0x7F9F 0x7FA1 0x7FA3 +0x7FA4 0x7FA5 0x7FA7 0x7FA8 0x7FA9 0x7FAE 0x7FAF 0x7FB0 0x7FB1 0x7FB2 0x7FB4 0x7FB6 0x7FB8 0x7FB9 0x7FBC 0x7FBD +0x7FBF 0x7FC0 0x7FC1 0x7FC2 0x7FC3 0x7FC5 0x7FC6 0x7FC8 0x7FCA 0x7FCB 0x7FCC 0x7FCE 0x7FD2 0x7FD4 0x7FD5 0x7FD8 +0x7FD9 0x7FDA 0x7FDB 0x7FDF 0x7FE0 0x7FE1 0x7FE5 0x7FE6 0x7FE7 0x7FE9 0x7FEB 0x7FEC 0x7FEE 0x7FEF 0x7FF0 0x7FF1 +0x7FF3 0x7FF7 0x7FF9 0x7FFA 0x7FFB 0x7FFC 0x7FFD 0x7FFE 0x8000 0x8001 0x8002 0x8003 0x8004 0x8005 0x8006 0x8007 +0x8008 0x8009 0x800B 0x800C 0x800D 0x800E 0x800F 0x8010 0x8011 0x8012 0x8014 0x8015 0x8016 0x8017 0x8018 0x8019 +0x801C 0x8020 0x8021 0x8022 0x8024 0x8025 0x8026 0x8027 0x8028 0x8029 0x802A 0x802C 0x802D 0x802E 0x8030 0x8031 +0x8032 0x8033 0x8035 0x8036 0x8037 0x8038 0x803B 0x803D 0x803F 0x8042 0x8043 0x8046 0x804A 0x804B 0x804C 0x804D +0x804F 0x8050 0x8051 0x8052 0x8054 0x8056 0x8058 0x805A 0x805E 0x805F 0x8061 0x8062 0x8064 0x8068 0x8069 0x806A +0x806F 0x8070 0x8071 0x8072 0x8073 0x8074 0x8075 0x8076 0x8077 0x8079 0x807D 0x807E 0x807F 0x8080 0x8083 0x8084 +0x8085 0x8086 0x8087 0x8089 0x808B 0x808C 0x808F 0x8090 0x8093 0x8096 0x8098 0x8099 0x809A 0x809B 0x809C 0x809D +0x809F 0x80A0 0x80A1 0x80A2 0x80A4 0x80A5 0x80A9 0x80AA 0x80AB 0x80AC 0x80AD 0x80AE 0x80AF 0x80B1 0x80B2 0x80B4 +0x80B7 0x80B8 0x80BA 0x80BC 0x80BD 0x80BE 0x80BF 0x80C0 0x80C1 0x80C2 0x80C3 0x80C4 0x80C6 0x80C8 0x80CC 0x80CD +0x80CE 0x80D4 0x80D6 0x80D7 0x80D9 0x80DA 0x80DB 0x80DC 0x80DD 0x80DE 0x80E0 0x80E1 0x80E3 0x80E4 0x80E5 0x80E7 +0x80E8 0x80E9 0x80EA 0x80EB 0x80EC 0x80ED 0x80EF 0x80F0 0x80F1 0x80F2 0x80F3 0x80F4 0x80F6 0x80F8 0x80FA 0x80FC +0x80FD 0x80FE 0x80FF 0x8102 0x8105 0x8106 0x8107 0x8108 0x8109 0x810A 0x810D 0x810E 0x810F 0x8110 0x8111 0x8112 +0x8113 0x8114 0x8116 0x8117 0x8118 0x811A 0x811B 0x811D 0x811E 0x811F 0x8122 0x8123 0x8124 0x8126 0x8127 0x8129 +0x812B 0x812C 0x812F 0x8130 0x8131 0x8132 0x8133 0x8136 0x8137 0x8138 0x8139 0x813E 0x813F 0x8146 0x8148 0x814A +0x814B 0x814C 0x814E 0x8150 0x8151 0x8152 0x8153 0x8154 0x8155 0x8156 0x8158 0x8159 0x815A 0x815F 0x8160 0x8161 +0x8165 0x8166 0x8167 0x8168 0x8169 0x816B 0x816D 0x816E 0x816F 0x8170 0x8171 0x8173 0x8174 0x8178 0x8179 0x817A +0x817B 0x817C 0x817D 0x817E 0x817F 0x8180 0x8182 0x8183 0x8188 0x818A 0x818D 0x818E 0x818F 0x8191 0x8193 0x8195 +0x8196 0x8198 0x8199 0x819A 0x819B 0x819C 0x819D 0x819E 0x81A0 0x81A2 0x81A3 0x81A4 0x81A5 0x81A6 0x81A8 0x81A9 +0x81AA 0x81B0 0x81B3 0x81B5 0x81B6 0x81B8 0x81BA 0x81BB 0x81BD 0x81BE 0x81BF 0x81C0 0x81C1 0x81C2 0x81C3 0x81C6 +0x81C8 0x81C9 0x81CA 0x81CC 0x81CD 0x81CF 0x81D1 0x81D3 0x81D8 0x81D9 0x81DA 0x81DC 0x81DF 0x81E0 0x81E2 0x81E3 +0x81E5 0x81E7 0x81E8 0x81EA 0x81EC 0x81ED 0x81F3 0x81F4 0x81FA 0x81FB 0x81FC 0x81FE 0x81FF 0x8200 0x8201 0x8202 +0x8204 0x8205 0x8206 0x8207 0x8208 0x8209 0x820A 0x820B 0x820C 0x820D 0x820E 0x8210 0x8212 0x8214 0x8216 0x8217 +0x8218 0x821B 0x821C 0x821E 0x821F 0x8220 0x8221 0x8222 0x8223 0x8225 0x8226 0x8228 0x8229 0x822A 0x822B 0x822C +0x822D 0x822E 0x822F 0x8230 0x8231 0x8232 0x8233 0x8234 0x8235 0x8236 0x8237 0x8238 0x8239 0x823A 0x823B 0x823E +0x8240 0x8244 0x8245 0x8247 0x8249 0x824B 0x824E 0x824F 0x8258 0x8259 0x825A 0x825D 0x825F 0x8262 0x8264 0x8266 +0x8268 0x826A 0x826B 0x826E 0x826F 0x8270 0x8271 0x8272 0x8273 0x8274 0x8276 0x8277 0x8278 0x8279 0x827A 0x827D +0x827E 0x827F 0x8280 0x8282 0x8283 0x8284 0x8288 0x828A 0x828B 0x828D 0x828E 0x828F 0x8291 0x8292 0x8297 0x8298 +0x8299 0x829A 0x829C 0x829D 0x829F 0x82A0 0x82A1 0x82A3 0x82A4 0x82A5 0x82A6 0x82A7 0x82A8 0x82A9 0x82AA 0x82AB +0x82AC 0x82AD 0x82AE 0x82AF 0x82B0 0x82B1 0x82B3 0x82B4 0x82B5 0x82B6 0x82B7 0x82B8 0x82B9 0x82BB 0x82BC 0x82BD +0x82BE 0x82BF 0x82C1 0x82C4 0x82C5 0x82C7 0x82C8 0x82C9 0x82CA 0x82CB 0x82CC 0x82CD 0x82CE 0x82CF 0x82D1 0x82D2 +0x82D3 0x82D4 0x82D5 0x82D6 0x82D7 0x82D8 0x82D9 0x82DB 0x82DC 0x82DD 0x82DE 0x82DF 0x82E0 0x82E1 0x82E3 0x82E4 +0x82E5 0x82E6 0x82E7 0x82E8 0x82EB 0x82EF 0x82F1 0x82F3 0x82F4 0x82F6 0x82F7 0x82F9 0x82FA 0x82FB 0x82FD 0x82FE +0x8300 0x8301 0x8302 0x8303 0x8304 0x8305 0x8306 0x8307 0x8308 0x8309 0x830B 0x830C 0x830D 0x830E 0x830F 0x8311 +0x8313 0x8314 0x8315 0x8316 0x8317 0x8318 0x831A 0x831B 0x831C 0x831D 0x8322 0x8323 0x8327 0x8328 0x8329 0x832B +0x832C 0x832D 0x832F 0x8331 0x8332 0x8333 0x8334 0x8335 0x8336 0x8338 0x8339 0x833A 0x833C 0x833D 0x8340 0x8341 +0x8343 0x8344 0x8345 0x8346 0x8347 0x8349 0x834A 0x834E 0x834F 0x8350 0x8351 0x8352 0x8353 0x8354 0x8356 0x8358 +0x8359 0x835A 0x835B 0x835C 0x835D 0x835E 0x835F 0x8360 0x8361 0x8363 0x8364 0x8365 0x8366 0x8367 0x8368 0x8369 +0x836A 0x836B 0x836C 0x836D 0x836E 0x836F 0x8373 0x8375 0x8377 0x8378 0x837A 0x837B 0x837C 0x837D 0x8380 0x8382 +0x8385 0x8386 0x8387 0x8389 0x838A 0x838E 0x8392 0x8393 0x8395 0x8396 0x8398 0x8399 0x839A 0x839B 0x839C 0x839D +0x839E 0x839F 0x83A0 0x83A2 0x83A3 0x83A6 0x83A7 0x83A8 0x83A9 0x83AA 0x83AB 0x83AF 0x83B0 0x83B1 0x83B2 0x83B3 +0x83B4 0x83B5 0x83B6 0x83B7 0x83B8 0x83B9 0x83BA 0x83BC 0x83BD 0x83BF 0x83C0 0x83C1 0x83C2 0x83C5 0x83C7 0x83C8 +0x83C9 0x83CA 0x83CC 0x83CD 0x83CE 0x83CF 0x83D1 0x83D3 0x83D4 0x83D6 0x83D8 0x83DC 0x83DD 0x83DF 0x83E0 0x83E1 +0x83E5 0x83E9 0x83EA 0x83EB 0x83EF 0x83F0 0x83F1 0x83F2 0x83F4 0x83F5 0x83F7 0x83F8 0x83F9 0x83FB 0x83FC 0x83FD +0x83FE 0x83FF 0x8401 0x8403 0x8404 0x8406 0x8407 0x840A 0x840B 0x840C 0x840D 0x840E 0x840F 0x8411 0x8413 0x8418 +0x841A 0x841C 0x841D 0x8420 0x8422 0x8423 0x8424 0x8425 0x8426 0x8427 0x8428 0x8429 0x842A 0x842C 0x8431 0x8433 +0x8434 0x8435 0x8438 0x8439 0x843C 0x843D 0x8446 0x8447 0x8449 0x844E 0x8451 0x8452 0x8453 0x8456 0x8457 0x8459 +0x845A 0x845B 0x845C 0x8460 0x8461 0x8462 0x8463 0x8464 0x8466 0x8469 0x846B 0x846C 0x846D 0x846E 0x846F 0x8470 +0x8471 0x8473 0x8474 0x8475 0x8476 0x8477 0x8478 0x8479 0x847A 0x8482 0x8484 0x8487 0x8488 0x8489 0x848B 0x848C +0x848D 0x848E 0x8490 0x8493 0x8494 0x8497 0x8499 0x849C 0x849D 0x849E 0x849F 0x84A1 0x84A8 0x84AD 0x84AF 0x84B1 +0x84B2 0x84B4 0x84B8 0x84B9 0x84BA 0x84BB 0x84BC 0x84BD 0x84BE 0x84BF 0x84C0 0x84C1 0x84C2 0x84C4 0x84C6 0x84C7 +0x84C9 0x84CA 0x84CB 0x84CD 0x84CF 0x84D0 0x84D1 0x84D3 0x84D6 0x84D9 0x84DA 0x84DD 0x84DF 0x84E0 0x84E2 0x84E3 +0x84E5 0x84E6 0x84EA 0x84EC 0x84EE 0x84EF 0x84F0 0x84F3 0x84F4 0x84F7 0x84FC 0x84FD 0x84FF 0x8500 0x8503 0x8504 +0x8506 0x8508 0x850A 0x850C 0x8511 0x8513 0x8514 0x8515 0x8517 0x8518 0x851A 0x851E 0x851F 0x8521 0x8523 0x8525 +0x8526 0x852B 0x852C 0x852D 0x852F 0x8534 0x8535 0x8537 0x8538 0x8539 0x853A 0x853B 0x853C 0x853D 0x853F 0x8540 +0x8541 0x8543 0x8546 0x8548 0x8549 0x854A 0x854B 0x854E 0x8552 0x8553 0x8555 0x8556 0x8557 0x8558 0x8559 0x855A +0x855E 0x8562 0x8563 0x8564 0x8565 0x8568 0x8569 0x856A 0x856D 0x8570 0x8572 0x8574 0x8577 0x8579 0x857A 0x857B +0x857E 0x8580 0x8581 0x8584 0x8585 0x8586 0x8587 0x8588 0x858A 0x858C 0x858F 0x8590 0x8591 0x8594 0x8597 0x8598 +0x8599 0x859B 0x859C 0x859F 0x85A0 0x85A2 0x85A4 0x85A6 0x85A8 0x85A9 0x85AA 0x85AB 0x85AC 0x85AE 0x85AF 0x85B0 +0x85B3 0x85B4 0x85B6 0x85B7 0x85B8 0x85B9 0x85BA 0x85BE 0x85BF 0x85C1 0x85C2 0x85C9 0x85CD 0x85CE 0x85CF 0x85D0 +0x85D3 0x85D5 0x85DC 0x85DD 0x85DF 0x85E0 0x85E4 0x85E5 0x85E6 0x85E8 0x85E9 0x85EA 0x85ED 0x85F4 0x85F6 0x85F7 +0x85F9 0x85FA 0x85FB 0x85FE 0x85FF 0x8600 0x8602 0x8604 0x8605 0x8606 0x8607 0x860A 0x860B 0x8611 0x8613 0x8616 +0x8617 0x8618 0x861A 0x861E 0x8621 0x8622 0x8626 0x8627 0x8629 0x862D 0x862F 0x8630 0x8635 0x8638 0x863A 0x863C +0x863F 0x8649 0x864D 0x864E 0x864F 0x8650 0x8651 0x8652 0x8653 0x8654 0x8655 0x8656 0x8659 0x865A 0x865B 0x865C +0x865E 0x865F 0x8661 0x8662 0x8663 0x8664 0x8667 0x866B 0x866C 0x866D 0x866E 0x866F 0x8670 0x8671 0x8673 0x8674 +0x8677 0x8678 0x8679 0x867A 0x867B 0x867C 0x867D 0x867E 0x867F 0x8680 0x8681 0x8682 0x8683 0x8684 0x8685 0x8686 +0x8687 0x868A 0x868B 0x868C 0x868D 0x868E 0x8690 0x8691 0x8693 0x8694 0x8695 0x8696 0x8697 0x8698 0x8699 0x869A +0x869C 0x869D 0x869E 0x86A1 0x86A2 0x86A3 0x86A4 0x86A5 0x86A7 0x86A8 0x86A9 0x86AA 0x86AB 0x86AC 0x86AF 0x86B0 +0x86B1 0x86B2 0x86B3 0x86B4 0x86B5 0x86B6 0x86B7 0x86B8 0x86B9 0x86BA 0x86C0 0x86C1 0x86C2 0x86C3 0x86C4 0x86C5 +0x86C6 0x86C7 0x86C8 0x86C9 0x86CA 0x86CB 0x86CD 0x86CE 0x86CF 0x86D0 0x86D1 0x86D4 0x86D8 0x86D9 0x86DB 0x86DE +0x86DF 0x86E4 0x86E9 0x86EC 0x86ED 0x86EE 0x86EF 0x86F0 0x86F1 0x86F2 0x86F3 0x86F4 0x86F8 0x86F9 0x86FA 0x86FB +0x86FE 0x8700 0x8702 0x8703 0x8705 0x8706 0x8707 0x8708 0x8709 0x870A 0x870D 0x870E 0x8710 0x8711 0x8712 0x8713 +0x8715 0x8717 0x8718 0x871A 0x871C 0x871E 0x8721 0x8722 0x8723 0x8725 0x8729 0x872E 0x8730 0x8731 0x8734 0x8737 +0x873B 0x873D 0x873E 0x873F 0x8740 0x8742 0x8744 0x8747 0x8748 0x8749 0x874B 0x874C 0x874E 0x8753 0x8755 0x8757 +0x8758 0x8759 0x875C 0x875F 0x8760 0x8763 0x8764 0x8765 0x8766 0x8768 0x876A 0x876E 0x8770 0x8772 0x8774 0x8776 +0x8778 0x877B 0x877C 0x877D 0x877E 0x877F 0x8780 0x8782 0x8783 0x8784 0x8785 0x8786 0x8788 0x878B 0x878D 0x8793 +0x8797 0x879E 0x879F 0x87A0 0x87A2 0x87A3 0x87A8 0x87AB 0x87AC 0x87AD 0x87AE 0x87AF 0x87B1 0x87B3 0x87B5 0x87BA +0x87BB 0x87BD 0x87BF 0x87C0 0x87C4 0x87C6 0x87C7 0x87C8 0x87CA 0x87CB 0x87CE 0x87CF 0x87D0 0x87D1 0x87D2 0x87D3 +0x87DB 0x87E0 0x87E2 0x87E3 0x87E5 0x87E7 0x87EA 0x87EB 0x87EC 0x87EE 0x87EF 0x87F2 0x87F3 0x87F6 0x87F7 0x87F9 +0x87FB 0x87FE 0x87FF 0x8801 0x8803 0x8804 0x8805 0x8806 0x880A 0x880B 0x880D 0x880E 0x880F 0x8810 0x8811 0x8813 +0x8814 0x8815 0x8816 0x881B 0x881F 0x8821 0x8822 0x8823 0x8827 0x8828 0x882D 0x8831 0x8832 0x8835 0x8836 0x8839 +0x883B 0x883C 0x8840 0x8842 0x8843 0x8844 0x8845 0x8846 0x884A 0x884C 0x884D 0x884E 0x8852 0x8853 0x8854 0x8855 +0x8856 0x8857 0x8859 0x885A 0x885B 0x885D 0x885E 0x8860 0x8861 0x8862 0x8863 0x8864 0x8865 0x8868 0x8869 0x886B +0x886C 0x886E 0x8870 0x8872 0x8875 0x8877 0x8879 0x887D 0x887E 0x887F 0x8881 0x8882 0x8884 0x8885 0x8886 0x8888 +0x888B 0x888D 0x8892 0x8893 0x8896 0x8897 0x8899 0x889C 0x889E 0x88A2 0x88A4 0x88AA 0x88AB 0x88AD 0x88AE 0x88AF +0x88B0 0x88B1 0x88B4 0x88B5 0x88B7 0x88BA 0x88BC 0x88BF 0x88C0 0x88C1 0x88C2 0x88C3 0x88C4 0x88C5 0x88C6 0x88C7 +0x88C8 0x88C9 0x88CA 0x88CB 0x88CE 0x88CF 0x88D1 0x88D2 0x88D4 0x88D5 0x88D8 0x88D9 0x88DB 0x88DC 0x88DD 0x88DF +0x88E1 0x88E2 0x88E3 0x88E4 0x88E5 0x88E8 0x88EC 0x88EF 0x88F0 0x88F1 0x88F2 0x88F3 0x88F4 0x88F5 0x88F8 0x88F9 +0x88FB 0x88FC 0x88FD 0x88FE 0x8902 0x8904 0x8907 0x890A 0x890C 0x890E 0x8910 0x8912 0x8913 0x8914 0x8915 0x8918 +0x8919 0x891A 0x891B 0x891D 0x891E 0x891F 0x8921 0x8925 0x8926 0x892A 0x892B 0x892F 0x8930 0x8932 0x8933 0x8934 +0x8935 0x8936 0x8938 0x893B 0x893D 0x8940 0x8941 0x8943 0x8944 0x8947 0x8948 0x894C 0x894D 0x894F 0x8955 0x8956 +0x895A 0x895C 0x895D 0x895E 0x895F 0x8960 0x8964 0x8966 0x896A 0x896B 0x896C 0x896D 0x896F 0x8972 0x8974 0x8976 +0x8977 0x897B 0x897E 0x897F 0x8980 0x8981 0x8983 0x8985 0x8986 0x8987 0x8988 0x898A 0x898B 0x898E 0x898F 0x8993 +0x8996 0x8997 0x8998 0x8999 0x899A 0x899C 0x89A1 0x89A4 0x89A5 0x89A6 0x89A7 0x89A9 0x89AA 0x89AC 0x89AF 0x89B2 +0x89B3 0x89B7 0x89BA 0x89BC 0x89BD 0x89BF 0x89C0 0x89C1 0x89C2 0x89C3 0x89C4 0x89C5 0x89C6 0x89C7 0x89C8 0x89C9 +0x89CA 0x89CB 0x89CC 0x89CD 0x89CE 0x89CF 0x89D0 0x89D1 0x89D2 0x89D4 0x89D6 0x89DA 0x89DC 0x89DD 0x89DE 0x89DF +0x89E3 0x89E5 0x89E6 0x89E7 0x89EB 0x89ED 0x89EF 0x89F1 0x89F3 0x89F4 0x89F6 0x89F8 0x89FC 0x89FF 0x8A00 0x8A01 +0x8A02 0x8A03 0x8A04 0x8A07 0x8A08 0x8A0A 0x8A0C 0x8A0E 0x8A0F 0x8A10 0x8A11 0x8A12 0x8A13 0x8A15 0x8A16 0x8A17 +0x8A18 0x8A1A 0x8A1B 0x8A1D 0x8A1F 0x8A22 0x8A23 0x8A25 0x8A29 0x8A2A 0x8A2B 0x8A2D 0x8A31 0x8A33 0x8A34 0x8A36 +0x8A38 0x8A3A 0x8A3B 0x8A3C 0x8A3E 0x8A40 0x8A41 0x8A46 0x8A48 0x8A4E 0x8A50 0x8A51 0x8A52 0x8A54 0x8A55 0x8A56 +0x8A57 0x8A58 0x8A5B 0x8A5D 0x8A5E 0x8A5F 0x8A60 0x8A61 0x8A62 0x8A63 0x8A66 0x8A68 0x8A69 0x8A6A 0x8A6B 0x8A6C +0x8A6D 0x8A6E 0x8A70 0x8A71 0x8A72 0x8A73 0x8A75 0x8A77 0x8A79 0x8A7A 0x8A7B 0x8A7C 0x8A7F 0x8A81 0x8A82 0x8A84 +0x8A85 0x8A86 0x8A87 0x8A89 0x8A8A 0x8A8C 0x8A8D 0x8A91 0x8A92 0x8A93 0x8A95 0x8A98 0x8A9A 0x8A9E 0x8AA0 0x8AA1 +0x8AA3 0x8AA4 0x8AA5 0x8AA6 0x8AA7 0x8AA8 0x8AA9 0x8AAA 0x8AAC 0x8AAD 0x8AB0 0x8AB2 0x8AB6 0x8AB9 0x8ABC 0x8ABE +0x8ABF 0x8AC2 0x8AC4 0x8AC7 0x8AC9 0x8ACB 0x8ACC 0x8ACD 0x8ACF 0x8AD1 0x8AD2 0x8AD3 0x8AD4 0x8AD6 0x8AD7 0x8ADA +0x8ADB 0x8ADC 0x8ADD 0x8ADE 0x8ADF 0x8AE0 0x8AE1 0x8AE2 0x8AE4 0x8AE6 0x8AE7 0x8AEA 0x8AEB 0x8AED 0x8AEE 0x8AF1 +0x8AF2 0x8AF3 0x8AF4 0x8AF6 0x8AF7 0x8AF8 0x8AFA 0x8AFC 0x8AFE 0x8AFF 0x8B00 0x8B01 0x8B02 0x8B04 0x8B05 0x8B07 +0x8B0A 0x8B0B 0x8B0C 0x8B0E 0x8B0F 0x8B10 0x8B14 0x8B16 0x8B17 0x8B19 0x8B1A 0x8B1B 0x8B1D 0x8B1E 0x8B20 0x8B21 +0x8B22 0x8B26 0x8B28 0x8B2B 0x8B2C 0x8B2D 0x8B2E 0x8B33 0x8B37 0x8B39 0x8B3E 0x8B41 0x8B46 0x8B49 0x8B4A 0x8B4C +0x8B4E 0x8B4F 0x8B53 0x8B56 0x8B58 0x8B59 0x8B5A 0x8B5B 0x8B5C 0x8B5E 0x8B5F 0x8B60 0x8B63 0x8B66 0x8B69 0x8B6A +0x8B6B 0x8B6C 0x8B6D 0x8B6F 0x8B70 0x8B71 0x8B72 0x8B74 0x8B77 0x8B78 0x8B7D 0x8B7F 0x8B80 0x8B83 0x8B85 0x8B86 +0x8B8A 0x8B8B 0x8B8C 0x8B8E 0x8B90 0x8B92 0x8B93 0x8B94 0x8B95 0x8B96 0x8B99 0x8B9A 0x8B9C 0x8B9E 0x8B9F 0x8BA0 +0x8BA1 0x8BA2 0x8BA3 0x8BA4 0x8BA5 0x8BA6 0x8BA7 0x8BA8 0x8BA9 0x8BAA 0x8BAB 0x8BAC 0x8BAD 0x8BAE 0x8BAF 0x8BB0 +0x8BB1 0x8BB2 0x8BB3 0x8BB4 0x8BB5 0x8BB6 0x8BB7 0x8BB8 0x8BB9 0x8BBA 0x8BBB 0x8BBC 0x8BBD 0x8BBE 0x8BBF 0x8BC0 +0x8BC1 0x8BC2 0x8BC3 0x8BC4 0x8BC5 0x8BC6 0x8BC7 0x8BC8 0x8BC9 0x8BCA 0x8BCB 0x8BCC 0x8BCD 0x8BCE 0x8BCF 0x8BD0 +0x8BD1 0x8BD2 0x8BD3 0x8BD4 0x8BD5 0x8BD6 0x8BD7 0x8BD8 0x8BD9 0x8BDA 0x8BDB 0x8BDC 0x8BDD 0x8BDE 0x8BDF 0x8BE0 +0x8BE1 0x8BE2 0x8BE3 0x8BE4 0x8BE5 0x8BE6 0x8BE7 0x8BE8 0x8BE9 0x8BEA 0x8BEB 0x8BEC 0x8BED 0x8BEE 0x8BEF 0x8BF0 +0x8BF1 0x8BF2 0x8BF3 0x8BF4 0x8BF5 0x8BF6 0x8BF7 0x8BF8 0x8BF9 0x8BFA 0x8BFB 0x8BFC 0x8BFD 0x8BFE 0x8BFF 0x8C00 +0x8C01 0x8C02 0x8C03 0x8C04 0x8C05 0x8C06 0x8C07 0x8C08 0x8C09 0x8C0A 0x8C0B 0x8C0C 0x8C0D 0x8C0E 0x8C0F 0x8C10 +0x8C11 0x8C12 0x8C13 0x8C14 0x8C15 0x8C16 0x8C17 0x8C18 0x8C19 0x8C1A 0x8C1B 0x8C1C 0x8C1D 0x8C1E 0x8C1F 0x8C20 +0x8C21 0x8C22 0x8C23 0x8C24 0x8C25 0x8C26 0x8C27 0x8C28 0x8C29 0x8C2A 0x8C2B 0x8C2C 0x8C2D 0x8C2E 0x8C2F 0x8C30 +0x8C31 0x8C32 0x8C33 0x8C34 0x8C35 0x8C36 0x8C37 0x8C3A 0x8C3C 0x8C3F 0x8C41 0x8C46 0x8C47 0x8C48 0x8C49 0x8C4A +0x8C4C 0x8C4E 0x8C50 0x8C54 0x8C55 0x8C57 0x8C5A 0x8C61 0x8C62 0x8C68 0x8C6A 0x8C6B 0x8C6C 0x8C6D 0x8C6E 0x8C73 +0x8C76 0x8C78 0x8C79 0x8C7A 0x8C7C 0x8C82 0x8C85 0x8C86 0x8C89 0x8C8A 0x8C8C 0x8C8D 0x8C8E 0x8C90 0x8C92 0x8C93 +0x8C94 0x8C98 0x8C99 0x8C9D 0x8C9E 0x8C9F 0x8CA0 0x8CA1 0x8CA2 0x8CA7 0x8CA8 0x8CA9 0x8CAA 0x8CAB 0x8CAC 0x8CAD +0x8CAE 0x8CAF 0x8CB0 0x8CB2 0x8CB3 0x8CB4 0x8CB6 0x8CB7 0x8CB8 0x8CBA 0x8CBB 0x8CBC 0x8CBD 0x8CBF 0x8CC0 0x8CC1 +0x8CC2 0x8CC3 0x8CC4 0x8CC5 0x8CC7 0x8CC8 0x8CCA 0x8CCD 0x8CCE 0x8CCF 0x8CD1 0x8CD2 0x8CD3 0x8CD5 0x8CD9 0x8CDA +0x8CDB 0x8CDC 0x8CDE 0x8CE0 0x8CE1 0x8CE2 0x8CE3 0x8CE4 0x8CE6 0x8CE7 0x8CE8 0x8CEA 0x8CEB 0x8CEC 0x8CED 0x8CF0 +0x8CF1 0x8CF4 0x8CF5 0x8CF8 0x8CFA 0x8CFB 0x8CFC 0x8CFD 0x8CFE 0x8D04 0x8D05 0x8D07 0x8D08 0x8D0A 0x8D0B 0x8D0D +0x8D0F 0x8D10 0x8D13 0x8D14 0x8D16 0x8D17 0x8D1B 0x8D1C 0x8D1D 0x8D1E 0x8D1F 0x8D20 0x8D21 0x8D22 0x8D23 0x8D24 +0x8D25 0x8D26 0x8D27 0x8D28 0x8D29 0x8D2A 0x8D2B 0x8D2C 0x8D2D 0x8D2E 0x8D2F 0x8D30 0x8D31 0x8D32 0x8D33 0x8D34 +0x8D35 0x8D36 0x8D37 0x8D38 0x8D39 0x8D3A 0x8D3B 0x8D3C 0x8D3D 0x8D3E 0x8D3F 0x8D40 0x8D41 0x8D42 0x8D43 0x8D44 +0x8D45 0x8D46 0x8D47 0x8D48 0x8D49 0x8D4A 0x8D4B 0x8D4C 0x8D4D 0x8D4E 0x8D4F 0x8D50 0x8D51 0x8D52 0x8D53 0x8D54 +0x8D55 0x8D56 0x8D57 0x8D58 0x8D59 0x8D5A 0x8D5B 0x8D5C 0x8D5D 0x8D5E 0x8D5F 0x8D60 0x8D61 0x8D62 0x8D63 0x8D64 +0x8D66 0x8D67 0x8D69 0x8D6A 0x8D6B 0x8D6C 0x8D6D 0x8D70 0x8D71 0x8D73 0x8D74 0x8D75 0x8D76 0x8D77 0x8D81 0x8D84 +0x8D85 0x8D8A 0x8D8B 0x8D91 0x8D94 0x8D95 0x8D96 0x8D99 0x8D9F 0x8DA3 0x8DA8 0x8DAF 0x8DB1 0x8DB2 0x8DB3 0x8DB4 +0x8DB5 0x8DB8 0x8DBA 0x8DBC 0x8DBE 0x8DBF 0x8DC2 0x8DC3 0x8DC4 0x8DC5 0x8DC6 0x8DCB 0x8DCC 0x8DCE 0x8DCF 0x8DD0 +0x8DD1 0x8DD6 0x8DD7 0x8DDA 0x8DDB 0x8DDD 0x8DDE 0x8DDF 0x8DE1 0x8DE3 0x8DE4 0x8DE6 0x8DE8 0x8DE9 0x8DEA 0x8DEB +0x8DEC 0x8DEF 0x8DF0 0x8DF1 0x8DF3 0x8DF5 0x8DF6 0x8DF7 0x8DF8 0x8DF9 0x8DFA 0x8DFB 0x8DFC 0x8DFD 0x8DFF 0x8E04 +0x8E05 0x8E08 0x8E09 0x8E0A 0x8E0C 0x8E0E 0x8E0F 0x8E10 0x8E12 0x8E14 0x8E16 0x8E1C 0x8E1D 0x8E1E 0x8E1F 0x8E21 +0x8E22 0x8E23 0x8E26 0x8E27 0x8E29 0x8E2A 0x8E2B 0x8E2C 0x8E2D 0x8E2E 0x8E2F 0x8E30 0x8E31 0x8E34 0x8E35 0x8E36 +0x8E39 0x8E3A 0x8E3C 0x8E3D 0x8E40 0x8E41 0x8E42 0x8E44 0x8E45 0x8E47 0x8E48 0x8E49 0x8E4A 0x8E4B 0x8E4C 0x8E4D +0x8E4F 0x8E50 0x8E51 0x8E52 0x8E53 0x8E54 0x8E55 0x8E59 0x8E5A 0x8E5C 0x8E5F 0x8E60 0x8E61 0x8E62 0x8E63 0x8E64 +0x8E66 0x8E67 0x8E69 0x8E6C 0x8E6D 0x8E6F 0x8E70 0x8E72 0x8E74 0x8E76 0x8E7A 0x8E7B 0x8E7C 0x8E7D 0x8E7E 0x8E7F +0x8E80 0x8E81 0x8E82 0x8E84 0x8E85 0x8E87 0x8E89 0x8E8A 0x8E8B 0x8E8D 0x8E8F 0x8E90 0x8E91 0x8E92 0x8E93 0x8E94 +0x8E95 0x8E99 0x8E9A 0x8E9C 0x8E9D 0x8E9E 0x8EA1 0x8EA5 0x8EA6 0x8EAA 0x8EAB 0x8EAC 0x8EAD 0x8EAF 0x8EB0 0x8EB1 +0x8EB2 0x8EBA 0x8EBC 0x8EBE 0x8EC0 0x8EC1 0x8EC5 0x8EC6 0x8EC8 0x8ECA 0x8ECB 0x8ECC 0x8ECD 0x8ECE 0x8ECF 0x8ED1 +0x8ED2 0x8ED4 0x8EDA 0x8EDB 0x8EDD 0x8EDF 0x8EE2 0x8EE3 0x8EE4 0x8EE8 0x8EEB 0x8EF1 0x8EF2 0x8EF8 0x8EF9 0x8EFA +0x8EFB 0x8EFC 0x8EFD 0x8EFE 0x8EFF 0x8F00 0x8F03 0x8F04 0x8F05 0x8F07 0x8F08 0x8F09 0x8F0A 0x8F0B 0x8F0C 0x8F12 +0x8F13 0x8F14 0x8F15 0x8F17 0x8F19 0x8F1B 0x8F1C 0x8F1D 0x8F1E 0x8F1F 0x8F25 0x8F26 0x8F27 0x8F29 0x8F2A 0x8F2C +0x8F2D 0x8F2E 0x8F2F 0x8F33 0x8F36 0x8F38 0x8F39 0x8F3B 0x8F3C 0x8F3E 0x8F3F 0x8F40 0x8F42 0x8F44 0x8F45 0x8F46 +0x8F49 0x8F4C 0x8F4D 0x8F4E 0x8F54 0x8F57 0x8F58 0x8F5C 0x8F5D 0x8F5F 0x8F61 0x8F62 0x8F63 0x8F64 0x8F66 0x8F67 +0x8F68 0x8F69 0x8F6A 0x8F6B 0x8F6C 0x8F6D 0x8F6E 0x8F6F 0x8F70 0x8F71 0x8F72 0x8F73 0x8F74 0x8F75 0x8F76 0x8F77 +0x8F78 0x8F79 0x8F7A 0x8F7B 0x8F7C 0x8F7D 0x8F7E 0x8F7F 0x8F80 0x8F81 0x8F82 0x8F83 0x8F84 0x8F85 0x8F86 0x8F87 +0x8F88 0x8F89 0x8F8A 0x8F8B 0x8F8C 0x8F8D 0x8F8E 0x8F8F 0x8F90 0x8F91 0x8F92 0x8F93 0x8F94 0x8F95 0x8F96 0x8F97 +0x8F98 0x8F99 0x8F9A 0x8F9B 0x8F9C 0x8F9E 0x8F9F 0x8FA3 0x8FA6 0x8FA7 0x8FA8 0x8FA9 0x8FAB 0x8FAD 0x8FAE 0x8FAF +0x8FB0 0x8FB1 0x8FB2 0x8FB4 0x8FB5 0x8FB6 0x8FB7 0x8FB9 0x8FBA 0x8FBB 0x8FBC 0x8FBD 0x8FBE 0x8FBF 0x8FC0 0x8FC1 +0x8FC2 0x8FC4 0x8FC5 0x8FC6 0x8FC7 0x8FC8 0x8FC9 0x8FCB 0x8FCC 0x8FCD 0x8FCE 0x8FD0 0x8FD1 0x8FD2 0x8FD3 0x8FD4 +0x8FD5 0x8FD6 0x8FD7 0x8FD8 0x8FD9 0x8FDA 0x8FDB 0x8FDC 0x8FDD 0x8FDE 0x8FDF 0x8FE0 0x8FE1 0x8FE2 0x8FE3 0x8FE4 +0x8FE5 0x8FE6 0x8FE8 0x8FE9 0x8FEA 0x8FEB 0x8FED 0x8FEE 0x8FEF 0x8FF0 0x8FF2 0x8FF3 0x8FF4 0x8FF5 0x8FF6 0x8FF7 +0x8FF8 0x8FF9 0x8FFA 0x8FFB 0x8FFC 0x8FFD 0x8FFE 0x8FFF 0x9000 0x9001 0x9002 0x9003 0x9004 0x9005 0x9006 0x9008 +0x9009 0x900A 0x900B 0x900C 0x900D 0x900E 0x900F 0x9010 0x9011 0x9012 0x9013 0x9014 0x9015 0x9016 0x9017 0x9019 +0x901A 0x901B 0x901C 0x901D 0x901E 0x901F 0x9020 0x9021 0x9022 0x9023 0x9024 0x9026 0x9027 0x902D 0x902E 0x902F +0x9031 0x9032 0x9034 0x9035 0x9036 0x9038 0x9039 0x903B 0x903C 0x903D 0x903E 0x903F 0x9041 0x9042 0x9044 0x9045 +0x9046 0x9047 0x9049 0x904A 0x904B 0x904D 0x904E 0x904F 0x9050 0x9051 0x9052 0x9053 0x9054 0x9055 0x9056 0x9057 +0x9058 0x9059 0x905B 0x905C 0x905D 0x905E 0x9060 0x9061 0x9062 0x9063 0x9065 0x9067 0x9068 0x9069 0x906B 0x906D +0x906E 0x906F 0x9070 0x9072 0x9073 0x9074 0x9075 0x9076 0x9077 0x9078 0x9079 0x907A 0x907B 0x907C 0x907D 0x907E +0x907F 0x9080 0x9081 0x9082 0x9083 0x9084 0x9085 0x9086 0x9087 0x9088 0x9089 0x908A 0x908B 0x908D 0x908F 0x9090 +0x9091 0x9093 0x9094 0x9095 0x9097 0x9098 0x9099 0x909B 0x909D 0x909E 0x909F 0x90A0 0x90A1 0x90A2 0x90A3 0x90A5 +0x90A6 0x90A7 0x90A8 0x90AA 0x90AC 0x90AE 0x90AF 0x90B0 0x90B1 0x90B2 0x90B3 0x90B4 0x90B5 0x90B6 0x90B8 0x90B9 +0x90BA 0x90BB 0x90BD 0x90BE 0x90BF 0x90C1 0x90C3 0x90C4 0x90C5 0x90C7 0x90C8 0x90CA 0x90CE 0x90CF 0x90D0 0x90D1 +0x90D3 0x90D7 0x90DA 0x90DB 0x90DC 0x90DD 0x90DE 0x90DF 0x90E1 0x90E2 0x90E4 0x90E6 0x90E7 0x90E8 0x90EA 0x90EB +0x90EC 0x90ED 0x90EF 0x90F4 0x90F5 0x90F7 0x90F8 0x90FD 0x90FE 0x90FF 0x9100 0x9102 0x9103 0x9104 0x9105 0x9106 +0x9109 0x910C 0x9111 0x9112 0x9114 0x9115 0x9116 0x9117 0x9118 0x9119 0x911A 0x911C 0x911E 0x9120 0x9122 0x9123 +0x9127 0x9129 0x912B 0x912D 0x912E 0x912F 0x9130 0x9131 0x9132 0x9133 0x9134 0x9136 0x9139 0x913A 0x9142 0x9143 +0x9145 0x9146 0x9147 0x9148 0x9149 0x914A 0x914B 0x914C 0x914D 0x914E 0x914F 0x9150 0x9152 0x9154 0x9155 0x9156 +0x9157 0x9158 0x915A 0x915C 0x915D 0x915E 0x9161 0x9162 0x9163 0x9164 0x9165 0x9166 0x9169 0x916A 0x916C 0x916E +0x916F 0x9170 0x9171 0x9172 0x9173 0x9174 0x9175 0x9176 0x9177 0x9178 0x9179 0x917A 0x917D 0x917E 0x917F 0x9181 +0x9182 0x9183 0x9184 0x9185 0x9187 0x9189 0x918B 0x918C 0x918D 0x9190 0x9191 0x9192 0x9196 0x9197 0x919A 0x919B +0x919C 0x919E 0x91A1 0x91A2 0x91A3 0x91A4 0x91A8 0x91AA 0x91AB 0x91AC 0x91AD 0x91AE 0x91AF 0x91B1 0x91B2 0x91B4 +0x91B5 0x91B8 0x91BA 0x91BE 0x91C0 0x91C1 0x91C3 0x91C5 0x91C6 0x91C7 0x91C8 0x91C9 0x91CA 0x91CB 0x91CC 0x91CD +0x91CE 0x91CF 0x91D0 0x91D1 0x91D2 0x91D3 0x91D4 0x91D5 0x91D6 0x91D7 0x91D8 0x91D9 0x91DA 0x91DB 0x91DC 0x91DD +0x91DF 0x91E1 0x91E2 0x91E3 0x91E4 0x91E6 0x91E7 0x91E8 0x91E9 0x91EA 0x91EB 0x91EC 0x91ED 0x91EE 0x91F1 0x91F3 +0x91F4 0x91F5 0x91F6 0x91F7 0x91F8 0x91F9 0x91FA 0x91FC 0x91FD 0x91FE 0x91FF 0x9200 0x9201 0x9202 0x9203 0x9204 +0x9205 0x9206 0x9207 0x9208 0x9209 0x920A 0x920C 0x920D 0x920E 0x920F 0x9210 0x9211 0x9212 0x9214 0x9215 0x9216 +0x9217 0x9219 0x921A 0x921C 0x921E 0x9223 0x9224 0x9225 0x9226 0x9227 0x9229 0x922A 0x922C 0x922D 0x922E 0x9230 +0x9231 0x9232 0x9233 0x9234 0x9236 0x9237 0x9238 0x9239 0x923A 0x923D 0x923E 0x923F 0x9240 0x9244 0x9245 0x9246 +0x9248 0x9249 0x924A 0x924B 0x924C 0x924D 0x924E 0x924F 0x9250 0x9251 0x9252 0x9253 0x9254 0x9255 0x9256 0x9257 +0x925A 0x925B 0x925D 0x925E 0x9260 0x9261 0x9262 0x9263 0x9264 0x9265 0x9266 0x9267 0x9268 0x926C 0x926D 0x926E +0x926F 0x9270 0x9271 0x9272 0x9273 0x9274 0x9276 0x9277 0x9278 0x9279 0x927A 0x927B 0x927C 0x927D 0x927E 0x927F +0x9280 0x9282 0x9283 0x9285 0x9286 0x9287 0x9288 0x928A 0x928B 0x928C 0x928D 0x928E 0x9291 0x9293 0x9294 0x9295 +0x9296 0x9297 0x9298 0x9299 0x929A 0x929B 0x929C 0x929D 0x92A0 0x92A1 0x92A2 0x92A3 0x92A4 0x92A5 0x92A6 0x92A7 +0x92A8 0x92A9 0x92AA 0x92AB 0x92AC 0x92AD 0x92AE 0x92B1 0x92B2 0x92B3 0x92B6 0x92B7 0x92B9 0x92BB 0x92BC 0x92C1 +0x92C2 0x92C3 0x92C5 0x92C6 0x92C7 0x92C8 0x92C9 0x92CC 0x92CF 0x92D0 0x92D2 0x92D5 0x92D7 0x92D9 0x92DD 0x92DF +0x92E3 0x92E4 0x92E5 0x92E6 0x92E7 0x92E8 0x92E9 0x92EA 0x92EC 0x92ED 0x92EE 0x92EF 0x92F0 0x92F1 0x92F2 0x92F3 +0x92F6 0x92F8 0x92F9 0x92FA 0x92FC 0x9300 0x9301 0x9302 0x9304 0x9306 0x9307 0x9308 0x930F 0x9310 0x9312 0x9315 +0x9318 0x9319 0x931A 0x931B 0x931E 0x931F 0x9320 0x9321 0x9322 0x9323 0x9324 0x9326 0x9327 0x9328 0x9329 0x932A +0x932B 0x932C 0x932E 0x932F 0x9332 0x9333 0x9335 0x9336 0x9338 0x933A 0x933B 0x933C 0x933E 0x9340 0x9341 0x9343 +0x9344 0x9345 0x9346 0x9347 0x9348 0x9349 0x934A 0x934B 0x934D 0x9351 0x9352 0x9354 0x9355 0x9356 0x9358 0x9359 +0x935A 0x935B 0x935C 0x935E 0x9360 0x9364 0x9365 0x9369 0x936A 0x936C 0x936D 0x936E 0x9370 0x9375 0x9376 0x937A +0x937C 0x937E 0x9382 0x9384 0x9385 0x9387 0x938A 0x938C 0x938F 0x9393 0x9394 0x9396 0x9397 0x9398 0x939A 0x939B +0x939D 0x93A1 0x93A2 0x93A3 0x93A4 0x93A6 0x93A7 0x93A9 0x93AA 0x93AC 0x93AD 0x93AE 0x93AF 0x93B0 0x93B2 0x93B3 +0x93B5 0x93B6 0x93B7 0x93B8 0x93B9 0x93BF 0x93C2 0x93C3 0x93C4 0x93C7 0x93C8 0x93CA 0x93CB 0x93CC 0x93CD 0x93CF +0x93D0 0x93D1 0x93D6 0x93D7 0x93D8 0x93DC 0x93DD 0x93DE 0x93DF 0x93E1 0x93E2 0x93E4 0x93E5 0x93E6 0x93E8 0x93F0 +0x93F1 0x93F5 0x93F6 0x93F7 0x93F9 0x93FA 0x93FB 0x93FD 0x9403 0x9404 0x9407 0x940B 0x940D 0x940E 0x940F 0x9410 +0x9412 0x9413 0x9414 0x9418 0x9419 0x941A 0x941D 0x9420 0x9421 0x9424 0x9425 0x9426 0x9427 0x9428 0x9429 0x942B +0x942E 0x942F 0x9431 0x9432 0x9433 0x9435 0x9436 0x9438 0x943A 0x943D 0x943E 0x943F 0x9440 0x9441 0x9442 0x9444 +0x944A 0x944C 0x9451 0x9452 0x9453 0x9454 0x9455 0x945A 0x945B 0x945E 0x9460 0x9462 0x9463 0x9464 0x9465 0x946A +0x946B 0x946D 0x9470 0x9471 0x9472 0x9473 0x9474 0x9475 0x9476 0x9477 0x9478 0x9479 0x947C 0x947D 0x947E 0x947F +0x9480 0x9481 0x9482 0x9483 0x9485 0x9486 0x9487 0x9488 0x9489 0x948A 0x948B 0x948C 0x948D 0x948E 0x948F 0x9490 +0x9491 0x9492 0x9493 0x9494 0x9495 0x9496 0x9497 0x9498 0x9499 0x949A 0x949B 0x949C 0x949D 0x949E 0x949F 0x94A0 +0x94A1 0x94A2 0x94A3 0x94A4 0x94A5 0x94A6 0x94A7 0x94A8 0x94A9 0x94AA 0x94AB 0x94AC 0x94AD 0x94AE 0x94AF 0x94B0 +0x94B1 0x94B2 0x94B3 0x94B4 0x94B5 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BB 0x94BC 0x94BD 0x94BE 0x94BF 0x94C0 +0x94C1 0x94C2 0x94C3 0x94C4 0x94C5 0x94C6 0x94C7 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC 0x94CD 0x94CE 0x94CF 0x94D0 +0x94D1 0x94D2 0x94D3 0x94D4 0x94D5 0x94D6 0x94D7 0x94D8 0x94D9 0x94DA 0x94DB 0x94DC 0x94DD 0x94DE 0x94DF 0x94E0 +0x94E1 0x94E2 0x94E3 0x94E4 0x94E5 0x94E6 0x94E7 0x94E8 0x94E9 0x94EA 0x94EB 0x94EC 0x94ED 0x94EE 0x94EF 0x94F0 +0x94F1 0x94F2 0x94F3 0x94F4 0x94F5 0x94F6 0x94F7 0x94F8 0x94F9 0x94FA 0x94FB 0x94FC 0x94FD 0x94FE 0x94FF 0x9500 +0x9501 0x9502 0x9503 0x9504 0x9505 0x9506 0x9507 0x9508 0x9509 0x950A 0x950B 0x950C 0x950D 0x950E 0x950F 0x9510 +0x9511 0x9512 0x9513 0x9514 0x9515 0x9516 0x9517 0x9518 0x9519 0x951A 0x951B 0x951C 0x951D 0x951E 0x951F 0x9520 +0x9521 0x9522 0x9523 0x9524 0x9525 0x9526 0x9527 0x9528 0x9529 0x952A 0x952B 0x952C 0x952D 0x952E 0x952F 0x9530 +0x9531 0x9532 0x9533 0x9534 0x9535 0x9536 0x9537 0x9538 0x9539 0x953A 0x953B 0x953C 0x953D 0x953E 0x953F 0x9540 +0x9541 0x9542 0x9543 0x9544 0x9545 0x9546 0x9547 0x9548 0x9549 0x954A 0x954B 0x954C 0x954D 0x954E 0x954F 0x9550 +0x9551 0x9552 0x9553 0x9554 0x9555 0x9556 0x9557 0x9558 0x9559 0x955A 0x955B 0x955C 0x955D 0x955E 0x955F 0x9560 +0x9561 0x9562 0x9563 0x9564 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C 0x956D 0x956E 0x956F 0x9570 +0x9571 0x9572 0x9573 0x9574 0x9575 0x9576 0x9577 0x9578 0x957A 0x957B 0x957C 0x957D 0x957F 0x9580 0x9581 0x9582 +0x9583 0x9586 0x9587 0x9588 0x9589 0x958A 0x958B 0x958C 0x958D 0x958E 0x958F 0x9590 0x9591 0x9592 0x9593 0x9594 +0x9596 0x9598 0x9599 0x959B 0x959C 0x959E 0x959F 0x95A0 0x95A1 0x95A2 0x95A3 0x95A4 0x95A5 0x95A7 0x95A8 0x95A9 +0x95AA 0x95AB 0x95AC 0x95AD 0x95AE 0x95B0 0x95B1 0x95B2 0x95B5 0x95B6 0x95B7 0x95B9 0x95BA 0x95BB 0x95BC 0x95BD +0x95BE 0x95BF 0x95C0 0x95C3 0x95C5 0x95C6 0x95C7 0x95C8 0x95C9 0x95CA 0x95CB 0x95CC 0x95CD 0x95D0 0x95D1 0x95D2 +0x95D3 0x95D4 0x95D5 0x95D6 0x95D8 0x95DA 0x95DB 0x95DC 0x95DE 0x95DF 0x95E0 0x95E1 0x95E2 0x95E3 0x95E4 0x95E5 +0x95E8 0x95E9 0x95EA 0x95EB 0x95EC 0x95ED 0x95EE 0x95EF 0x95F0 0x95F1 0x95F2 0x95F3 0x95F4 0x95F5 0x95F6 0x95F7 +0x95F8 0x95F9 0x95FA 0x95FB 0x95FC 0x95FD 0x95FE 0x95FF 0x9600 0x9601 0x9602 0x9603 0x9604 0x9605 0x9606 0x9607 +0x9608 0x9609 0x960A 0x960B 0x960C 0x960D 0x960E 0x960F 0x9610 0x9611 0x9612 0x9613 0x9614 0x9615 0x9616 0x9617 +0x9618 0x9619 0x961A 0x961B 0x961C 0x961D 0x961E 0x961F 0x9620 0x9621 0x9622 0x9623 0x9624 0x9627 0x9628 0x962A +0x962C 0x962D 0x962E 0x962F 0x9630 0x9631 0x9632 0x9633 0x9634 0x9635 0x9636 0x9639 0x963A 0x963B 0x963C 0x963D +0x963F 0x9640 0x9641 0x9642 0x9644 0x9645 0x9646 0x9647 0x9648 0x9649 0x964B 0x964C 0x964D 0x964E 0x964F 0x9650 +0x9651 0x9654 0x9655 0x9658 0x965B 0x965C 0x965D 0x965E 0x965F 0x9661 0x9662 0x9663 0x9664 0x9665 0x9666 0x9667 +0x9668 0x9669 0x966A 0x966C 0x9670 0x9672 0x9673 0x9674 0x9675 0x9676 0x9677 0x9678 0x967A 0x967D 0x9683 0x9684 +0x9685 0x9686 0x9688 0x9689 0x968A 0x968B 0x968D 0x968E 0x968F 0x9690 0x9691 0x9694 0x9695 0x9697 0x9698 0x9699 +0x969B 0x969C 0x96A0 0x96A3 0x96A4 0x96A7 0x96A8 0x96A9 0x96AA 0x96AE 0x96B0 0x96B1 0x96B2 0x96B3 0x96B4 0x96B6 +0x96B7 0x96B8 0x96B9 0x96BA 0x96BB 0x96BC 0x96BD 0x96BE 0x96C0 0x96C1 0x96C3 0x96C4 0x96C5 0x96C6 0x96C7 0x96C9 +0x96CA 0x96CB 0x96CC 0x96CD 0x96CE 0x96CF 0x96D1 0x96D2 0x96D4 0x96D5 0x96D6 0x96D8 0x96D9 0x96DB 0x96DC 0x96DE +0x96E0 0x96E2 0x96E3 0x96E8 0x96E9 0x96EA 0x96EB 0x96EF 0x96F0 0x96F1 0x96F2 0x96F3 0x96F6 0x96F7 0x96F9 0x96FB +0x96FE 0x9700 0x9701 0x9702 0x9704 0x9705 0x9706 0x9707 0x9708 0x9709 0x970A 0x970D 0x970E 0x970F 0x9711 0x9713 +0x9716 0x9719 0x971C 0x971E 0x9721 0x9722 0x9724 0x9726 0x9727 0x9728 0x972A 0x972D 0x9730 0x9732 0x9738 0x9739 +0x973D 0x973E 0x9742 0x9744 0x9746 0x9748 0x9749 0x974D 0x974F 0x9751 0x9752 0x9753 0x9754 0x9756 0x9758 0x9759 +0x975A 0x975B 0x975C 0x975D 0x975E 0x9760 0x9761 0x9762 0x9764 0x9765 0x9766 0x9767 0x9768 0x9769 0x976A 0x976B +0x976C 0x976D 0x976E 0x9770 0x9771 0x9772 0x9773 0x9774 0x9776 0x9777 0x9778 0x9779 0x977A 0x977B 0x977C 0x977D +0x977F 0x9780 0x9781 0x9784 0x9785 0x9786 0x978B 0x978C 0x978D 0x978E 0x978F 0x9790 0x9791 0x9792 0x9794 0x9798 +0x979C 0x97A0 0x97A1 0x97A3 0x97A6 0x97A7 0x97A8 0x97AB 0x97AC 0x97AD 0x97AE 0x97AF 0x97B2 0x97B3 0x97B4 0x97BD +0x97BE 0x97BF 0x97C1 0x97C2 0x97C3 0x97C6 0x97C8 0x97C9 0x97CB 0x97CC 0x97CD 0x97D3 0x97D9 0x97DB 0x97DC 0x97DE +0x97E1 0x97E6 0x97E7 0x97E8 0x97E9 0x97EA 0x97EB 0x97EC 0x97ED 0x97EE 0x97F1 0x97F2 0x97F3 0x97F5 0x97F6 0x97F9 +0x97FB 0x97FE 0x97FF 0x9800 0x9801 0x9802 0x9803 0x9804 0x9805 0x9806 0x9807 0x9808 0x980A 0x980C 0x980D 0x980E +0x980F 0x9810 0x9811 0x9812 0x9813 0x9814 0x9816 0x9817 0x9818 0x981A 0x981C 0x9820 0x9821 0x9824 0x9826 0x982B +0x982C 0x982D 0x982E 0x9830 0x9832 0x9834 0x9835 0x9837 0x9838 0x9839 0x983B 0x983C 0x983D 0x9846 0x984B 0x984C +0x984D 0x984E 0x984F 0x9851 0x9852 0x9853 0x9854 0x9855 0x9857 0x9858 0x9859 0x985A 0x985B 0x985E 0x9862 0x9863 +0x9865 0x9867 0x9869 0x986B 0x986C 0x986F 0x9870 0x9871 0x9872 0x9873 0x9874 0x9875 0x9876 0x9877 0x9878 0x9879 +0x987A 0x987B 0x987C 0x987D 0x987E 0x987F 0x9880 0x9881 0x9882 0x9883 0x9884 0x9885 0x9886 0x9887 0x9888 0x9889 +0x988A 0x988B 0x988C 0x988D 0x988E 0x988F 0x9890 0x9891 0x9892 0x9893 0x9894 0x9895 0x9896 0x9897 0x9898 0x9899 +0x989A 0x989B 0x989C 0x989D 0x989E 0x989F 0x98A0 0x98A1 0x98A2 0x98A3 0x98A4 0x98A5 0x98A6 0x98A7 0x98A8 0x98A9 +0x98AA 0x98AC 0x98AD 0x98AE 0x98AF 0x98B1 0x98B2 0x98B3 0x98B6 0x98B8 0x98BA 0x98BB 0x98BC 0x98BD 0x98BE 0x98BF +0x98C0 0x98C1 0x98C2 0x98C3 0x98C4 0x98C6 0x98C7 0x98C8 0x98C9 0x98CB 0x98CC 0x98CE 0x98CF 0x98D0 0x98D1 0x98D2 +0x98D3 0x98D4 0x98D5 0x98D6 0x98D7 0x98D8 0x98D9 0x98DA 0x98DB 0x98DC 0x98DE 0x98DF 0x98E0 0x98E1 0x98E2 0x98E3 +0x98E5 0x98E7 0x98E8 0x98E9 0x98EA 0x98EB 0x98ED 0x98EE 0x98EF 0x98F2 0x98F4 0x98F6 0x98F9 0x98FA 0x98FC 0x98FD +0x98FE 0x98FF 0x9900 0x9902 0x9903 0x9904 0x9905 0x9907 0x9908 0x9909 0x990A 0x990C 0x990D 0x990E 0x990F 0x9910 +0x9911 0x9912 0x9913 0x9914 0x9915 0x9916 0x9917 0x9918 0x991A 0x991B 0x991C 0x991D 0x991E 0x991F 0x9920 0x9921 +0x9924 0x9928 0x992C 0x992E 0x9931 0x9932 0x9933 0x9935 0x9936 0x9937 0x9938 0x993A 0x993C 0x993D 0x993E 0x993F +0x9941 0x9942 0x9943 0x9945 0x9948 0x9949 0x994A 0x994B 0x994C 0x994D 0x9950 0x9951 0x9952 0x9954 0x9955 0x9957 +0x9958 0x995C 0x995E 0x9962 0x9963 0x9964 0x9965 0x9966 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x996D 0x996E +0x996F 0x9970 0x9971 0x9972 0x9973 0x9974 0x9975 0x9976 0x9977 0x9978 0x9979 0x997A 0x997B 0x997C 0x997D 0x997E +0x997F 0x9980 0x9981 0x9982 0x9983 0x9984 0x9985 0x9986 0x9987 0x9988 0x9989 0x998A 0x998B 0x998C 0x998D 0x998E +0x998F 0x9990 0x9991 0x9992 0x9993 0x9994 0x9995 0x9996 0x9997 0x9998 0x9999 0x999D 0x999E 0x99A5 0x99A7 0x99A8 +0x99AC 0x99AD 0x99AE 0x99AF 0x99B0 0x99B1 0x99B2 0x99B3 0x99B4 0x99B5 0x99B9 0x99BA 0x99BB 0x99BC 0x99BD 0x99C1 +0x99C2 0x99C3 0x99C4 0x99C5 0x99C6 0x99C7 0x99C8 0x99C9 0x99CB 0x99CC 0x99CD 0x99CE 0x99CF 0x99D0 0x99D1 0x99D2 +0x99D3 0x99D4 0x99D5 0x99D6 0x99D7 0x99D8 0x99D9 0x99DB 0x99DC 0x99DD 0x99DF 0x99E1 0x99E2 0x99E3 0x99E4 0x99E5 +0x99E7 0x99E9 0x99EA 0x99EC 0x99ED 0x99EE 0x99F0 0x99F1 0x99F2 0x99F8 0x99FB 0x99FC 0x99FF 0x9A01 0x9A02 0x9A03 +0x9A04 0x9A05 0x9A06 0x9A08 0x9A0A 0x9A0C 0x9A0D 0x9A0E 0x9A0F 0x9A11 0x9A12 0x9A13 0x9A16 0x9A19 0x9A1E 0x9A20 +0x9A24 0x9A27 0x9A28 0x9A2B 0x9A2D 0x9A2E 0x9A2F 0x9A30 0x9A31 0x9A35 0x9A36 0x9A37 0x9A38 0x9A3E 0x9A40 0x9A41 +0x9A42 0x9A43 0x9A44 0x9A45 0x9A4A 0x9A4C 0x9A4D 0x9A4E 0x9A4F 0x9A50 0x9A52 0x9A55 0x9A57 0x9A5A 0x9A5B 0x9A5F +0x9A62 0x9A63 0x9A64 0x9A65 0x9A66 0x9A69 0x9A6A 0x9A6B 0x9A6C 0x9A6D 0x9A6E 0x9A6F 0x9A70 0x9A71 0x9A72 0x9A73 +0x9A74 0x9A75 0x9A76 0x9A77 0x9A78 0x9A79 0x9A7A 0x9A7B 0x9A7C 0x9A7D 0x9A7E 0x9A7F 0x9A80 0x9A81 0x9A82 0x9A83 +0x9A84 0x9A85 0x9A86 0x9A87 0x9A88 0x9A89 0x9A8A 0x9A8B 0x9A8C 0x9A8D 0x9A8E 0x9A8F 0x9A90 0x9A91 0x9A92 0x9A93 +0x9A94 0x9A95 0x9A96 0x9A97 0x9A98 0x9A99 0x9A9A 0x9A9B 0x9A9C 0x9A9D 0x9A9E 0x9A9F 0x9AA0 0x9AA1 0x9AA2 0x9AA3 +0x9AA4 0x9AA5 0x9AA6 0x9AA7 0x9AA8 0x9AAB 0x9AAD 0x9AAF 0x9AB0 0x9AB1 0x9AB3 0x9AB4 0x9AB6 0x9AB7 0x9AB8 0x9AB9 +0x9ABA 0x9ABB 0x9ABC 0x9ABE 0x9ABF 0x9AC0 0x9AC1 0x9AC2 0x9AC3 0x9AC4 0x9AC5 0x9AC6 0x9AC7 0x9AC8 0x9ACA 0x9ACB +0x9ACC 0x9ACD 0x9ACE 0x9ACF 0x9AD0 0x9AD1 0x9AD2 0x9AD3 0x9AD4 0x9AD5 0x9AD6 0x9AD8 0x9AD9 0x9ADC 0x9ADD 0x9ADE +0x9ADF 0x9AE1 0x9AE2 0x9AE3 0x9AE5 0x9AE6 0x9AE7 0x9AEA 0x9AEB 0x9AEC 0x9AED 0x9AEE 0x9AEF 0x9AF1 0x9AF2 0x9AF3 +0x9AF4 0x9AF6 0x9AF7 0x9AF9 0x9AFA 0x9AFB 0x9AFC 0x9AFD 0x9AFE 0x9B01 0x9B03 0x9B04 0x9B05 0x9B06 0x9B08 0x9B0A +0x9B0B 0x9B0C 0x9B0D 0x9B0E 0x9B0F 0x9B10 0x9B11 0x9B12 0x9B13 0x9B15 0x9B16 0x9B17 0x9B18 0x9B19 0x9B1A 0x9B1E +0x9B1F 0x9B20 0x9B22 0x9B23 0x9B24 0x9B25 0x9B27 0x9B28 0x9B29 0x9B2A 0x9B2B 0x9B2E 0x9B2F 0x9B31 0x9B32 0x9B33 +0x9B35 0x9B36 0x9B37 0x9B39 0x9B3A 0x9B3B 0x9B3C 0x9B3E 0x9B3F 0x9B41 0x9B42 0x9B43 0x9B44 0x9B45 0x9B46 0x9B47 +0x9B48 0x9B49 0x9B4A 0x9B4B 0x9B4C 0x9B4D 0x9B4E 0x9B4F 0x9B51 0x9B52 0x9B54 0x9B55 0x9B56 0x9B58 0x9B59 0x9B5A +0x9B5B 0x9B5C 0x9B5F 0x9B60 0x9B61 0x9B62 0x9B64 0x9B66 0x9B67 0x9B68 0x9B69 0x9B6C 0x9B6F 0x9B70 0x9B71 0x9B74 +0x9B75 0x9B76 0x9B77 0x9B7A 0x9B7B 0x9B7C 0x9B7D 0x9B7E 0x9B80 0x9B81 0x9B82 0x9B83 0x9B84 0x9B85 0x9B86 0x9B87 +0x9B88 0x9B8A 0x9B8B 0x9B8D 0x9B8E 0x9B90 0x9B91 0x9B92 0x9B93 0x9B95 0x9B96 0x9B97 0x9B9A 0x9B9B 0x9B9C 0x9B9D +0x9B9E 0x9B9F 0x9BA0 0x9BA1 0x9BA2 0x9BA3 0x9BA4 0x9BA5 0x9BA6 0x9BA8 0x9BAA 0x9BAB 0x9BAD 0x9BAE 0x9BAF 0x9BB0 +0x9BB3 0x9BB4 0x9BB5 0x9BB6 0x9BB8 0x9BB9 0x9BBA 0x9BBD 0x9BBF 0x9BC0 0x9BC1 0x9BC3 0x9BC4 0x9BC6 0x9BC7 0x9BC8 +0x9BC9 0x9BCA 0x9BCF 0x9BD1 0x9BD2 0x9BD3 0x9BD4 0x9BD5 0x9BD6 0x9BD7 0x9BD9 0x9BDA 0x9BDB 0x9BDC 0x9BDD 0x9BDE +0x9BE0 0x9BE1 0x9BE2 0x9BE3 0x9BE4 0x9BE5 0x9BE6 0x9BE7 0x9BE8 0x9BEA 0x9BEB 0x9BEC 0x9BED 0x9BF0 0x9BF1 0x9BF2 +0x9BF4 0x9BF5 0x9BF6 0x9BF7 0x9BF8 0x9BFB 0x9BFD 0x9BFF 0x9C01 0x9C02 0x9C03 0x9C04 0x9C05 0x9C06 0x9C07 0x9C08 +0x9C09 0x9C0A 0x9C0B 0x9C0C 0x9C0D 0x9C0E 0x9C0F 0x9C10 0x9C12 0x9C13 0x9C14 0x9C15 0x9C17 0x9C1B 0x9C1C 0x9C1D +0x9C1F 0x9C20 0x9C21 0x9C23 0x9C24 0x9C25 0x9C27 0x9C28 0x9C29 0x9C2D 0x9C2E 0x9C2F 0x9C30 0x9C31 0x9C32 0x9C33 +0x9C35 0x9C36 0x9C37 0x9C39 0x9C3A 0x9C3B 0x9C3C 0x9C3E 0x9C40 0x9C42 0x9C45 0x9C46 0x9C47 0x9C48 0x9C49 0x9C4A +0x9C4B 0x9C4D 0x9C52 0x9C54 0x9C56 0x9C57 0x9C58 0x9C59 0x9C5A 0x9C5D 0x9C5F 0x9C60 0x9C63 0x9C64 0x9C65 0x9C66 +0x9C67 0x9C68 0x9C6D 0x9C6E 0x9C6F 0x9C72 0x9C74 0x9C75 0x9C76 0x9C77 0x9C78 0x9C7A 0x9C7C 0x9C7D 0x9C7E 0x9C7F +0x9C80 0x9C81 0x9C82 0x9C83 0x9C84 0x9C85 0x9C86 0x9C87 0x9C88 0x9C89 0x9C8A 0x9C8B 0x9C8C 0x9C8D 0x9C8E 0x9C8F +0x9C90 0x9C91 0x9C92 0x9C93 0x9C94 0x9C95 0x9C96 0x9C97 0x9C98 0x9C99 0x9C9A 0x9C9B 0x9C9C 0x9C9D 0x9C9E 0x9C9F +0x9CA0 0x9CA1 0x9CA2 0x9CA3 0x9CA4 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAA 0x9CAB 0x9CAC 0x9CAD 0x9CAE 0x9CAF +0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 0x9CB6 0x9CB7 0x9CB8 0x9CB9 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CBE 0x9CBF +0x9CC0 0x9CC1 0x9CC2 0x9CC3 0x9CC4 0x9CC5 0x9CC6 0x9CC7 0x9CC8 0x9CC9 0x9CCA 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF +0x9CD0 0x9CD1 0x9CD2 0x9CD3 0x9CD4 0x9CD5 0x9CD6 0x9CD7 0x9CD8 0x9CD9 0x9CDA 0x9CDB 0x9CDC 0x9CDD 0x9CDE 0x9CDF +0x9CE0 0x9CE1 0x9CE2 0x9CE3 0x9CE4 0x9CE5 0x9CE6 0x9CE7 0x9CE9 0x9CEA 0x9CEB 0x9CEC 0x9CED 0x9CF0 0x9CF1 0x9CF2 +0x9CF3 0x9CF4 0x9CF5 0x9CF6 0x9CF7 0x9CF9 0x9CFA 0x9CFB 0x9CFC 0x9CFD 0x9CFE 0x9CFF 0x9D00 0x9D02 0x9D03 0x9D04 +0x9D05 0x9D06 0x9D07 0x9D08 0x9D09 0x9D0E 0x9D10 0x9D12 0x9D14 0x9D15 0x9D1B 0x9D1C 0x9D1D 0x9D1E 0x9D1F 0x9D23 +0x9D26 0x9D28 0x9D2A 0x9D2B 0x9D2C 0x9D2F 0x9D30 0x9D33 0x9D34 0x9D37 0x9D3B 0x9D3D 0x9D3E 0x9D3F 0x9D41 0x9D42 +0x9D43 0x9D44 0x9D46 0x9D48 0x9D4F 0x9D50 0x9D51 0x9D52 0x9D53 0x9D59 0x9D5C 0x9D5D 0x9D5E 0x9D5F 0x9D60 0x9D61 +0x9D64 0x9D6A 0x9D6B 0x9D6C 0x9D6E 0x9D6F 0x9D70 0x9D72 0x9D77 0x9D7A 0x9D7E 0x9D84 0x9D86 0x9D87 0x9D89 0x9D8A +0x9D8F 0x9D92 0x9D93 0x9D96 0x9D98 0x9D9A 0x9DA0 0x9DA1 0x9DA4 0x9DA5 0x9DA9 0x9DAA 0x9DAB 0x9DAC 0x9DAF 0x9DB1 +0x9DB2 0x9DB4 0x9DB5 0x9DB8 0x9DB9 0x9DBA 0x9DBB 0x9DBC 0x9DBF 0x9DC0 0x9DC1 0x9DC2 0x9DC3 0x9DC4 0x9DC6 0x9DC8 +0x9DC9 0x9DCA 0x9DCF 0x9DD3 0x9DD6 0x9DD7 0x9DD9 0x9DDA 0x9DDF 0x9DE5 0x9DE6 0x9DEB 0x9DED 0x9DEF 0x9DF2 0x9DF3 +0x9DF4 0x9DF8 0x9DF9 0x9DFA 0x9DFD 0x9DFF 0x9E02 0x9E07 0x9E0A 0x9E0C 0x9E0F 0x9E11 0x9E15 0x9E18 0x9E19 0x9E1A +0x9E1B 0x9E1D 0x9E1E 0x9E1F 0x9E20 0x9E21 0x9E22 0x9E23 0x9E24 0x9E25 0x9E26 0x9E27 0x9E28 0x9E29 0x9E2A 0x9E2B +0x9E2C 0x9E2D 0x9E2E 0x9E2F 0x9E30 0x9E31 0x9E32 0x9E33 0x9E34 0x9E35 0x9E36 0x9E37 0x9E38 0x9E39 0x9E3A 0x9E3B +0x9E3C 0x9E3D 0x9E3E 0x9E3F 0x9E40 0x9E41 0x9E42 0x9E43 0x9E44 0x9E45 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4A 0x9E4B +0x9E4C 0x9E4D 0x9E4E 0x9E4F 0x9E50 0x9E51 0x9E52 0x9E53 0x9E54 0x9E55 0x9E56 0x9E57 0x9E58 0x9E59 0x9E5A 0x9E5B +0x9E5C 0x9E5D 0x9E5E 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E63 0x9E64 0x9E65 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B +0x9E6C 0x9E6D 0x9E6E 0x9E6F 0x9E70 0x9E71 0x9E72 0x9E73 0x9E74 0x9E75 0x9E78 0x9E79 0x9E7A 0x9E7C 0x9E7D 0x9E7E +0x9E7F 0x9E80 0x9E81 0x9E82 0x9E83 0x9E86 0x9E87 0x9E88 0x9E89 0x9E8A 0x9E8B 0x9E8C 0x9E8D 0x9E8E 0x9E90 0x9E91 +0x9E92 0x9E93 0x9E94 0x9E95 0x9E96 0x9E97 0x9E99 0x9E9A 0x9E9B 0x9E9C 0x9E9D 0x9E9F 0x9EA0 0x9EA1 0x9EA4 0x9EA5 +0x9EA6 0x9EA7 0x9EA8 0x9EA9 0x9EAA 0x9EAB 0x9EAC 0x9EAD 0x9EAE 0x9EAF 0x9EB0 0x9EB1 0x9EB2 0x9EB3 0x9EB4 0x9EB5 +0x9EB6 0x9EB7 0x9EB8 0x9EB9 0x9EBA 0x9EBB 0x9EBC 0x9EBD 0x9EBE 0x9EBF 0x9EC0 0x9EC1 0x9EC2 0x9EC3 0x9EC4 0x9EC5 +0x9EC6 0x9EC7 0x9EC8 0x9EC9 0x9ECA 0x9ECB 0x9ECC 0x9ECD 0x9ECE 0x9ECF 0x9ED0 0x9ED1 0x9ED2 0x9ED3 0x9ED4 0x9ED5 +0x9ED6 0x9ED7 0x9ED8 0x9ED9 0x9EDA 0x9EDB 0x9EDC 0x9EDD 0x9EDE 0x9EDF 0x9EE0 0x9EE1 0x9EE2 0x9EE3 0x9EE4 0x9EE5 +0x9EE6 0x9EE7 0x9EE8 0x9EE9 0x9EEA 0x9EEB 0x9EEC 0x9EED 0x9EEE 0x9EEF 0x9EF0 0x9EF1 0x9EF2 0x9EF3 0x9EF4 0x9EF5 +0x9EF6 0x9EF7 0x9EF8 0x9EF9 0x9EFA 0x9EFB 0x9EFC 0x9EFD 0x9EFE 0x9EFF 0x9F00 0x9F01 0x9F02 0x9F03 0x9F04 0x9F05 +0x9F06 0x9F07 0x9F08 0x9F09 0x9F0A 0x9F0B 0x9F0C 0x9F0D 0x9F0E 0x9F0F 0x9F10 0x9F11 0x9F12 0x9F13 0x9F14 0x9F15 +0x9F16 0x9F17 0x9F18 0x9F19 0x9F1A 0x9F1B 0x9F1C 0x9F1D 0x9F1E 0x9F1F 0x9F20 0x9F21 0x9F22 0x9F23 0x9F24 0x9F25 +0x9F26 0x9F27 0x9F28 0x9F29 0x9F2A 0x9F2B 0x9F2C 0x9F2D 0x9F2E 0x9F2F 0x9F30 0x9F31 0x9F32 0x9F33 0x9F34 0x9F35 +0x9F36 0x9F37 0x9F38 0x9F39 0x9F3A 0x9F3B 0x9F3C 0x9F3D 0x9F3E 0x9F3F 0x9F40 0x9F41 0x9F42 0x9F43 0x9F44 0x9F45 +0x9F46 0x9F47 0x9F48 0x9F49 0x9F4A 0x9F4B 0x9F4C 0x9F4D 0x9F4E 0x9F4F 0x9F50 0x9F51 0x9F52 0x9F53 0x9F54 0x9F55 +0x9F56 0x9F57 0x9F58 0x9F59 0x9F5A 0x9F5B 0x9F5C 0x9F5D 0x9F5E 0x9F5F 0x9F60 0x9F61 0x9F62 0x9F63 0x9F64 0x9F65 +0x9F66 0x9F67 0x9F68 0x9F69 0x9F6A 0x9F6B 0x9F6C 0x9F6D 0x9F6E 0x9F6F 0x9F70 0x9F71 0x9F72 0x9F73 0x9F74 0x9F75 +0x9F76 0x9F77 0x9F78 0x9F79 0x9F7A 0x9F7B 0x9F7C 0x9F7D 0x9F7E 0x9F7F 0x9F80 0x9F81 0x9F82 0x9F83 0x9F84 0x9F85 +0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A 0x9F8B 0x9F8C 0x9F8D 0x9F8E 0x9F8F 0x9F90 0x9F91 0x9F92 0x9F93 0x9F94 0x9F95 +0x9F96 0x9F97 0x9F98 0x9F99 0x9F9A 0x9F9B 0x9F9C 0x9F9D 0x9F9E 0x9F9F 0x9FA0 0x9FA1 0x9FA2 0x9FA3 0x9FA4 0x9FA5 +0x9FB0 0x9FB1 0x9FBF 0x9FCD 0x9FCE 0x9FCF 0x9FD4 0x9FEB 0x9FEC 0x9FED 0x9FFD 0xAC00 0xAC01 0xAC02 0xAC03 0xAC04 +0xAC05 0xAC06 0xAC07 0xAC08 0xAC09 0xAC0A 0xAC0B 0xAC0C 0xAC0D 0xAC0E 0xAC0F 0xAC10 0xAC11 0xAC12 0xAC13 0xAC14 +0xAC15 0xAC16 0xAC17 0xAC18 0xAC19 0xAC1A 0xAC1B 0xAC1C 0xAC1D 0xAC1E 0xAC1F 0xAC20 0xAC21 0xAC22 0xAC23 0xAC24 +0xAC25 0xAC26 0xAC27 0xAC28 0xAC29 0xAC2A 0xAC2B 0xAC2C 0xAC2D 0xAC2E 0xAC2F 0xAC30 0xAC31 0xAC32 0xAC33 0xAC34 +0xAC35 0xAC36 0xAC37 0xAC38 0xAC39 0xAC3A 0xAC3B 0xAC3C 0xAC3D 0xAC3E 0xAC3F 0xAC40 0xAC41 0xAC42 0xAC43 0xAC44 +0xAC45 0xAC46 0xAC47 0xAC48 0xAC49 0xAC4A 0xAC4B 0xAC4C 0xAC4D 0xAC4E 0xAC4F 0xAC50 0xAC51 0xAC52 0xAC53 0xAC54 +0xAC55 0xAC56 0xAC57 0xAC58 0xAC59 0xAC5A 0xAC5B 0xAC5C 0xAC5D 0xAC5E 0xAC5F 0xAC60 0xAC61 0xAC62 0xAC63 0xAC64 +0xAC65 0xAC66 0xAC67 0xAC68 0xAC69 0xAC6A 0xAC6B 0xAC6C 0xAC6D 0xAC6E 0xAC6F 0xAC70 0xAC71 0xAC72 0xAC73 0xAC74 +0xAC75 0xAC76 0xAC77 0xAC78 0xAC79 0xAC7A 0xAC7B 0xAC7C 0xAC7D 0xAC7E 0xAC7F 0xAC80 0xAC81 0xAC82 0xAC83 0xAC84 +0xAC85 0xAC86 0xAC87 0xAC88 0xAC89 0xAC8A 0xAC8B 0xAC8C 0xAC8D 0xAC8E 0xAC8F 0xAC90 0xAC91 0xAC92 0xAC93 0xAC94 +0xAC95 0xAC96 0xAC97 0xAC98 0xAC99 0xAC9A 0xAC9B 0xAC9C 0xAC9D 0xAC9E 0xAC9F 0xACA0 0xACA1 0xACA2 0xACA3 0xACA4 +0xACA5 0xACA6 0xACA7 0xACA8 0xACA9 0xACAA 0xACAB 0xACAC 0xACAD 0xACAE 0xACAF 0xACB0 0xACB1 0xACB2 0xACB3 0xACB4 +0xACB5 0xACB6 0xACB7 0xACB8 0xACB9 0xACBA 0xACBB 0xACBC 0xACBD 0xACBE 0xACBF 0xACC0 0xACC1 0xACC2 0xACC3 0xACC4 +0xACC5 0xACC6 0xACC7 0xACC8 0xACC9 0xACCA 0xACCB 0xACCC 0xACCD 0xACCE 0xACCF 0xACD0 0xACD1 0xACD2 0xACD3 0xACD4 +0xACD5 0xACD6 0xACD7 0xACD8 0xACD9 0xACDA 0xACDB 0xACDC 0xACDD 0xACDE 0xACDF 0xACE0 0xACE1 0xACE2 0xACE3 0xACE4 +0xACE7 0xACE8 0xACE9 0xACEA 0xACEB 0xACEC 0xACEE 0xACEF 0xACF0 0xACF1 0xACF2 0xACF3 0xACF4 0xACF5 0xACF6 0xACF7 +0xACF9 0xACFA 0xACFB 0xACFC 0xACFD 0xAD00 0xAD03 0xAD04 0xAD06 0xAD0C 0xAD0D 0xAD0E 0xAD0F 0xAD10 0xAD11 0xAD12 +0xAD18 0xAD19 0xAD1C 0xAD1F 0xAD20 0xAD22 0xAD28 0xAD29 0xAD2A 0xAD2B 0xAD2C 0xAD2D 0xAD34 0xAD35 0xAD38 0xAD3B +0xAD3C 0xAD3E 0xAD44 0xAD45 0xAD46 0xAD47 0xAD48 0xAD49 0xAD50 0xAD51 0xAD54 0xAD57 0xAD58 0xAD60 0xAD61 0xAD62 +0xAD63 0xAD64 0xAD65 0xAD6C 0xAD6D 0xAD70 0xAD73 0xAD74 0xAD75 0xAD76 0xAD78 0xAD7B 0xAD7C 0xAD7D 0xAD7E 0xAD7F +0xAD80 0xAD81 0xAD82 0xAD83 0xAD86 0xAD88 0xAD89 0xAD8C 0xAD8F 0xAD90 0xAD98 0xAD99 0xAD9A 0xAD9B 0xAD9C 0xAD9D +0xADA4 0xADA5 0xADA8 0xADAB 0xADAC 0xADB4 0xADB5 0xADB6 0xADB7 0xADB8 0xADB9 0xADC0 0xADC1 0xADC4 0xADC7 0xADC8 +0xADCA 0xADD0 0xADD1 0xADD2 0xADD3 0xADD4 0xADD5 0xADDC 0xADDD 0xADE0 0xADE4 0xADE8 0xADEC 0xADED 0xADEE 0xADEF +0xADF0 0xADF1 0xADF8 0xADF9 0xADFA 0xADFB 0xADFC 0xADFD 0xADFE 0xADFF 0xAE00 0xAE01 0xAE02 0xAE03 0xAE04 0xAE05 +0xAE06 0xAE07 0xAE08 0xAE09 0xAE0A 0xAE0B 0xAE0C 0xAE0D 0xAE0E 0xAE0F 0xAE11 0xAE12 0xAE13 0xAE14 0xAE15 0xAE18 +0xAE1C 0xAE20 0xAE24 0xAE25 0xAE26 0xAE27 0xAE28 0xAE29 0xAE30 0xAE31 0xAE32 0xAE33 0xAE34 0xAE35 0xAE36 0xAE37 +0xAE38 0xAE39 0xAE3A 0xAE3B 0xAE3C 0xAE3D 0xAE3E 0xAE3F 0xAE40 0xAE41 0xAE42 0xAE43 0xAE44 0xAE45 0xAE46 0xAE47 +0xAE48 0xAE49 0xAE4A 0xAE4B 0xAE4C 0xAE4D 0xAE4E 0xAE50 0xAE53 0xAE54 0xAE56 0xAE5C 0xAE5D 0xAE5E 0xAE5F 0xAE60 +0xAE61 0xAE62 0xAE63 0xAE65 0xAE68 0xAE69 0xAE6A 0xAE6C 0xAE6F 0xAE70 0xAE73 0xAE76 0xAE78 0xAE79 0xAE7A 0xAE7B +0xAE7C 0xAE7D 0xAE81 0xAE84 0xAE85 0xAE86 0xAE88 0xAE8B 0xAE8C 0xAE8D 0xAE94 0xAE95 0xAE96 0xAE97 0xAE98 0xAE99 +0xAEA0 0xAEA1 0xAEA4 0xAEB0 0xAEB1 0xAEB2 0xAEB3 0xAEB4 0xAEB5 0xAEBC 0xAEBD 0xAEBE 0xAEC0 0xAEC2 0xAEC3 0xAEC4 +0xAECC 0xAECD 0xAECE 0xAECF 0xAED0 0xAED1 0xAED2 0xAED3 0xAED5 0xAED8 0xAED9 0xAEDA 0xAEDC 0xAEDF 0xAEE0 0xAEE8 +0xAEE9 0xAEEA 0xAEEB 0xAEEC 0xAEED 0xAEF1 0xAEF4 0xAEF5 0xAEF8 0xAEFB 0xAEFC 0xAF04 0xAF05 0xAF06 0xAF07 0xAF08 +0xAF09 0xAF0D 0xAF10 0xAF11 0xAF17 0xAF20 0xAF21 0xAF22 0xAF23 0xAF24 0xAF25 0xAF2C 0xAF2D 0xAF30 0xAF31 0xAF32 +0xAF33 0xAF34 0xAF36 0xAF38 0xAF3B 0xAF3C 0xAF3D 0xAF3E 0xAF3F 0xAF40 0xAF41 0xAF42 0xAF43 0xAF45 0xAF47 0xAF48 +0xAF49 0xAF4C 0xAF4F 0xAF50 0xAF58 0xAF59 0xAF5A 0xAF5B 0xAF5C 0xAF5D 0xAF64 0xAF65 0xAF68 0xAF6B 0xAF6C 0xAF74 +0xAF75 0xAF76 0xAF77 0xAF78 0xAF79 0xAF80 0xAF81 0xAF84 0xAF87 0xAF88 0xAF90 0xAF91 0xAF92 0xAF93 0xAF94 0xAF95 +0xAF9C 0xAF9D 0xAFA0 0xAFA3 0xAFA4 0xAFAC 0xAFAD 0xAFAE 0xAFAF 0xAFB0 0xAFB1 0xAFB2 0xAFB8 0xAFB9 0xAFBC 0xAFBF +0xAFC0 0xAFC1 0xAFC7 0xAFC8 0xAFC9 0xAFCA 0xAFCB 0xAFCC 0xAFCD 0xAFCE 0xAFCF 0xAFD4 0xAFD5 0xAFD8 0xAFDB 0xAFDC +0xAFE4 0xAFE5 0xAFE6 0xAFE7 0xAFE8 0xAFE9 0xAFF0 0xAFF1 0xAFF4 0xAFF7 0xAFF8 0xB000 0xB001 0xB002 0xB003 0xB004 +0xB005 0xB00C 0xB00D 0xB010 0xB013 0xB014 0xB01C 0xB01D 0xB01E 0xB01F 0xB020 0xB021 0xB028 0xB029 0xB02C 0xB030 +0xB038 0xB039 0xB03A 0xB03B 0xB03C 0xB03D 0xB044 0xB045 0xB048 0xB04A 0xB04B 0xB04C 0xB04D 0xB04E 0xB053 0xB054 +0xB055 0xB056 0xB057 0xB058 0xB059 0xB05A 0xB05B 0xB05D 0xB05F 0xB060 0xB061 0xB064 0xB067 0xB068 0xB06B 0xB070 +0xB071 0xB072 0xB073 0xB074 0xB075 0xB07C 0xB07D 0xB080 0xB083 0xB084 0xB08B 0xB08C 0xB08D 0xB08E 0xB08F 0xB090 +0xB091 0xB095 0xB098 0xB099 0xB09A 0xB09B 0xB09C 0xB09F 0xB0A0 0xB0A1 0xB0A2 0xB0A4 0xB0A8 0xB0A9 0xB0AA 0xB0AB +0xB0AC 0xB0AD 0xB0AE 0xB0AF 0xB0B0 0xB0B1 0xB0B2 0xB0B3 0xB0B4 0xB0B5 0xB0B8 0xB0BB 0xB0BC 0xB0C4 0xB0C5 0xB0C6 +0xB0C7 0xB0C8 0xB0C9 0xB0CE 0xB0D0 0xB0D1 0xB0D4 0xB0D7 0xB0D8 0xB0E0 0xB0E1 0xB0E2 0xB0E3 0xB0E4 0xB0E5 0xB0E6 +0xB0E7 0xB0E9 0xB0EC 0xB0ED 0xB0F0 0xB0FC 0xB0FD 0xB0FE 0xB0FF 0xB100 0xB101 0xB108 0xB109 0xB10A 0xB10B 0xB10C +0xB10F 0xB110 0xB111 0xB112 0xB113 0xB117 0xB118 0xB119 0xB11A 0xB11B 0xB11C 0xB11D 0xB11E 0xB11F 0xB120 0xB121 +0xB122 0xB123 0xB124 0xB125 0xB128 0xB12B 0xB12C 0xB134 0xB135 0xB136 0xB137 0xB138 0xB139 0xB13C 0xB13D 0xB13E +0xB13F 0xB140 0xB141 0xB143 0xB144 0xB147 0xB148 0xB14B 0xB150 0xB151 0xB152 0xB153 0xB154 0xB155 0xB156 0xB157 +0xB158 0xB159 0xB15A 0xB15B 0xB15C 0xB15D 0xB160 0xB163 0xB164 0xB16C 0xB16D 0xB16E 0xB16F 0xB170 0xB171 0xB178 +0xB179 0xB17A 0xB17B 0xB17C 0xB17E 0xB17F 0xB180 0xB181 0xB182 0xB188 0xB189 0xB18A 0xB18B 0xB18C 0xB18D 0xB18E +0xB18F 0xB190 0xB191 0xB192 0xB193 0xB194 0xB195 0xB198 0xB19B 0xB19C 0xB1A4 0xB1A5 0xB1A6 0xB1A7 0xB1A8 0xB1A9 +0xB1B0 0xB1B4 0xB1B8 0xB1C0 0xB1C1 0xB1C2 0xB1C3 0xB1C4 0xB1C5 0xB1CC 0xB1CD 0xB1D0 0xB1D3 0xB1D4 0xB1DC 0xB1DD +0xB1DE 0xB1DF 0xB1E0 0xB1E1 0xB1E6 0xB1E8 0xB1E9 0xB1EC 0xB1EF 0xB1F0 0xB1F8 0xB1F9 0xB1FA 0xB1FB 0xB1FC 0xB1FD +0xB204 0xB205 0xB208 0xB20B 0xB20C 0xB20D 0xB210 0xB213 0xB214 0xB215 0xB216 0xB217 0xB218 0xB219 0xB21B 0xB21D +0xB21E 0xB220 0xB221 0xB224 0xB227 0xB228 0xB230 0xB231 0xB232 0xB233 0xB234 0xB235 0xB23C 0xB23D 0xB240 0xB243 +0xB244 0xB24C 0xB24D 0xB24E 0xB24F 0xB250 0xB251 0xB258 0xB259 0xB25C 0xB25F 0xB260 0xB268 0xB269 0xB26A 0xB26B +0xB26C 0xB26D 0xB26F 0xB274 0xB275 0xB278 0xB27B 0xB27C 0xB284 0xB285 0xB286 0xB287 0xB288 0xB289 0xB28A 0xB28B +0xB290 0xB291 0xB294 0xB297 0xB298 0xB299 0xB29A 0xB29C 0xB2A0 0xB2A1 0xB2A2 0xB2A3 0xB2A4 0xB2A5 0xB2A6 0xB2A7 +0xB2AA 0xB2AB 0xB2AC 0xB2AD 0xB2B0 0xB2B3 0xB2B4 0xB2BC 0xB2BD 0xB2BE 0xB2BF 0xB2C0 0xB2C1 0xB2C8 0xB2C9 0xB2CC +0xB2CF 0xB2D0 0xB2D1 0xB2D2 0xB2D3 0xB2D4 0xB2D8 0xB2D9 0xB2DA 0xB2DB 0xB2DC 0xB2DD 0xB2DE 0xB2E0 0xB2E2 0xB2E3 +0xB2E4 0xB2E5 0xB2E6 0xB2E8 0xB2EB 0xB2EC 0xB2ED 0xB2EE 0xB2EF 0xB2F0 0xB2F2 0xB2F3 0xB2F4 0xB2F5 0xB2F6 0xB2F7 +0xB2F8 0xB2F9 0xB2FA 0xB2FB 0xB2FC 0xB2FD 0xB2FE 0xB2FF 0xB300 0xB301 0xB304 0xB307 0xB308 0xB310 0xB311 0xB312 +0xB313 0xB314 0xB315 0xB316 0xB319 0xB31C 0xB31D 0xB320 0xB324 0xB327 0xB32C 0xB32D 0xB32E 0xB32F 0xB330 0xB331 +0xB338 0xB33C 0xB348 0xB349 0xB34A 0xB34B 0xB34C 0xB34D 0xB34E 0xB354 0xB355 0xB356 0xB358 0xB359 0xB35B 0xB35C +0xB35E 0xB35F 0xB364 0xB365 0xB366 0xB367 0xB368 0xB369 0xB36A 0xB36B 0xB36D 0xB36E 0xB36F 0xB370 0xB371 0xB374 +0xB377 0xB378 0xB380 0xB381 0xB382 0xB383 0xB384 0xB385 0xB386 0xB38A 0xB38C 0xB38D 0xB38F 0xB390 0xB393 0xB394 +0xB398 0xB39C 0xB39D 0xB39E 0xB39F 0xB3A0 0xB3A1 0xB3A8 0xB3A9 0xB3AC 0xB3B0 0xB3B8 0xB3B9 0xB3BA 0xB3BB 0xB3BC +0xB3BD 0xB3C4 0xB3C5 0xB3C6 0xB3C7 0xB3C8 0xB3CB 0xB3CC 0xB3CE 0xB3CF 0xB3D0 0xB3D3 0xB3D4 0xB3D5 0xB3D6 0xB3D7 +0xB3D8 0xB3D9 0xB3DA 0xB3DB 0xB3DC 0xB3DD 0xB3DE 0xB3DF 0xB3E0 0xB3E1 0xB3E4 0xB3E8 0xB3F0 0xB3F1 0xB3F2 0xB3F3 +0xB3F4 0xB3F5 0xB3FC 0xB400 0xB403 0xB404 0xB40C 0xB40D 0xB40E 0xB40F 0xB410 0xB411 0xB418 0xB419 0xB41C 0xB41F +0xB420 0xB424 0xB428 0xB429 0xB42A 0xB42B 0xB42C 0xB42D 0xB434 0xB435 0xB438 0xB43B 0xB43C 0xB444 0xB445 0xB446 +0xB447 0xB448 0xB449 0xB44F 0xB450 0xB451 0xB452 0xB454 0xB457 0xB458 0xB459 0xB45A 0xB45B 0xB460 0xB461 0xB462 +0xB463 0xB464 0xB465 0xB46A 0xB46C 0xB46D 0xB470 0xB473 0xB474 0xB47C 0xB47D 0xB47E 0xB47F 0xB480 0xB481 0xB488 +0xB489 0xB48C 0xB48F 0xB490 0xB498 0xB499 0xB49A 0xB49B 0xB49C 0xB49D 0xB4A4 0xB4A5 0xB4A8 0xB4AB 0xB4AC 0xB4B4 +0xB4B5 0xB4B6 0xB4B7 0xB4B8 0xB4B9 0xB4C0 0xB4C1 0xB4C4 0xB4C8 0xB4D0 0xB4D1 0xB4D2 0xB4D3 0xB4D4 0xB4D5 0xB4DC +0xB4DD 0xB4DE 0xB4DF 0xB4E0 0xB4E3 0xB4E4 0xB4E5 0xB4E6 0xB4E7 0xB4E8 0xB4EC 0xB4ED 0xB4EE 0xB4EF 0xB4F0 0xB4F1 +0xB4F8 0xB4F9 0xB4FA 0xB4FC 0xB4FF 0xB500 0xB508 0xB509 0xB50A 0xB50B 0xB50C 0xB50D 0xB511 0xB514 0xB515 0xB516 +0xB518 0xB51B 0xB51C 0xB524 0xB525 0xB526 0xB527 0xB528 0xB529 0xB52A 0xB52B 0xB52D 0xB52E 0xB52F 0xB530 0xB531 +0xB532 0xB534 0xB537 0xB538 0xB539 0xB53A 0xB53B 0xB53F 0xB540 0xB541 0xB542 0xB543 0xB544 0xB545 0xB54B 0xB54C +0xB54D 0xB54E 0xB550 0xB553 0xB554 0xB55C 0xB55D 0xB55E 0xB55F 0xB560 0xB561 0xB567 0xB568 0xB569 0xB56C 0xB570 +0xB578 0xB579 0xB57A 0xB57B 0xB57C 0xB57D 0xB584 0xB585 0xB588 0xB594 0xB595 0xB596 0xB597 0xB598 0xB599 0xB5A0 +0xB5A1 0xB5A4 0xB5A7 0xB5A8 0xB5AA 0xB5AB 0xB5AF 0xB5B0 0xB5B1 0xB5B2 0xB5B3 0xB5B4 0xB5B5 0xB5BB 0xB5BC 0xB5BD +0xB5BE 0xB5C0 0xB5C3 0xB5C4 0xB5CC 0xB5CD 0xB5CE 0xB5CF 0xB5D0 0xB5D1 0xB5D8 0xB5D9 0xB5DC 0xB5DF 0xB5E8 0xB5E9 +0xB5EA 0xB5EB 0xB5EC 0xB5ED 0xB5F4 0xB5F5 0xB5F8 0xB604 0xB605 0xB606 0xB607 0xB608 0xB609 0xB610 0xB611 0xB612 +0xB614 0xB617 0xB618 0xB619 0xB61A 0xB61F 0xB620 0xB621 0xB622 0xB623 0xB624 0xB625 0xB62C 0xB62D 0xB630 0xB634 +0xB63C 0xB63D 0xB63E 0xB63F 0xB640 0xB641 0xB647 0xB648 0xB649 0xB64C 0xB64F 0xB650 0xB658 0xB659 0xB65A 0xB65B +0xB65C 0xB65D 0xB664 0xB665 0xB668 0xB66B 0xB66C 0xB674 0xB675 0xB676 0xB677 0xB678 0xB679 0xB680 0xB681 0xB690 +0xB691 0xB692 0xB693 0xB694 0xB695 0xB69C 0xB69D 0xB6A0 0xB6A3 0xB6A4 0xB6A6 0xB6A7 0xB6AB 0xB6AC 0xB6AD 0xB6AE +0xB6AF 0xB6B0 0xB6B1 0xB6B5 0xB6B8 0xB6BC 0xB6BF 0xB6C8 0xB6C9 0xB6CA 0xB6CB 0xB6CC 0xB6CD 0xB6D4 0xB6D8 0xB6DB +0xB6DC 0xB6E4 0xB6E5 0xB6E6 0xB6E7 0xB6E8 0xB6E9 0xB6F0 0xB6F4 0xB6F7 0xB6F8 0xB700 0xB701 0xB702 0xB703 0xB704 +0xB705 0xB70C 0xB70D 0xB710 0xB714 0xB71C 0xB71D 0xB71E 0xB71F 0xB720 0xB721 0xB728 0xB729 0xB72A 0xB72B 0xB72C +0xB72F 0xB730 0xB732 0xB733 0xB737 0xB738 0xB739 0xB73A 0xB73B 0xB73C 0xB73D 0xB73E 0xB743 0xB744 0xB745 0xB748 +0xB74C 0xB754 0xB755 0xB756 0xB757 0xB758 0xB759 0xB760 0xB761 0xB764 0xB767 0xB768 0xB770 0xB771 0xB772 0xB773 +0xB774 0xB775 0xB77B 0xB77C 0xB77D 0xB780 0xB783 0xB784 0xB788 0xB78C 0xB78D 0xB78E 0xB78F 0xB790 0xB791 0xB792 +0xB793 0xB794 0xB795 0xB796 0xB797 0xB798 0xB799 0xB79C 0xB79F 0xB7A0 0xB7A8 0xB7A9 0xB7AA 0xB7AB 0xB7AC 0xB7AD +0xB7B0 0xB7B1 0xB7B2 0xB7B4 0xB7B5 0xB7B8 0xB7BB 0xB7BC 0xB7C4 0xB7C5 0xB7C6 0xB7C7 0xB7C8 0xB7C9 0xB7D0 0xB7D4 +0xB7E0 0xB7E1 0xB7E2 0xB7E3 0xB7E4 0xB7E5 0xB7EC 0xB7ED 0xB7F0 0xB7F2 0xB7F3 0xB7F4 0xB7FC 0xB7FD 0xB7FE 0xB7FF +0xB800 0xB801 0xB802 0xB804 0xB806 0xB807 0xB808 0xB809 0xB80C 0xB80F 0xB810 0xB818 0xB819 0xB81A 0xB81B 0xB81C +0xB81D 0xB821 0xB822 0xB823 0xB824 0xB825 0xB828 0xB82B 0xB82C 0xB830 0xB834 0xB835 0xB836 0xB837 0xB838 0xB839 +0xB83C 0xB83E 0xB840 0xB841 0xB844 0xB847 0xB848 0xB850 0xB851 0xB852 0xB853 0xB854 0xB855 0xB85C 0xB85D 0xB860 +0xB863 0xB864 0xB868 0xB86B 0xB86C 0xB86D 0xB86E 0xB86F 0xB870 0xB871 0xB874 0xB876 0xB877 0xB878 0xB879 0xB87C +0xB880 0xB888 0xB889 0xB88A 0xB88B 0xB88C 0xB88D 0xB894 0xB895 0xB896 0xB897 0xB898 0xB89B 0xB89C 0xB8A4 0xB8A5 +0xB8A6 0xB8A7 0xB8A8 0xB8A9 0xB8B0 0xB8B1 0xB8B4 0xB8B5 0xB8B7 0xB8B8 0xB8C0 0xB8C1 0xB8C2 0xB8C3 0xB8C4 0xB8C5 +0xB8CC 0xB8CD 0xB8CE 0xB8CF 0xB8D0 0xB8D3 0xB8D4 0xB8DC 0xB8DD 0xB8DE 0xB8DF 0xB8E0 0xB8E1 0xB8E8 0xB8E9 0xB8EC +0xB8EF 0xB8F0 0xB8F3 0xB8F8 0xB8F9 0xB8FA 0xB8FB 0xB8FC 0xB8FD 0xB900 0xB902 0xB904 0xB905 0xB908 0xB90B 0xB90C +0xB914 0xB915 0xB916 0xB917 0xB918 0xB919 0xB920 0xB921 0xB924 0xB928 0xB930 0xB931 0xB932 0xB933 0xB934 0xB935 +0xB93C 0xB93D 0xB940 0xB943 0xB944 0xB94C 0xB94D 0xB94E 0xB94F 0xB950 0xB951 0xB958 0xB959 0xB95C 0xB95F 0xB960 +0xB968 0xB969 0xB96A 0xB96B 0xB96C 0xB96D 0xB974 0xB975 0xB978 0xB97B 0xB97C 0xB97D 0xB980 0xB984 0xB985 0xB986 +0xB987 0xB988 0xB989 0xB98A 0xB98B 0xB98D 0xB98E 0xB98F 0xB990 0xB991 0xB994 0xB998 0xB99E 0xB9A0 0xB9A1 0xB9A2 +0xB9A3 0xB9A4 0xB9A5 0xB9AC 0xB9AD 0xB9AE 0xB9AF 0xB9B0 0xB9B3 0xB9B4 0xB9BC 0xB9BD 0xB9BE 0xB9BF 0xB9C0 0xB9C1 +0xB9C2 0xB9C4 0xB9C6 0xB9C8 0xB9C9 0xB9CA 0xB9CB 0xB9CC 0xB9CD 0xB9CE 0xB9CF 0xB9D0 0xB9D1 0xB9D2 0xB9D4 0xB9D8 +0xB9D9 0xB9DA 0xB9DB 0xB9DC 0xB9DD 0xB9DE 0xB9DF 0xB9E0 0xB9E1 0xB9E2 0xB9E3 0xB9E4 0xB9E5 0xB9E6 0xB9E7 0xB9E8 +0xB9EB 0xB9EC 0xB9ED 0xB9F4 0xB9F5 0xB9F6 0xB9F7 0xB9F8 0xB9F9 0xB9FA 0xB9FB 0xB9FC 0xB9FD 0xB9FE 0xB9FF 0xBA00 +0xBA01 0xBA02 0xBA03 0xBA04 0xBA05 0xBA06 0xBA07 0xBA08 0xBA10 0xBA11 0xBA12 0xBA13 0xBA14 0xBA15 0xBA18 0xBA1C +0xBA1D 0xBA1E 0xBA1F 0xBA20 0xBA2C 0xBA2D 0xBA2E 0xBA2F 0xBA30 0xBA31 0xBA32 0xBA33 0xBA34 0xBA35 0xBA36 0xBA37 +0xBA38 0xBA39 0xBA3A 0xBA3B 0xBA3C 0xBA3D 0xBA3E 0xBA3F 0xBA40 0xBA41 0xBA42 0xBA43 0xBA44 0xBA45 0xBA46 0xBA47 +0xBA48 0xBA49 0xBA4A 0xBA4B 0xBA4C 0xBA4D 0xBA4E 0xBA4F 0xBA50 0xBA51 0xBA52 0xBA53 0xBA54 0xBA55 0xBA56 0xBA57 +0xBA58 0xBA59 0xBA5A 0xBA5B 0xBA5C 0xBA60 0xBA64 0xBA65 0xBA66 0xBA67 0xBA68 0xBA69 0xBA6A 0xBA6B 0xBA6C 0xBA6D +0xBA6E 0xBA6F 0xBA70 0xBA71 0xBA72 0xBA73 0xBA74 0xBA75 0xBA76 0xBA77 0xBA78 0xBA79 0xBA7A 0xBA7B 0xBA7C 0xBA7D +0xBA7E 0xBA7F 0xBA80 0xBA81 0xBA82 0xBA83 0xBA84 0xBA85 0xBA86 0xBA87 0xBA89 0xBA8C 0xBA8D 0xBA8E 0xBA8F 0xBA90 +0xBA93 0xBA94 0xBA9C 0xBA9D 0xBA9E 0xBA9F 0xBAA0 0xBAA1 0xBAA2 0xBAA3 0xBAA4 0xBAA5 0xBAA6 0xBAA7 0xBAA8 0xBAA9 +0xBAAA 0xBAAB 0xBAAC 0xBAAD 0xBAAE 0xBAAF 0xBAB0 0xBAB1 0xBAB2 0xBAB3 0xBAB4 0xBAB5 0xBAB6 0xBAB7 0xBAB8 0xBAB9 +0xBABA 0xBABB 0xBABC 0xBABD 0xBABF 0xBAC3 0xBAC4 0xBAC5 0xBAC6 0xBAC8 0xBACB 0xBACC 0xBAD4 0xBAD5 0xBAD6 0xBAD7 +0xBAD8 0xBAD9 0xBAE0 0xBAE4 0xBAE8 0xBAF0 0xBAF1 0xBAF2 0xBAF3 0xBAF4 0xBAF5 0xBAFC 0xBAFD 0xBAFE 0xBB00 0xBB03 +0xBB04 0xBB0C 0xBB0D 0xBB0E 0xBB0F 0xBB10 0xBB11 0xBB18 0xBB19 0xBB1C 0xBB1F 0xBB20 0xBB28 0xBB29 0xBB2A 0xBB2B +0xBB2C 0xBB2D 0xBB34 0xBB35 0xBB36 0xBB38 0xBB3A 0xBB3B 0xBB3C 0xBB3D 0xBB3E 0xBB40 0xBB44 0xBB45 0xBB46 0xBB47 +0xBB48 0xBB49 0xBB4B 0xBB4D 0xBB4F 0xBB50 0xBB51 0xBB54 0xBB57 0xBB58 0xBB60 0xBB61 0xBB62 0xBB63 0xBB64 0xBB65 +0xBB6C 0xBB6D 0xBB6E 0xBB70 0xBB74 0xBB7C 0xBB7D 0xBB7E 0xBB7F 0xBB80 0xBB81 0xBB88 0xBB89 0xBB8A 0xBB8C 0xBB90 +0xBB98 0xBB99 0xBB9A 0xBB9B 0xBB9C 0xBB9D 0xBBA4 0xBBA5 0xBBA6 0xBBA8 0xBBAB 0xBBAC 0xBBB4 0xBBB5 0xBBB6 0xBBB7 +0xBBB8 0xBBB9 0xBBC0 0xBBC1 0xBBC3 0xBBC4 0xBBC7 0xBBC8 0xBBC9 0xBBCA 0xBBCB 0xBBCC 0xBBCD 0xBBCE 0xBBCF 0xBBD0 +0xBBD1 0xBBD2 0xBBD3 0xBBD4 0xBBD5 0xBBD9 0xBBDC 0xBBDD 0xBBDE 0xBBE0 0xBBE4 0xBBEC 0xBBED 0xBBEE 0xBBEF 0xBBF0 +0xBBF1 0xBBF2 0xBBF8 0xBBF9 0xBBFC 0xBBFF 0xBC00 0xBC01 0xBC02 0xBC03 0xBC04 0xBC05 0xBC06 0xBC07 0xBC08 0xBC09 +0xBC0A 0xBC0B 0xBC0C 0xBC0D 0xBC0E 0xBC0F 0xBC10 0xBC11 0xBC14 0xBC15 0xBC16 0xBC17 0xBC18 0xBC1B 0xBC1C 0xBC1D +0xBC1E 0xBC1F 0xBC20 0xBC23 0xBC24 0xBC25 0xBC26 0xBC27 0xBC28 0xBC29 0xBC2B 0xBC2C 0xBC2D 0xBC2F 0xBC30 0xBC31 +0xBC32 0xBC33 0xBC34 0xBC35 0xBC36 0xBC37 0xBC38 0xBC39 0xBC3A 0xBC3B 0xBC3C 0xBC3D 0xBC3E 0xBC3F 0xBC40 0xBC41 +0xBC42 0xBC43 0xBC44 0xBC45 0xBC46 0xBC49 0xBC4C 0xBC4D 0xBC4E 0xBC50 0xBC54 0xBC5C 0xBC5D 0xBC5E 0xBC5F 0xBC60 +0xBC61 0xBC67 0xBC68 0xBC69 0xBC6A 0xBC6B 0xBC6C 0xBC6F 0xBC70 0xBC77 0xBC78 0xBC79 0xBC7A 0xBC7B 0xBC7C 0xBC7D +0xBC84 0xBC85 0xBC86 0xBC88 0xBC8B 0xBC8C 0xBC8D 0xBC8E 0xBC90 0xBC94 0xBC95 0xBC96 0xBC97 0xBC98 0xBC99 0xBC9A +0xBC9C 0xBC9D 0xBC9F 0xBCA0 0xBCA1 0xBCA2 0xBCA3 0xBCA4 0xBCA7 0xBCA8 0xBCB0 0xBCB1 0xBCB2 0xBCB3 0xBCB4 0xBCB5 +0xBCB8 0xBCB9 0xBCBC 0xBCBD 0xBCC0 0xBCC3 0xBCC4 0xBCC8 0xBCCC 0xBCCD 0xBCCE 0xBCCF 0xBCD0 0xBCD1 0xBCD2 0xBCD3 +0xBCD4 0xBCD5 0xBCD8 0xBCD9 0xBCDC 0xBCE0 0xBCE8 0xBCE9 0xBCEA 0xBCEB 0xBCEC 0xBCED 0xBCF4 0xBCF5 0xBCF6 0xBCF7 +0xBCF8 0xBCFB 0xBCFC 0xBCFD 0xBCFE 0xBCFF 0xBD04 0xBD05 0xBD06 0xBD07 0xBD08 0xBD09 0xBD0A 0xBD0B 0xBD0D 0xBD0F +0xBD10 0xBD11 0xBD14 0xBD17 0xBD18 0xBD20 0xBD21 0xBD22 0xBD23 0xBD24 0xBD25 0xBD2C 0xBD30 0xBD33 0xBD34 0xBD3C +0xBD3D 0xBD3E 0xBD3F 0xBD40 0xBD41 0xBD48 0xBD49 0xBD4A 0xBD4C 0xBD4F 0xBD50 0xBD58 0xBD59 0xBD5A 0xBD5B 0xBD5C +0xBD5D 0xBD64 0xBD65 0xBD68 0xBD6C 0xBD74 0xBD75 0xBD76 0xBD77 0xBD78 0xBD79 0xBD80 0xBD81 0xBD82 0xBD84 0xBD87 +0xBD88 0xBD89 0xBD8A 0xBD8B 0xBD8E 0xBD90 0xBD91 0xBD92 0xBD93 0xBD94 0xBD95 0xBD96 0xBD97 0xBD98 0xBD99 0xBD9A +0xBD9B 0xBD9C 0xBD9D 0xBDA0 0xBDA3 0xBDA4 0xBDAC 0xBDAD 0xBDAE 0xBDAF 0xBDB0 0xBDB1 0xBDB4 0xBDB8 0xBDB9 0xBDBC +0xBDBF 0xBDC0 0xBDC1 0xBDC8 0xBDC9 0xBDCA 0xBDCB 0xBDCC 0xBDCD 0xBDD4 0xBDD5 0xBDD8 0xBDDB 0xBDDC 0xBDE4 0xBDE5 +0xBDE6 0xBDE7 0xBDE8 0xBDE9 0xBDF0 0xBDF1 0xBDF2 0xBDF4 0xBDF7 0xBDF8 0xBE00 0xBE01 0xBE02 0xBE03 0xBE04 0xBE05 +0xBE0C 0xBE0D 0xBE10 0xBE13 0xBE14 0xBE15 0xBE17 0xBE18 0xBE1B 0xBE1C 0xBE1D 0xBE1E 0xBE1F 0xBE20 0xBE21 0xBE22 +0xBE23 0xBE25 0xBE27 0xBE28 0xBE29 0xBE2C 0xBE30 0xBE38 0xBE39 0xBE3A 0xBE3B 0xBE3C 0xBE3D 0xBE44 0xBE45 0xBE46 +0xBE47 0xBE48 0xBE49 0xBE4A 0xBE4B 0xBE4C 0xBE4E 0xBE54 0xBE55 0xBE56 0xBE57 0xBE58 0xBE59 0xBE5A 0xBE5B 0xBE5C +0xBE5D 0xBE5F 0xBE60 0xBE61 0xBE62 0xBE63 0xBE64 0xBE65 0xBE66 0xBE67 0xBE68 0xBE69 0xBE6A 0xBE70 0xBE71 0xBE72 +0xBE73 0xBE74 0xBE75 0xBE76 0xBE79 0xBE7B 0xBE7C 0xBE7D 0xBE7E 0xBE7F 0xBE80 0xBE83 0xBE84 0xBE8C 0xBE8D 0xBE8E +0xBE8F 0xBE90 0xBE91 0xBE92 0xBE93 0xBE94 0xBE95 0xBE96 0xBE98 0xBE99 0xBE9C 0xBEA8 0xBEA9 0xBEAA 0xBEAB 0xBEAC +0xBEAD 0xBEAE 0xBEB4 0xBEB5 0xBEB6 0xBEB7 0xBEB8 0xBEBB 0xBEBC 0xBEC4 0xBEC5 0xBEC6 0xBEC7 0xBEC8 0xBEC9 0xBECA +0xBECB 0xBECC 0xBECD 0xBECE 0xBED0 0xBED1 0xBED4 0xBED7 0xBED8 0xBED9 0xBEE0 0xBEE1 0xBEE2 0xBEE3 0xBEE4 0xBEE5 +0xBEE6 0xBEEC 0xBEED 0xBEEE 0xBEEF 0xBEF0 0xBEF3 0xBEF4 0xBEFC 0xBEFD 0xBEFE 0xBEFF 0xBF00 0xBF01 0xBF02 0xBF03 +0xBF04 0xBF05 0xBF06 0xBF08 0xBF09 0xBF0C 0xBF0F 0xBF10 0xBF18 0xBF19 0xBF1A 0xBF1B 0xBF1C 0xBF1D 0xBF1F 0xBF21 +0xBF24 0xBF25 0xBF26 0xBF27 0xBF28 0xBF2B 0xBF2C 0xBF34 0xBF35 0xBF36 0xBF37 0xBF38 0xBF39 0xBF3A 0xBF3B 0xBF3C +0xBF3D 0xBF3E 0xBF40 0xBF41 0xBF44 0xBF47 0xBF48 0xBF50 0xBF51 0xBF52 0xBF53 0xBF54 0xBF55 0xBF59 0xBF5B 0xBF5C +0xBF60 0xBF63 0xBF78 0xBF7F 0xBF94 0xBF98 0xBF9B 0xBFA4 0xBFA5 0xBFAC 0xBFB0 0xBFB1 0xBFB4 0xBFC0 0xBFC1 0xBFC2 +0xBFC3 0xBFC4 0xBFC5 0xBFCC 0xBFCD 0xBFD0 0xBFD3 0xBFD4 0xBFD5 0xBFDC 0xBFDD 0xBFDF 0xBFE1 0xBFE5 0xBFE8 0xBFEF +0xC004 0xC020 0xC021 0xC03C 0xC03D 0xC040 0xC043 0xC044 0xC051 0xC058 0xC059 0xC05C 0xC05F 0xC060 0xC068 0xC069 +0xC06A 0xC06B 0xC06C 0xC06D 0xC074 0xC090 0xC091 0xC094 0xC097 0xC098 0xC0A0 0xC0A1 0xC0A2 0xC0A3 0xC0A4 0xC0A5 +0xC0A6 0xC0A7 0xC0AB 0xC0AC 0xC0AD 0xC0AE 0xC0AF 0xC0B0 0xC0B1 0xC0B2 0xC0B3 0xC0B4 0xC0B5 0xC0B6 0xC0B7 0xC0B8 +0xC0B9 0xC0BA 0xC0BB 0xC0BC 0xC0BD 0xC0BE 0xC0BF 0xC0C0 0xC0C1 0xC0C2 0xC0C3 0xC0C4 0xC0C5 0xC0C6 0xC0C7 0xC0C8 +0xC0C9 0xC0CA 0xC0CB 0xC0CC 0xC0CF 0xC0D0 0xC0D2 0xC0D8 0xC0D9 0xC0DA 0xC0DB 0xC0DC 0xC0DD 0xC0E3 0xC0E4 0xC0E5 +0xC0E8 0xC0EB 0xC0EC 0xC0F4 0xC0F5 0xC0F6 0xC0F7 0xC0F8 0xC0F9 0xC0FB 0xC0FE 0xC0FF 0xC100 0xC101 0xC104 0xC108 +0xC10A 0xC110 0xC111 0xC112 0xC113 0xC114 0xC115 0xC11C 0xC11D 0xC11E 0xC11F 0xC120 0xC123 0xC124 0xC125 0xC126 +0xC127 0xC128 0xC12A 0xC12C 0xC12D 0xC12E 0xC12F 0xC130 0xC131 0xC134 0xC136 0xC138 0xC139 0xC13C 0xC13F 0xC140 +0xC148 0xC149 0xC14A 0xC14B 0xC14C 0xC14D 0xC14E 0xC151 0xC152 0xC154 0xC155 0xC156 0xC157 0xC158 0xC15B 0xC15C +0xC15F 0xC160 0xC164 0xC165 0xC166 0xC167 0xC168 0xC169 0xC170 0xC171 0xC173 0xC174 0xC178 0xC180 0xC181 0xC182 +0xC183 0xC184 0xC185 0xC18A 0xC18C 0xC18D 0xC18E 0xC18F 0xC190 0xC193 0xC194 0xC195 0xC196 0xC197 0xC198 0xC19C +0xC19D 0xC19E 0xC19F 0xC1A0 0xC1A1 0xC1A3 0xC1A5 0xC1A6 0xC1A8 0xC1A9 0xC1AC 0xC1B0 0xC1B8 0xC1B9 0xC1BA 0xC1BB +0xC1BC 0xC1BD 0xC1C4 0xC1C5 0xC1C8 0xC1CB 0xC1CC 0xC1D4 0xC1D5 0xC1D6 0xC1D7 0xC1D8 0xC1D9 0xC1E0 0xC1E1 0xC1E4 +0xC1E7 0xC1E8 0xC1F0 0xC1F1 0xC1F2 0xC1F3 0xC1F4 0xC1F5 0xC1FC 0xC1FD 0xC200 0xC203 0xC204 0xC20C 0xC20D 0xC20E +0xC20F 0xC210 0xC211 0xC216 0xC218 0xC219 0xC21C 0xC21F 0xC220 0xC221 0xC224 0xC227 0xC228 0xC229 0xC22A 0xC22B +0xC22C 0xC22D 0xC22E 0xC22F 0xC231 0xC232 0xC233 0xC234 0xC235 0xC238 0xC23B 0xC23C 0xC244 0xC245 0xC246 0xC247 +0xC248 0xC249 0xC250 0xC251 0xC254 0xC257 0xC258 0xC260 0xC261 0xC262 0xC263 0xC264 0xC265 0xC26C 0xC26D 0xC270 +0xC273 0xC274 0xC27C 0xC27D 0xC27E 0xC27F 0xC280 0xC281 0xC286 0xC288 0xC289 0xC28C 0xC28F 0xC290 0xC298 0xC299 +0xC29A 0xC29B 0xC29C 0xC29D 0xC2A4 0xC2A5 0xC2A8 0xC2AB 0xC2AC 0xC2AD 0xC2AE 0xC2AF 0xC2B0 0xC2B2 0xC2B3 0xC2B4 +0xC2B5 0xC2B6 0xC2B7 0xC2B8 0xC2B9 0xC2BA 0xC2BB 0xC2BC 0xC2BD 0xC2BE 0xC2BF 0xC2C0 0xC2C1 0xC2C4 0xC2C8 0xC2D0 +0xC2D1 0xC2D2 0xC2D3 0xC2D4 0xC2D5 0xC2DC 0xC2DD 0xC2DE 0xC2E0 0xC2E2 0xC2E3 0xC2E4 0xC2E5 0xC2E6 0xC2E8 0xC2EB +0xC2EC 0xC2ED 0xC2EE 0xC2EF 0xC2F0 0xC2F1 0xC2F3 0xC2F4 0xC2F6 0xC2F8 0xC2F9 0xC2FB 0xC2FC 0xC2FF 0xC300 0xC301 +0xC302 0xC308 0xC309 0xC30A 0xC30B 0xC30C 0xC30D 0xC30E 0xC311 0xC313 0xC314 0xC315 0xC316 0xC317 0xC318 0xC31B +0xC31C 0xC324 0xC325 0xC326 0xC327 0xC328 0xC329 0xC32A 0xC32B 0xC32C 0xC32D 0xC32E 0xC32F 0xC330 0xC331 0xC334 +0xC337 0xC338 0xC340 0xC341 0xC342 0xC343 0xC344 0xC345 0xC34C 0xC34D 0xC34E 0xC34F 0xC350 0xC353 0xC354 0xC35C +0xC35D 0xC35E 0xC35F 0xC360 0xC361 0xC362 0xC363 0xC364 0xC365 0xC366 0xC367 0xC368 0xC369 0xC36A 0xC36C 0xC36F +0xC370 0xC372 0xC378 0xC379 0xC37A 0xC37B 0xC37C 0xC37D 0xC382 0xC384 0xC385 0xC386 0xC387 0xC388 0xC38B 0xC38C +0xC394 0xC395 0xC396 0xC397 0xC398 0xC399 0xC39A 0xC39B 0xC39C 0xC39D 0xC39E 0xC39F 0xC3A0 0xC3A1 0xC3A4 0xC3A7 +0xC3A8 0xC3B0 0xC3B1 0xC3B2 0xC3B3 0xC3B4 0xC3B5 0xC3BC 0xC3BD 0xC3BE 0xC3BF 0xC3C0 0xC3C3 0xC3C4 0xC3CC 0xC3CD +0xC3CE 0xC3CF 0xC3D0 0xC3D1 0xC3D2 0xC3D3 0xC3D4 0xC3D5 0xC3D6 0xC3D7 0xC3D8 0xC3D9 0xC3DA 0xC3DC 0xC3DF 0xC3E0 +0xC3E2 0xC3E8 0xC3E9 0xC3EA 0xC3EB 0xC3EC 0xC3ED 0xC3F1 0xC3F4 0xC3F5 0xC3F8 0xC3FB 0xC3FC 0xC404 0xC405 0xC406 +0xC407 0xC408 0xC409 0xC40B 0xC410 0xC411 0xC414 0xC417 0xC418 0xC420 0xC421 0xC422 0xC423 0xC424 0xC425 0xC42C +0xC42D 0xC430 0xC433 0xC434 0xC43C 0xC43D 0xC43E 0xC43F 0xC440 0xC441 0xC448 0xC449 0xC44C 0xC44F 0xC450 0xC458 +0xC459 0xC45A 0xC45B 0xC45C 0xC45D 0xC464 0xC465 0xC468 0xC46B 0xC46C 0xC474 0xC475 0xC476 0xC477 0xC478 0xC479 +0xC47A 0xC47B 0xC47C 0xC47D 0xC47E 0xC47F 0xC480 0xC481 0xC484 0xC487 0xC488 0xC490 0xC491 0xC492 0xC493 0xC494 +0xC495 0xC49C 0xC49D 0xC4A0 0xC4A3 0xC4A4 0xC4AC 0xC4AD 0xC4AE 0xC4AF 0xC4B0 0xC4B1 0xC4B8 0xC4B9 0xC4BC 0xC4BF +0xC4C0 0xC4C8 0xC4C9 0xC4CA 0xC4CB 0xC4CC 0xC4CD 0xC4D3 0xC4D4 0xC4D5 0xC4D8 0xC4DB 0xC4DC 0xC4E4 0xC4E5 0xC4E6 +0xC4E7 0xC4E8 0xC4E9 0xC4F0 0xC4F1 0xC4F4 0xC4F7 0xC4F8 0xC4FA 0xC4FF 0xC500 0xC501 0xC502 0xC503 0xC504 0xC505 +0xC50C 0xC50D 0xC510 0xC514 0xC51C 0xC51D 0xC51E 0xC51F 0xC520 0xC521 0xC528 0xC529 0xC52B 0xC52C 0xC52F 0xC530 +0xC531 0xC538 0xC539 0xC53A 0xC53B 0xC53C 0xC53D 0xC53F 0xC540 0xC543 0xC544 0xC545 0xC546 0xC547 0xC548 0xC549 +0xC54A 0xC54B 0xC54C 0xC54D 0xC54E 0xC54F 0xC550 0xC551 0xC552 0xC553 0xC554 0xC555 0xC556 0xC557 0xC558 0xC559 +0xC55A 0xC55B 0xC55C 0xC55D 0xC55E 0xC55F 0xC560 0xC561 0xC562 0xC563 0xC564 0xC565 0xC566 0xC567 0xC568 0xC569 +0xC56A 0xC56B 0xC56C 0xC56D 0xC56E 0xC56F 0xC570 0xC571 0xC572 0xC573 0xC574 0xC575 0xC576 0xC577 0xC578 0xC579 +0xC57A 0xC57B 0xC57C 0xC57D 0xC57E 0xC57F 0xC580 0xC581 0xC582 0xC583 0xC584 0xC585 0xC586 0xC587 0xC588 0xC589 +0xC58A 0xC58B 0xC58C 0xC58D 0xC58E 0xC58F 0xC590 0xC591 0xC592 0xC593 0xC594 0xC595 0xC596 0xC597 0xC598 0xC599 +0xC59A 0xC59B 0xC59C 0xC59D 0xC59E 0xC59F 0xC5A0 0xC5A1 0xC5A2 0xC5A3 0xC5A4 0xC5A5 0xC5A6 0xC5A7 0xC5A8 0xC5A9 +0xC5AA 0xC5AB 0xC5AC 0xC5AD 0xC5AE 0xC5AF 0xC5B0 0xC5B1 0xC5B2 0xC5B3 0xC5B4 0xC5B5 0xC5B6 0xC5B7 0xC5B8 0xC5B9 +0xC5BA 0xC5BB 0xC5BC 0xC5BD 0xC5BE 0xC5BF 0xC5C0 0xC5C1 0xC5C2 0xC5C3 0xC5C4 0xC5C5 0xC5C6 0xC5C7 0xC5C8 0xC5C9 +0xC5CA 0xC5CB 0xC5CC 0xC5CD 0xC5CE 0xC5CF 0xC5D0 0xC5D1 0xC5D4 0xC5D7 0xC5D8 0xC5E0 0xC5E1 0xC5E2 0xC5E3 0xC5E4 +0xC5E5 0xC5E6 0xC5E7 0xC5E8 0xC5E9 0xC5EA 0xC5EB 0xC5EC 0xC5ED 0xC5EE 0xC5EF 0xC5F0 0xC5F1 0xC5F2 0xC5F3 0xC5F4 +0xC5F5 0xC5F6 0xC5F7 0xC5F8 0xC5F9 0xC5FA 0xC5FB 0xC5FC 0xC5FD 0xC5FE 0xC5FF 0xC600 0xC601 0xC602 0xC603 0xC604 +0xC605 0xC606 0xC607 0xC608 0xC609 0xC60C 0xC60F 0xC610 0xC618 0xC619 0xC61A 0xC61B 0xC61C 0xC61D 0xC620 0xC624 +0xC625 0xC626 0xC628 0xC629 0xC62A 0xC62B 0xC62C 0xC62D 0xC62E 0xC62F 0xC630 0xC631 0xC632 0xC633 0xC634 0xC635 +0xC636 0xC637 0xC638 0xC639 0xC63A 0xC63B 0xC63C 0xC63D 0xC63E 0xC63F 0xC640 0xC641 0xC644 0xC647 0xC648 0xC64E +0xC650 0xC651 0xC652 0xC653 0xC654 0xC655 0xC658 0xC659 0xC65C 0xC65D 0xC660 0xC661 0xC662 0xC663 0xC664 0xC66C +0xC66D 0xC66E 0xC66F 0xC670 0xC671 0xC678 0xC679 0xC67C 0xC67F 0xC680 0xC682 0xC688 0xC689 0xC68A 0xC68B 0xC68C +0xC68D 0xC692 0xC694 0xC695 0xC698 0xC699 0xC69A 0xC69B 0xC69C 0xC69D 0xC6A4 0xC6A5 0xC6A6 0xC6A7 0xC6A8 0xC6A9 +0xC6AC 0xC6B0 0xC6B1 0xC6B2 0xC6B3 0xC6B4 0xC6B5 0xC6B6 0xC6B7 0xC6B8 0xC6B9 0xC6BA 0xC6BB 0xC6BC 0xC6BE 0xC6BF +0xC6C0 0xC6C1 0xC6C2 0xC6C3 0xC6C4 0xC6C5 0xC6C6 0xC6C7 0xC6C8 0xC6C9 0xC6CA 0xC6CB 0xC6CC 0xC6CD 0xC6D0 0xC6D1 +0xC6D2 0xC6D3 0xC6D4 0xC6D8 0xC6DC 0xC6DD 0xC6DE 0xC6DF 0xC6E0 0xC6E1 0xC6E4 0xC6E5 0xC6E8 0xC6E9 0xC6EC 0xC6EF +0xC6F0 0xC6F8 0xC6F9 0xC6FA 0xC6FB 0xC6FC 0xC6FD 0xC701 0xC704 0xC705 0xC708 0xC70B 0xC70C 0xC70E 0xC713 0xC714 +0xC715 0xC716 0xC717 0xC718 0xC719 0xC71C 0xC71D 0xC720 0xC721 0xC724 0xC727 0xC728 0xC730 0xC731 0xC732 0xC733 +0xC734 0xC735 0xC736 0xC737 0xC738 0xC739 0xC73C 0xC73D 0xC73E 0xC73F 0xC740 0xC741 0xC742 0xC743 0xC744 0xC745 +0xC746 0xC747 0xC748 0xC749 0xC74A 0xC74B 0xC74C 0xC74D 0xC74E 0xC74F 0xC750 0xC751 0xC752 0xC753 0xC754 0xC755 +0xC756 0xC757 0xC758 0xC759 0xC75C 0xC75F 0xC760 0xC766 0xC768 0xC769 0xC76A 0xC76B 0xC76C 0xC76D 0xC774 0xC775 +0xC776 0xC777 0xC778 0xC779 0xC77A 0xC77B 0xC77C 0xC77D 0xC77E 0xC77F 0xC780 0xC781 0xC782 0xC783 0xC784 0xC785 +0xC786 0xC787 0xC788 0xC789 0xC78A 0xC78B 0xC78C 0xC78D 0xC78E 0xC78F 0xC790 0xC791 0xC793 0xC794 0xC796 0xC797 +0xC798 0xC799 0xC79A 0xC7A0 0xC7A1 0xC7A2 0xC7A3 0xC7A4 0xC7A5 0xC7A6 0xC7A7 0xC7A9 0xC7AA 0xC7AB 0xC7AC 0xC7AD +0xC7B0 0xC7B2 0xC7B3 0xC7B4 0xC7BC 0xC7BD 0xC7BE 0xC7BF 0xC7C0 0xC7C1 0xC7C2 0xC7C8 0xC7C9 0xC7CC 0xC7CE 0xC7CF +0xC7D0 0xC7D8 0xC7D9 0xC7DA 0xC7DB 0xC7DC 0xC7DD 0xC7E4 0xC7E5 0xC7E8 0xC7EB 0xC7EC 0xC7F4 0xC7F5 0xC7F6 0xC7F7 +0xC7F8 0xC7F9 0xC800 0xC801 0xC802 0xC804 0xC806 0xC807 0xC808 0xC809 0xC80A 0xC80B 0xC810 0xC811 0xC812 0xC813 +0xC814 0xC815 0xC816 0xC819 0xC81B 0xC81C 0xC81D 0xC820 0xC823 0xC824 0xC82C 0xC82D 0xC82E 0xC82F 0xC830 0xC831 +0xC832 0xC836 0xC838 0xC839 0xC83C 0xC83F 0xC840 0xC841 0xC842 0xC843 0xC847 0xC848 0xC849 0xC84A 0xC84B 0xC84C +0xC84D 0xC84E 0xC851 0xC853 0xC854 0xC855 0xC858 0xC85C 0xC864 0xC865 0xC866 0xC867 0xC868 0xC869 0xC870 0xC871 +0xC874 0xC877 0xC878 0xC87A 0xC880 0xC881 0xC882 0xC883 0xC884 0xC885 0xC886 0xC887 0xC88B 0xC88C 0xC88D 0xC890 +0xC892 0xC893 0xC894 0xC895 0xC896 0xC89C 0xC89D 0xC89E 0xC89F 0xC8A0 0xC8A1 0xC8A6 0xC8A8 0xC8A9 0xC8AC 0xC8AF +0xC8B0 0xC8B8 0xC8B9 0xC8BA 0xC8BB 0xC8BC 0xC8BD 0xC8C4 0xC8C5 0xC8C8 0xC8CB 0xC8CC 0xC8D4 0xC8D5 0xC8D6 0xC8D7 +0xC8D8 0xC8D9 0xC8E0 0xC8E1 0xC8E4 0xC8E7 0xC8E8 0xC8F0 0xC8F1 0xC8F2 0xC8F3 0xC8F4 0xC8F5 0xC8FB 0xC8FC 0xC8FD +0xC900 0xC903 0xC904 0xC905 0xC906 0xC908 0xC90C 0xC90D 0xC90E 0xC90F 0xC910 0xC911 0xC917 0xC918 0xC919 0xC91C +0xC91F 0xC920 0xC928 0xC929 0xC92A 0xC92B 0xC92C 0xC92D 0xC934 0xC935 0xC938 0xC93B 0xC93C 0xC944 0xC945 0xC946 +0xC947 0xC948 0xC949 0xC950 0xC951 0xC954 0xC957 0xC958 0xC960 0xC961 0xC962 0xC963 0xC964 0xC965 0xC96C 0xC96D +0xC970 0xC974 0xC97C 0xC97D 0xC97E 0xC97F 0xC980 0xC981 0xC988 0xC989 0xC98C 0xC98F 0xC990 0xC991 0xC992 0xC994 +0xC998 0xC999 0xC99A 0xC99B 0xC99C 0xC99D 0xC99E 0xC9A4 0xC9A5 0xC9A8 0xC9AC 0xC9B4 0xC9B5 0xC9B6 0xC9B7 0xC9B8 +0xC9B9 0xC9C0 0xC9C1 0xC9C4 0xC9C7 0xC9C8 0xC9CA 0xC9CF 0xC9D0 0xC9D1 0xC9D2 0xC9D3 0xC9D4 0xC9D5 0xC9D6 0xC9D7 +0xC9D8 0xC9D9 0xC9DA 0xC9DB 0xC9DC 0xC9DD 0xC9DE 0xC9E0 0xC9E2 0xC9E3 0xC9E4 0xC9E7 0xC9E8 0xC9EC 0xC9ED 0xC9EE +0xC9EF 0xC9F0 0xC9F1 0xC9F2 0xC9F7 0xC9F8 0xC9F9 0xC9FA 0xC9FB 0xC9FC 0xC9FF 0xCA00 0xCA08 0xCA09 0xCA0A 0xCA0B +0xCA0C 0xCA0D 0xCA0E 0xCA0F 0xCA10 0xCA11 0xCA12 0xCA13 0xCA14 0xCA15 0xCA18 0xCA1A 0xCA1C 0xCA24 0xCA25 0xCA26 +0xCA27 0xCA28 0xCA29 0xCA2D 0xCA30 0xCA31 0xCA32 0xCA33 0xCA34 0xCA37 0xCA38 0xCA40 0xCA41 0xCA42 0xCA43 0xCA44 +0xCA45 0xCA46 0xCA47 0xCA48 0xCA49 0xCA4A 0xCA4B 0xCA4C 0xCA4D 0xCA50 0xCA53 0xCA54 0xCA57 0xCA58 0xCA5B 0xCA5C +0xCA5D 0xCA5E 0xCA5F 0xCA60 0xCA61 0xCA67 0xCA68 0xCA69 0xCA6A 0xCA6B 0xCA6C 0xCA6F 0xCA70 0xCA78 0xCA79 0xCA7A +0xCA7B 0xCA7C 0xCA7D 0xCA7E 0xCA7F 0xCA80 0xCA81 0xCA82 0xCA83 0xCA84 0xCA85 0xCA88 0xCA8B 0xCA8C 0xCA94 0xCA95 +0xCA96 0xCA97 0xCA98 0xCA99 0xCAA0 0xCAA1 0xCAA2 0xCAA3 0xCAA4 0xCAA7 0xCAA8 0xCAB0 0xCAB1 0xCAB2 0xCAB3 0xCAB4 +0xCAB5 0xCAB6 0xCAB7 0xCAB8 0xCAB9 0xCABA 0xCABB 0xCABC 0xCABD 0xCABE 0xCAC0 0xCAC3 0xCAC4 0xCAC6 0xCACC 0xCACD +0xCACE 0xCACF 0xCAD0 0xCAD1 0xCAD2 0xCAD3 0xCAD7 0xCAD8 0xCAD9 0xCADC 0xCADF 0xCAE0 0xCAE8 0xCAE9 0xCAEA 0xCAEB +0xCAEC 0xCAED 0xCAF4 0xCAF5 0xCAF8 0xCAFB 0xCAFC 0xCB08 0xCB10 0xCB11 0xCB14 0xCB17 0xCB18 0xCB20 0xCB21 0xCB22 +0xCB23 0xCB24 0xCB25 0xCB26 0xCB27 0xCB28 0xCB29 0xCB2A 0xCB2B 0xCB2C 0xCB2D 0xCB30 0xCB32 0xCB34 0xCB3C 0xCB3D +0xCB3F 0xCB40 0xCB41 0xCB48 0xCB49 0xCB4A 0xCB4C 0xCB4F 0xCB50 0xCB52 0xCB58 0xCB59 0xCB5A 0xCB5B 0xCB5C 0xCB5D +0xCB64 0xCB65 0xCB68 0xCB6B 0xCB6C 0xCB74 0xCB75 0xCB77 0xCB78 0xCB79 0xCB80 0xCB81 0xCB84 0xCB87 0xCB88 0xCB90 +0xCB91 0xCB92 0xCB93 0xCB94 0xCB95 0xCB9C 0xCB9D 0xCBA0 0xCBA3 0xCBA4 0xCBAC 0xCBAD 0xCBAF 0xCBB1 0xCBB8 0xCBB9 +0xCBBC 0xCBC0 0xCBC8 0xCBC9 0xCBCA 0xCBCB 0xCBCC 0xCBCD 0xCBD4 0xCBD5 0xCBD8 0xCBDB 0xCBDC 0xCBE4 0xCBE5 0xCBE6 +0xCBE7 0xCBE8 0xCBE9 0xCBEA 0xCBF0 0xCBF1 0xCBF4 0xCBF8 0xCC00 0xCC01 0xCC02 0xCC03 0xCC04 0xCC05 0xCC06 0xCC0C +0xCC0D 0xCC10 0xCC13 0xCC14 0xCC1C 0xCC1D 0xCC1E 0xCC1F 0xCC20 0xCC21 0xCC22 0xCC26 0xCC27 0xCC28 0xCC29 0xCC2C +0xCC2E 0xCC2F 0xCC30 0xCC31 0xCC38 0xCC39 0xCC3A 0xCC3B 0xCC3C 0xCC3D 0xCC3E 0xCC3F 0xCC42 0xCC44 0xCC45 0xCC48 +0xCC4B 0xCC4C 0xCC54 0xCC55 0xCC56 0xCC57 0xCC58 0xCC59 0xCC5B 0xCC5E 0xCC60 0xCC61 0xCC64 0xCC66 0xCC68 0xCC70 +0xCC71 0xCC72 0xCC73 0xCC74 0xCC75 0xCC7A 0xCC7C 0xCC7D 0xCC91 0xCC98 0xCC99 0xCC9C 0xCC9F 0xCCA0 0xCCA7 0xCCA8 +0xCCA9 0xCCAA 0xCCAB 0xCCAC 0xCCAD 0xCCAE 0xCCB2 0xCCB4 0xCCB5 0xCCB8 0xCCBB 0xCCBC 0xCCC3 0xCCC4 0xCCC5 0xCCC6 +0xCCC7 0xCCC8 0xCCC9 0xCCCA 0xCCD0 0xCCD1 0xCCD4 0xCCD7 0xCCD8 0xCCE0 0xCCE1 0xCCE2 0xCCE3 0xCCE4 0xCCE5 0xCCEC +0xCCED 0xCCF0 0xCCF4 0xCCFC 0xCCFD 0xCCFE 0xCCFF 0xCD00 0xCD01 0xCD08 0xCD09 0xCD0C 0xCD0F 0xCD10 0xCD18 0xCD19 +0xCD1A 0xCD1B 0xCD1C 0xCD1D 0xCD23 0xCD24 0xCD25 0xCD28 0xCD2B 0xCD2C 0xCD34 0xCD35 0xCD36 0xCD37 0xCD38 0xCD39 +0xCD40 0xCD44 0xCD50 0xCD51 0xCD52 0xCD53 0xCD54 0xCD55 0xCD5C 0xCD5D 0xCD60 0xCD63 0xCD64 0xCD6C 0xCD6D 0xCD6E +0xCD6F 0xCD70 0xCD71 0xCD78 0xCD79 0xCD7C 0xCD80 0xCD88 0xCD89 0xCD8A 0xCD8B 0xCD8C 0xCD8D 0xCD94 0xCD95 0xCD98 +0xCD9B 0xCD9C 0xCDA4 0xCDA5 0xCDA6 0xCDA7 0xCDA8 0xCDA9 0xCDB0 0xCDB1 0xCDB4 0xCDB7 0xCDB8 0xCDC0 0xCDC1 0xCDC2 +0xCDC3 0xCDC4 0xCDC5 0xCDCC 0xCDCD 0xCDD0 0xCDD4 0xCDDC 0xCDDD 0xCDDE 0xCDDF 0xCDE0 0xCDE1 0xCDE8 0xCDE9 0xCDEC +0xCDEF 0xCDF0 0xCDF8 0xCDF9 0xCDFA 0xCDFB 0xCDFC 0xCDFD 0xCE04 0xCE05 0xCE08 0xCE0C 0xCE14 0xCE15 0xCE16 0xCE17 +0xCE18 0xCE19 0xCE20 0xCE21 0xCE24 0xCE27 0xCE28 0xCE29 0xCE2C 0xCE30 0xCE31 0xCE32 0xCE33 0xCE34 0xCE35 0xCE3C +0xCE3D 0xCE40 0xCE44 0xCE4C 0xCE4D 0xCE4E 0xCE4F 0xCE50 0xCE51 0xCE58 0xCE59 0xCE5C 0xCE5F 0xCE60 0xCE61 0xCE62 +0xCE68 0xCE69 0xCE6A 0xCE6B 0xCE6C 0xCE6D 0xCE6E 0xCE70 0xCE72 0xCE74 0xCE75 0xCE78 0xCE7B 0xCE7C 0xCE84 0xCE85 +0xCE86 0xCE87 0xCE88 0xCE89 0xCE8D 0xCE8E 0xCE90 0xCE91 0xCE94 0xCE97 0xCE98 0xCEA0 0xCEA1 0xCEA2 0xCEA3 0xCEA4 +0xCEA5 0xCEA8 0xCEA9 0xCEAA 0xCEAC 0xCEAD 0xCEB0 0xCEB4 0xCEBC 0xCEBD 0xCEBE 0xCEBF 0xCEC0 0xCEC1 0xCEC4 0xCEC8 +0xCEC9 0xCECC 0xCED8 0xCED9 0xCEDA 0xCEDB 0xCEDC 0xCEDD 0xCEE4 0xCEE5 0xCEE8 0xCEEB 0xCEEC 0xCEF4 0xCEF5 0xCEF6 +0xCEF7 0xCEF8 0xCEF9 0xCEFB 0xCEFD 0xCEFE 0xCF00 0xCF01 0xCF04 0xCF07 0xCF08 0xCF10 0xCF11 0xCF12 0xCF13 0xCF14 +0xCF15 0xCF18 0xCF19 0xCF1A 0xCF1C 0xCF1D 0xCF20 0xCF23 0xCF24 0xCF2C 0xCF2D 0xCF2E 0xCF2F 0xCF30 0xCF31 0xCF38 +0xCF39 0xCF3C 0xCF40 0xCF48 0xCF49 0xCF4A 0xCF4B 0xCF4C 0xCF4D 0xCF54 0xCF55 0xCF58 0xCF5B 0xCF5C 0xCF64 0xCF65 +0xCF66 0xCF67 0xCF68 0xCF69 0xCF6A 0xCF6E 0xCF70 0xCF71 0xCF74 0xCF78 0xCF80 0xCF81 0xCF82 0xCF83 0xCF84 0xCF85 +0xCF8C 0xCF8D 0xCF90 0xCF93 0xCF94 0xCF9C 0xCF9D 0xCF9E 0xCF9F 0xCFA0 0xCFA1 0xCFA8 0xCFA9 0xCFAC 0xCFB0 0xCFB8 +0xCFB9 0xCFBA 0xCFBB 0xCFBC 0xCFBD 0xCFC4 0xCFC5 0xCFC8 0xCFCC 0xCFD4 0xCFD5 0xCFD6 0xCFD7 0xCFD8 0xCFD9 0xCFE0 +0xCFE1 0xCFE4 0xCFE7 0xCFE8 0xCFF0 0xCFF1 0xCFF2 0xCFF3 0xCFF4 0xCFF5 0xCFFA 0xCFFC 0xCFFD 0xD000 0xD003 0xD004 +0xD00C 0xD00D 0xD00E 0xD00F 0xD010 0xD011 0xD018 0xD019 0xD01C 0xD020 0xD028 0xD029 0xD02A 0xD02B 0xD02C 0xD02D +0xD034 0xD035 0xD038 0xD03B 0xD03C 0xD044 0xD045 0xD046 0xD047 0xD048 0xD049 0xD050 0xD051 0xD054 0xD058 0xD060 +0xD061 0xD062 0xD063 0xD064 0xD065 0xD068 0xD06C 0xD06D 0xD070 0xD072 0xD074 0xD076 0xD07C 0xD07D 0xD07E 0xD07F +0xD080 0xD081 0xD084 0xD088 0xD089 0xD08C 0xD090 0xD098 0xD099 0xD09A 0xD09B 0xD09C 0xD09D 0xD0A4 0xD0A5 0xD0A8 +0xD0AB 0xD0AC 0xD0B4 0xD0B5 0xD0B6 0xD0B7 0xD0B8 0xD0B9 0xD0BE 0xD0C0 0xD0C1 0xD0C4 0xD0C7 0xD0C8 0xD0C9 0xD0CA +0xD0CF 0xD0D0 0xD0D1 0xD0D2 0xD0D3 0xD0D4 0xD0D5 0xD0DA 0xD0DC 0xD0DD 0xD0E0 0xD0E2 0xD0E3 0xD0E4 0xD0E5 0xD0EC +0xD0ED 0xD0EE 0xD0EF 0xD0F0 0xD0F1 0xD0F6 0xD0F8 0xD0F9 0xD0FC 0xD100 0xD108 0xD109 0xD10A 0xD10B 0xD10C 0xD10D +0xD114 0xD115 0xD118 0xD11A 0xD124 0xD125 0xD126 0xD127 0xD128 0xD129 0xD130 0xD131 0xD134 0xD137 0xD138 0xD139 +0xD13A 0xD13B 0xD140 0xD141 0xD142 0xD143 0xD144 0xD145 0xD14C 0xD14D 0xD150 0xD153 0xD154 0xD15C 0xD15D 0xD15E +0xD15F 0xD160 0xD161 0xD166 0xD168 0xD169 0xD16C 0xD16F 0xD170 0xD178 0xD179 0xD17A 0xD17B 0xD17C 0xD17D 0xD184 +0xD185 0xD188 0xD18C 0xD194 0xD195 0xD196 0xD197 0xD198 0xD199 0xD1A0 0xD1A1 0xD1A4 0xD1A7 0xD1A8 0xD1B0 0xD1B1 +0xD1B2 0xD1B3 0xD1B4 0xD1B5 0xD1B7 0xD1B8 0xD1B9 0xD1BA 0xD1BC 0xD1BD 0xD1C0 0xD1C4 0xD1CC 0xD1CD 0xD1CE 0xD1CF +0xD1D0 0xD1D1 0xD1D8 0xD1E8 0xD1E9 0xD1EA 0xD1EB 0xD1EC 0xD1ED 0xD1F4 0xD1F5 0xD1F8 0xD1FB 0xD1FC 0xD204 0xD205 +0xD206 0xD207 0xD208 0xD209 0xD210 0xD211 0xD214 0xD218 0xD220 0xD221 0xD222 0xD223 0xD224 0xD225 0xD22C 0xD22D +0xD230 0xD233 0xD234 0xD236 0xD23C 0xD23D 0xD23E 0xD23F 0xD240 0xD241 0xD248 0xD249 0xD24C 0xD24F 0xD250 0xD254 +0xD258 0xD259 0xD25A 0xD25B 0xD25C 0xD25D 0xD264 0xD265 0xD268 0xD26B 0xD26C 0xD274 0xD275 0xD276 0xD277 0xD278 +0xD279 0xD280 0xD281 0xD284 0xD287 0xD288 0xD290 0xD291 0xD292 0xD293 0xD294 0xD295 0xD29C 0xD29D 0xD2A0 0xD2A4 +0xD2AC 0xD2AD 0xD2AE 0xD2AF 0xD2B0 0xD2B1 0xD2B8 0xD2B9 0xD2BB 0xD2BC 0xD2BF 0xD2C0 0xD2C1 0xD2C2 0xD2C4 0xD2C8 +0xD2C9 0xD2CA 0xD2CB 0xD2CC 0xD2CD 0xD2D1 0xD2D4 0xD2D5 0xD2D8 0xD2DC 0xD2E0 0xD2E4 0xD2E5 0xD2E6 0xD2E7 0xD2E8 +0xD2E9 0xD2F0 0xD2F1 0xD2F4 0xD2F7 0xD2F8 0xD300 0xD301 0xD302 0xD303 0xD304 0xD305 0xD308 0xD30A 0xD30C 0xD30D +0xD30E 0xD310 0xD311 0xD313 0xD314 0xD316 0xD31C 0xD31D 0xD31E 0xD31F 0xD320 0xD321 0xD323 0xD324 0xD325 0xD326 +0xD328 0xD329 0xD32C 0xD32F 0xD330 0xD338 0xD339 0xD33A 0xD33B 0xD33C 0xD33D 0xD341 0xD344 0xD345 0xD348 0xD34C +0xD354 0xD355 0xD356 0xD357 0xD358 0xD359 0xD35D 0xD360 0xD361 0xD364 0xD370 0xD371 0xD372 0xD373 0xD374 0xD375 +0xD37C 0xD37D 0xD380 0xD383 0xD384 0xD38C 0xD38D 0xD38E 0xD38F 0xD390 0xD391 0xD395 0xD396 0xD398 0xD399 0xD39C +0xD39F 0xD3A0 0xD3A8 0xD3A9 0xD3AA 0xD3AB 0xD3AC 0xD3AD 0xD3B2 0xD3B4 0xD3B5 0xD3B8 0xD3B9 0xD3BB 0xD3BC 0xD3C4 +0xD3C5 0xD3C6 0xD3C7 0xD3C8 0xD3C9 0xD3D0 0xD3D1 0xD3D4 0xD3D7 0xD3D8 0xD3E0 0xD3E1 0xD3E2 0xD3E3 0xD3E4 0xD3E5 +0xD3EC 0xD3ED 0xD3EE 0xD3F0 0xD3F3 0xD3F4 0xD3FC 0xD3FD 0xD3FE 0xD3FF 0xD400 0xD401 0xD404 0xD405 0xD406 0xD408 +0xD409 0xD40C 0xD410 0xD418 0xD419 0xD41A 0xD41B 0xD41C 0xD41D 0xD424 0xD440 0xD441 0xD444 0xD448 0xD450 0xD451 +0xD452 0xD453 0xD454 0xD455 0xD45C 0xD45D 0xD460 0xD463 0xD464 0xD46C 0xD46D 0xD46E 0xD46F 0xD470 0xD471 0xD478 +0xD479 0xD47C 0xD47F 0xD480 0xD482 0xD488 0xD489 0xD48A 0xD48B 0xD48C 0xD48D 0xD494 0xD495 0xD498 0xD49B 0xD49C +0xD4A4 0xD4A5 0xD4A6 0xD4A7 0xD4A8 0xD4A9 0xD4B0 0xD4B1 0xD4B4 0xD4B8 0xD4C0 0xD4C1 0xD4C2 0xD4C3 0xD4C4 0xD4C5 +0xD4CC 0xD4CD 0xD4D0 0xD4D4 0xD4DC 0xD4DD 0xD4DE 0xD4DF 0xD4E0 0xD4E1 0xD4E8 0xD4E9 0xD4EC 0xD4EF 0xD4F0 0xD4F8 +0xD4F9 0xD4FA 0xD4FB 0xD4FC 0xD4FD 0xD504 0xD505 0xD508 0xD50B 0xD50C 0xD510 0xD514 0xD515 0xD516 0xD517 0xD518 +0xD519 0xD520 0xD521 0xD524 0xD528 0xD530 0xD531 0xD532 0xD533 0xD534 0xD535 0xD53C 0xD53D 0xD540 0xD543 0xD544 +0xD54C 0xD54D 0xD54E 0xD54F 0xD550 0xD551 0xD555 0xD556 0xD558 0xD559 0xD55C 0xD55F 0xD560 0xD561 0xD563 0xD564 +0xD565 0xD567 0xD568 0xD569 0xD56A 0xD56B 0xD56C 0xD56D 0xD56E 0xD570 0xD571 0xD572 0xD573 0xD574 0xD575 0xD578 +0xD57B 0xD57C 0xD584 0xD585 0xD586 0xD587 0xD588 0xD589 0xD58B 0xD58D 0xD58F 0xD590 0xD591 0xD594 0xD598 0xD5A0 +0xD5A1 0xD5A2 0xD5A3 0xD5A4 0xD5A5 0xD5AB 0xD5AC 0xD5AD 0xD5BC 0xD5BD 0xD5BE 0xD5BF 0xD5C0 0xD5C1 0xD5C8 0xD5C9 +0xD5CC 0xD5CF 0xD5D0 0xD5D1 0xD5D2 0xD5D5 0xD5D7 0xD5D8 0xD5D9 0xD5DA 0xD5DB 0xD5DC 0xD5DD 0xD5E0 0xD5E1 0xD5E2 +0xD5E3 0xD5E4 0xD5E5 0xD5E8 0xD5EB 0xD5EC 0xD5F4 0xD5F5 0xD5F6 0xD5F7 0xD5F8 0xD5F9 0xD5FE 0xD5FF 0xD600 0xD601 +0xD604 0xD607 0xD608 0xD610 0xD611 0xD612 0xD613 0xD614 0xD615 0xD61C 0xD61D 0xD620 0xD624 0xD62C 0xD62D 0xD62E +0xD62F 0xD630 0xD631 0xD638 0xD639 0xD63B 0xD63C 0xD63D 0xD63F 0xD640 0xD641 0xD644 0xD645 0xD647 0xD648 0xD649 +0xD64A 0xD64B 0xD64C 0xD64D 0xD651 0xD654 0xD655 0xD658 0xD65B 0xD65C 0xD660 0xD664 0xD665 0xD666 0xD667 0xD668 +0xD669 0xD670 0xD671 0xD674 0xD677 0xD678 0xD680 0xD681 0xD682 0xD683 0xD684 0xD685 0xD68C 0xD68D 0xD690 0xD693 +0xD694 0xD69C 0xD69D 0xD69E 0xD69F 0xD6A0 0xD6A1 0xD6A8 0xD6A9 0xD6AC 0xD6AF 0xD6B0 0xD6B8 0xD6B9 0xD6BA 0xD6BB +0xD6BC 0xD6BD 0xD6C4 0xD6C5 0xD6C8 0xD6CB 0xD6CC 0xD6CD 0xD6CE 0xD6D0 0xD6D1 0xD6D2 0xD6D3 0xD6D4 0xD6D5 0xD6D6 +0xD6D7 0xD6D8 0xD6D9 0xD6DC 0xD6DD 0xD6E0 0xD6E1 0xD6E4 0xD6E8 0xD6F0 0xD6F1 0xD6F2 0xD6F3 0xD6F4 0xD6F5 0xD6FC +0xD6FD 0xD700 0xD703 0xD704 0xD70C 0xD70D 0xD70E 0xD70F 0xD710 0xD711 0xD718 0xD719 0xD71C 0xD71F 0xD720 0xD728 +0xD729 0xD72A 0xD72B 0xD72C 0xD72D 0xD734 0xD735 0xD738 0xD73A 0xD73B 0xD73C 0xD743 0xD744 0xD745 0xD746 0xD747 +0xD748 0xD749 0xD74D 0xD750 0xD751 0xD752 0xD754 0xD755 0xD756 0xD757 0xD758 0xD759 0xD75D 0xD75F 0xD760 0xD761 +0xD762 0xD763 0xD764 0xD765 0xD768 0xD769 0xD76A 0xD76B 0xD76C 0xD76D 0xD770 0xD773 0xD774 0xD77C 0xD77D 0xD77E +0xD77F 0xD780 0xD781 0xD788 0xD789 0xD78A 0xD78B 0xD78C 0xD78D 0xD78E 0xD78F 0xD790 0xD797 0xD798 0xD799 0xD79A +0xD79B 0xD79C 0xD79D 0xD79E 0xD7A0 0xD7A1 0xD7A2 0xD7A3 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE007 +0xE008 0xE009 0xE00A 0xE00B 0xE00C 0xE00D 0xE020 0xE021 0xE022 0xE023 0xE030 0xE031 0xE032 0xE033 0xE040 0xE041 +0xE042 0xE043 0xE044 0xE045 0xE050 0xE051 0xE052 0xE053 0xE054 0xE055 0xE056 0xE057 0xE058 0xE059 0xE05A 0xE05B +0xE05C 0xE05D 0xE070 0xE071 0xE072 0xE073 0xE080 0xE081 0xE082 0xE083 0xE090 0xE091 0xE092 0xE093 0xE094 0xE095 +0xE09D 0xE0A0 0xE0A1 0xE0A2 0xE0A3 0xE0B0 0xE0B1 0xE0B2 0xE0B3 0xF000 0xF001 0xF007 0xF020 0xF021 0xF022 0xF023 +0xF024 0xF025 0xF026 0xF027 0xF028 0xF029 0xF02A 0xF030 0xF031 0xF032 0xF033 0xF034 0xF035 0xF036 0xF037 0xF038 +0xF039 0xF03A 0xF03B 0xF03C 0xF03D 0xF8FF 0xFE10 0xFE11 0xFE12 0xFE13 0xFE14 0xFE15 0xFE16 0xFE17 0xFE18 0xFE19 +0xFE30 0xFE31 0xFE33 0xFE34 0xFE35 0xFE36 0xFE37 0xFE38 0xFE39 0xFE3A 0xFE3B 0xFE3C 0xFE3D 0xFE3E 0xFE3F 0xFE40 +0xFE41 0xFE42 0xFE43 0xFE44 0xFE49 0xFE4A 0xFE4B 0xFE4C 0xFE4D 0xFE4E 0xFE4F 0xFE50 0xFE51 0xFE52 0xFE54 0xFE55 +0xFE56 0xFE57 0xFE59 0xFE5A 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0xFE5F 0xFE60 0xFE61 0xFE62 0xFE63 0xFE64 0xFE65 0xFE66 +0xFE68 0xFE69 0xFE6A 0xFE6B 0xFF01 0xFF02 0xFF03 0xFF04 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C +0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C +0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C +0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C +0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C +0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C +0xFF5D 0xFF5E 0xFF5F 0xFF60 0xFF61 0xFF62 0xFF63 0xFF64 0xFF65 0xFF66 0xFF67 0xFF68 0xFF69 0xFF6A 0xFF6B 0xFF6C +0xFF6D 0xFF6E 0xFF6F 0xFF70 0xFF71 0xFF72 0xFF73 0xFF74 0xFF75 0xFF76 0xFF77 0xFF78 0xFF79 0xFF7A 0xFF7B 0xFF7C +0xFF7D 0xFF7E 0xFF7F 0xFF80 0xFF81 0xFF82 0xFF83 0xFF84 0xFF85 0xFF86 0xFF87 0xFF88 0xFF89 0xFF8A 0xFF8B 0xFF8C +0xFF8D 0xFF8E 0xFF8F 0xFF90 0xFF91 0xFF92 0xFF93 0xFF94 0xFF95 0xFF96 0xFF97 0xFF98 0xFF99 0xFF9A 0xFF9B 0xFF9C +0xFF9D 0xFF9E 0xFF9F 0xFFE0 0xFFE1 0xFFE2 0xFFE3 0xFFE4 0xFFE5 0xFFE9 0xFFEB 0xFFFC 0xFFFD 0xFFFE diff --git a/resources/fonts/fusion/font_fusion_hant_8x8.frf b/resources/fonts/fusion/font_fusion_hant_8x8.frf new file mode 100644 index 000000000..d3ed541a8 Binary files /dev/null and b/resources/fonts/fusion/font_fusion_hant_8x8.frf differ diff --git a/resources/fonts/fusion/font_fusion_hant_8x8.pbm b/resources/fonts/fusion/font_fusion_hant_8x8.pbm new file mode 100644 index 000000000..779c9b9c3 Binary files /dev/null and b/resources/fonts/fusion/font_fusion_hant_8x8.pbm differ diff --git a/resources/fonts/fusion/font_fusion_hant_8x8.txt b/resources/fonts/fusion/font_fusion_hant_8x8.txt new file mode 100644 index 000000000..cd88777dd --- /dev/null +++ b/resources/fonts/fusion/font_fusion_hant_8x8.txt @@ -0,0 +1,1379 @@ +0x0020 0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F +0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F +0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F +0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F +0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F +0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E 0x00A1 +0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00AF 0x00B0 0x00B1 0x00B2 +0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00B8 0x00B9 0x00BA 0x00BB 0x00BC 0x00BD 0x00BE 0x00BF 0x00C0 0x00C1 0x00C2 +0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 +0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 +0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 +0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0100 0x0101 0x0102 +0x0103 0x0104 0x0105 0x0106 0x0107 0x0108 0x0109 0x010A 0x010B 0x010C 0x010D 0x010E 0x010F 0x0110 0x0111 0x0112 +0x0113 0x0114 0x0115 0x0116 0x0117 0x0118 0x0119 0x011A 0x011B 0x011C 0x011D 0x011E 0x011F 0x0120 0x0121 0x0122 +0x0123 0x0124 0x0125 0x0126 0x0127 0x0128 0x0129 0x012A 0x012B 0x012C 0x012D 0x012E 0x012F 0x0130 0x0131 0x0132 +0x0133 0x0134 0x0135 0x0136 0x0137 0x0138 0x0139 0x013A 0x013B 0x013C 0x013D 0x013E 0x013F 0x0140 0x0141 0x0142 +0x0143 0x0144 0x0145 0x0146 0x0147 0x0148 0x0149 0x014A 0x014B 0x014C 0x014D 0x014E 0x014F 0x0150 0x0151 0x0152 +0x0153 0x0154 0x0155 0x0156 0x0157 0x0158 0x0159 0x015A 0x015B 0x015C 0x015D 0x015E 0x015F 0x0160 0x0161 0x0162 +0x0163 0x0164 0x0165 0x0166 0x0167 0x0168 0x0169 0x016A 0x016B 0x016C 0x016D 0x016E 0x016F 0x0170 0x0171 0x0172 +0x0173 0x0174 0x0175 0x0176 0x0177 0x0178 0x0179 0x017A 0x017B 0x017C 0x017D 0x017E 0x017F 0x0192 0x0197 0x01A0 +0x01A1 0x01AC 0x01AF 0x01B0 0x01C0 0x01C1 0x01C2 0x01C3 0x01CD 0x01CE 0x01CF 0x01D0 0x01D1 0x01D2 0x01D3 0x01D4 +0x01D5 0x01D6 0x01D7 0x01D8 0x01D9 0x01DA 0x01DB 0x01DC 0x01DE 0x01DF 0x01E0 0x01E1 0x01E2 0x01E3 0x01E6 0x01E7 +0x01E8 0x01E9 0x01EA 0x01EB 0x01EC 0x01ED 0x01F0 0x01F4 0x01F5 0x01F8 0x01F9 0x01FA 0x01FB 0x01FC 0x01FD 0x01FE +0x01FF 0x0218 0x0219 0x021A 0x021B 0x021E 0x021F 0x0221 0x0226 0x0227 0x0228 0x0229 0x022A 0x022B 0x022C 0x022D +0x022E 0x022F 0x0230 0x0231 0x0232 0x0233 0x0235 0x0236 0x0237 0x0244 0x2010 0x2011 0x2012 0x2013 0x2014 0x2015 +0x2016 0x2017 0x2018 0x2019 0x201A 0x201C 0x201D 0x201E 0x2020 0x2021 0x2022 0x2023 0x2025 0x2026 0x2027 0x2030 +0x2031 0x2032 0x2033 0x2034 0x2035 0x2037 0x2038 0x2039 0x203A 0x203B 0x203C 0x203E 0x203F 0x2044 0x2103 0x2109 +0x2160 0x2161 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 0x216A 0x216B 0x2170 0x2171 0x2172 0x2173 +0x2174 0x2175 0x2176 0x2177 0x2178 0x2179 0x2181 0x2182 0x2190 0x2191 0x2192 0x2193 0x2194 0x2195 0x2196 0x2197 +0x2198 0x2199 0x219A 0x219B 0x21BA 0x21BB 0x21D0 0x21D1 0x21D2 0x21D3 0x21D4 0x21D5 0x21D6 0x21D7 0x21D8 0x21D9 +0x21DA 0x21DB 0x21E0 0x21E1 0x21E2 0x21E3 0x21E4 0x21E5 0x21E6 0x21E7 0x21E8 0x21E9 0x21EA 0x21EB 0x21EC 0x21ED +0x21EE 0x21EF 0x21F0 0x21F1 0x21F2 0x21F3 0x21FD 0x21FE 0x21FF 0x2200 0x2202 0x2203 0x2207 0x2208 0x220B 0x2211 +0x2212 0x221A 0x221D 0x221E 0x221F 0x2220 0x2225 0x2227 0x2228 0x2229 0x222A 0x222B 0x222C 0x222E 0x2234 0x2235 +0x223D 0x2252 0x2260 0x2261 0x2266 0x2267 0x226A 0x226B 0x2282 0x2283 0x2286 0x2287 0x22A5 0x22BF 0x2460 0x2461 +0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 0x246A 0x246B 0x246C 0x246D 0x246E 0x246F 0x2470 0x2471 +0x2472 0x2473 0x2500 0x2501 0x2502 0x2503 0x2504 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C 0x250D +0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C 0x251D +0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C 0x252D +0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C 0x253D +0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0x254C 0x254D +0x254E 0x254F 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D +0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x256D +0x256E 0x256F 0x2570 0x2571 0x2572 0x2573 0x2574 0x2575 0x2576 0x2577 0x2578 0x2579 0x257A 0x257B 0x257C 0x257D +0x257E 0x257F 0x2580 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 0x2589 0x258A 0x258B 0x258C 0x258D +0x258E 0x258F 0x2590 0x2591 0x2592 0x2593 0x2594 0x2595 0x2596 0x2597 0x2598 0x2599 0x259A 0x259B 0x259C 0x259D +0x259E 0x259F 0x25A0 0x25A1 0x25A2 0x25A3 0x25A4 0x25A5 0x25A6 0x25A7 0x25A8 0x25A9 0x25AA 0x25AB 0x25AC 0x25AD +0x25AE 0x25AF 0x25B0 0x25B1 0x25B2 0x25B3 0x25B4 0x25B5 0x25B6 0x25B7 0x25B8 0x25B9 0x25BA 0x25BB 0x25BC 0x25BD +0x25BE 0x25BF 0x25C0 0x25C1 0x25C2 0x25C3 0x25C4 0x25C5 0x25C6 0x25C7 0x25C8 0x25C9 0x25CA 0x25CB 0x25CC 0x25CD +0x25CE 0x25CF 0x25D0 0x25D1 0x25D2 0x25D3 0x25D4 0x25D5 0x25D6 0x25D7 0x25D8 0x25D9 0x25DA 0x25DB 0x25DC 0x25DD +0x25DE 0x25DF 0x25E0 0x25E1 0x25E2 0x25E3 0x25E4 0x25E5 0x25E6 0x25E7 0x25E8 0x25E9 0x25EA 0x25EB 0x25EC 0x25ED +0x25EE 0x25EF 0x25F0 0x25F1 0x25F2 0x25F3 0x25F4 0x25F5 0x25F6 0x25F7 0x25F8 0x25F9 0x25FA 0x25FB 0x25FC 0x25FD +0x25FE 0x25FF 0x2600 0x2602 0x2604 0x2605 0x2606 0x2609 0x260A 0x260B 0x260C 0x260D 0x260E 0x260F 0x2616 0x2617 +0x262D 0x262E 0x262F 0x2630 0x2631 0x2632 0x2633 0x2634 0x2635 0x2636 0x2637 0x2639 0x263A 0x263B 0x263C 0x263D +0x263E 0x2640 0x2641 0x2642 0x2660 0x2661 0x2662 0x2663 0x2664 0x2665 0x2666 0x2667 0x2668 0x2669 0x266A 0x266B +0x266C 0x266D 0x266E 0x266F 0x2680 0x2681 0x2682 0x2683 0x2684 0x2685 0x2686 0x2687 0x2688 0x2689 0x268A 0x268B +0x268C 0x268D 0x268E 0x268F 0x2694 0x2698 0x2699 0x26AA 0x26AB 0x26AC 0x26C9 0x26CA 0x26F6 0x2800 0x2801 0x2802 +0x2803 0x2804 0x2805 0x2806 0x2807 0x2808 0x2809 0x280A 0x280B 0x280C 0x280D 0x280E 0x280F 0x2810 0x2811 0x2812 +0x2813 0x2814 0x2815 0x2816 0x2817 0x2818 0x2819 0x281A 0x281B 0x281C 0x281D 0x281E 0x281F 0x2820 0x2821 0x2822 +0x2823 0x2824 0x2825 0x2826 0x2827 0x2828 0x2829 0x282A 0x282B 0x282C 0x282D 0x282E 0x282F 0x2830 0x2831 0x2832 +0x2833 0x2834 0x2835 0x2836 0x2837 0x2838 0x2839 0x283A 0x283B 0x283C 0x283D 0x283E 0x283F 0x2840 0x2841 0x2842 +0x2843 0x2844 0x2845 0x2846 0x2847 0x2848 0x2849 0x284A 0x284B 0x284C 0x284D 0x284E 0x284F 0x2850 0x2851 0x2852 +0x2853 0x2854 0x2855 0x2856 0x2857 0x2858 0x2859 0x285A 0x285B 0x285C 0x285D 0x285E 0x285F 0x2860 0x2861 0x2862 +0x2863 0x2864 0x2865 0x2866 0x2867 0x2868 0x2869 0x286A 0x286B 0x286C 0x286D 0x286E 0x286F 0x2870 0x2871 0x2872 +0x2873 0x2874 0x2875 0x2876 0x2877 0x2878 0x2879 0x287A 0x287B 0x287C 0x287D 0x287E 0x287F 0x2880 0x2881 0x2882 +0x2883 0x2884 0x2885 0x2886 0x2887 0x2888 0x2889 0x288A 0x288B 0x288C 0x288D 0x288E 0x288F 0x2890 0x2891 0x2892 +0x2893 0x2894 0x2895 0x2896 0x2897 0x2898 0x2899 0x289A 0x289B 0x289C 0x289D 0x289E 0x289F 0x28A0 0x28A1 0x28A2 +0x28A3 0x28A4 0x28A5 0x28A6 0x28A7 0x28A8 0x28A9 0x28AA 0x28AB 0x28AC 0x28AD 0x28AE 0x28AF 0x28B0 0x28B1 0x28B2 +0x28B3 0x28B4 0x28B5 0x28B6 0x28B7 0x28B8 0x28B9 0x28BA 0x28BB 0x28BC 0x28BD 0x28BE 0x28BF 0x28C0 0x28C1 0x28C2 +0x28C3 0x28C4 0x28C5 0x28C6 0x28C7 0x28C8 0x28C9 0x28CA 0x28CB 0x28CC 0x28CD 0x28CE 0x28CF 0x28D0 0x28D1 0x28D2 +0x28D3 0x28D4 0x28D5 0x28D6 0x28D7 0x28D8 0x28D9 0x28DA 0x28DB 0x28DC 0x28DD 0x28DE 0x28DF 0x28E0 0x28E1 0x28E2 +0x28E3 0x28E4 0x28E5 0x28E6 0x28E7 0x28E8 0x28E9 0x28EA 0x28EB 0x28EC 0x28ED 0x28EE 0x28EF 0x28F0 0x28F1 0x28F2 +0x28F3 0x28F4 0x28F5 0x28F6 0x28F7 0x28F8 0x28F9 0x28FA 0x28FB 0x28FC 0x28FD 0x28FE 0x28FF 0x3000 0x3001 0x3002 +0x3003 0x3004 0x3005 0x3006 0x3007 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0x3012 +0x3013 0x3014 0x3015 0x3016 0x3017 0x3018 0x3019 0x301A 0x301B 0x301C 0x301D 0x301E 0x301F 0x3020 0x3021 0x3022 +0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 0x3029 0x3036 0x3037 0x3038 0x3039 0x303A 0x303C 0x303E 0x303F 0x3041 +0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 +0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 +0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 +0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 +0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 +0x3092 0x3093 0x309B 0x309C 0x309D 0x309E 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA +0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA +0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA +0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA +0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA +0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x30FB 0x30FC 0x30FD 0x30FE +0x3105 0x3106 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 +0x3115 0x3116 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 +0x3125 0x3126 0x3127 0x3128 0x3129 0x312A 0x312B 0x312C 0x312D 0x312E 0x312F 0x3131 0x3132 0x3133 0x3134 0x3135 +0x3136 0x3137 0x3138 0x3139 0x313A 0x313B 0x313C 0x313D 0x313E 0x313F 0x3140 0x3141 0x3142 0x3143 0x3144 0x3145 +0x3146 0x3147 0x3148 0x3149 0x314A 0x314B 0x314C 0x314D 0x314E 0x314F 0x3150 0x3151 0x3152 0x3153 0x3154 0x3155 +0x3156 0x3157 0x3158 0x3159 0x315A 0x315B 0x315C 0x315D 0x315E 0x315F 0x3160 0x3161 0x3162 0x3163 0x3164 0x3220 +0x3221 0x3222 0x3223 0x3224 0x3225 0x3226 0x3227 0x3228 0x3229 0x3231 0x3232 0x3239 0x3268 0x3280 0x3281 0x3282 +0x3283 0x3284 0x3285 0x3286 0x3287 0x3288 0x3289 0x32A3 0x32A4 0x32A5 0x32A6 0x32A7 0x32A8 0x32FF 0x4E00 0x4E01 +0x4E02 0x4E03 0x4E04 0x4E05 0x4E06 0x4E07 0x4E08 0x4E09 0x4E0A 0x4E0B 0x4E0C 0x4E0D 0x4E0E 0x4E0F 0x4E10 0x4E11 +0x4E12 0x4E13 0x4E14 0x4E15 0x4E16 0x4E17 0x4E18 0x4E19 0x4E1A 0x4E1B 0x4E1C 0x4E1D 0x4E1E 0x4E1F 0x4E20 0x4E21 +0x4E22 0x4E23 0x4E24 0x4E25 0x4E26 0x4E27 0x4E28 0x4E29 0x4E2A 0x4E2B 0x4E2C 0x4E2D 0x4E2E 0x4E2F 0x4E30 0x4E31 +0x4E32 0x4E33 0x4E34 0x4E35 0x4E36 0x4E37 0x4E38 0x4E39 0x4E3A 0x4E3B 0x4E3C 0x4E3D 0x4E3E 0x4E3F 0x4E40 0x4E41 +0x4E42 0x4E43 0x4E44 0x4E45 0x4E46 0x4E47 0x4E48 0x4E49 0x4E4A 0x4E4B 0x4E4C 0x4E4D 0x4E4E 0x4E4F 0x4E50 0x4E51 +0x4E52 0x4E53 0x4E54 0x4E55 0x4E56 0x4E57 0x4E58 0x4E59 0x4E5A 0x4E5B 0x4E5C 0x4E5D 0x4E5E 0x4E5F 0x4E60 0x4E61 +0x4E62 0x4E63 0x4E64 0x4E65 0x4E66 0x4E67 0x4E68 0x4E69 0x4E6A 0x4E6B 0x4E6C 0x4E6D 0x4E6E 0x4E6F 0x4E70 0x4E71 +0x4E72 0x4E73 0x4E74 0x4E75 0x4E76 0x4E77 0x4E78 0x4E79 0x4E7A 0x4E7B 0x4E7C 0x4E7D 0x4E7E 0x4E7F 0x4E80 0x4E81 +0x4E82 0x4E83 0x4E84 0x4E85 0x4E86 0x4E87 0x4E88 0x4E89 0x4E8A 0x4E8B 0x4E8C 0x4E8D 0x4E8E 0x4E8F 0x4E90 0x4E91 +0x4E92 0x4E93 0x4E94 0x4E95 0x4E96 0x4E97 0x4E98 0x4E99 0x4E9A 0x4E9B 0x4E9C 0x4E9D 0x4E9E 0x4E9F 0x4EA0 0x4EA1 +0x4EA2 0x4EA3 0x4EA4 0x4EA5 0x4EA6 0x4EA7 0x4EA8 0x4EA9 0x4EAA 0x4EAB 0x4EAC 0x4EAD 0x4EAE 0x4EAF 0x4EB0 0x4EB1 +0x4EB2 0x4EB3 0x4EB4 0x4EB5 0x4EB6 0x4EB7 0x4EB8 0x4EB9 0x4EBA 0x4EBB 0x4EBC 0x4EBD 0x4EBE 0x4EBF 0x4EC0 0x4EC1 +0x4EC2 0x4EC3 0x4EC4 0x4EC5 0x4EC6 0x4EC7 0x4EC8 0x4EC9 0x4ECA 0x4ECB 0x4ECC 0x4ECD 0x4ECE 0x4ECF 0x4ED0 0x4ED1 +0x4ED2 0x4ED3 0x4ED4 0x4ED5 0x4ED6 0x4ED7 0x4ED8 0x4ED9 0x4EDA 0x4EDB 0x4EDC 0x4EDD 0x4EDE 0x4EDF 0x4EE0 0x4EE1 +0x4EE2 0x4EE3 0x4EE4 0x4EE5 0x4EE6 0x4EE7 0x4EE8 0x4EE9 0x4EEA 0x4EEB 0x4EEC 0x4EED 0x4EEE 0x4EEF 0x4EF0 0x4EF1 +0x4EF2 0x4EF3 0x4EF4 0x4EF5 0x4EF6 0x4EF7 0x4EF8 0x4EF9 0x4EFA 0x4EFB 0x4EFC 0x4EFD 0x4EFE 0x4EFF 0x4F00 0x4F01 +0x4F02 0x4F03 0x4F04 0x4F05 0x4F06 0x4F07 0x4F08 0x4F09 0x4F0A 0x4F0B 0x4F0C 0x4F0D 0x4F0E 0x4F0F 0x4F10 0x4F11 +0x4F12 0x4F13 0x4F14 0x4F15 0x4F16 0x4F17 0x4F18 0x4F19 0x4F1A 0x4F1B 0x4F1C 0x4F1D 0x4F1E 0x4F1F 0x4F20 0x4F21 +0x4F22 0x4F23 0x4F24 0x4F25 0x4F26 0x4F27 0x4F28 0x4F29 0x4F2A 0x4F2B 0x4F2C 0x4F2D 0x4F2E 0x4F2F 0x4F30 0x4F31 +0x4F32 0x4F33 0x4F34 0x4F35 0x4F36 0x4F37 0x4F38 0x4F39 0x4F3A 0x4F3B 0x4F3C 0x4F3D 0x4F3E 0x4F3F 0x4F40 0x4F41 +0x4F42 0x4F43 0x4F44 0x4F45 0x4F46 0x4F47 0x4F48 0x4F49 0x4F4A 0x4F4B 0x4F4C 0x4F4D 0x4F4E 0x4F4F 0x4F50 0x4F51 +0x4F52 0x4F53 0x4F54 0x4F55 0x4F56 0x4F57 0x4F58 0x4F59 0x4F5A 0x4F5B 0x4F5C 0x4F5D 0x4F5E 0x4F5F 0x4F60 0x4F61 +0x4F62 0x4F63 0x4F64 0x4F65 0x4F66 0x4F67 0x4F68 0x4F69 0x4F6A 0x4F6B 0x4F6C 0x4F6D 0x4F6E 0x4F6F 0x4F70 0x4F71 +0x4F72 0x4F73 0x4F74 0x4F75 0x4F76 0x4F77 0x4F78 0x4F79 0x4F7A 0x4F7B 0x4F7C 0x4F7D 0x4F7E 0x4F7F 0x4F80 0x4F81 +0x4F82 0x4F83 0x4F84 0x4F85 0x4F86 0x4F87 0x4F88 0x4F89 0x4F8A 0x4F8B 0x4F8C 0x4F8D 0x4F8E 0x4F8F 0x4F90 0x4F91 +0x4F92 0x4F93 0x4F94 0x4F95 0x4F96 0x4F97 0x4F98 0x4F99 0x4F9A 0x4F9B 0x4F9C 0x4F9D 0x4F9E 0x4F9F 0x4FA0 0x4FA1 +0x4FA2 0x4FA3 0x4FA4 0x4FA5 0x4FA6 0x4FA7 0x4FA8 0x4FA9 0x4FAA 0x4FAB 0x4FAC 0x4FAD 0x4FAE 0x4FAF 0x4FB0 0x4FB1 +0x4FB2 0x4FB3 0x4FB4 0x4FB5 0x4FB6 0x4FB7 0x4FB8 0x4FB9 0x4FBA 0x4FBB 0x4FBC 0x4FBD 0x4FBE 0x4FBF 0x4FC0 0x4FC1 +0x4FC2 0x4FC3 0x4FC4 0x4FC5 0x4FC6 0x4FC7 0x4FC8 0x4FC9 0x4FCA 0x4FCB 0x4FCC 0x4FCD 0x4FCE 0x4FCF 0x4FD0 0x4FD1 +0x4FD2 0x4FD3 0x4FD4 0x4FD5 0x4FD6 0x4FD7 0x4FD8 0x4FD9 0x4FDA 0x4FDB 0x4FDC 0x4FDD 0x4FDE 0x4FDF 0x4FE0 0x4FE1 +0x4FE2 0x4FE3 0x4FE4 0x4FE5 0x4FE6 0x4FE7 0x4FE8 0x4FE9 0x4FEA 0x4FEB 0x4FEC 0x4FED 0x4FEE 0x4FEF 0x4FF0 0x4FF1 +0x4FF2 0x4FF3 0x4FF4 0x4FF5 0x4FF6 0x4FF7 0x4FF8 0x4FF9 0x4FFA 0x4FFB 0x4FFC 0x4FFD 0x4FFE 0x4FFF 0x5000 0x5001 +0x5002 0x5003 0x5004 0x5005 0x5006 0x5007 0x5008 0x5009 0x500A 0x500B 0x500C 0x500D 0x500E 0x500F 0x5010 0x5011 +0x5012 0x5013 0x5014 0x5015 0x5016 0x5017 0x5018 0x5019 0x501A 0x501B 0x501C 0x501D 0x501E 0x501F 0x5020 0x5021 +0x5022 0x5023 0x5024 0x5025 0x5026 0x5027 0x5028 0x5029 0x502A 0x502B 0x502C 0x502D 0x502E 0x502F 0x5030 0x5031 +0x5033 0x5034 0x5035 0x5036 0x5037 0x5039 0x503A 0x503B 0x503C 0x503E 0x5040 0x5041 0x5043 0x5045 0x5046 0x5047 +0x5048 0x5049 0x504A 0x504B 0x504C 0x504D 0x504E 0x504F 0x5050 0x5051 0x5053 0x5055 0x5056 0x5057 0x505A 0x505B +0x505C 0x505D 0x505E 0x505F 0x5060 0x5061 0x5062 0x5063 0x5064 0x5065 0x5068 0x5069 0x506A 0x506B 0x506C 0x506D +0x506E 0x506F 0x5070 0x5072 0x5073 0x5074 0x5075 0x5076 0x5077 0x5078 0x507A 0x507B 0x507D 0x507E 0x507F 0x5080 +0x5082 0x5083 0x5085 0x5087 0x5088 0x5089 0x508B 0x508C 0x508D 0x508E 0x5091 0x5092 0x5094 0x5095 0x5096 0x5098 +0x5099 0x509A 0x509B 0x509C 0x509D 0x509E 0x50A2 0x50A3 0x50A4 0x50A5 0x50A7 0x50A8 0x50A9 0x50AC 0x50AD 0x50AE +0x50AF 0x50B0 0x50B1 0x50B2 0x50B3 0x50B4 0x50B5 0x50B6 0x50B7 0x50B8 0x50BA 0x50BB 0x50BD 0x50BE 0x50BF 0x50C1 +0x50C2 0x50C4 0x50C5 0x50C6 0x50C7 0x50C8 0x50C9 0x50CA 0x50CB 0x50CD 0x50CE 0x50CF 0x50D1 0x50D3 0x50D4 0x50D5 +0x50D6 0x50D7 0x50D9 0x50DA 0x50DB 0x50DC 0x50DD 0x50DE 0x50E0 0x50E3 0x50E4 0x50E5 0x50E6 0x50E7 0x50E8 0x50E9 +0x50EA 0x50EB 0x50EC 0x50ED 0x50EE 0x50EF 0x50F0 0x50F1 0x50F3 0x50F5 0x50F6 0x50F8 0x50F9 0x50FB 0x50FD 0x50FE +0x50FF 0x5100 0x5101 0x5102 0x5103 0x5104 0x5105 0x5106 0x5107 0x5108 0x5109 0x510A 0x510B 0x510C 0x510D 0x510E +0x5110 0x5111 0x5112 0x5113 0x5114 0x5115 0x5116 0x5117 0x5118 0x511A 0x511C 0x511F 0x5120 0x5121 0x5122 0x5124 +0x5125 0x5126 0x5129 0x512A 0x512D 0x512E 0x5130 0x5131 0x5132 0x5133 0x5134 0x5135 0x5137 0x5138 0x5139 0x513A +0x513B 0x513C 0x513D 0x513F 0x5140 0x5141 0x5142 0x5143 0x5144 0x5145 0x5146 0x5147 0x5148 0x5149 0x514A 0x514B +0x514C 0x514D 0x514E 0x514F 0x5150 0x5151 0x5152 0x5153 0x5154 0x5155 0x5156 0x5157 0x5159 0x515A 0x515B 0x515C +0x515D 0x515E 0x515F 0x5161 0x5162 0x5163 0x5165 0x5166 0x5167 0x5168 0x5169 0x516A 0x516B 0x516C 0x516D 0x516E +0x516F 0x5170 0x5171 0x5172 0x5173 0x5174 0x5175 0x5176 0x5177 0x5178 0x5179 0x517B 0x517C 0x517D 0x5180 0x5181 +0x5182 0x5183 0x5184 0x5185 0x5186 0x5187 0x5188 0x5189 0x518A 0x518B 0x518C 0x518D 0x518E 0x518F 0x5190 0x5191 +0x5192 0x5193 0x5194 0x5195 0x5196 0x5197 0x5198 0x5199 0x519A 0x519B 0x519C 0x519D 0x519E 0x51A0 0x51A2 0x51A4 +0x51A5 0x51A6 0x51A7 0x51A8 0x51A9 0x51AA 0x51AB 0x51AC 0x51AD 0x51AE 0x51AF 0x51B0 0x51B1 0x51B2 0x51B3 0x51B4 +0x51B5 0x51B6 0x51B7 0x51B9 0x51BB 0x51BC 0x51BD 0x51BE 0x51C0 0x51C3 0x51C4 0x51C5 0x51C6 0x51C7 0x51C8 0x51C9 +0x51CA 0x51CB 0x51CC 0x51CD 0x51CE 0x51CF 0x51D0 0x51D1 0x51D3 0x51D4 0x51D6 0x51D7 0x51D8 0x51D9 0x51DB 0x51DC +0x51DD 0x51DE 0x51E0 0x51E1 0x51E2 0x51E4 0x51E5 0x51E6 0x51E7 0x51E9 0x51EA 0x51EB 0x51ED 0x51EE 0x51EF 0x51F0 +0x51F1 0x51F3 0x51F4 0x51F5 0x51F6 0x51F7 0x51F8 0x51F9 0x51FA 0x51FB 0x51FC 0x51FD 0x51FE 0x51FF 0x5200 0x5201 +0x5202 0x5203 0x5204 0x5205 0x5206 0x5207 0x5208 0x5209 0x520A 0x520B 0x520C 0x520D 0x520E 0x5210 0x5211 0x5212 +0x5213 0x5214 0x5215 0x5216 0x5217 0x5218 0x5219 0x521A 0x521B 0x521C 0x521D 0x521E 0x5220 0x5221 0x5223 0x5224 +0x5225 0x5227 0x5228 0x5229 0x522A 0x522B 0x522C 0x522D 0x522E 0x5230 0x5231 0x5232 0x5233 0x5235 0x5236 0x5237 +0x5238 0x5239 0x523A 0x523B 0x523D 0x523F 0x5240 0x5241 0x5242 0x5243 0x5244 0x5245 0x5246 0x5247 0x5249 0x524A +0x524B 0x524C 0x524D 0x524E 0x524F 0x5250 0x5251 0x5252 0x5254 0x5255 0x5256 0x5257 0x525A 0x525B 0x525C 0x525D +0x525E 0x525F 0x5261 0x5262 0x5263 0x5264 0x5265 0x5267 0x5269 0x526A 0x526B 0x526C 0x526D 0x526E 0x526F 0x5270 +0x5271 0x5272 0x5273 0x5274 0x5275 0x5277 0x5278 0x527A 0x527B 0x527C 0x527D 0x527E 0x527F 0x5280 0x5281 0x5282 +0x5283 0x5284 0x5287 0x5288 0x5289 0x528A 0x528B 0x528C 0x528D 0x528F 0x5290 0x5291 0x5292 0x5293 0x5294 0x5296 +0x5297 0x5298 0x5299 0x529B 0x529C 0x529D 0x529E 0x529F 0x52A0 0x52A1 0x52A2 0x52A3 0x52A4 0x52A6 0x52A8 0x52A9 +0x52AA 0x52AB 0x52AC 0x52AD 0x52AE 0x52B1 0x52B2 0x52B3 0x52B4 0x52B5 0x52B9 0x52BB 0x52BC 0x52BE 0x52BF 0x52C0 +0x52C1 0x52C2 0x52C3 0x52C5 0x52C7 0x52C9 0x52CB 0x52CD 0x52D0 0x52D2 0x52D3 0x52D4 0x52D5 0x52D6 0x52D7 0x52D8 +0x52D9 0x52DA 0x52DB 0x52DD 0x52DE 0x52DF 0x52E0 0x52E2 0x52E3 0x52E4 0x52E5 0x52E6 0x52E7 0x52E9 0x52EB 0x52EF +0x52F0 0x52F1 0x52F2 0x52F3 0x52F4 0x52F5 0x52F7 0x52F8 0x52F9 0x52FA 0x52FB 0x52FC 0x52FD 0x52FE 0x52FF 0x5300 +0x5301 0x5302 0x5303 0x5304 0x5305 0x5306 0x5308 0x5309 0x530A 0x530B 0x530D 0x530E 0x530F 0x5310 0x5311 0x5312 +0x5315 0x5316 0x5317 0x5318 0x5319 0x531A 0x531B 0x531C 0x531D 0x531E 0x531F 0x5320 0x5321 0x5322 0x5323 0x5326 +0x5327 0x532A 0x532D 0x532E 0x532F 0x5330 0x5331 0x5333 0x5334 0x5337 0x5338 0x5339 0x533A 0x533B 0x533C 0x533D +0x533E 0x533F 0x5340 0x5341 0x5342 0x5343 0x5344 0x5345 0x5346 0x5347 0x5348 0x5349 0x534A 0x534B 0x534C 0x534D +0x534E 0x534F 0x5350 0x5351 0x5352 0x5353 0x5354 0x5355 0x5356 0x5357 0x5358 0x535A 0x535C 0x535D 0x535E 0x535F +0x5360 0x5361 0x5362 0x5363 0x5364 0x5365 0x5366 0x5367 0x5368 0x5369 0x536A 0x536B 0x536C 0x536D 0x536E 0x536F +0x5370 0x5371 0x5372 0x5373 0x5374 0x5375 0x5377 0x5378 0x5379 0x537A 0x537B 0x537C 0x537D 0x537F 0x5382 0x5383 +0x5384 0x5385 0x5386 0x5389 0x538A 0x538B 0x538C 0x538D 0x538E 0x538F 0x5390 0x5392 0x5393 0x5394 0x5395 0x5396 +0x5397 0x5398 0x5399 0x539A 0x539C 0x539D 0x539E 0x539F 0x53A0 0x53A2 0x53A3 0x53A4 0x53A5 0x53A6 0x53A7 0x53A8 +0x53A9 0x53AC 0x53AD 0x53AE 0x53B0 0x53B2 0x53B3 0x53B4 0x53B6 0x53B7 0x53B9 0x53BB 0x53BE 0x53BF 0x53C1 0x53C2 +0x53C3 0x53C4 0x53C6 0x53C7 0x53C8 0x53C9 0x53CA 0x53CB 0x53CC 0x53CD 0x53CE 0x53D1 0x53D2 0x53D4 0x53D5 0x53D6 +0x53D7 0x53D8 0x53D9 0x53DA 0x53DB 0x53DF 0x53E0 0x53E1 0x53E2 0x53E3 0x53E4 0x53E5 0x53E6 0x53E8 0x53E9 0x53EA +0x53EB 0x53EC 0x53ED 0x53EE 0x53EF 0x53F0 0x53F1 0x53F2 0x53F3 0x53F5 0x53F6 0x53F7 0x53F8 0x53F9 0x53FA 0x53FB +0x53FC 0x53FD 0x53FE 0x5401 0x5403 0x5404 0x5406 0x5407 0x5408 0x5409 0x540A 0x540B 0x540C 0x540D 0x540E 0x540F +0x5410 0x5411 0x5412 0x5413 0x5414 0x5415 0x5416 0x5417 0x5418 0x5419 0x541B 0x541C 0x541D 0x541E 0x541F 0x5420 +0x5421 0x5423 0x5424 0x5425 0x5426 0x5427 0x5428 0x5429 0x542A 0x542B 0x542C 0x542D 0x542E 0x542F 0x5430 0x5431 +0x5432 0x5433 0x5434 0x5435 0x5436 0x5437 0x5438 0x5439 0x543B 0x543C 0x543D 0x543E 0x543F 0x5440 0x5441 0x5442 +0x5443 0x5445 0x5446 0x5447 0x5448 0x5449 0x544A 0x544B 0x544E 0x544F 0x5450 0x5451 0x5452 0x5453 0x5454 0x5455 +0x5456 0x5457 0x5458 0x5459 0x545B 0x545C 0x545D 0x545F 0x5460 0x5461 0x5462 0x5463 0x5464 0x5465 0x5466 0x5467 +0x5468 0x546A 0x546B 0x546C 0x546F 0x5470 0x5471 0x5472 0x5473 0x5474 0x5475 0x5476 0x5477 0x5478 0x547A 0x547B +0x547C 0x547D 0x547E 0x547F 0x5480 0x5481 0x5482 0x5484 0x5486 0x5487 0x5488 0x5489 0x548B 0x548C 0x548D 0x548E +0x548F 0x5490 0x5491 0x5492 0x5493 0x5494 0x5495 0x5496 0x5497 0x5498 0x5499 0x549A 0x549B 0x549D 0x54A0 0x54A1 +0x54A2 0x54A3 0x54A4 0x54A5 0x54A6 0x54A7 0x54A8 0x54A9 0x54AA 0x54AB 0x54AC 0x54AD 0x54AE 0x54AF 0x54B0 0x54B1 +0x54B2 0x54B3 0x54B4 0x54B5 0x54B6 0x54B7 0x54B8 0x54B9 0x54BA 0x54BB 0x54BC 0x54BD 0x54BE 0x54BF 0x54C0 0x54C1 +0x54C2 0x54C3 0x54C4 0x54C5 0x54C6 0x54C7 0x54C8 0x54C9 0x54CA 0x54CB 0x54CC 0x54CD 0x54CE 0x54CF 0x54D0 0x54D1 +0x54D2 0x54D3 0x54D4 0x54D5 0x54D6 0x54D7 0x54D8 0x54D9 0x54DA 0x54DC 0x54DD 0x54DE 0x54DF 0x54E0 0x54E1 0x54E2 +0x54E4 0x54E5 0x54E6 0x54E7 0x54E8 0x54E9 0x54EA 0x54EB 0x54ED 0x54EE 0x54F1 0x54F2 0x54F3 0x54F7 0x54F8 0x54FA +0x54FB 0x54FC 0x54FD 0x54FF 0x5501 0x5503 0x5504 0x5505 0x5506 0x5507 0x5508 0x5509 0x550A 0x550B 0x550C 0x550E +0x550F 0x5510 0x5511 0x5512 0x5513 0x5514 0x5516 0x5517 0x551A 0x551B 0x551C 0x551D 0x551E 0x5520 0x5521 0x5522 +0x5523 0x5524 0x5525 0x5526 0x5527 0x552A 0x552C 0x552D 0x552E 0x552F 0x5530 0x5531 0x5532 0x5533 0x5534 0x5535 +0x5536 0x5537 0x5538 0x5539 0x553B 0x553C 0x553E 0x553F 0x5540 0x5541 0x5543 0x5544 0x5545 0x5546 0x5548 0x5549 +0x554A 0x554B 0x554C 0x554D 0x554E 0x554F 0x5550 0x5551 0x5552 0x5553 0x5555 0x5556 0x5557 0x5559 0x555B 0x555C +0x555D 0x555E 0x555F 0x5561 0x5562 0x5563 0x5564 0x5565 0x5566 0x5567 0x5569 0x556A 0x556B 0x556C 0x556D 0x556E +0x556F 0x5570 0x5571 0x5572 0x5574 0x5575 0x5576 0x5577 0x5578 0x5579 0x557B 0x557C 0x557D 0x557E 0x557F 0x5580 +0x5581 0x5582 0x5583 0x5584 0x5586 0x5587 0x5588 0x5589 0x558A 0x558B 0x558C 0x558D 0x558E 0x558F 0x5591 0x5592 +0x5593 0x5594 0x5595 0x5598 0x5599 0x559A 0x559C 0x559D 0x559E 0x559F 0x55A1 0x55A2 0x55A3 0x55A4 0x55A5 0x55A6 +0x55A7 0x55A8 0x55A9 0x55AA 0x55AB 0x55AC 0x55AD 0x55AE 0x55B0 0x55B1 0x55B2 0x55B3 0x55B5 0x55B6 0x55B7 0x55B9 +0x55BA 0x55BB 0x55BC 0x55BD 0x55BE 0x55BF 0x55C0 0x55C2 0x55C3 0x55C4 0x55C5 0x55C6 0x55C7 0x55C8 0x55C9 0x55CA +0x55CB 0x55CC 0x55CD 0x55CE 0x55CF 0x55D0 0x55D1 0x55D2 0x55D3 0x55D4 0x55D5 0x55D6 0x55D7 0x55D9 0x55DA 0x55DB +0x55DC 0x55DD 0x55DE 0x55DF 0x55E1 0x55E2 0x55E3 0x55E4 0x55E5 0x55E6 0x55E7 0x55E8 0x55E9 0x55EA 0x55EB 0x55EC +0x55EE 0x55EF 0x55F0 0x55F1 0x55F2 0x55F3 0x55F5 0x55F6 0x55F7 0x55F9 0x55FA 0x55FB 0x55FC 0x55FD 0x55FE 0x55FF +0x5600 0x5601 0x5602 0x5604 0x5605 0x5606 0x5608 0x5609 0x560C 0x560D 0x560E 0x560F 0x5610 0x5611 0x5612 0x5613 +0x5614 0x5615 0x5616 0x5617 0x5618 0x561A 0x561B 0x561C 0x561D 0x561E 0x561F 0x5621 0x5622 0x5623 0x5624 0x5625 +0x5627 0x5629 0x562A 0x562B 0x562C 0x562D 0x562E 0x562F 0x5630 0x5631 0x5632 0x5633 0x5634 0x5635 0x5636 0x5638 +0x5639 0x563A 0x563B 0x563D 0x563E 0x563F 0x5640 0x5641 0x5642 0x5643 0x5645 0x5646 0x5647 0x5648 0x5649 0x564A +0x564C 0x564D 0x564E 0x564F 0x5650 0x5652 0x5653 0x5654 0x5657 0x5658 0x5659 0x565A 0x565B 0x565C 0x565D 0x565E +0x5660 0x5662 0x5663 0x5664 0x5665 0x5666 0x5668 0x5669 0x566A 0x566B 0x566C 0x566D 0x566E 0x566F 0x5670 0x5671 +0x5672 0x5673 0x5674 0x5676 0x5677 0x5678 0x5679 0x567A 0x567B 0x567C 0x567E 0x567F 0x5680 0x5681 0x5682 0x5683 +0x5684 0x5685 0x5686 0x5687 0x5689 0x568A 0x568C 0x568D 0x568E 0x568F 0x5690 0x5692 0x5693 0x5694 0x5695 0x5697 +0x5698 0x5699 0x569A 0x569B 0x569C 0x569D 0x569F 0x56A0 0x56A1 0x56A2 0x56A3 0x56A4 0x56A5 0x56A6 0x56A7 0x56A8 +0x56AA 0x56AB 0x56AC 0x56AD 0x56AE 0x56AF 0x56B1 0x56B2 0x56B3 0x56B4 0x56B5 0x56B6 0x56B7 0x56B9 0x56BC 0x56BD +0x56BE 0x56BF 0x56C0 0x56C1 0x56C2 0x56C3 0x56C5 0x56C6 0x56C8 0x56C9 0x56CA 0x56CB 0x56CC 0x56CD 0x56CE 0x56D1 +0x56D2 0x56D3 0x56D4 0x56D6 0x56D7 0x56D8 0x56D9 0x56DA 0x56DB 0x56DC 0x56DD 0x56DE 0x56DF 0x56E0 0x56E1 0x56E2 +0x56E3 0x56E4 0x56E5 0x56E6 0x56E7 0x56E8 0x56E9 0x56EA 0x56EB 0x56EC 0x56ED 0x56EE 0x56EF 0x56F0 0x56F1 0x56F2 +0x56F3 0x56F4 0x56F5 0x56F6 0x56F7 0x56F8 0x56F9 0x56FA 0x56FB 0x56FC 0x56FD 0x56FE 0x56FF 0x5700 0x5701 0x5702 +0x5703 0x5704 0x5705 0x5706 0x5707 0x5708 0x5709 0x570A 0x570B 0x570C 0x570D 0x570E 0x570F 0x5710 0x5711 0x5712 +0x5713 0x5714 0x5715 0x5716 0x5717 0x5718 0x5719 0x571A 0x571B 0x571C 0x571D 0x571E 0x571F 0x5720 0x5721 0x5722 +0x5723 0x5724 0x5726 0x5727 0x5728 0x5729 0x572A 0x572B 0x572C 0x572D 0x572E 0x572F 0x5730 0x5732 0x5733 0x5734 +0x5737 0x5738 0x5739 0x573A 0x573B 0x573E 0x5740 0x5741 0x5742 0x5745 0x5747 0x5749 0x574A 0x574B 0x574C 0x574D +0x574E 0x574F 0x5750 0x5751 0x5752 0x5754 0x5757 0x575A 0x575B 0x575C 0x575D 0x575E 0x575F 0x5760 0x5761 0x5762 +0x5764 0x5765 0x5766 0x5768 0x5769 0x576A 0x576B 0x576C 0x576D 0x576E 0x576F 0x5770 0x5771 0x5772 0x5773 0x5774 +0x5775 0x5776 0x5777 0x577B 0x577C 0x577D 0x577F 0x5780 0x5782 0x5783 0x5784 0x5785 0x5786 0x5787 0x5788 0x5789 +0x578B 0x578C 0x578D 0x578E 0x578F 0x5792 0x5793 0x5794 0x5795 0x5797 0x5798 0x5799 0x579A 0x579B 0x579D 0x579E +0x579F 0x57A0 0x57A1 0x57A2 0x57A3 0x57A4 0x57A5 0x57A6 0x57A7 0x57A8 0x57A9 0x57AA 0x57AB 0x57AD 0x57AE 0x57AF +0x57B0 0x57B1 0x57B2 0x57B3 0x57B4 0x57B5 0x57B6 0x57B8 0x57B9 0x57BA 0x57BB 0x57BC 0x57BD 0x57BE 0x57BF 0x57C0 +0x57C1 0x57C2 0x57C3 0x57C6 0x57C7 0x57C8 0x57CB 0x57CC 0x57CE 0x57CF 0x57D0 0x57D2 0x57D3 0x57D4 0x57D5 0x57D6 +0x57D7 0x57D8 0x57D9 0x57DA 0x57DC 0x57DD 0x57DE 0x57DF 0x57E0 0x57E1 0x57E2 0x57E3 0x57E4 0x57E5 0x57E7 0x57E8 +0x57E9 0x57EA 0x57EB 0x57EC 0x57ED 0x57EE 0x57EF 0x57F0 0x57F1 0x57F2 0x57F3 0x57F4 0x57F5 0x57F6 0x57F7 0x57F8 +0x57F9 0x57FA 0x57FB 0x57FC 0x57FD 0x5800 0x5801 0x5802 0x5803 0x5804 0x5805 0x5806 0x5807 0x5808 0x5809 0x580A +0x580B 0x580C 0x580D 0x580E 0x5810 0x5811 0x5814 0x5815 0x5816 0x5817 0x5819 0x581B 0x581C 0x581D 0x581E 0x5820 +0x5821 0x5823 0x5824 0x5825 0x5827 0x5828 0x5829 0x582A 0x582C 0x582D 0x582E 0x582F 0x5830 0x5831 0x5832 0x5833 +0x5834 0x5835 0x5836 0x5837 0x5838 0x5839 0x583A 0x583B 0x583C 0x583D 0x583E 0x583F 0x5840 0x5841 0x5842 0x5843 +0x5844 0x5845 0x5846 0x5848 0x5849 0x584A 0x584B 0x584C 0x584D 0x584E 0x584F 0x5851 0x5852 0x5853 0x5854 0x5855 +0x5857 0x5858 0x5859 0x585A 0x585B 0x585D 0x585E 0x5861 0x5862 0x5863 0x5864 0x5865 0x5868 0x5869 0x586B 0x586C +0x586D 0x586E 0x586F 0x5870 0x5871 0x5872 0x5873 0x5874 0x5875 0x5876 0x5878 0x5879 0x587A 0x587B 0x587C 0x587D +0x587E 0x587F 0x5880 0x5881 0x5882 0x5883 0x5884 0x5885 0x5886 0x5887 0x5888 0x5889 0x588A 0x588B 0x588E 0x588F +0x5890 0x5891 0x5892 0x5893 0x5894 0x5895 0x5897 0x5898 0x5899 0x589A 0x589C 0x589D 0x589E 0x589F 0x58A0 0x58A1 +0x58A3 0x58A5 0x58A6 0x58A8 0x58A9 0x58AB 0x58AC 0x58AE 0x58AF 0x58B1 0x58B3 0x58B6 0x58B8 0x58B9 0x58BA 0x58BB +0x58BC 0x58BD 0x58BE 0x58BF 0x58C1 0x58C2 0x58C5 0x58C6 0x58C7 0x58C8 0x58C9 0x58CA 0x58CB 0x58CC 0x58CE 0x58CF +0x58D1 0x58D2 0x58D3 0x58D4 0x58D5 0x58D6 0x58D7 0x58D8 0x58D9 0x58DA 0x58DB 0x58DC 0x58DD 0x58DE 0x58DF 0x58E0 +0x58E2 0x58E3 0x58E4 0x58E5 0x58E7 0x58E8 0x58E9 0x58EA 0x58EB 0x58EC 0x58EE 0x58EF 0x58F0 0x58F1 0x58F2 0x58F3 +0x58F4 0x58F6 0x58F7 0x58F8 0x58F9 0x58FA 0x58FB 0x58FC 0x58FD 0x58FE 0x58FF 0x5902 0x5903 0x5904 0x5906 0x5907 +0x5909 0x590A 0x590B 0x590C 0x590D 0x590E 0x590F 0x5910 0x5912 0x5913 0x5914 0x5915 0x5916 0x5917 0x5918 0x5919 +0x591A 0x591B 0x591C 0x591F 0x5920 0x5922 0x5924 0x5925 0x5927 0x5928 0x5929 0x592A 0x592B 0x592C 0x592D 0x592E +0x592F 0x5930 0x5931 0x5932 0x5933 0x5934 0x5937 0x5938 0x5939 0x593A 0x593C 0x593D 0x593E 0x593F 0x5940 0x5941 +0x5942 0x5944 0x5945 0x5947 0x5948 0x5949 0x594A 0x594B 0x594C 0x594E 0x594F 0x5950 0x5951 0x5953 0x5954 0x5955 +0x5956 0x5957 0x5958 0x595A 0x595C 0x5960 0x5961 0x5962 0x5964 0x5965 0x5967 0x5968 0x5969 0x596A 0x596B 0x596C +0x596D 0x596E 0x5970 0x5971 0x5972 0x5973 0x5974 0x5976 0x5977 0x5978 0x5979 0x597B 0x597C 0x597D 0x597E 0x597F +0x5980 0x5981 0x5982 0x5983 0x5984 0x5985 0x5986 0x5987 0x5988 0x5989 0x598A 0x598D 0x598E 0x598F 0x5990 0x5992 +0x5993 0x5996 0x5997 0x5998 0x5999 0x599B 0x599D 0x599E 0x59A0 0x59A1 0x59A2 0x59A3 0x59A4 0x59A5 0x59A6 0x59A7 +0x59A8 0x59A9 0x59AA 0x59AB 0x59AC 0x59AD 0x59AE 0x59AF 0x59B1 0x59B2 0x59B3 0x59B4 0x59B5 0x59B6 0x59B8 0x59B9 +0x59BA 0x59BB 0x59BC 0x59BD 0x59BE 0x59C0 0x59C1 0x59C3 0x59C5 0x59C6 0x59C7 0x59C8 0x59C9 0x59CA 0x59CB 0x59CC +0x59CD 0x59CE 0x59CF 0x59D0 0x59D1 0x59D2 0x59D3 0x59D4 0x59D6 0x59D7 0x59D8 0x59D9 0x59DA 0x59DB 0x59DC 0x59DD +0x59DE 0x59E0 0x59E1 0x59E3 0x59E4 0x59E5 0x59E6 0x59E8 0x59E9 0x59EA 0x59EB 0x59EC 0x59ED 0x59EE 0x59F1 0x59F2 +0x59F3 0x59F4 0x59F5 0x59F6 0x59F7 0x59F8 0x59F9 0x59FA 0x59FB 0x59FC 0x59FD 0x59FE 0x59FF 0x5A00 0x5A01 0x5A03 +0x5A04 0x5A05 0x5A06 0x5A07 0x5A08 0x5A09 0x5A0A 0x5A0C 0x5A0D 0x5A0F 0x5A11 0x5A12 0x5A13 0x5A15 0x5A16 0x5A17 +0x5A18 0x5A19 0x5A1A 0x5A1B 0x5A1C 0x5A1E 0x5A1F 0x5A20 0x5A23 0x5A25 0x5A29 0x5A2B 0x5A2D 0x5A2E 0x5A2F 0x5A31 +0x5A32 0x5A33 0x5A34 0x5A35 0x5A36 0x5A37 0x5A38 0x5A39 0x5A3C 0x5A3E 0x5A3F 0x5A40 0x5A41 0x5A42 0x5A43 0x5A44 +0x5A46 0x5A47 0x5A48 0x5A49 0x5A4A 0x5A4B 0x5A4C 0x5A4D 0x5A50 0x5A51 0x5A52 0x5A53 0x5A55 0x5A56 0x5A57 0x5A58 +0x5A5A 0x5A5B 0x5A5C 0x5A5D 0x5A5E 0x5A5F 0x5A60 0x5A62 0x5A64 0x5A65 0x5A66 0x5A67 0x5A69 0x5A6A 0x5A6B 0x5A6C +0x5A6D 0x5A70 0x5A73 0x5A74 0x5A75 0x5A76 0x5A77 0x5A78 0x5A7A 0x5A7B 0x5A7C 0x5A7D 0x5A7F 0x5A82 0x5A83 0x5A84 +0x5A86 0x5A8A 0x5A8B 0x5A8C 0x5A8E 0x5A8F 0x5A90 0x5A92 0x5A93 0x5A94 0x5A95 0x5A96 0x5A97 0x5A9A 0x5A9B 0x5A9C +0x5A9D 0x5A9E 0x5A9F 0x5AA0 0x5AA2 0x5AA4 0x5AA5 0x5AA6 0x5AA7 0x5AA9 0x5AAA 0x5AAC 0x5AAD 0x5AAE 0x5AAF 0x5AB0 +0x5AB1 0x5AB2 0x5AB3 0x5AB4 0x5AB5 0x5AB6 0x5AB7 0x5AB8 0x5AB9 0x5ABA 0x5ABB 0x5ABC 0x5ABD 0x5ABE 0x5ABF 0x5AC0 +0x5AC1 0x5AC2 0x5AC4 0x5AC6 0x5AC7 0x5AC8 0x5AC9 0x5ACA 0x5ACB 0x5ACC 0x5ACD 0x5ACF 0x5AD0 0x5AD2 0x5AD4 0x5AD5 +0x5AD6 0x5AD7 0x5AD8 0x5AD9 0x5ADA 0x5ADB 0x5ADC 0x5ADD 0x5ADE 0x5ADF 0x5AE0 0x5AE1 0x5AE2 0x5AE3 0x5AE4 0x5AE5 +0x5AE6 0x5AE8 0x5AE9 0x5AEA 0x5AEB 0x5AEC 0x5AED 0x5AEE 0x5AF1 0x5AF2 0x5AF3 0x5AF4 0x5AF5 0x5AF6 0x5AF7 0x5AF8 +0x5AF9 0x5AFA 0x5AFB 0x5AFD 0x5AFF 0x5B00 0x5B01 0x5B02 0x5B03 0x5B05 0x5B07 0x5B08 0x5B09 0x5B0B 0x5B0C 0x5B0F +0x5B10 0x5B13 0x5B14 0x5B16 0x5B17 0x5B19 0x5B1A 0x5B1B 0x5B1D 0x5B1E 0x5B20 0x5B21 0x5B22 0x5B23 0x5B24 0x5B25 +0x5B26 0x5B27 0x5B28 0x5B2A 0x5B2C 0x5B2D 0x5B2E 0x5B2F 0x5B30 0x5B32 0x5B34 0x5B36 0x5B37 0x5B38 0x5B3C 0x5B3D +0x5B3E 0x5B3F 0x5B40 0x5B43 0x5B45 0x5B47 0x5B48 0x5B4B 0x5B4C 0x5B4D 0x5B4E 0x5B50 0x5B51 0x5B52 0x5B53 0x5B54 +0x5B55 0x5B56 0x5B57 0x5B58 0x5B59 0x5B5A 0x5B5B 0x5B5C 0x5B5D 0x5B5E 0x5B5F 0x5B62 0x5B63 0x5B64 0x5B65 0x5B66 +0x5B69 0x5B6A 0x5B6B 0x5B6C 0x5B6D 0x5B6E 0x5B70 0x5B71 0x5B72 0x5B73 0x5B75 0x5B77 0x5B78 0x5B7A 0x5B7B 0x5B7C +0x5B7D 0x5B7F 0x5B80 0x5B81 0x5B82 0x5B83 0x5B84 0x5B85 0x5B87 0x5B88 0x5B89 0x5B8B 0x5B8C 0x5B8D 0x5B8E 0x5B8F +0x5B90 0x5B92 0x5B93 0x5B95 0x5B96 0x5B97 0x5B98 0x5B99 0x5B9A 0x5B9B 0x5B9C 0x5B9D 0x5B9E 0x5B9F 0x5BA0 0x5BA1 +0x5BA2 0x5BA3 0x5BA4 0x5BA5 0x5BA6 0x5BA7 0x5BA8 0x5BAA 0x5BAB 0x5BAC 0x5BAD 0x5BAE 0x5BB0 0x5BB3 0x5BB4 0x5BB5 +0x5BB6 0x5BB8 0x5BB9 0x5BBD 0x5BBE 0x5BBF 0x5BC0 0x5BC1 0x5BC2 0x5BC3 0x5BC4 0x5BC5 0x5BC6 0x5BC7 0x5BC9 0x5BCA +0x5BCB 0x5BCC 0x5BCD 0x5BCE 0x5BD0 0x5BD1 0x5BD2 0x5BD3 0x5BD4 0x5BD6 0x5BD7 0x5BD8 0x5BD9 0x5BDB 0x5BDD 0x5BDE +0x5BDF 0x5BE0 0x5BE1 0x5BE2 0x5BE3 0x5BE4 0x5BE5 0x5BE6 0x5BE7 0x5BE8 0x5BE9 0x5BEA 0x5BEB 0x5BEC 0x5BEE 0x5BEF +0x5BF0 0x5BF1 0x5BF2 0x5BF3 0x5BF5 0x5BF6 0x5BF8 0x5BF9 0x5BFA 0x5BFB 0x5BFC 0x5BFE 0x5BFF 0x5C01 0x5C02 0x5C03 +0x5C04 0x5C05 0x5C06 0x5C07 0x5C08 0x5C09 0x5C0A 0x5C0B 0x5C0C 0x5C0D 0x5C0E 0x5C0F 0x5C10 0x5C11 0x5C12 0x5C13 +0x5C14 0x5C15 0x5C16 0x5C17 0x5C18 0x5C19 0x5C1A 0x5C1B 0x5C1C 0x5C1D 0x5C1F 0x5C20 0x5C22 0x5C23 0x5C24 0x5C25 +0x5C27 0x5C28 0x5C2A 0x5C2C 0x5C2D 0x5C30 0x5C31 0x5C33 0x5C34 0x5C35 0x5C36 0x5C37 0x5C38 0x5C39 0x5C3A 0x5C3B +0x5C3C 0x5C3D 0x5C3E 0x5C3F 0x5C40 0x5C41 0x5C42 0x5C43 0x5C44 0x5C45 0x5C46 0x5C47 0x5C48 0x5C49 0x5C4A 0x5C4B +0x5C4C 0x5C4D 0x5C4E 0x5C4F 0x5C50 0x5C51 0x5C53 0x5C54 0x5C55 0x5C56 0x5C58 0x5C59 0x5C5B 0x5C5C 0x5C5D 0x5C5E +0x5C60 0x5C61 0x5C62 0x5C63 0x5C64 0x5C65 0x5C66 0x5C67 0x5C68 0x5C69 0x5C6A 0x5C6C 0x5C6D 0x5C6E 0x5C6F 0x5C70 +0x5C71 0x5C72 0x5C73 0x5C74 0x5C75 0x5C76 0x5C79 0x5C7A 0x5C7B 0x5C7C 0x5C7E 0x5C7F 0x5C81 0x5C82 0x5C83 0x5C86 +0x5C88 0x5C89 0x5C8A 0x5C8B 0x5C8C 0x5C8D 0x5C8F 0x5C90 0x5C91 0x5C92 0x5C93 0x5C94 0x5C95 0x5C96 0x5C97 0x5C98 +0x5C99 0x5C9A 0x5C9B 0x5C9C 0x5C9D 0x5C9E 0x5C9F 0x5CA0 0x5CA1 0x5CA2 0x5CA3 0x5CA4 0x5CA5 0x5CA6 0x5CA7 0x5CA8 +0x5CA9 0x5CAA 0x5CAB 0x5CAC 0x5CAD 0x5CAE 0x5CAF 0x5CB0 0x5CB1 0x5CB3 0x5CB5 0x5CB6 0x5CB7 0x5CB8 0x5CBA 0x5CBB +0x5CBC 0x5CBD 0x5CBE 0x5CBF 0x5CC0 0x5CC1 0x5CC2 0x5CC3 0x5CC4 0x5CC5 0x5CC6 0x5CC7 0x5CC8 0x5CC9 0x5CCA 0x5CCB +0x5CCC 0x5CCE 0x5CCF 0x5CD0 0x5CD2 0x5CD3 0x5CD4 0x5CD6 0x5CD7 0x5CD8 0x5CD9 0x5CDA 0x5CDB 0x5CDE 0x5CDF 0x5CE0 +0x5CE1 0x5CE3 0x5CE4 0x5CE5 0x5CE6 0x5CE7 0x5CE8 0x5CE9 0x5CEA 0x5CEC 0x5CED 0x5CEE 0x5CEF 0x5CF0 0x5CF1 0x5CF4 +0x5CF6 0x5CF7 0x5CF8 0x5CF9 0x5CFA 0x5CFB 0x5CFD 0x5CFF 0x5D00 0x5D01 0x5D02 0x5D03 0x5D04 0x5D05 0x5D06 0x5D07 +0x5D0B 0x5D0C 0x5D0D 0x5D0E 0x5D0F 0x5D10 0x5D11 0x5D12 0x5D14 0x5D15 0x5D16 0x5D17 0x5D18 0x5D19 0x5D1A 0x5D1B +0x5D1D 0x5D1E 0x5D1F 0x5D20 0x5D21 0x5D22 0x5D23 0x5D24 0x5D25 0x5D26 0x5D27 0x5D28 0x5D29 0x5D2C 0x5D2D 0x5D2E +0x5D30 0x5D31 0x5D32 0x5D33 0x5D34 0x5D35 0x5D36 0x5D37 0x5D38 0x5D39 0x5D3A 0x5D3C 0x5D3D 0x5D3E 0x5D3F 0x5D40 +0x5D41 0x5D42 0x5D43 0x5D44 0x5D45 0x5D47 0x5D49 0x5D4A 0x5D4B 0x5D4C 0x5D4E 0x5D50 0x5D51 0x5D52 0x5D55 0x5D56 +0x5D58 0x5D59 0x5D5A 0x5D5B 0x5D5C 0x5D5D 0x5D5E 0x5D62 0x5D63 0x5D65 0x5D67 0x5D68 0x5D69 0x5D6B 0x5D6C 0x5D6F +0x5D71 0x5D72 0x5D73 0x5D74 0x5D76 0x5D77 0x5D79 0x5D7A 0x5D7C 0x5D7D 0x5D7E 0x5D7F 0x5D80 0x5D81 0x5D82 0x5D84 +0x5D85 0x5D86 0x5D87 0x5D88 0x5D89 0x5D8A 0x5D8B 0x5D8C 0x5D8D 0x5D90 0x5D92 0x5D93 0x5D94 0x5D95 0x5D97 0x5D99 +0x5D9A 0x5D9C 0x5D9D 0x5D9E 0x5D9F 0x5DA0 0x5DA1 0x5DA2 0x5DA6 0x5DA7 0x5DA8 0x5DA9 0x5DAA 0x5DAC 0x5DAD 0x5DAE +0x5DAF 0x5DB0 0x5DB1 0x5DB2 0x5DB4 0x5DB5 0x5DB7 0x5DB8 0x5DBA 0x5DBC 0x5DBD 0x5DC0 0x5DC2 0x5DC3 0x5DC5 0x5DC6 +0x5DC7 0x5DC9 0x5DCB 0x5DCC 0x5DCD 0x5DCF 0x5DD1 0x5DD2 0x5DD3 0x5DD4 0x5DD5 0x5DD6 0x5DD8 0x5DDB 0x5DDD 0x5DDE +0x5DDF 0x5DE0 0x5DE1 0x5DE2 0x5DE3 0x5DE4 0x5DE5 0x5DE6 0x5DE7 0x5DE8 0x5DE9 0x5DEA 0x5DEB 0x5DED 0x5DEE 0x5DEF +0x5DF0 0x5DF1 0x5DF2 0x5DF3 0x5DF4 0x5DF5 0x5DF7 0x5DF8 0x5DF9 0x5DFB 0x5DFD 0x5DFE 0x5DFF 0x5E00 0x5E01 0x5E02 +0x5E03 0x5E04 0x5E05 0x5E06 0x5E08 0x5E0A 0x5E0B 0x5E0C 0x5E0E 0x5E0F 0x5E10 0x5E11 0x5E14 0x5E15 0x5E16 0x5E17 +0x5E18 0x5E19 0x5E1A 0x5E1B 0x5E1C 0x5E1D 0x5E1F 0x5E20 0x5E21 0x5E22 0x5E23 0x5E24 0x5E25 0x5E26 0x5E27 0x5E28 +0x5E29 0x5E2B 0x5E2D 0x5E2E 0x5E2F 0x5E30 0x5E31 0x5E33 0x5E34 0x5E35 0x5E36 0x5E37 0x5E38 0x5E3B 0x5E3C 0x5E3D +0x5E3E 0x5E3F 0x5E40 0x5E41 0x5E42 0x5E43 0x5E44 0x5E45 0x5E47 0x5E48 0x5E4A 0x5E4B 0x5E4C 0x5E4D 0x5E4E 0x5E4F +0x5E53 0x5E54 0x5E55 0x5E56 0x5E57 0x5E58 0x5E59 0x5E5B 0x5E5C 0x5E5D 0x5E5E 0x5E5F 0x5E60 0x5E61 0x5E62 0x5E63 +0x5E64 0x5E66 0x5E67 0x5E68 0x5E69 0x5E6A 0x5E6B 0x5E6C 0x5E6D 0x5E6E 0x5E6F 0x5E70 0x5E72 0x5E73 0x5E74 0x5E75 +0x5E76 0x5E77 0x5E78 0x5E79 0x5E7A 0x5E7B 0x5E7C 0x5E7D 0x5E7E 0x5E7F 0x5E80 0x5E81 0x5E82 0x5E83 0x5E84 0x5E85 +0x5E86 0x5E87 0x5E88 0x5E89 0x5E8A 0x5E8B 0x5E8C 0x5E8D 0x5E8F 0x5E90 0x5E91 0x5E93 0x5E94 0x5E95 0x5E96 0x5E97 +0x5E99 0x5E9A 0x5E9B 0x5E9C 0x5E9D 0x5E9E 0x5E9F 0x5EA0 0x5EA2 0x5EA3 0x5EA4 0x5EA5 0x5EA6 0x5EA7 0x5EA8 0x5EAA +0x5EAB 0x5EAC 0x5EAD 0x5EAE 0x5EB0 0x5EB1 0x5EB2 0x5EB3 0x5EB4 0x5EB5 0x5EB6 0x5EB7 0x5EB8 0x5EB9 0x5EBC 0x5EBE +0x5EC1 0x5EC2 0x5EC3 0x5EC4 0x5EC5 0x5EC6 0x5EC7 0x5EC8 0x5EC9 0x5ECA 0x5ECB 0x5ECC 0x5ECD 0x5ECE 0x5ECF 0x5ED0 +0x5ED1 0x5ED2 0x5ED3 0x5ED4 0x5ED5 0x5ED6 0x5ED7 0x5ED8 0x5ED9 0x5EDA 0x5EDB 0x5EDC 0x5EDD 0x5EDE 0x5EDF 0x5EE0 +0x5EE1 0x5EE2 0x5EE3 0x5EE5 0x5EE6 0x5EE7 0x5EE8 0x5EE9 0x5EEA 0x5EEC 0x5EEE 0x5EEF 0x5EF0 0x5EF1 0x5EF2 0x5EF3 +0x5EF4 0x5EF6 0x5EF7 0x5EF8 0x5EFA 0x5EFB 0x5EFC 0x5EFE 0x5EFF 0x5F00 0x5F01 0x5F02 0x5F03 0x5F04 0x5F05 0x5F06 +0x5F07 0x5F08 0x5F09 0x5F0A 0x5F0B 0x5F0C 0x5F0D 0x5F0E 0x5F0F 0x5F10 0x5F11 0x5F12 0x5F13 0x5F14 0x5F15 0x5F16 +0x5F17 0x5F18 0x5F1A 0x5F1B 0x5F1C 0x5F1D 0x5F1F 0x5F20 0x5F22 0x5F23 0x5F24 0x5F25 0x5F26 0x5F27 0x5F28 0x5F29 +0x5F2A 0x5F2D 0x5F2E 0x5F2F 0x5F30 0x5F31 0x5F33 0x5F34 0x5F35 0x5F36 0x5F37 0x5F38 0x5F39 0x5F3A 0x5F3C 0x5F3E +0x5F40 0x5F41 0x5F43 0x5F44 0x5F45 0x5F46 0x5F48 0x5F49 0x5F4A 0x5F4B 0x5F4C 0x5F4E 0x5F4F 0x5F50 0x5F51 0x5F52 +0x5F53 0x5F54 0x5F55 0x5F56 0x5F57 0x5F58 0x5F59 0x5F5B 0x5F5C 0x5F5D 0x5F5E 0x5F5F 0x5F60 0x5F61 0x5F62 0x5F63 +0x5F64 0x5F65 0x5F66 0x5F67 0x5F68 0x5F69 0x5F6A 0x5F6B 0x5F6C 0x5F6D 0x5F6E 0x5F6F 0x5F70 0x5F71 0x5F72 0x5F73 +0x5F74 0x5F76 0x5F77 0x5F78 0x5F79 0x5F7B 0x5F7C 0x5F7D 0x5F7E 0x5F7F 0x5F80 0x5F81 0x5F82 0x5F83 0x5F84 0x5F85 +0x5F86 0x5F87 0x5F88 0x5F89 0x5F8A 0x5F8B 0x5F8C 0x5F90 0x5F91 0x5F92 0x5F93 0x5F95 0x5F96 0x5F97 0x5F98 0x5F99 +0x5F9B 0x5F9C 0x5F9E 0x5F9F 0x5FA0 0x5FA1 0x5FA5 0x5FA6 0x5FA7 0x5FA8 0x5FA9 0x5FAA 0x5FAB 0x5FAC 0x5FAD 0x5FAE +0x5FAF 0x5FB3 0x5FB4 0x5FB5 0x5FB7 0x5FB9 0x5FBC 0x5FBD 0x5FC3 0x5FC4 0x5FC5 0x5FC6 0x5FC9 0x5FCC 0x5FCD 0x5FCF +0x5FD0 0x5FD1 0x5FD2 0x5FD3 0x5FD6 0x5FD7 0x5FD8 0x5FD9 0x5FDC 0x5FDD 0x5FDE 0x5FDF 0x5FE0 0x5FE1 0x5FE3 0x5FE4 +0x5FE7 0x5FE8 0x5FEA 0x5FEB 0x5FED 0x5FEE 0x5FF0 0x5FF1 0x5FF3 0x5FF5 0x5FF8 0x5FFA 0x5FFB 0x5FFC 0x5FFD 0x5FFE +0x5FFF 0x6000 0x6001 0x6002 0x6003 0x6004 0x6005 0x6006 0x600A 0x600D 0x600E 0x600F 0x6010 0x6012 0x6014 0x6015 +0x6016 0x6017 0x6019 0x601B 0x601C 0x601D 0x6020 0x6021 0x6025 0x6026 0x6027 0x6028 0x6029 0x602A 0x602B 0x602F +0x6031 0x6033 0x6035 0x6039 0x603A 0x603B 0x603C 0x603F 0x6041 0x6042 0x6043 0x6046 0x6047 0x604A 0x604B 0x604D +0x604F 0x6050 0x6052 0x6053 0x6054 0x6055 0x6059 0x605A 0x605D 0x605F 0x6060 0x6062 0x6063 0x6064 0x6065 0x6067 +0x6068 0x6069 0x606A 0x606B 0x606C 0x606D 0x606F 0x6070 0x6073 0x6075 0x6076 0x6077 0x6078 0x6079 0x607A 0x607B +0x607C 0x607D 0x607F 0x6081 0x6083 0x6084 0x6085 0x6086 0x6088 0x6089 0x608B 0x608C 0x608D 0x6092 0x6094 0x6095 +0x6096 0x6097 0x609A 0x609B 0x609D 0x609E 0x609F 0x60A0 0x60A2 0x60A3 0x60A4 0x60A6 0x60A7 0x60A8 0x60A9 0x60AA +0x60AB 0x60AC 0x60AD 0x60AE 0x60AF 0x60B0 0x60B1 0x60B2 0x60B3 0x60B4 0x60B5 0x60B6 0x60B8 0x60BB 0x60BC 0x60BD +0x60BE 0x60C5 0x60C6 0x60C7 0x60CA 0x60CB 0x60CE 0x60D1 0x60D3 0x60D4 0x60D5 0x60D7 0x60D8 0x60D9 0x60DA 0x60DB +0x60DC 0x60DD 0x60DF 0x60E0 0x60E1 0x60E2 0x60E3 0x60E6 0x60E7 0x60E8 0x60E9 0x60EB 0x60EC 0x60ED 0x60EE 0x60EF +0x60F0 0x60F1 0x60F2 0x60F3 0x60F4 0x60F6 0x60F7 0x60F9 0x60FA 0x60FB 0x60FC 0x6100 0x6101 0x6103 0x6106 0x6108 +0x6109 0x610A 0x610D 0x610E 0x610F 0x6110 0x6112 0x6113 0x6114 0x6115 0x6116 0x611A 0x611B 0x611C 0x611F 0x6120 +0x6121 0x6123 0x6124 0x6126 0x6127 0x6128 0x612B 0x612C 0x612D 0x6130 0x6134 0x6137 0x613C 0x613D 0x613E 0x613F +0x6142 0x6144 0x6146 0x6147 0x6148 0x614A 0x614B 0x614C 0x614D 0x614E 0x6151 0x6153 0x6155 0x6158 0x6159 0x615A +0x615C 0x615D 0x615F 0x6160 0x6162 0x6163 0x6164 0x6165 0x6167 0x6168 0x616A 0x616B 0x616C 0x616D 0x616E 0x616F +0x6170 0x6171 0x6173 0x6174 0x6175 0x6176 0x6177 0x617C 0x617D 0x617E 0x6181 0x6182 0x6183 0x6187 0x618A 0x618B +0x618D 0x618E 0x618F 0x6190 0x6191 0x6192 0x6193 0x6194 0x6195 0x6196 0x6198 0x6199 0x619A 0x619D 0x61A4 0x61A7 +0x61A8 0x61A9 0x61AB 0x61AC 0x61AD 0x61AE 0x61AF 0x61B1 0x61B2 0x61B6 0x61B7 0x61B9 0x61BA 0x61BE 0x61C1 0x61C2 +0x61C3 0x61C6 0x61C7 0x61C8 0x61C9 0x61CA 0x61CB 0x61CC 0x61CD 0x61D0 0x61D1 0x61D2 0x61D4 0x61DE 0x61DF 0x61E3 +0x61E6 0x61E8 0x61F2 0x61F4 0x61F5 0x61F6 0x61F7 0x61F8 0x61FA 0x61FC 0x61FD 0x61FE 0x61FF 0x6200 0x6206 0x6207 +0x6208 0x6209 0x620A 0x620B 0x620C 0x620D 0x620E 0x620F 0x6210 0x6211 0x6212 0x6213 0x6214 0x6215 0x6216 0x6217 +0x6218 0x6219 0x621A 0x621B 0x621D 0x621E 0x621F 0x6221 0x6222 0x6223 0x6224 0x6225 0x6226 0x6227 0x6229 0x622A +0x622C 0x622D 0x622E 0x622F 0x6230 0x6231 0x6232 0x6233 0x6234 0x6236 0x6237 0x6238 0x623A 0x623B 0x623D 0x623E +0x623F 0x6240 0x6241 0x6242 0x6243 0x6245 0x6246 0x6247 0x6248 0x6249 0x624A 0x624B 0x624C 0x624D 0x624E 0x6250 +0x6251 0x6252 0x6253 0x6254 0x6255 0x6258 0x6259 0x625A 0x625B 0x625E 0x6260 0x6261 0x6263 0x6264 0x6265 0x6266 +0x6267 0x6268 0x6269 0x626A 0x626B 0x626C 0x626D 0x626E 0x626F 0x6270 0x6271 0x6273 0x6276 0x6279 0x627A 0x627C +0x627D 0x627E 0x627F 0x6280 0x6282 0x6283 0x6284 0x6286 0x6288 0x6289 0x628A 0x628C 0x628F 0x6291 0x6292 0x6293 +0x6294 0x6295 0x6296 0x6297 0x6298 0x629A 0x629B 0x629C 0x629E 0x629F 0x62A0 0x62A1 0x62A2 0x62A4 0x62A5 0x62A6 +0x62A8 0x62AB 0x62AC 0x62AE 0x62B1 0x62B5 0x62B6 0x62B9 0x62BA 0x62BB 0x62BC 0x62BD 0x62BF 0x62C2 0x62C3 0x62C4 +0x62C5 0x62C6 0x62C7 0x62C8 0x62C9 0x62CA 0x62CB 0x62CC 0x62CD 0x62CE 0x62CF 0x62D0 0x62D1 0x62D2 0x62D3 0x62D4 +0x62D6 0x62D7 0x62D8 0x62D9 0x62DA 0x62DB 0x62DC 0x62DD 0x62DF 0x62E0 0x62E1 0x62E2 0x62E3 0x62E4 0x62E5 0x62E6 +0x62E7 0x62E8 0x62E9 0x62EC 0x62ED 0x62EE 0x62EF 0x62F1 0x62F3 0x62F4 0x62F5 0x62F6 0x62F7 0x62FC 0x62FD 0x62FE +0x62FF 0x6301 0x6302 0x6307 0x6308 0x6309 0x630C 0x630E 0x6311 0x6313 0x6316 0x6319 0x631A 0x631B 0x631C 0x631D +0x631E 0x631F 0x6320 0x6321 0x6322 0x6323 0x6324 0x6325 0x6326 0x6327 0x6328 0x632A 0x632B 0x632F 0x6332 0x6335 +0x6339 0x633A 0x633B 0x633C 0x633D 0x633E 0x633F 0x6342 0x6343 0x6345 0x6346 0x6349 0x634B 0x634C 0x634D 0x634E +0x634F 0x6350 0x6355 0x6357 0x6358 0x635C 0x635E 0x635F 0x6361 0x6362 0x6363 0x6367 0x6368 0x6369 0x636B 0x636D +0x636E 0x636F 0x6371 0x6372 0x6376 0x6377 0x637A 0x637B 0x637D 0x637F 0x6380 0x6382 0x6383 0x6384 0x6387 0x6388 +0x6389 0x638A 0x638C 0x638E 0x638F 0x6390 0x6392 0x6396 0x6397 0x6398 0x6399 0x639B 0x639E 0x639F 0x63A0 0x63A1 +0x63A2 0x63A3 0x63A5 0x63A7 0x63A8 0x63A9 0x63AA 0x63AB 0x63AC 0x63AD 0x63AE 0x63AF 0x63B0 0x63B1 0x63B2 0x63B3 +0x63B4 0x63B5 0x63B7 0x63B8 0x63B9 0x63BA 0x63BB 0x63BC 0x63BE 0x63C0 0x63C3 0x63C4 0x63C5 0x63C6 0x63C8 0x63C9 +0x63CC 0x63CD 0x63CE 0x63CF 0x63D0 0x63D2 0x63D5 0x63D6 0x63DA 0x63DB 0x63DE 0x63E0 0x63E1 0x63E2 0x63E3 0x63E4 +0x63E6 0x63E9 0x63EA 0x63EC 0x63ED 0x63EE 0x63F2 0x63F3 0x63F4 0x63F6 0x63F7 0x63F8 0x63F9 0x63FA 0x63FB 0x63FC +0x63FD 0x63FE 0x63FF 0x6400 0x6401 0x6402 0x6405 0x6406 0x6407 0x640A 0x640B 0x640C 0x640D 0x640F 0x6410 0x6412 +0x6413 0x6414 0x6415 0x6416 0x6417 0x6419 0x641B 0x641C 0x641D 0x641E 0x6420 0x6421 0x6422 0x6423 0x6425 0x6426 +0x6427 0x6428 0x642A 0x642C 0x642D 0x6430 0x6432 0x6434 0x6435 0x6436 0x643A 0x643D 0x643E 0x643F 0x6440 0x6441 +0x6442 0x6443 0x6444 0x6445 0x6446 0x6447 0x6448 0x644A 0x644B 0x644E 0x644F 0x6451 0x6452 0x6454 0x6458 0x6459 +0x645B 0x645C 0x645E 0x645F 0x6460 0x6467 0x6469 0x646D 0x646F 0x6470 0x6471 0x6473 0x6474 0x6475 0x6476 0x6477 +0x6478 0x6479 0x647A 0x647B 0x647D 0x6482 0x6483 0x6484 0x6485 0x6487 0x6488 0x648D 0x648F 0x6490 0x6491 0x6492 +0x6493 0x6495 0x6496 0x6498 0x6499 0x649A 0x649D 0x649E 0x649F 0x64A2 0x64A3 0x64A4 0x64A5 0x64A9 0x64AB 0x64AC +0x64AD 0x64AE 0x64B0 0x64B2 0x64B3 0x64B4 0x64B5 0x64B7 0x64B8 0x64B9 0x64BA 0x64BB 0x64BC 0x64BE 0x64BF 0x64C0 +0x64C1 0x64C2 0x64C4 0x64C5 0x64C7 0x64CA 0x64CB 0x64CD 0x64CE 0x64D0 0x64D2 0x64D3 0x64D4 0x64D6 0x64D7 0x64D8 +0x64DA 0x64DD 0x64DE 0x64E0 0x64E1 0x64E2 0x64E3 0x64E4 0x64E5 0x64E6 0x64E7 0x64E9 0x64EC 0x64ED 0x64EF 0x64F0 +0x64F1 0x64F2 0x64F4 0x64F6 0x64F7 0x64F8 0x64FA 0x64FB 0x64FC 0x64FD 0x64FE 0x64FF 0x6500 0x6504 0x6505 0x6506 +0x6509 0x650F 0x6511 0x6512 0x6514 0x6516 0x6518 0x6519 0x651B 0x651C 0x651D 0x651E 0x6522 0x6523 0x6524 0x6525 +0x652A 0x652B 0x652C 0x652E 0x652F 0x6530 0x6534 0x6535 0x6536 0x6537 0x6538 0x6539 0x653A 0x653B 0x653D 0x653E +0x653F 0x6541 0x6543 0x6545 0x6548 0x6549 0x654C 0x654D 0x654E 0x654F 0x6551 0x6554 0x6555 0x6556 0x6557 0x6558 +0x6559 0x655B 0x655C 0x655D 0x655E 0x6560 0x6562 0x6563 0x6566 0x6569 0x656B 0x656C 0x656D 0x6570 0x6572 0x6574 +0x6575 0x6577 0x6578 0x6579 0x657E 0x6582 0x6583 0x6585 0x6586 0x6587 0x6588 0x6589 0x658B 0x658C 0x658E 0x658F +0x6590 0x6591 0x6593 0x6595 0x6597 0x6599 0x659B 0x659C 0x659D 0x659E 0x659F 0x65A0 0x65A1 0x65A2 0x65A4 0x65A5 +0x65A7 0x65A8 0x65A9 0x65AB 0x65AC 0x65AD 0x65AF 0x65B0 0x65B2 0x65B6 0x65B7 0x65B8 0x65B9 0x65BC 0x65BD 0x65C1 +0x65C2 0x65C3 0x65C4 0x65C5 0x65C6 0x65CB 0x65CC 0x65CE 0x65CF 0x65D0 0x65D2 0x65D6 0x65D7 0x65D9 0x65DB 0x65DE +0x65E0 0x65E1 0x65E2 0x65E3 0x65E5 0x65E6 0x65E7 0x65E8 0x65E9 0x65EC 0x65ED 0x65EE 0x65EF 0x65F0 0x65F1 0x65F2 +0x65F3 0x65F4 0x65F5 0x65F6 0x65F7 0x65F8 0x65FA 0x65FB 0x65FC 0x65FD 0x65FF 0x6600 0x6602 0x6603 0x6604 0x6605 +0x6606 0x6607 0x6608 0x6609 0x660A 0x660B 0x660C 0x660D 0x660E 0x660F 0x6610 0x6611 0x6612 0x6613 0x6614 0x6615 +0x6619 0x661A 0x661C 0x661D 0x661E 0x661F 0x6620 0x6621 0x6622 0x6623 0x6624 0x6625 0x6626 0x6627 0x6628 0x662A +0x662B 0x662D 0x662E 0x662F 0x6630 0x6631 0x6632 0x6633 0x6634 0x6635 0x6636 0x663A 0x663B 0x663C 0x663D 0x663E +0x663F 0x6641 0x6642 0x6643 0x6644 0x6645 0x6649 0x664A 0x664B 0x664C 0x664F 0x6650 0x6652 0x6653 0x6654 0x6655 +0x6656 0x6657 0x6659 0x665A 0x665B 0x665D 0x665E 0x665F 0x6661 0x6662 0x6664 0x6665 0x6666 0x6667 0x6668 0x6669 +0x666A 0x666B 0x666C 0x666E 0x666F 0x6670 0x6671 0x6673 0x6674 0x6676 0x6677 0x6678 0x6679 0x667A 0x667B 0x667E +0x6681 0x6682 0x6683 0x6684 0x6685 0x6687 0x6688 0x6689 0x668B 0x668C 0x668D 0x668E 0x6690 0x6691 0x6692 0x6695 +0x6696 0x6697 0x6698 0x669D 0x66A0 0x66A2 0x66A3 0x66A6 0x66A7 0x66A8 0x66AA 0x66AB 0x66AE 0x66B1 0x66B2 0x66B3 +0x66B4 0x66B5 0x66B6 0x66B8 0x66B9 0x66BB 0x66BC 0x66BE 0x66BF 0x66C1 0x66C4 0x66C6 0x66C7 0x66C8 0x66C9 0x66CC +0x66D6 0x66D9 0x66DA 0x66DB 0x66DC 0x66DD 0x66E0 0x66E3 0x66E6 0x66E8 0x66E9 0x66EC 0x66EF 0x66F0 0x66F1 0x66F2 +0x66F3 0x66F4 0x66F5 0x66F7 0x66F8 0x66F9 0x66FA 0x66FC 0x66FD 0x66FE 0x66FF 0x6700 0x6701 0x6703 0x6706 0x6708 +0x6709 0x670A 0x670B 0x670D 0x670F 0x6710 0x6711 0x6712 0x6713 0x6714 0x6715 0x6716 0x6717 0x6718 0x671B 0x671D +0x671E 0x671F 0x6723 0x6725 0x6726 0x6727 0x6728 0x6729 0x672A 0x672B 0x672C 0x672D 0x672E 0x672F 0x6730 0x6731 +0x6732 0x6733 0x6734 0x6735 0x6736 0x6737 0x6738 0x673A 0x673D 0x673F 0x6740 0x6741 0x6742 0x6743 0x6744 0x6745 +0x6746 0x6748 0x6749 0x674B 0x674C 0x674E 0x674F 0x6750 0x6751 0x6753 0x6755 0x6756 0x6757 0x6759 0x675C 0x675E +0x675F 0x6760 0x6761 0x6762 0x6763 0x6764 0x6765 0x6767 0x6768 0x6769 0x676A 0x676D 0x676E 0x676F 0x6770 0x6771 +0x6772 0x6773 0x6774 0x6775 0x6777 0x677A 0x677B 0x677C 0x677E 0x677F 0x6781 0x6784 0x6785 0x6787 0x6789 0x678B +0x678C 0x678D 0x678F 0x6790 0x6791 0x6792 0x6793 0x6795 0x6797 0x6798 0x6799 0x679A 0x679C 0x679D 0x679E 0x679F +0x67A0 0x67A1 0x67A2 0x67A3 0x67A5 0x67A6 0x67A7 0x67A8 0x67A9 0x67AA 0x67AB 0x67AD 0x67AF 0x67B0 0x67B1 0x67B2 +0x67B3 0x67B4 0x67B5 0x67B6 0x67B7 0x67B8 0x67B9 0x67BE 0x67C1 0x67C3 0x67C4 0x67C6 0x67C8 0x67CA 0x67CE 0x67CF +0x67D0 0x67D1 0x67D2 0x67D3 0x67D4 0x67D6 0x67D8 0x67D9 0x67DA 0x67DC 0x67DD 0x67DE 0x67E0 0x67E2 0x67E4 0x67E5 +0x67E7 0x67E9 0x67EC 0x67EE 0x67EF 0x67F0 0x67F1 0x67F3 0x67F4 0x67F5 0x67F6 0x67F7 0x67FA 0x67FB 0x67FD 0x67FE +0x67FF 0x6800 0x6802 0x6803 0x6804 0x6805 0x6807 0x6808 0x6809 0x680A 0x680B 0x680C 0x680E 0x680F 0x6810 0x6811 +0x6812 0x6813 0x6814 0x6816 0x6817 0x6818 0x681D 0x681E 0x681F 0x6821 0x6822 0x6829 0x682A 0x682B 0x682F 0x6832 +0x6833 0x6834 0x6837 0x6838 0x6839 0x683B 0x683C 0x683D 0x683E 0x683F 0x6840 0x6841 0x6842 0x6843 0x6844 0x6845 +0x6846 0x6848 0x6849 0x684A 0x684B 0x684C 0x684D 0x684E 0x6850 0x6851 0x6853 0x6854 0x6855 0x6859 0x685C 0x685D +0x685F 0x6860 0x6861 0x6862 0x6863 0x6864 0x6865 0x6866 0x6867 0x6868 0x6869 0x686A 0x686B 0x686C 0x686D 0x686F +0x6872 0x6874 0x6876 0x6877 0x6879 0x687E 0x687F 0x6881 0x6882 0x6883 0x6885 0x6886 0x6887 0x688C 0x688D 0x688F +0x6890 0x6893 0x6894 0x6897 0x6898 0x689B 0x689C 0x689D 0x689F 0x68A0 0x68A1 0x68A2 0x68A3 0x68A6 0x68A7 0x68A8 +0x68AD 0x68AF 0x68B0 0x68B1 0x68B2 0x68B3 0x68B4 0x68B5 0x68B6 0x68B9 0x68BA 0x68BC 0x68BD 0x68BE 0x68BF 0x68C0 +0x68C1 0x68C2 0x68C4 0x68C5 0x68C6 0x68C9 0x68CA 0x68CB 0x68CD 0x68D0 0x68D1 0x68D2 0x68D3 0x68D4 0x68D5 0x68D6 +0x68D7 0x68D8 0x68DA 0x68DF 0x68E0 0x68E1 0x68E3 0x68E4 0x68E7 0x68E8 0x68EA 0x68EB 0x68EC 0x68EE 0x68EF 0x68F0 +0x68F1 0x68F2 0x68F5 0x68F6 0x68F8 0x68F9 0x68FA 0x68FB 0x68FC 0x68FD 0x6900 0x6901 0x6904 0x6905 0x6906 0x6907 +0x6908 0x690B 0x690C 0x690D 0x690E 0x690F 0x6910 0x6911 0x6912 0x6913 0x6919 0x691A 0x691B 0x691C 0x691D 0x691F +0x6920 0x6921 0x6922 0x6923 0x6924 0x6925 0x6926 0x6927 0x6928 0x692A 0x692B 0x692D 0x6930 0x6934 0x6935 0x6936 +0x6938 0x6939 0x693D 0x693F 0x6940 0x6942 0x694A 0x6952 0x6953 0x6954 0x6955 0x6957 0x6959 0x695A 0x695B 0x695C +0x695D 0x695E 0x695F 0x6960 0x6961 0x6962 0x6963 0x6966 0x6968 0x6969 0x696A 0x696B 0x696C 0x696D 0x696E 0x696F +0x6971 0x6973 0x6974 0x6975 0x6977 0x6978 0x6979 0x697C 0x697D 0x697E 0x6980 0x6981 0x6982 0x6983 0x6984 0x6985 +0x6986 0x6987 0x6988 0x6989 0x698A 0x698D 0x698E 0x6991 0x6994 0x6995 0x6996 0x6998 0x699B 0x699C 0x69A0 0x69A3 +0x69A5 0x69A6 0x69A7 0x69A8 0x69AA 0x69AB 0x69AD 0x69AE 0x69B0 0x69B1 0x69B2 0x69B4 0x69B7 0x69BB 0x69BC 0x69BE +0x69BF 0x69C1 0x69C3 0x69C5 0x69C7 0x69CA 0x69CB 0x69CC 0x69CD 0x69CE 0x69CF 0x69D0 0x69D1 0x69D3 0x69D4 0x69D8 +0x69D9 0x69DA 0x69DB 0x69DC 0x69DD 0x69DE 0x69DF 0x69E0 0x69E4 0x69E5 0x69E7 0x69E8 0x69EA 0x69EB 0x69ED 0x69F1 +0x69F2 0x69F3 0x69F9 0x69FA 0x69FB 0x69FC 0x69FD 0x69FE 0x69FF 0x6A01 0x6A02 0x6A05 0x6A0A 0x6A0B 0x6A0C 0x6A11 +0x6A12 0x6A13 0x6A14 0x6A17 0x6A18 0x6A19 0x6A1B 0x6A1E 0x6A1F 0x6A21 0x6A22 0x6A23 0x6A28 0x6A29 0x6A2A 0x6A2B +0x6A2E 0x6A2F 0x6A31 0x6A33 0x6A35 0x6A36 0x6A38 0x6A39 0x6A3A 0x6A3D 0x6A3E 0x6A3F 0x6A44 0x6A47 0x6A48 0x6A4B +0x6A50 0x6A51 0x6A52 0x6A53 0x6A58 0x6A59 0x6A5A 0x6A5B 0x6A5E 0x6A5F 0x6A61 0x6A62 0x6A65 0x6A66 0x6A6B 0x6A71 +0x6A72 0x6A74 0x6A78 0x6A79 0x6A7C 0x6A7D 0x6A7E 0x6A7F 0x6A80 0x6A81 0x6A84 0x6A87 0x6A89 0x6A8D 0x6A8E 0x6A90 +0x6A91 0x6A94 0x6A96 0x6A97 0x6A9C 0x6A9E 0x6A9F 0x6AA0 0x6AA2 0x6AA3 0x6AA8 0x6AA9 0x6AAA 0x6AAB 0x6AAC 0x6AAE +0x6AAF 0x6AB3 0x6AB4 0x6AB5 0x6AB8 0x6ABB 0x6AC1 0x6AC2 0x6AC3 0x6AC6 0x6AC8 0x6ACD 0x6AD1 0x6AD3 0x6ADA 0x6ADB +0x6ADD 0x6ADE 0x6ADF 0x6AE5 0x6AE7 0x6AE8 0x6AEA 0x6AEB 0x6AEC 0x6AF1 0x6AF3 0x6AF6 0x6AF8 0x6AFA 0x6AFB 0x6AFC +0x6B02 0x6B04 0x6B05 0x6B09 0x6B0A 0x6B0C 0x6B0F 0x6B10 0x6B12 0x6B13 0x6B16 0x6B17 0x6B1D 0x6B1E 0x6B1F 0x6B20 +0x6B21 0x6B22 0x6B23 0x6B24 0x6B27 0x6B2C 0x6B32 0x6B37 0x6B38 0x6B39 0x6B3A 0x6B3B 0x6B3D 0x6B3E 0x6B3F 0x6B43 +0x6B45 0x6B46 0x6B47 0x6B49 0x6B4C 0x6B4E 0x6B50 0x6B53 0x6B54 0x6B58 0x6B59 0x6B5B 0x6B5C 0x6B5F 0x6B61 0x6B62 +0x6B63 0x6B64 0x6B65 0x6B66 0x6B67 0x6B69 0x6B6A 0x6B6C 0x6B6F 0x6B72 0x6B73 0x6B74 0x6B77 0x6B78 0x6B79 0x6B7A +0x6B7B 0x6B7C 0x6B7F 0x6B80 0x6B81 0x6B82 0x6B83 0x6B84 0x6B86 0x6B87 0x6B89 0x6B8A 0x6B8B 0x6B8D 0x6B92 0x6B93 +0x6B95 0x6B96 0x6B98 0x6B9A 0x6B9B 0x6B9E 0x6BA1 0x6BA2 0x6BA3 0x6BA4 0x6BAA 0x6BAB 0x6BAD 0x6BAE 0x6BAF 0x6BB1 +0x6BB2 0x6BB3 0x6BB4 0x6BB5 0x6BB7 0x6BBA 0x6BBB 0x6BBC 0x6BBD 0x6BBF 0x6BC0 0x6BC1 0x6BC2 0x6BC5 0x6BC6 0x6BCB +0x6BCC 0x6BCD 0x6BCE 0x6BCF 0x6BD0 0x6BD1 0x6BD2 0x6BD3 0x6BD4 0x6BD5 0x6BD6 0x6BD7 0x6BD8 0x6BD9 0x6BDA 0x6BDB +0x6BDF 0x6BE1 0x6BEA 0x6BEB 0x6BEC 0x6BEF 0x6BF3 0x6BF4 0x6BF5 0x6BF7 0x6BF9 0x6BFD 0x6BFF 0x6C02 0x6C05 0x6C06 +0x6C07 0x6C08 0x6C09 0x6C0A 0x6C0C 0x6C0D 0x6C0F 0x6C10 0x6C11 0x6C13 0x6C14 0x6C15 0x6C16 0x6C17 0x6C18 0x6C19 +0x6C1A 0x6C1B 0x6C1C 0x6C1D 0x6C1E 0x6C1F 0x6C20 0x6C21 0x6C22 0x6C23 0x6C24 0x6C25 0x6C26 0x6C27 0x6C28 0x6C29 +0x6C2A 0x6C2B 0x6C2C 0x6C2D 0x6C2E 0x6C2F 0x6C30 0x6C31 0x6C32 0x6C33 0x6C34 0x6C35 0x6C36 0x6C37 0x6C38 0x6C39 +0x6C3A 0x6C3B 0x6C3C 0x6C3D 0x6C3E 0x6C3F 0x6C40 0x6C41 0x6C42 0x6C43 0x6C46 0x6C47 0x6C48 0x6C49 0x6C4A 0x6C4B +0x6C4D 0x6C4E 0x6C4F 0x6C50 0x6C54 0x6C55 0x6C57 0x6C59 0x6C5A 0x6C5B 0x6C5C 0x6C5D 0x6C5E 0x6C5F 0x6C60 0x6C61 +0x6C62 0x6C64 0x6C67 0x6C68 0x6C69 0x6C6A 0x6C6B 0x6C6D 0x6C70 0x6C72 0x6C73 0x6C74 0x6C76 0x6C78 0x6C79 0x6C7A +0x6C7D 0x6C7E 0x6C81 0x6C82 0x6C83 0x6C84 0x6C85 0x6C86 0x6C87 0x6C88 0x6C89 0x6C8C 0x6C8D 0x6C8F 0x6C90 0x6C92 +0x6C93 0x6C94 0x6C95 0x6C96 0x6C98 0x6C99 0x6C9A 0x6C9B 0x6C9C 0x6C9F 0x6CA1 0x6CA2 0x6CA3 0x6CA4 0x6CA5 0x6CA6 +0x6CA7 0x6CA8 0x6CA9 0x6CAA 0x6CAB 0x6CAC 0x6CAD 0x6CAE 0x6CB1 0x6CB2 0x6CB3 0x6CB5 0x6CB8 0x6CB9 0x6CBA 0x6CBB +0x6CBC 0x6CBD 0x6CBE 0x6CBF 0x6CC1 0x6CC2 0x6CC3 0x6CC4 0x6CC5 0x6CC6 0x6CC7 0x6CC9 0x6CCA 0x6CCC 0x6CD0 0x6CD3 +0x6CD4 0x6CD5 0x6CD6 0x6CD7 0x6CD9 0x6CDA 0x6CDB 0x6CDC 0x6CDD 0x6CDE 0x6CE0 0x6CE1 0x6CE2 0x6CE3 0x6CE5 0x6CE8 +0x6CEA 0x6CEB 0x6CEE 0x6CEF 0x6CF0 0x6CF1 0x6CF3 0x6CF5 0x6CF6 0x6CF7 0x6CF8 0x6CFA 0x6CFB 0x6CFC 0x6CFD 0x6CFE +0x6D01 0x6D04 0x6D05 0x6D07 0x6D08 0x6D0B 0x6D0C 0x6D0D 0x6D0E 0x6D10 0x6D11 0x6D12 0x6D13 0x6D16 0x6D17 0x6D18 +0x6D19 0x6D1A 0x6D1B 0x6D1E 0x6D1F 0x6D22 0x6D23 0x6D25 0x6D27 0x6D28 0x6D29 0x6D2A 0x6D2B 0x6D2D 0x6D2E 0x6D31 +0x6D32 0x6D33 0x6D34 0x6D35 0x6D36 0x6D38 0x6D39 0x6D3A 0x6D3B 0x6D3C 0x6D3D 0x6D3E 0x6D3F 0x6D41 0x6D43 0x6D44 +0x6D45 0x6D46 0x6D47 0x6D48 0x6D49 0x6D4A 0x6D4B 0x6D4D 0x6D4E 0x6D4F 0x6D50 0x6D51 0x6D52 0x6D53 0x6D54 0x6D55 +0x6D59 0x6D5A 0x6D5B 0x6D5C 0x6D5E 0x6D5F 0x6D60 0x6D61 0x6D63 0x6D64 0x6D65 0x6D66 0x6D69 0x6D6A 0x6D6C 0x6D6D +0x6D6E 0x6D6F 0x6D70 0x6D72 0x6D74 0x6D77 0x6D78 0x6D79 0x6D7B 0x6D7C 0x6D7F 0x6D82 0x6D84 0x6D85 0x6D87 0x6D88 +0x6D89 0x6D8A 0x6D8C 0x6D8D 0x6D8E 0x6D8F 0x6D90 0x6D91 0x6D93 0x6D94 0x6D95 0x6D97 0x6D98 0x6D99 0x6D9A 0x6D9B +0x6D9C 0x6D9D 0x6D9E 0x6D9F 0x6DA0 0x6DA1 0x6DA2 0x6DA3 0x6DA4 0x6DA6 0x6DA7 0x6DA8 0x6DA9 0x6DAA 0x6DAB 0x6DAD +0x6DAE 0x6DAF 0x6DB2 0x6DB4 0x6DB5 0x6DB7 0x6DB8 0x6DBC 0x6DBF 0x6DC0 0x6DC3 0x6DC4 0x6DC5 0x6DC6 0x6DC7 0x6DCB +0x6DCC 0x6DCD 0x6DCF 0x6DD1 0x6DD2 0x6DD5 0x6DD6 0x6DD8 0x6DD9 0x6DDA 0x6DDC 0x6DDD 0x6DDE 0x6DDF 0x6DE0 0x6DE1 +0x6DE4 0x6DE5 0x6DE6 0x6DE8 0x6DE9 0x6DEA 0x6DEB 0x6DEC 0x6DEE 0x6DEF 0x6DF1 0x6DF3 0x6DF4 0x6DF5 0x6DF6 0x6DF7 +0x6DF8 0x6DF9 0x6DFA 0x6DFB 0x6DFC 0x6DFD 0x6E05 0x6E07 0x6E08 0x6E09 0x6E0A 0x6E0B 0x6E0C 0x6E0D 0x6E0E 0x6E10 +0x6E11 0x6E13 0x6E14 0x6E15 0x6E16 0x6E17 0x6E19 0x6E1A 0x6E1B 0x6E1D 0x6E1F 0x6E20 0x6E21 0x6E22 0x6E23 0x6E24 +0x6E25 0x6E26 0x6E29 0x6E2B 0x6E2C 0x6E2D 0x6E2E 0x6E2F 0x6E30 0x6E32 0x6E34 0x6E36 0x6E38 0x6E3A 0x6E3C 0x6E3D +0x6E3E 0x6E43 0x6E44 0x6E49 0x6E4A 0x6E4B 0x6E4D 0x6E4E 0x6E51 0x6E53 0x6E54 0x6E56 0x6E58 0x6E5B 0x6E5C 0x6E5D +0x6E5E 0x6E5F 0x6E61 0x6E62 0x6E63 0x6E66 0x6E67 0x6E68 0x6E69 0x6E6A 0x6E6B 0x6E6E 0x6E6F 0x6E72 0x6E73 0x6E74 +0x6E76 0x6E7A 0x6E7B 0x6E7E 0x6E7F 0x6E80 0x6E81 0x6E82 0x6E83 0x6E85 0x6E86 0x6E87 0x6E88 0x6E89 0x6E8C 0x6E8D +0x6E8E 0x6E8F 0x6E90 0x6E96 0x6E98 0x6E9A 0x6E9C 0x6E9D 0x6E9E 0x6E9F 0x6EA0 0x6EA2 0x6EA5 0x6EA6 0x6EA7 0x6EAA +0x6EAB 0x6EAE 0x6EAF 0x6EB1 0x6EB2 0x6EB3 0x6EB4 0x6EB5 0x6EB6 0x6EB7 0x6EB9 0x6EBA 0x6EBB 0x6EBC 0x6EBD 0x6EC1 +0x6EC2 0x6EC3 0x6EC4 0x6EC5 0x6EC6 0x6EC7 0x6EC8 0x6EC9 0x6ECB 0x6ECC 0x6ECD 0x6ECE 0x6ECF 0x6ED1 0x6ED3 0x6ED4 +0x6ED5 0x6ED7 0x6ED8 0x6ED9 0x6EDA 0x6EDD 0x6EDE 0x6EDF 0x6EE0 0x6EE1 0x6EE2 0x6EE4 0x6EE5 0x6EE6 0x6EE7 0x6EE8 +0x6EE9 0x6EEA 0x6EEB 0x6EEC 0x6EEE 0x6EEF 0x6EF2 0x6EF4 0x6EF7 0x6EF8 0x6EF9 0x6EFB 0x6EFE 0x6EFF 0x6F01 0x6F02 +0x6F06 0x6F08 0x6F09 0x6F0A 0x6F0B 0x6F0C 0x6F0D 0x6F0F 0x6F11 0x6F13 0x6F14 0x6F15 0x6F16 0x6F1A 0x6F20 0x6F22 +0x6F23 0x6F24 0x6F25 0x6F26 0x6F27 0x6F29 0x6F2A 0x6F2B 0x6F2C 0x6F2D 0x6F2F 0x6F30 0x6F31 0x6F32 0x6F33 0x6F34 +0x6F35 0x6F36 0x6F37 0x6F38 0x6F39 0x6F3B 0x6F3C 0x6F3E 0x6F3F 0x6F41 0x6F45 0x6F46 0x6F47 0x6F4A 0x6F4B 0x6F4D +0x6F4F 0x6F51 0x6F54 0x6F55 0x6F56 0x6F57 0x6F58 0x6F59 0x6F5A 0x6F5B 0x6F5C 0x6F5E 0x6F5F 0x6F60 0x6F62 0x6F63 +0x6F64 0x6F66 0x6F69 0x6F6D 0x6F6E 0x6F6F 0x6F70 0x6F72 0x6F74 0x6F75 0x6F76 0x6F77 0x6F78 0x6F7A 0x6F7C 0x6F7D +0x6F7E 0x6F7F 0x6F80 0x6F81 0x6F82 0x6F84 0x6F86 0x6F87 0x6F88 0x6F89 0x6F8C 0x6F8D 0x6F8E 0x6F90 0x6F91 0x6F92 +0x6F94 0x6F97 0x6F9B 0x6F9C 0x6FA0 0x6FA1 0x6FA3 0x6FA4 0x6FA5 0x6FA6 0x6FA7 0x6FA8 0x6FA9 0x6FAA 0x6FAB 0x6FAD +0x6FAE 0x6FAF 0x6FB1 0x6FB3 0x6FB4 0x6FB6 0x6FB9 0x6FBC 0x6FBD 0x6FBE 0x6FC0 0x6FC1 0x6FC2 0x6FC3 0x6FC6 0x6FC7 +0x6FC9 0x6FCA 0x6FCB 0x6FD1 0x6FD2 0x6FD4 0x6FD5 0x6FD8 0x6FDA 0x6FDB 0x6FDC 0x6FDE 0x6FDF 0x6FE0 0x6FE1 0x6FE4 +0x6FE8 0x6FE9 0x6FEB 0x6FEC 0x6FEE 0x6FEF 0x6FF0 0x6FF1 0x6FF3 0x6FF6 0x6FFA 0x6FFC 0x6FFE 0x7001 0x7002 0x7005 +0x7006 0x7009 0x700B 0x700C 0x700D 0x700F 0x7011 0x7014 0x7015 0x7018 0x701A 0x701B 0x701C 0x701D 0x701E 0x701F +0x7020 0x7021 0x7023 0x7026 0x7027 0x7028 0x702C 0x702F 0x7030 0x7031 0x7032 0x7035 0x7037 0x7039 0x703C 0x703E +0x7043 0x7044 0x7048 0x704C 0x704F 0x7050 0x7051 0x7054 0x7055 0x7058 0x705D 0x705E 0x7060 0x7063 0x7064 0x7065 +0x7067 0x7069 0x706B 0x706C 0x706D 0x706F 0x7070 0x7074 0x7075 0x7076 0x7078 0x707A 0x707C 0x707D 0x707E 0x707F +0x7080 0x7081 0x7085 0x7086 0x7089 0x708A 0x708C 0x708E 0x7092 0x7094 0x7095 0x7096 0x7098 0x7099 0x709A 0x709C +0x709D 0x709E 0x709F 0x70A1 0x70A3 0x70A4 0x70A9 0x70AB 0x70AC 0x70AD 0x70AE 0x70AF 0x70B0 0x70B1 0x70B3 0x70B5 +0x70B7 0x70B8 0x70B9 0x70BA 0x70BB 0x70BC 0x70BD 0x70C0 0x70C1 0x70C2 0x70C3 0x70C7 0x70C8 0x70CA 0x70CB 0x70CE +0x70CF 0x70D3 0x70D4 0x70D8 0x70D9 0x70DA 0x70DB 0x70DC 0x70DD 0x70DF 0x70E0 0x70E4 0x70E6 0x70E7 0x70E8 0x70E9 +0x70EB 0x70EC 0x70ED 0x70EF 0x70F1 0x70F4 0x70F6 0x70F7 0x70F9 0x70FA 0x70FB 0x70FD 0x7104 0x7106 0x7109 0x710A +0x710C 0x7110 0x7113 0x7114 0x7115 0x7116 0x7117 0x7118 0x7119 0x711A 0x711C 0x711E 0x7120 0x7121 0x7122 0x7126 +0x712E 0x712F 0x7130 0x7131 0x7136 0x713A 0x713C 0x713F 0x7140 0x7141 0x7143 0x7145 0x7146 0x7147 0x7149 0x714A +0x714B 0x714C 0x714E 0x714F 0x7150 0x7151 0x7152 0x7153 0x7155 0x7156 0x7159 0x715A 0x715C 0x715E 0x715F 0x7162 +0x7163 0x7164 0x7165 0x7166 0x7167 0x7168 0x7169 0x716C 0x716E 0x7172 0x7173 0x7174 0x7178 0x717A 0x717D 0x717F +0x7180 0x7184 0x7185 0x7187 0x7188 0x7189 0x718A 0x718F 0x7190 0x7192 0x7194 0x7195 0x7197 0x7198 0x7199 0x719B +0x719C 0x719F 0x71A0 0x71A2 0x71A5 0x71A8 0x71AC 0x71AF 0x71B0 0x71B1 0x71B2 0x71B3 0x71B5 0x71B9 0x71BA 0x71BB +0x71BE 0x71C0 0x71C1 0x71C3 0x71C4 0x71C8 0x71C9 0x71CA 0x71CB 0x71CE 0x71CF 0x71D0 0x71D2 0x71D4 0x71D5 0x71D6 +0x71D7 0x71D9 0x71DA 0x71DC 0x71DF 0x71E0 0x71E1 0x71E5 0x71E6 0x71E7 0x71EC 0x71ED 0x71EE 0x71F4 0x71F5 0x71F6 +0x71F8 0x71F9 0x71FB 0x71FC 0x71FE 0x71FF 0x7200 0x7201 0x7206 0x7207 0x720C 0x720D 0x7210 0x7213 0x7214 0x7215 +0x721A 0x721B 0x721D 0x721F 0x7228 0x722A 0x722B 0x722C 0x722D 0x7230 0x7231 0x7232 0x7235 0x7236 0x7237 0x7238 +0x7239 0x723A 0x723B 0x723C 0x723D 0x723E 0x723F 0x7240 0x7241 0x7242 0x7246 0x7247 0x7248 0x724B 0x724C 0x724D +0x7252 0x7256 0x7258 0x7259 0x725A 0x725B 0x725D 0x725E 0x725F 0x7260 0x7261 0x7262 0x7263 0x7264 0x7265 0x7266 +0x7267 0x7269 0x726E 0x726F 0x7272 0x7274 0x7275 0x7277 0x7278 0x7279 0x727A 0x727B 0x727D 0x727E 0x727F 0x7280 +0x7281 0x7282 0x7284 0x7287 0x728A 0x728B 0x728D 0x728F 0x7292 0x7296 0x7297 0x729B 0x729F 0x72A0 0x72A1 0x72A2 +0x72A7 0x72A8 0x72AC 0x72AD 0x72AE 0x72AF 0x72B0 0x72B2 0x72B4 0x72B6 0x72B7 0x72B8 0x72B9 0x72BC 0x72C0 0x72C1 +0x72C2 0x72C3 0x72C4 0x72C6 0x72C8 0x72C9 0x72CD 0x72CE 0x72D0 0x72D2 0x72D3 0x72D7 0x72D9 0x72DB 0x72DD 0x72DE +0x72DF 0x72E0 0x72E1 0x72E2 0x72E8 0x72E9 0x72EC 0x72ED 0x72EE 0x72EF 0x72F0 0x72F1 0x72F2 0x72F3 0x72F4 0x72F7 +0x72F8 0x72F9 0x72FA 0x72FB 0x72FC 0x72FD 0x7301 0x7303 0x7304 0x7306 0x7307 0x730A 0x730B 0x730E 0x7313 0x7314 +0x7315 0x7316 0x7317 0x7319 0x731B 0x731C 0x731D 0x731E 0x731F 0x7321 0x7322 0x7325 0x7329 0x732A 0x732B 0x732C +0x732E 0x732F 0x7330 0x7331 0x7334 0x7336 0x7337 0x7338 0x7339 0x733A 0x733B 0x733E 0x733F 0x7341 0x7343 0x7344 +0x7345 0x7347 0x734D 0x734E 0x734F 0x7350 0x7352 0x7355 0x7357 0x735A 0x735B 0x7360 0x7362 0x7363 0x7364 0x7368 +0x736A 0x736B 0x736C 0x736D 0x736E 0x736F 0x7370 0x7372 0x7374 0x7375 0x7377 0x7378 0x737A 0x737B 0x737C 0x737E +0x7380 0x7381 0x7383 0x7384 0x7386 0x7387 0x7389 0x738A 0x738B 0x738E 0x738F 0x7391 0x7392 0x7393 0x7394 0x7395 +0x7396 0x7397 0x7398 0x7399 0x739A 0x739B 0x739E 0x739F 0x73A0 0x73A1 0x73A2 0x73A4 0x73A5 0x73A6 0x73A7 0x73A8 +0x73A9 0x73AB 0x73AD 0x73AE 0x73AF 0x73B0 0x73B1 0x73B2 0x73B3 0x73B5 0x73B6 0x73B7 0x73B9 0x73BA 0x73BB 0x73BC +0x73BD 0x73BF 0x73C0 0x73C2 0x73C3 0x73C4 0x73C5 0x73C7 0x73C8 0x73C9 0x73CA 0x73CB 0x73CC 0x73CD 0x73CE 0x73CF +0x73D0 0x73D1 0x73D2 0x73D5 0x73D6 0x73D7 0x73D9 0x73DB 0x73DD 0x73DE 0x73E0 0x73E1 0x73E2 0x73E3 0x73E4 0x73E5 +0x73E6 0x73E7 0x73E8 0x73E9 0x73EA 0x73EB 0x73ED 0x73EE 0x73F0 0x73F1 0x73F2 0x73F5 0x73F6 0x73F7 0x73F8 0x73F9 +0x73FA 0x73FD 0x73FE 0x7400 0x7401 0x7402 0x7403 0x7404 0x7405 0x7406 0x7407 0x7408 0x7409 0x740A 0x740D 0x740E +0x740F 0x7410 0x7413 0x7414 0x7415 0x741A 0x741B 0x741E 0x741F 0x7420 0x7421 0x7422 0x7424 0x7425 0x7426 0x7428 +0x742A 0x742B 0x742C 0x742D 0x742E 0x742F 0x7430 0x7431 0x7432 0x7433 0x7434 0x7435 0x7436 0x7437 0x7438 0x743A +0x743C 0x743F 0x7440 0x7441 0x7442 0x7443 0x7444 0x7445 0x7446 0x744A 0x744B 0x744C 0x7451 0x7452 0x7453 0x7454 +0x7455 0x7456 0x7457 0x7459 0x745A 0x745B 0x745C 0x745D 0x745E 0x745F 0x7460 0x7462 0x7463 0x7464 0x7465 0x7467 +0x7468 0x7469 0x746A 0x746C 0x746D 0x746F 0x7470 0x7471 0x7472 0x7473 0x7476 0x7477 0x7478 0x747D 0x747E 0x7480 +0x7481 0x7482 0x7483 0x7486 0x7487 0x7488 0x7489 0x748A 0x748B 0x748E 0x748F 0x7490 0x7492 0x7495 0x7497 0x7498 +0x749C 0x749E 0x749F 0x74A0 0x74A1 0x74A2 0x74A3 0x74A4 0x74A5 0x74A6 0x74A7 0x74A8 0x74A9 0x74AA 0x74AB 0x74AC +0x74AE 0x74B0 0x74B1 0x74B2 0x74B5 0x74B8 0x74B9 0x74BA 0x74BD 0x74BF 0x74C0 0x74C5 0x74C6 0x74C8 0x74CA 0x74CC +0x74CF 0x74D2 0x74D3 0x74D4 0x74D6 0x74D8 0x74DA 0x74DB 0x74DC 0x74DE 0x74E0 0x74E2 0x74E3 0x74E4 0x74E6 0x74E7 +0x74E9 0x74EE 0x74EF 0x74F0 0x74F1 0x74F2 0x74F4 0x74F6 0x74F7 0x74F8 0x74FB 0x74FF 0x7501 0x7503 0x7504 0x7505 +0x7507 0x750C 0x750D 0x750E 0x750F 0x7511 0x7513 0x7515 0x7516 0x7517 0x7518 0x7519 0x751A 0x751B 0x751C 0x751D +0x751E 0x751F 0x7521 0x7522 0x7523 0x7525 0x7526 0x7528 0x7529 0x752A 0x752B 0x752C 0x752D 0x752E 0x752F 0x7530 +0x7531 0x7532 0x7533 0x7534 0x7535 0x7537 0x7538 0x7539 0x753A 0x753B 0x753C 0x753D 0x753E 0x753F 0x7540 0x7544 +0x7545 0x7546 0x7547 0x7548 0x7549 0x754A 0x754B 0x754C 0x754D 0x754E 0x754F 0x7551 0x7553 0x7554 0x7556 0x7559 +0x755A 0x755B 0x755C 0x755D 0x755F 0x7560 0x7562 0x7563 0x7564 0x7565 0x7566 0x7567 0x7569 0x756A 0x756B 0x756C +0x756D 0x756F 0x7570 0x7572 0x7573 0x7574 0x7575 0x7576 0x7577 0x7578 0x7579 0x757A 0x757D 0x757E 0x757F 0x7580 +0x7581 0x7582 0x7583 0x7584 0x7586 0x7587 0x7589 0x758A 0x758B 0x758C 0x758D 0x758E 0x758F 0x7590 0x7591 0x7592 +0x7594 0x7595 0x7596 0x7597 0x7598 0x7599 0x759A 0x759D 0x759F 0x75A0 0x75A1 0x75A2 0x75A3 0x75A4 0x75A5 0x75A7 +0x75AA 0x75AB 0x75AC 0x75AD 0x75AE 0x75AF 0x75B0 0x75B1 0x75B2 0x75B3 0x75B4 0x75B5 0x75B6 0x75B8 0x75B9 0x75BA +0x75BB 0x75BC 0x75BD 0x75BE 0x75BF 0x75C0 0x75C1 0x75C2 0x75C3 0x75C4 0x75C5 0x75C7 0x75C8 0x75C9 0x75CA 0x75CB +0x75CC 0x75CD 0x75CE 0x75CF 0x75D0 0x75D1 0x75D2 0x75D3 0x75D4 0x75D5 0x75D6 0x75D7 0x75D8 0x75D9 0x75DA 0x75DB +0x75DD 0x75DE 0x75DF 0x75E0 0x75E1 0x75E2 0x75E3 0x75E4 0x75E6 0x75E7 0x75E8 0x75E9 0x75EA 0x75EB 0x75ED 0x75EF +0x75F0 0x75F1 0x75F2 0x75F3 0x75F4 0x75F5 0x75F6 0x75F7 0x75F8 0x75F9 0x75FA 0x75FB 0x75FC 0x75FD 0x75FE 0x75FF +0x7600 0x7601 0x7602 0x7603 0x7604 0x7605 0x7606 0x7608 0x7609 0x760A 0x760B 0x760C 0x760D 0x760F 0x7610 0x7611 +0x7613 0x7614 0x7615 0x7616 0x7617 0x7618 0x7619 0x761A 0x761B 0x761C 0x761D 0x761E 0x761F 0x7620 0x7621 0x7622 +0x7623 0x7624 0x7625 0x7626 0x7627 0x7628 0x7629 0x762A 0x762B 0x762D 0x762E 0x762F 0x7630 0x7631 0x7632 0x7633 +0x7634 0x7635 0x7638 0x763A 0x763B 0x763C 0x763D 0x763E 0x763F 0x7640 0x7642 0x7643 0x7646 0x7647 0x7648 0x7649 +0x764C 0x764D 0x764E 0x7650 0x7652 0x7653 0x7654 0x7656 0x7657 0x7658 0x7659 0x765A 0x765C 0x765E 0x765F 0x7660 +0x7661 0x7662 0x7663 0x7664 0x7665 0x7666 0x7667 0x7668 0x7669 0x766A 0x766B 0x766C 0x766D 0x766E 0x766F 0x7670 +0x7671 0x7672 0x7675 0x7676 0x7678 0x7679 0x767A 0x767B 0x767C 0x767D 0x767E 0x767F 0x7680 0x7681 0x7682 0x7683 +0x7684 0x7686 0x7687 0x7688 0x7689 0x768A 0x768B 0x768E 0x768F 0x7690 0x7691 0x7692 0x7693 0x7695 0x7696 0x7699 +0x769A 0x769B 0x769C 0x769D 0x769E 0x76A4 0x76A6 0x76AA 0x76AB 0x76AD 0x76AE 0x76AF 0x76B0 0x76B1 0x76B2 0x76B4 +0x76B5 0x76B6 0x76B7 0x76B8 0x76B9 0x76BA 0x76BB 0x76BD 0x76BE 0x76BF 0x76C2 0x76C3 0x76C4 0x76C5 0x76C6 0x76C8 +0x76C9 0x76CA 0x76CC 0x76CD 0x76CE 0x76CF 0x76D0 0x76D1 0x76D2 0x76D3 0x76D4 0x76D6 0x76D7 0x76D8 0x76DA 0x76DB +0x76DC 0x76DD 0x76DE 0x76DF 0x76E1 0x76E3 0x76E4 0x76E5 0x76E6 0x76E7 0x76E8 0x76E9 0x76EA 0x76EC 0x76ED 0x76EE +0x76EF 0x76F0 0x76F1 0x76F2 0x76F3 0x76F4 0x76F5 0x76F7 0x76F8 0x76F9 0x76FA 0x76FB 0x76FC 0x76FE 0x7701 0x7704 +0x7707 0x7708 0x7709 0x770A 0x770B 0x770C 0x770D 0x7712 0x7715 0x7719 0x771A 0x771B 0x771C 0x771E 0x771F 0x7720 +0x7722 0x7724 0x7725 0x7726 0x7728 0x7729 0x772C 0x772D 0x772F 0x7735 0x7736 0x7737 0x7738 0x773A 0x773C 0x773D +0x773E 0x7740 0x7741 0x7743 0x7744 0x7746 0x7747 0x774D 0x774E 0x774F 0x7750 0x7751 0x7752 0x775A 0x775B 0x775C +0x775E 0x7761 0x7762 0x7763 0x7765 0x7766 0x7768 0x7769 0x776A 0x776B 0x776C 0x7779 0x777A 0x777D 0x777E 0x777F +0x7780 0x7784 0x7785 0x7786 0x7787 0x778B 0x778C 0x778D 0x778E 0x778F 0x7791 0x7792 0x7793 0x7798 0x779A 0x779C +0x779E 0x779F 0x77A0 0x77A2 0x77A4 0x77A5 0x77A7 0x77A9 0x77AA 0x77AB 0x77AC 0x77AD 0x77B0 0x77B3 0x77B5 0x77B6 +0x77B7 0x77B9 0x77BB 0x77BC 0x77BD 0x77BF 0x77C7 0x77CB 0x77CD 0x77CE 0x77D3 0x77D7 0x77DA 0x77DB 0x77DC 0x77DE +0x77E2 0x77E3 0x77E5 0x77E7 0x77E9 0x77EB 0x77EC 0x77ED 0x77EE 0x77EF 0x77F0 0x77F3 0x77F4 0x77F6 0x77F7 0x77F8 +0x77F9 0x77FA 0x77FB 0x77FC 0x77FD 0x77FE 0x77FF 0x7800 0x7801 0x7802 0x7803 0x7804 0x7805 0x7806 0x7807 0x7808 +0x7809 0x780C 0x780D 0x780E 0x780F 0x7810 0x7811 0x7812 0x7813 0x7814 0x7815 0x7816 0x7817 0x7818 0x781A 0x781C +0x781D 0x781F 0x7820 0x7821 0x7822 0x7823 0x7825 0x7826 0x7827 0x7828 0x7829 0x782A 0x782B 0x782C 0x782D 0x782E +0x782F 0x7830 0x7831 0x7832 0x7833 0x7834 0x7835 0x7837 0x7838 0x7839 0x783A 0x783B 0x783C 0x783E 0x783F 0x7840 +0x7841 0x7843 0x7845 0x7847 0x7848 0x7849 0x784A 0x784B 0x784C 0x784D 0x784E 0x784F 0x7850 0x7852 0x7853 0x7854 +0x7855 0x7856 0x7857 0x7859 0x785A 0x785C 0x785D 0x785E 0x7860 0x7862 0x7864 0x7865 0x7866 0x7868 0x7869 0x786A +0x786B 0x786C 0x786D 0x786E 0x786F 0x7870 0x7871 0x7872 0x7874 0x7875 0x7877 0x7879 0x787B 0x787C 0x787E 0x787F +0x7880 0x7881 0x7883 0x7884 0x7885 0x7886 0x7887 0x7888 0x7889 0x788C 0x788D 0x788E 0x788F 0x7891 0x7893 0x7894 +0x7895 0x7896 0x7897 0x7898 0x789A 0x789B 0x789C 0x789F 0x78A1 0x78A3 0x78A5 0x78A7 0x78A8 0x78A9 0x78AA 0x78AD +0x78AF 0x78B0 0x78B1 0x78B2 0x78B3 0x78B4 0x78B5 0x78B6 0x78B8 0x78B9 0x78BA 0x78BB 0x78BC 0x78BE 0x78C1 0x78C5 +0x78C6 0x78C8 0x78C9 0x78CA 0x78CB 0x78CE 0x78CF 0x78D0 0x78D1 0x78D4 0x78D5 0x78D8 0x78D9 0x78DA 0x78DC 0x78E0 +0x78E1 0x78E2 0x78E3 0x78E7 0x78E8 0x78EC 0x78EF 0x78F2 0x78F4 0x78F5 0x78F7 0x78F9 0x78FA 0x78FB 0x78FD 0x78FE +0x7901 0x7903 0x7904 0x7905 0x7906 0x7907 0x790C 0x790E 0x7910 0x7911 0x7912 0x7913 0x7916 0x7919 0x791E 0x7921 +0x7924 0x7926 0x792A 0x792B 0x792C 0x7931 0x7933 0x7934 0x7935 0x793A 0x793B 0x793C 0x793D 0x793E 0x7940 0x7941 +0x7942 0x7943 0x7945 0x7946 0x7947 0x7948 0x7949 0x794A 0x794B 0x794E 0x794F 0x7950 0x7953 0x7955 0x7956 0x7957 +0x795A 0x795B 0x795C 0x795D 0x795E 0x795F 0x7960 0x7962 0x7965 0x7967 0x7968 0x7969 0x796B 0x796D 0x796F 0x7972 +0x7977 0x7978 0x797A 0x797C 0x797E 0x797F 0x7980 0x7981 0x7984 0x7985 0x798A 0x798B 0x798D 0x798E 0x798F 0x7991 +0x7992 0x7994 0x7995 0x7998 0x799A 0x799B 0x799D 0x799F 0x79A0 0x79A1 0x79A4 0x79A5 0x79A6 0x79A7 0x79A9 0x79AA +0x79AE 0x79B0 0x79B1 0x79B3 0x79B8 0x79B9 0x79BA 0x79BB 0x79BD 0x79BE 0x79BF 0x79C0 0x79C1 0x79C2 0x79C3 0x79C6 +0x79C8 0x79C9 0x79CA 0x79CB 0x79CD 0x79CF 0x79D1 0x79D2 0x79D5 0x79D8 0x79DD 0x79DE 0x79DF 0x79E1 0x79E3 0x79E4 +0x79E6 0x79E7 0x79E9 0x79EB 0x79EC 0x79ED 0x79EF 0x79F0 0x79F8 0x79FB 0x79FD 0x79FE 0x7A00 0x7A02 0x7A03 0x7A04 +0x7A05 0x7A06 0x7A08 0x7A09 0x7A0B 0x7A0C 0x7A0D 0x7A0E 0x7A11 0x7A14 0x7A16 0x7A17 0x7A18 0x7A19 0x7A1A 0x7A1C +0x7A1E 0x7A1F 0x7A20 0x7A23 0x7A26 0x7A2E 0x7A31 0x7A32 0x7A33 0x7A36 0x7A37 0x7A39 0x7A3B 0x7A3C 0x7A3D 0x7A3E +0x7A3F 0x7A40 0x7A42 0x7A43 0x7A44 0x7A46 0x7A47 0x7A49 0x7A4B 0x7A4C 0x7A4D 0x7A4E 0x7A4F 0x7A50 0x7A51 0x7A57 +0x7A59 0x7A5C 0x7A5E 0x7A5F 0x7A60 0x7A61 0x7A62 0x7A63 0x7A66 0x7A68 0x7A69 0x7A6B 0x7A6D 0x7A70 0x7A74 0x7A75 +0x7A76 0x7A77 0x7A78 0x7A79 0x7A7A 0x7A7D 0x7A7F 0x7A80 0x7A81 0x7A83 0x7A84 0x7A85 0x7A86 0x7A88 0x7A8A 0x7A8D +0x7A8E 0x7A91 0x7A92 0x7A93 0x7A95 0x7A96 0x7A97 0x7A98 0x7A9C 0x7A9D 0x7A9F 0x7AA0 0x7AA3 0x7AA5 0x7AA6 0x7AA8 +0x7AA9 0x7AAA 0x7AAC 0x7AAD 0x7AAE 0x7AAF 0x7AB0 0x7AB3 0x7AB5 0x7AB6 0x7AB8 0x7ABA 0x7ABE 0x7ABF 0x7AC3 0x7AC4 +0x7AC5 0x7AC7 0x7AC8 0x7ACA 0x7ACB 0x7ACD 0x7ACF 0x7AD1 0x7AD2 0x7AD3 0x7AD5 0x7AD6 0x7AD7 0x7AD8 0x7AD9 0x7ADA +0x7ADC 0x7ADD 0x7ADE 0x7ADF 0x7AE0 0x7AE1 0x7AE2 0x7AE3 0x7AE5 0x7AE6 0x7AEA 0x7AEB 0x7AED 0x7AEF 0x7AF0 0x7AF6 +0x7AF7 0x7AF8 0x7AF9 0x7AFA 0x7AFD 0x7AFF 0x7B02 0x7B03 0x7B04 0x7B06 0x7B08 0x7B0A 0x7B0B 0x7B0F 0x7B11 0x7B14 +0x7B15 0x7B18 0x7B19 0x7B1B 0x7B1E 0x7B20 0x7B24 0x7B25 0x7B26 0x7B28 0x7B2A 0x7B2B 0x7B2C 0x7B2D 0x7B2E 0x7B2F +0x7B31 0x7B33 0x7B35 0x7B36 0x7B38 0x7B39 0x7B3A 0x7B3C 0x7B3E 0x7B40 0x7B45 0x7B46 0x7B47 0x7B48 0x7B49 0x7B4A +0x7B4B 0x7B4C 0x7B4D 0x7B4E 0x7B4F 0x7B50 0x7B51 0x7B52 0x7B54 0x7B56 0x7B58 0x7B5A 0x7B5B 0x7B5C 0x7B5D 0x7B60 +0x7B62 0x7B64 0x7B65 0x7B66 0x7B67 0x7B69 0x7B6C 0x7B6E 0x7B6F 0x7B70 0x7B71 0x7B72 0x7B74 0x7B75 0x7B76 0x7B77 +0x7B79 0x7B7A 0x7B7B 0x7B7C 0x7B7D 0x7B7E 0x7B7F 0x7B80 0x7B84 0x7B85 0x7B86 0x7B87 0x7B8B 0x7B8D 0x7B8E 0x7B8F +0x7B90 0x7B92 0x7B93 0x7B94 0x7B95 0x7B96 0x7B97 0x7B98 0x7B99 0x7B9A 0x7B9C 0x7B9D 0x7B9F 0x7BA0 0x7BA1 0x7BA2 +0x7BA3 0x7BA6 0x7BA7 0x7BA8 0x7BA9 0x7BAA 0x7BAB 0x7BAC 0x7BAD 0x7BB1 0x7BB4 0x7BB8 0x7BC0 0x7BC1 0x7BC4 0x7BC6 +0x7BC7 0x7BC9 0x7BCB 0x7BCC 0x7BCF 0x7BD1 0x7BD2 0x7BD3 0x7BD4 0x7BD9 0x7BDA 0x7BDB 0x7BDD 0x7BE0 0x7BE1 0x7BE2 +0x7BE4 0x7BE5 0x7BE6 0x7BE9 0x7BEA 0x7BED 0x7BEE 0x7BEF 0x7BF0 0x7BF1 0x7BF2 0x7BF3 0x7BF6 0x7BF7 0x7BFC 0x7BFE +0x7C00 0x7C03 0x7C07 0x7C09 0x7C0B 0x7C0C 0x7C0D 0x7C0F 0x7C11 0x7C12 0x7C13 0x7C14 0x7C15 0x7C16 0x7C17 0x7C1D +0x7C1E 0x7C1F 0x7C20 0x7C21 0x7C23 0x7C26 0x7C27 0x7C29 0x7C2A 0x7C2B 0x7C30 0x7C37 0x7C38 0x7C39 0x7C3D 0x7C3E +0x7C3F 0x7C40 0x7C41 0x7C43 0x7C4C 0x7C4D 0x7C4F 0x7C50 0x7C53 0x7C54 0x7C56 0x7C57 0x7C58 0x7C59 0x7C5B 0x7C5C +0x7C5D 0x7C5F 0x7C60 0x7C63 0x7C64 0x7C65 0x7C69 0x7C6A 0x7C6C 0x7C6E 0x7C72 0x7C73 0x7C74 0x7C75 0x7C78 0x7C79 +0x7C7B 0x7C7C 0x7C7D 0x7C7E 0x7C81 0x7C82 0x7C83 0x7C84 0x7C89 0x7C8B 0x7C8D 0x7C90 0x7C91 0x7C92 0x7C95 0x7C97 +0x7C98 0x7C9B 0x7C9C 0x7C9D 0x7C9E 0x7C9F 0x7CA1 0x7CA2 0x7CA4 0x7CA5 0x7CA6 0x7CA7 0x7CA8 0x7CAA 0x7CAB 0x7CAC +0x7CAD 0x7CAE 0x7CB1 0x7CB2 0x7CB3 0x7CB5 0x7CB9 0x7CBA 0x7CBC 0x7CBD 0x7CBE 0x7CBF 0x7CC0 0x7CC1 0x7CC2 0x7CC4 +0x7CC5 0x7CC7 0x7CC8 0x7CC9 0x7CCA 0x7CCC 0x7CCD 0x7CCE 0x7CD2 0x7CD5 0x7CD6 0x7CD7 0x7CD8 0x7CD9 0x7CDC 0x7CDD +0x7CDE 0x7CDF 0x7CE0 0x7CE2 0x7CE7 0x7CE8 0x7CEC 0x7CED 0x7CEF 0x7CF0 0x7CF2 0x7CF4 0x7CF5 0x7CF6 0x7CF8 0x7CF9 +0x7CFA 0x7CFB 0x7CFE 0x7D00 0x7D02 0x7D03 0x7D04 0x7D05 0x7D06 0x7D07 0x7D08 0x7D09 0x7D0A 0x7D0B 0x7D0D 0x7D10 +0x7D11 0x7D13 0x7D14 0x7D15 0x7D16 0x7D17 0x7D18 0x7D19 0x7D1A 0x7D1B 0x7D1C 0x7D1D 0x7D1E 0x7D20 0x7D21 0x7D22 +0x7D27 0x7D2B 0x7D2C 0x7D2E 0x7D2F 0x7D30 0x7D31 0x7D32 0x7D33 0x7D35 0x7D39 0x7D3A 0x7D3C 0x7D3F 0x7D40 0x7D42 +0x7D43 0x7D44 0x7D45 0x7D46 0x7D4B 0x7D4C 0x7D4E 0x7D4F 0x7D50 0x7D53 0x7D55 0x7D56 0x7D5A 0x7D5B 0x7D5C 0x7D5D +0x7D5E 0x7D61 0x7D62 0x7D63 0x7D66 0x7D68 0x7D6A 0x7D6E 0x7D70 0x7D71 0x7D72 0x7D73 0x7D75 0x7D76 0x7D77 0x7D79 +0x7D7A 0x7D7D 0x7D7F 0x7D81 0x7D83 0x7D84 0x7D86 0x7D88 0x7D89 0x7D8C 0x7D8E 0x7D8F 0x7D91 0x7D93 0x7D96 0x7D99 +0x7D9A 0x7D9B 0x7D9C 0x7D9D 0x7D9E 0x7D9F 0x7DA0 0x7DA1 0x7DA2 0x7DA3 0x7DA6 0x7DA7 0x7DAA 0x7DAB 0x7DAC 0x7DAD +0x7DAE 0x7DAF 0x7DB0 0x7DB1 0x7DB2 0x7DB3 0x7DB4 0x7DB5 0x7DB7 0x7DB8 0x7DB9 0x7DBA 0x7DBB 0x7DBD 0x7DBE 0x7DBF +0x7DC1 0x7DC4 0x7DC7 0x7DC8 0x7DCA 0x7DCB 0x7DCC 0x7DCF 0x7DD1 0x7DD2 0x7DD3 0x7DD4 0x7DD5 0x7DD6 0x7DD7 0x7DD8 +0x7DD9 0x7DDA 0x7DDC 0x7DDD 0x7DDE 0x7DE0 0x7DE1 0x7DE3 0x7DE4 0x7DE6 0x7DE8 0x7DE9 0x7DEA 0x7DEC 0x7DEF 0x7DF1 +0x7DF2 0x7DF4 0x7DF6 0x7DF9 0x7DFB 0x7DFC 0x7E01 0x7E04 0x7E05 0x7E08 0x7E09 0x7E0A 0x7E0B 0x7E10 0x7E11 0x7E12 +0x7E15 0x7E17 0x7E1B 0x7E1D 0x7E1E 0x7E1F 0x7E20 0x7E21 0x7E22 0x7E23 0x7E26 0x7E27 0x7E29 0x7E2B 0x7E2D 0x7E2E +0x7E2F 0x7E31 0x7E32 0x7E33 0x7E34 0x7E35 0x7E36 0x7E37 0x7E39 0x7E3A 0x7E3B 0x7E3D 0x7E3E 0x7E3F 0x7E41 0x7E43 +0x7E44 0x7E45 0x7E46 0x7E47 0x7E48 0x7E4A 0x7E4B 0x7E4D 0x7E4E 0x7E51 0x7E52 0x7E54 0x7E55 0x7E56 0x7E59 0x7E5A +0x7E5D 0x7E5E 0x7E61 0x7E62 0x7E66 0x7E67 0x7E69 0x7E6A 0x7E6B 0x7E6D 0x7E6E 0x7E6F 0x7E70 0x7E73 0x7E76 0x7E79 +0x7E7B 0x7E7C 0x7E7D 0x7E7E 0x7E7F 0x7E81 0x7E82 0x7E83 0x7E86 0x7E87 0x7E88 0x7E89 0x7E8A 0x7E8C 0x7E8D 0x7E8E +0x7E8F 0x7E90 0x7E92 0x7E93 0x7E94 0x7E95 0x7E96 0x7E98 0x7E9A 0x7E9B 0x7E9C 0x7E9F 0x7EA0 0x7EA1 0x7EA2 0x7EA3 +0x7EA4 0x7EA5 0x7EA6 0x7EA7 0x7EA8 0x7EA9 0x7EAA 0x7EAB 0x7EAC 0x7EAD 0x7EAE 0x7EAF 0x7EB0 0x7EB1 0x7EB2 0x7EB3 +0x7EB4 0x7EB5 0x7EB6 0x7EB7 0x7EB8 0x7EB9 0x7EBA 0x7EBB 0x7EBC 0x7EBD 0x7EBE 0x7EBF 0x7EC0 0x7EC1 0x7EC2 0x7EC3 +0x7EC4 0x7EC5 0x7EC6 0x7EC7 0x7EC8 0x7EC9 0x7ECA 0x7ECB 0x7ECC 0x7ECD 0x7ECE 0x7ECF 0x7ED0 0x7ED1 0x7ED2 0x7ED3 +0x7ED4 0x7ED5 0x7ED6 0x7ED7 0x7ED8 0x7ED9 0x7EDA 0x7EDB 0x7EDC 0x7EDD 0x7EDE 0x7EDF 0x7EE0 0x7EE1 0x7EE2 0x7EE3 +0x7EE4 0x7EE5 0x7EE6 0x7EE7 0x7EE8 0x7EE9 0x7EEA 0x7EEB 0x7EEC 0x7EED 0x7EEE 0x7EEF 0x7EF0 0x7EF1 0x7EF2 0x7EF3 +0x7EF4 0x7EF5 0x7EF6 0x7EF7 0x7EF8 0x7EF9 0x7EFA 0x7EFB 0x7EFC 0x7EFD 0x7EFE 0x7EFF 0x7F00 0x7F01 0x7F02 0x7F03 +0x7F04 0x7F05 0x7F06 0x7F07 0x7F08 0x7F09 0x7F0A 0x7F0B 0x7F0C 0x7F0D 0x7F0E 0x7F0F 0x7F10 0x7F11 0x7F12 0x7F13 +0x7F14 0x7F15 0x7F16 0x7F17 0x7F18 0x7F19 0x7F1A 0x7F1B 0x7F1C 0x7F1D 0x7F1E 0x7F1F 0x7F20 0x7F21 0x7F22 0x7F23 +0x7F24 0x7F25 0x7F26 0x7F27 0x7F28 0x7F29 0x7F2A 0x7F2B 0x7F2C 0x7F2D 0x7F2E 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 +0x7F34 0x7F35 0x7F36 0x7F38 0x7F39 0x7F3A 0x7F3D 0x7F42 0x7F43 0x7F44 0x7F45 0x7F48 0x7F49 0x7F4C 0x7F4D 0x7F4E +0x7F4F 0x7F50 0x7F51 0x7F52 0x7F53 0x7F54 0x7F55 0x7F57 0x7F58 0x7F5A 0x7F5B 0x7F5C 0x7F5D 0x7F5E 0x7F5F 0x7F60 +0x7F61 0x7F62 0x7F63 0x7F65 0x7F66 0x7F67 0x7F68 0x7F69 0x7F6A 0x7F6B 0x7F6C 0x7F6D 0x7F6E 0x7F70 0x7F71 0x7F72 +0x7F73 0x7F74 0x7F75 0x7F76 0x7F77 0x7F78 0x7F79 0x7F7D 0x7F7E 0x7F81 0x7F82 0x7F83 0x7F85 0x7F86 0x7F87 0x7F88 +0x7F8A 0x7F8B 0x7F8C 0x7F8E 0x7F91 0x7F93 0x7F94 0x7F95 0x7F96 0x7F97 0x7F9A 0x7F9D 0x7F9E 0x7F9F 0x7FA1 0x7FA3 +0x7FA4 0x7FA5 0x7FA7 0x7FA8 0x7FA9 0x7FAE 0x7FAF 0x7FB0 0x7FB1 0x7FB2 0x7FB4 0x7FB6 0x7FB8 0x7FB9 0x7FBC 0x7FBD +0x7FBF 0x7FC0 0x7FC1 0x7FC2 0x7FC3 0x7FC5 0x7FC6 0x7FC8 0x7FCA 0x7FCB 0x7FCC 0x7FCE 0x7FD2 0x7FD4 0x7FD5 0x7FD8 +0x7FD9 0x7FDA 0x7FDB 0x7FDF 0x7FE0 0x7FE1 0x7FE5 0x7FE6 0x7FE7 0x7FE9 0x7FEB 0x7FEC 0x7FEE 0x7FEF 0x7FF0 0x7FF1 +0x7FF3 0x7FF7 0x7FF9 0x7FFA 0x7FFB 0x7FFC 0x7FFD 0x7FFE 0x8000 0x8001 0x8002 0x8003 0x8004 0x8005 0x8006 0x8007 +0x8008 0x8009 0x800B 0x800C 0x800D 0x800E 0x800F 0x8010 0x8011 0x8012 0x8014 0x8015 0x8016 0x8017 0x8018 0x8019 +0x801C 0x8020 0x8021 0x8022 0x8024 0x8025 0x8026 0x8027 0x8028 0x8029 0x802A 0x802C 0x802D 0x802E 0x8030 0x8031 +0x8032 0x8033 0x8035 0x8036 0x8037 0x8038 0x803B 0x803D 0x803F 0x8042 0x8043 0x8046 0x804A 0x804B 0x804C 0x804D +0x804F 0x8050 0x8051 0x8052 0x8054 0x8056 0x8058 0x805A 0x805E 0x805F 0x8061 0x8062 0x8064 0x8068 0x8069 0x806A +0x806F 0x8070 0x8071 0x8072 0x8073 0x8074 0x8075 0x8076 0x8077 0x8079 0x807D 0x807E 0x807F 0x8080 0x8083 0x8084 +0x8085 0x8086 0x8087 0x8089 0x808B 0x808C 0x808F 0x8090 0x8093 0x8096 0x8098 0x8099 0x809A 0x809B 0x809C 0x809D +0x809F 0x80A0 0x80A1 0x80A2 0x80A4 0x80A5 0x80A9 0x80AA 0x80AB 0x80AC 0x80AD 0x80AE 0x80AF 0x80B1 0x80B2 0x80B4 +0x80B7 0x80B8 0x80BA 0x80BC 0x80BD 0x80BE 0x80BF 0x80C0 0x80C1 0x80C2 0x80C3 0x80C4 0x80C6 0x80C8 0x80CC 0x80CD +0x80CE 0x80D4 0x80D6 0x80D7 0x80D9 0x80DA 0x80DB 0x80DC 0x80DD 0x80DE 0x80E0 0x80E1 0x80E3 0x80E4 0x80E5 0x80E7 +0x80E8 0x80E9 0x80EA 0x80EB 0x80EC 0x80ED 0x80EF 0x80F0 0x80F1 0x80F2 0x80F3 0x80F4 0x80F6 0x80F8 0x80FA 0x80FC +0x80FD 0x80FE 0x80FF 0x8102 0x8105 0x8106 0x8107 0x8108 0x8109 0x810A 0x810D 0x810E 0x810F 0x8110 0x8111 0x8112 +0x8113 0x8114 0x8116 0x8117 0x8118 0x811A 0x811B 0x811D 0x811E 0x811F 0x8122 0x8123 0x8124 0x8126 0x8127 0x8129 +0x812B 0x812C 0x812F 0x8130 0x8131 0x8132 0x8133 0x8136 0x8137 0x8138 0x8139 0x813E 0x813F 0x8146 0x8148 0x814A +0x814B 0x814C 0x814E 0x8150 0x8151 0x8152 0x8153 0x8154 0x8155 0x8156 0x8158 0x8159 0x815A 0x815F 0x8160 0x8161 +0x8165 0x8166 0x8167 0x8168 0x8169 0x816B 0x816D 0x816E 0x816F 0x8170 0x8171 0x8173 0x8174 0x8178 0x8179 0x817A +0x817B 0x817C 0x817D 0x817E 0x817F 0x8180 0x8182 0x8183 0x8188 0x818A 0x818D 0x818E 0x818F 0x8191 0x8193 0x8195 +0x8196 0x8198 0x8199 0x819A 0x819B 0x819C 0x819D 0x819E 0x81A0 0x81A2 0x81A3 0x81A4 0x81A5 0x81A6 0x81A8 0x81A9 +0x81AA 0x81B0 0x81B3 0x81B5 0x81B6 0x81B8 0x81BA 0x81BB 0x81BD 0x81BE 0x81BF 0x81C0 0x81C1 0x81C2 0x81C3 0x81C6 +0x81C8 0x81C9 0x81CA 0x81CC 0x81CD 0x81CF 0x81D1 0x81D3 0x81D8 0x81D9 0x81DA 0x81DC 0x81DF 0x81E0 0x81E2 0x81E3 +0x81E5 0x81E7 0x81E8 0x81EA 0x81EC 0x81ED 0x81F3 0x81F4 0x81FA 0x81FB 0x81FC 0x81FE 0x81FF 0x8200 0x8201 0x8202 +0x8204 0x8205 0x8206 0x8207 0x8208 0x8209 0x820A 0x820B 0x820C 0x820D 0x820E 0x8210 0x8212 0x8214 0x8216 0x8217 +0x8218 0x821B 0x821C 0x821E 0x821F 0x8220 0x8221 0x8222 0x8223 0x8225 0x8226 0x8228 0x8229 0x822A 0x822B 0x822C +0x822D 0x822E 0x822F 0x8230 0x8231 0x8232 0x8233 0x8234 0x8235 0x8236 0x8237 0x8238 0x8239 0x823A 0x823B 0x823E +0x8240 0x8244 0x8245 0x8247 0x8249 0x824B 0x824E 0x824F 0x8258 0x8259 0x825A 0x825D 0x825F 0x8262 0x8264 0x8266 +0x8268 0x826A 0x826B 0x826E 0x826F 0x8270 0x8271 0x8272 0x8273 0x8274 0x8276 0x8277 0x8278 0x8279 0x827A 0x827D +0x827E 0x827F 0x8280 0x8282 0x8283 0x8284 0x8288 0x828A 0x828B 0x828D 0x828E 0x828F 0x8291 0x8292 0x8297 0x8298 +0x8299 0x829A 0x829C 0x829D 0x829F 0x82A0 0x82A1 0x82A3 0x82A4 0x82A5 0x82A6 0x82A7 0x82A8 0x82A9 0x82AA 0x82AB +0x82AC 0x82AD 0x82AE 0x82AF 0x82B0 0x82B1 0x82B3 0x82B4 0x82B5 0x82B6 0x82B7 0x82B8 0x82B9 0x82BB 0x82BC 0x82BD +0x82BE 0x82BF 0x82C1 0x82C4 0x82C5 0x82C7 0x82C8 0x82C9 0x82CA 0x82CB 0x82CC 0x82CD 0x82CE 0x82CF 0x82D1 0x82D2 +0x82D3 0x82D4 0x82D5 0x82D6 0x82D7 0x82D8 0x82D9 0x82DB 0x82DC 0x82DD 0x82DE 0x82DF 0x82E0 0x82E1 0x82E3 0x82E4 +0x82E5 0x82E6 0x82E7 0x82E8 0x82EB 0x82EF 0x82F1 0x82F3 0x82F4 0x82F6 0x82F7 0x82F9 0x82FA 0x82FB 0x82FD 0x82FE +0x8300 0x8301 0x8302 0x8303 0x8304 0x8305 0x8306 0x8307 0x8308 0x8309 0x830B 0x830C 0x830D 0x830E 0x830F 0x8311 +0x8313 0x8314 0x8315 0x8316 0x8317 0x8318 0x831A 0x831B 0x831C 0x831D 0x8322 0x8323 0x8327 0x8328 0x8329 0x832B +0x832C 0x832D 0x832F 0x8331 0x8332 0x8333 0x8334 0x8335 0x8336 0x8338 0x8339 0x833A 0x833C 0x833D 0x8340 0x8341 +0x8343 0x8344 0x8345 0x8346 0x8347 0x8349 0x834A 0x834E 0x834F 0x8350 0x8351 0x8352 0x8353 0x8354 0x8356 0x8358 +0x8359 0x835A 0x835B 0x835C 0x835D 0x835E 0x835F 0x8360 0x8361 0x8363 0x8364 0x8365 0x8366 0x8367 0x8368 0x8369 +0x836A 0x836B 0x836C 0x836D 0x836E 0x836F 0x8373 0x8375 0x8377 0x8378 0x837A 0x837B 0x837C 0x837D 0x8380 0x8382 +0x8385 0x8386 0x8387 0x8389 0x838A 0x838E 0x8392 0x8393 0x8395 0x8396 0x8398 0x8399 0x839A 0x839B 0x839C 0x839D +0x839E 0x839F 0x83A0 0x83A2 0x83A3 0x83A6 0x83A7 0x83A8 0x83A9 0x83AA 0x83AB 0x83AF 0x83B0 0x83B1 0x83B2 0x83B3 +0x83B4 0x83B5 0x83B6 0x83B7 0x83B8 0x83B9 0x83BA 0x83BC 0x83BD 0x83BF 0x83C0 0x83C1 0x83C2 0x83C5 0x83C7 0x83C8 +0x83C9 0x83CA 0x83CC 0x83CD 0x83CE 0x83CF 0x83D1 0x83D3 0x83D4 0x83D6 0x83D8 0x83DC 0x83DD 0x83DF 0x83E0 0x83E1 +0x83E5 0x83E9 0x83EA 0x83EB 0x83EF 0x83F0 0x83F1 0x83F2 0x83F4 0x83F5 0x83F7 0x83F8 0x83F9 0x83FB 0x83FC 0x83FD +0x83FE 0x83FF 0x8401 0x8403 0x8404 0x8406 0x8407 0x840A 0x840B 0x840C 0x840D 0x840E 0x840F 0x8411 0x8413 0x8418 +0x841A 0x841C 0x841D 0x8420 0x8422 0x8423 0x8424 0x8425 0x8426 0x8427 0x8428 0x8429 0x842A 0x842C 0x8431 0x8433 +0x8434 0x8435 0x8438 0x8439 0x843C 0x843D 0x8446 0x8447 0x8449 0x844E 0x8451 0x8452 0x8453 0x8456 0x8457 0x8459 +0x845A 0x845B 0x845C 0x8460 0x8461 0x8462 0x8463 0x8464 0x8466 0x8469 0x846B 0x846C 0x846D 0x846E 0x846F 0x8470 +0x8471 0x8473 0x8474 0x8475 0x8476 0x8477 0x8478 0x8479 0x847A 0x8482 0x8484 0x8487 0x8488 0x8489 0x848B 0x848C +0x848D 0x848E 0x8490 0x8493 0x8494 0x8497 0x8499 0x849C 0x849D 0x849E 0x849F 0x84A1 0x84A8 0x84AD 0x84AF 0x84B1 +0x84B2 0x84B4 0x84B8 0x84B9 0x84BA 0x84BB 0x84BC 0x84BD 0x84BE 0x84BF 0x84C0 0x84C1 0x84C2 0x84C4 0x84C6 0x84C7 +0x84C9 0x84CA 0x84CB 0x84CD 0x84CF 0x84D0 0x84D1 0x84D3 0x84D6 0x84D9 0x84DA 0x84DD 0x84DF 0x84E0 0x84E2 0x84E3 +0x84E5 0x84E6 0x84EA 0x84EC 0x84EE 0x84EF 0x84F0 0x84F3 0x84F4 0x84F7 0x84FC 0x84FD 0x84FF 0x8500 0x8503 0x8504 +0x8506 0x8508 0x850A 0x850C 0x8511 0x8513 0x8514 0x8515 0x8517 0x8518 0x851A 0x851E 0x851F 0x8521 0x8523 0x8525 +0x8526 0x852B 0x852C 0x852D 0x852F 0x8534 0x8535 0x8537 0x8538 0x8539 0x853A 0x853B 0x853C 0x853D 0x853F 0x8540 +0x8541 0x8543 0x8546 0x8548 0x8549 0x854A 0x854B 0x854E 0x8552 0x8553 0x8555 0x8556 0x8557 0x8558 0x8559 0x855A +0x855E 0x8562 0x8563 0x8564 0x8565 0x8568 0x8569 0x856A 0x856D 0x8570 0x8572 0x8574 0x8577 0x8579 0x857A 0x857B +0x857E 0x8580 0x8581 0x8584 0x8585 0x8586 0x8587 0x8588 0x858A 0x858C 0x858F 0x8590 0x8591 0x8594 0x8597 0x8598 +0x8599 0x859B 0x859C 0x859F 0x85A0 0x85A2 0x85A4 0x85A6 0x85A8 0x85A9 0x85AA 0x85AB 0x85AC 0x85AE 0x85AF 0x85B0 +0x85B3 0x85B4 0x85B6 0x85B7 0x85B8 0x85B9 0x85BA 0x85BE 0x85BF 0x85C1 0x85C2 0x85C9 0x85CD 0x85CE 0x85CF 0x85D0 +0x85D3 0x85D5 0x85DC 0x85DD 0x85DF 0x85E0 0x85E4 0x85E5 0x85E6 0x85E8 0x85E9 0x85EA 0x85ED 0x85F4 0x85F6 0x85F7 +0x85F9 0x85FA 0x85FB 0x85FE 0x85FF 0x8600 0x8602 0x8604 0x8605 0x8606 0x8607 0x860A 0x860B 0x8611 0x8613 0x8616 +0x8617 0x8618 0x861A 0x861E 0x8621 0x8622 0x8626 0x8627 0x8629 0x862D 0x862F 0x8630 0x8635 0x8638 0x863A 0x863C +0x863F 0x8649 0x864D 0x864E 0x864F 0x8650 0x8651 0x8652 0x8653 0x8654 0x8655 0x8656 0x8659 0x865A 0x865B 0x865C +0x865E 0x865F 0x8661 0x8662 0x8663 0x8664 0x8667 0x866B 0x866C 0x866D 0x866E 0x866F 0x8670 0x8671 0x8673 0x8674 +0x8677 0x8678 0x8679 0x867A 0x867B 0x867C 0x867D 0x867E 0x867F 0x8680 0x8681 0x8682 0x8683 0x8684 0x8685 0x8686 +0x8687 0x868A 0x868B 0x868C 0x868D 0x868E 0x8690 0x8691 0x8693 0x8694 0x8695 0x8696 0x8697 0x8698 0x8699 0x869A +0x869C 0x869D 0x869E 0x86A1 0x86A2 0x86A3 0x86A4 0x86A5 0x86A7 0x86A8 0x86A9 0x86AA 0x86AB 0x86AC 0x86AF 0x86B0 +0x86B1 0x86B2 0x86B3 0x86B4 0x86B5 0x86B6 0x86B7 0x86B8 0x86B9 0x86BA 0x86C0 0x86C1 0x86C2 0x86C3 0x86C4 0x86C5 +0x86C6 0x86C7 0x86C8 0x86C9 0x86CA 0x86CB 0x86CD 0x86CE 0x86CF 0x86D0 0x86D1 0x86D4 0x86D8 0x86D9 0x86DB 0x86DE +0x86DF 0x86E4 0x86E9 0x86EC 0x86ED 0x86EE 0x86EF 0x86F0 0x86F1 0x86F2 0x86F3 0x86F4 0x86F8 0x86F9 0x86FA 0x86FB +0x86FE 0x8700 0x8702 0x8703 0x8705 0x8706 0x8707 0x8708 0x8709 0x870A 0x870D 0x870E 0x8710 0x8711 0x8712 0x8713 +0x8715 0x8717 0x8718 0x871A 0x871C 0x871E 0x8721 0x8722 0x8723 0x8725 0x8729 0x872E 0x8730 0x8731 0x8734 0x8737 +0x873B 0x873D 0x873E 0x873F 0x8740 0x8742 0x8744 0x8747 0x8748 0x8749 0x874B 0x874C 0x874E 0x8753 0x8755 0x8757 +0x8758 0x8759 0x875C 0x875F 0x8760 0x8763 0x8764 0x8765 0x8766 0x8768 0x876A 0x876E 0x8770 0x8772 0x8774 0x8776 +0x8778 0x877B 0x877C 0x877D 0x877E 0x877F 0x8780 0x8782 0x8783 0x8784 0x8785 0x8786 0x8788 0x878B 0x878D 0x8793 +0x8797 0x879E 0x879F 0x87A0 0x87A2 0x87A3 0x87A8 0x87AB 0x87AC 0x87AD 0x87AE 0x87AF 0x87B1 0x87B3 0x87B5 0x87BA +0x87BB 0x87BD 0x87BF 0x87C0 0x87C4 0x87C6 0x87C7 0x87C8 0x87CA 0x87CB 0x87CE 0x87CF 0x87D0 0x87D1 0x87D2 0x87D3 +0x87DB 0x87E0 0x87E2 0x87E3 0x87E5 0x87E7 0x87EA 0x87EB 0x87EC 0x87EE 0x87EF 0x87F2 0x87F3 0x87F6 0x87F7 0x87F9 +0x87FB 0x87FE 0x87FF 0x8801 0x8803 0x8804 0x8805 0x8806 0x880A 0x880B 0x880D 0x880E 0x880F 0x8810 0x8811 0x8813 +0x8814 0x8815 0x8816 0x881B 0x881F 0x8821 0x8822 0x8823 0x8827 0x8828 0x882D 0x8831 0x8832 0x8835 0x8836 0x8839 +0x883B 0x883C 0x8840 0x8842 0x8843 0x8844 0x8845 0x8846 0x884A 0x884C 0x884D 0x884E 0x8852 0x8853 0x8854 0x8855 +0x8856 0x8857 0x8859 0x885A 0x885B 0x885D 0x885E 0x8860 0x8861 0x8862 0x8863 0x8864 0x8865 0x8868 0x8869 0x886B +0x886C 0x886E 0x8870 0x8872 0x8875 0x8877 0x8879 0x887D 0x887E 0x887F 0x8881 0x8882 0x8884 0x8885 0x8886 0x8888 +0x888B 0x888D 0x8892 0x8893 0x8896 0x8897 0x8899 0x889C 0x889E 0x88A2 0x88A4 0x88AA 0x88AB 0x88AD 0x88AE 0x88AF +0x88B0 0x88B1 0x88B4 0x88B5 0x88B7 0x88BA 0x88BC 0x88BF 0x88C0 0x88C1 0x88C2 0x88C3 0x88C4 0x88C5 0x88C6 0x88C7 +0x88C8 0x88C9 0x88CA 0x88CB 0x88CE 0x88CF 0x88D1 0x88D2 0x88D4 0x88D5 0x88D8 0x88D9 0x88DB 0x88DC 0x88DD 0x88DF +0x88E1 0x88E2 0x88E3 0x88E4 0x88E5 0x88E8 0x88EC 0x88EF 0x88F0 0x88F1 0x88F2 0x88F3 0x88F4 0x88F5 0x88F8 0x88F9 +0x88FB 0x88FC 0x88FD 0x88FE 0x8902 0x8904 0x8907 0x890A 0x890C 0x890E 0x8910 0x8912 0x8913 0x8914 0x8915 0x8918 +0x8919 0x891A 0x891B 0x891D 0x891E 0x891F 0x8921 0x8925 0x8926 0x892A 0x892B 0x892F 0x8930 0x8932 0x8933 0x8934 +0x8935 0x8936 0x8938 0x893B 0x893D 0x8940 0x8941 0x8943 0x8944 0x8947 0x8948 0x894C 0x894D 0x894F 0x8955 0x8956 +0x895A 0x895C 0x895D 0x895E 0x895F 0x8960 0x8964 0x8966 0x896A 0x896B 0x896C 0x896D 0x896F 0x8972 0x8974 0x8976 +0x8977 0x897B 0x897E 0x897F 0x8980 0x8981 0x8983 0x8985 0x8986 0x8987 0x8988 0x898A 0x898B 0x898E 0x898F 0x8993 +0x8996 0x8997 0x8998 0x8999 0x899A 0x899C 0x89A1 0x89A4 0x89A5 0x89A6 0x89A7 0x89A9 0x89AA 0x89AC 0x89AF 0x89B2 +0x89B3 0x89B7 0x89BA 0x89BC 0x89BD 0x89BF 0x89C0 0x89C1 0x89C2 0x89C3 0x89C4 0x89C5 0x89C6 0x89C7 0x89C8 0x89C9 +0x89CA 0x89CB 0x89CC 0x89CD 0x89CE 0x89CF 0x89D0 0x89D1 0x89D2 0x89D4 0x89D6 0x89DA 0x89DC 0x89DD 0x89DE 0x89DF +0x89E3 0x89E5 0x89E6 0x89E7 0x89EB 0x89ED 0x89EF 0x89F1 0x89F3 0x89F4 0x89F6 0x89F8 0x89FC 0x89FF 0x8A00 0x8A01 +0x8A02 0x8A03 0x8A04 0x8A07 0x8A08 0x8A0A 0x8A0C 0x8A0E 0x8A0F 0x8A10 0x8A11 0x8A12 0x8A13 0x8A15 0x8A16 0x8A17 +0x8A18 0x8A1A 0x8A1B 0x8A1D 0x8A1F 0x8A22 0x8A23 0x8A25 0x8A29 0x8A2A 0x8A2B 0x8A2D 0x8A31 0x8A33 0x8A34 0x8A36 +0x8A38 0x8A3A 0x8A3B 0x8A3C 0x8A3E 0x8A40 0x8A41 0x8A46 0x8A48 0x8A4E 0x8A50 0x8A51 0x8A52 0x8A54 0x8A55 0x8A56 +0x8A57 0x8A58 0x8A5B 0x8A5D 0x8A5E 0x8A5F 0x8A60 0x8A61 0x8A62 0x8A63 0x8A66 0x8A68 0x8A69 0x8A6A 0x8A6B 0x8A6C +0x8A6D 0x8A6E 0x8A70 0x8A71 0x8A72 0x8A73 0x8A75 0x8A77 0x8A79 0x8A7A 0x8A7B 0x8A7C 0x8A7F 0x8A81 0x8A82 0x8A84 +0x8A85 0x8A86 0x8A87 0x8A89 0x8A8A 0x8A8C 0x8A8D 0x8A91 0x8A92 0x8A93 0x8A95 0x8A98 0x8A9A 0x8A9E 0x8AA0 0x8AA1 +0x8AA3 0x8AA4 0x8AA5 0x8AA6 0x8AA7 0x8AA8 0x8AA9 0x8AAA 0x8AAC 0x8AAD 0x8AB0 0x8AB2 0x8AB6 0x8AB9 0x8ABC 0x8ABE +0x8ABF 0x8AC2 0x8AC4 0x8AC7 0x8AC9 0x8ACB 0x8ACC 0x8ACD 0x8ACF 0x8AD1 0x8AD2 0x8AD3 0x8AD4 0x8AD6 0x8AD7 0x8ADA +0x8ADB 0x8ADC 0x8ADD 0x8ADE 0x8ADF 0x8AE0 0x8AE1 0x8AE2 0x8AE4 0x8AE6 0x8AE7 0x8AEA 0x8AEB 0x8AED 0x8AEE 0x8AF1 +0x8AF2 0x8AF3 0x8AF4 0x8AF6 0x8AF7 0x8AF8 0x8AFA 0x8AFC 0x8AFE 0x8AFF 0x8B00 0x8B01 0x8B02 0x8B04 0x8B05 0x8B07 +0x8B0A 0x8B0B 0x8B0C 0x8B0E 0x8B0F 0x8B10 0x8B14 0x8B16 0x8B17 0x8B19 0x8B1A 0x8B1B 0x8B1D 0x8B1E 0x8B20 0x8B21 +0x8B22 0x8B26 0x8B28 0x8B2B 0x8B2C 0x8B2D 0x8B2E 0x8B33 0x8B37 0x8B39 0x8B3E 0x8B41 0x8B46 0x8B49 0x8B4A 0x8B4C +0x8B4E 0x8B4F 0x8B53 0x8B56 0x8B58 0x8B59 0x8B5A 0x8B5B 0x8B5C 0x8B5E 0x8B5F 0x8B60 0x8B63 0x8B66 0x8B69 0x8B6A +0x8B6B 0x8B6C 0x8B6D 0x8B6F 0x8B70 0x8B71 0x8B72 0x8B74 0x8B77 0x8B78 0x8B7D 0x8B7F 0x8B80 0x8B83 0x8B85 0x8B86 +0x8B8A 0x8B8B 0x8B8C 0x8B8E 0x8B90 0x8B92 0x8B93 0x8B94 0x8B95 0x8B96 0x8B99 0x8B9A 0x8B9C 0x8B9E 0x8B9F 0x8BA0 +0x8BA1 0x8BA2 0x8BA3 0x8BA4 0x8BA5 0x8BA6 0x8BA7 0x8BA8 0x8BA9 0x8BAA 0x8BAB 0x8BAC 0x8BAD 0x8BAE 0x8BAF 0x8BB0 +0x8BB1 0x8BB2 0x8BB3 0x8BB4 0x8BB5 0x8BB6 0x8BB7 0x8BB8 0x8BB9 0x8BBA 0x8BBB 0x8BBC 0x8BBD 0x8BBE 0x8BBF 0x8BC0 +0x8BC1 0x8BC2 0x8BC3 0x8BC4 0x8BC5 0x8BC6 0x8BC7 0x8BC8 0x8BC9 0x8BCA 0x8BCB 0x8BCC 0x8BCD 0x8BCE 0x8BCF 0x8BD0 +0x8BD1 0x8BD2 0x8BD3 0x8BD4 0x8BD5 0x8BD6 0x8BD7 0x8BD8 0x8BD9 0x8BDA 0x8BDB 0x8BDC 0x8BDD 0x8BDE 0x8BDF 0x8BE0 +0x8BE1 0x8BE2 0x8BE3 0x8BE4 0x8BE5 0x8BE6 0x8BE7 0x8BE8 0x8BE9 0x8BEA 0x8BEB 0x8BEC 0x8BED 0x8BEE 0x8BEF 0x8BF0 +0x8BF1 0x8BF2 0x8BF3 0x8BF4 0x8BF5 0x8BF6 0x8BF7 0x8BF8 0x8BF9 0x8BFA 0x8BFB 0x8BFC 0x8BFD 0x8BFE 0x8BFF 0x8C00 +0x8C01 0x8C02 0x8C03 0x8C04 0x8C05 0x8C06 0x8C07 0x8C08 0x8C09 0x8C0A 0x8C0B 0x8C0C 0x8C0D 0x8C0E 0x8C0F 0x8C10 +0x8C11 0x8C12 0x8C13 0x8C14 0x8C15 0x8C16 0x8C17 0x8C18 0x8C19 0x8C1A 0x8C1B 0x8C1C 0x8C1D 0x8C1E 0x8C1F 0x8C20 +0x8C21 0x8C22 0x8C23 0x8C24 0x8C25 0x8C26 0x8C27 0x8C28 0x8C29 0x8C2A 0x8C2B 0x8C2C 0x8C2D 0x8C2E 0x8C2F 0x8C30 +0x8C31 0x8C32 0x8C33 0x8C34 0x8C35 0x8C36 0x8C37 0x8C3A 0x8C3C 0x8C3F 0x8C41 0x8C46 0x8C47 0x8C48 0x8C49 0x8C4A +0x8C4C 0x8C4E 0x8C50 0x8C54 0x8C55 0x8C57 0x8C5A 0x8C61 0x8C62 0x8C68 0x8C6A 0x8C6B 0x8C6C 0x8C6D 0x8C6E 0x8C73 +0x8C76 0x8C78 0x8C79 0x8C7A 0x8C7C 0x8C82 0x8C85 0x8C86 0x8C89 0x8C8A 0x8C8C 0x8C8D 0x8C8E 0x8C90 0x8C92 0x8C93 +0x8C94 0x8C98 0x8C99 0x8C9D 0x8C9E 0x8C9F 0x8CA0 0x8CA1 0x8CA2 0x8CA7 0x8CA8 0x8CA9 0x8CAA 0x8CAB 0x8CAC 0x8CAD +0x8CAE 0x8CAF 0x8CB0 0x8CB2 0x8CB3 0x8CB4 0x8CB6 0x8CB7 0x8CB8 0x8CBA 0x8CBB 0x8CBC 0x8CBD 0x8CBF 0x8CC0 0x8CC1 +0x8CC2 0x8CC3 0x8CC4 0x8CC5 0x8CC7 0x8CC8 0x8CCA 0x8CCD 0x8CCE 0x8CCF 0x8CD1 0x8CD2 0x8CD3 0x8CD5 0x8CD9 0x8CDA +0x8CDB 0x8CDC 0x8CDE 0x8CE0 0x8CE1 0x8CE2 0x8CE3 0x8CE4 0x8CE6 0x8CE7 0x8CE8 0x8CEA 0x8CEB 0x8CEC 0x8CED 0x8CF0 +0x8CF1 0x8CF4 0x8CF5 0x8CF8 0x8CFA 0x8CFB 0x8CFC 0x8CFD 0x8CFE 0x8D04 0x8D05 0x8D07 0x8D08 0x8D0A 0x8D0B 0x8D0D +0x8D0F 0x8D10 0x8D13 0x8D14 0x8D16 0x8D17 0x8D1B 0x8D1C 0x8D1D 0x8D1E 0x8D1F 0x8D20 0x8D21 0x8D22 0x8D23 0x8D24 +0x8D25 0x8D26 0x8D27 0x8D28 0x8D29 0x8D2A 0x8D2B 0x8D2C 0x8D2D 0x8D2E 0x8D2F 0x8D30 0x8D31 0x8D32 0x8D33 0x8D34 +0x8D35 0x8D36 0x8D37 0x8D38 0x8D39 0x8D3A 0x8D3B 0x8D3C 0x8D3D 0x8D3E 0x8D3F 0x8D40 0x8D41 0x8D42 0x8D43 0x8D44 +0x8D45 0x8D46 0x8D47 0x8D48 0x8D49 0x8D4A 0x8D4B 0x8D4C 0x8D4D 0x8D4E 0x8D4F 0x8D50 0x8D51 0x8D52 0x8D53 0x8D54 +0x8D55 0x8D56 0x8D57 0x8D58 0x8D59 0x8D5A 0x8D5B 0x8D5C 0x8D5D 0x8D5E 0x8D5F 0x8D60 0x8D61 0x8D62 0x8D63 0x8D64 +0x8D66 0x8D67 0x8D69 0x8D6A 0x8D6B 0x8D6C 0x8D6D 0x8D70 0x8D71 0x8D73 0x8D74 0x8D75 0x8D76 0x8D77 0x8D81 0x8D84 +0x8D85 0x8D8A 0x8D8B 0x8D91 0x8D94 0x8D95 0x8D96 0x8D99 0x8D9F 0x8DA3 0x8DA8 0x8DAF 0x8DB1 0x8DB2 0x8DB3 0x8DB4 +0x8DB5 0x8DB8 0x8DBA 0x8DBC 0x8DBE 0x8DBF 0x8DC2 0x8DC3 0x8DC4 0x8DC5 0x8DC6 0x8DCB 0x8DCC 0x8DCE 0x8DCF 0x8DD0 +0x8DD1 0x8DD6 0x8DD7 0x8DDA 0x8DDB 0x8DDD 0x8DDE 0x8DDF 0x8DE1 0x8DE3 0x8DE4 0x8DE6 0x8DE8 0x8DE9 0x8DEA 0x8DEB +0x8DEC 0x8DEF 0x8DF0 0x8DF1 0x8DF3 0x8DF5 0x8DF6 0x8DF7 0x8DF8 0x8DF9 0x8DFA 0x8DFB 0x8DFC 0x8DFD 0x8DFF 0x8E04 +0x8E05 0x8E08 0x8E09 0x8E0A 0x8E0C 0x8E0E 0x8E0F 0x8E10 0x8E12 0x8E14 0x8E16 0x8E1C 0x8E1D 0x8E1E 0x8E1F 0x8E21 +0x8E22 0x8E23 0x8E26 0x8E27 0x8E29 0x8E2A 0x8E2B 0x8E2C 0x8E2D 0x8E2E 0x8E2F 0x8E30 0x8E31 0x8E34 0x8E35 0x8E36 +0x8E39 0x8E3A 0x8E3C 0x8E3D 0x8E40 0x8E41 0x8E42 0x8E44 0x8E45 0x8E47 0x8E48 0x8E49 0x8E4A 0x8E4B 0x8E4C 0x8E4D +0x8E4F 0x8E50 0x8E51 0x8E52 0x8E53 0x8E54 0x8E55 0x8E59 0x8E5A 0x8E5C 0x8E5F 0x8E60 0x8E61 0x8E62 0x8E63 0x8E64 +0x8E66 0x8E67 0x8E69 0x8E6C 0x8E6D 0x8E6F 0x8E70 0x8E72 0x8E74 0x8E76 0x8E7A 0x8E7B 0x8E7C 0x8E7D 0x8E7E 0x8E7F +0x8E80 0x8E81 0x8E82 0x8E84 0x8E85 0x8E87 0x8E89 0x8E8A 0x8E8B 0x8E8D 0x8E8F 0x8E90 0x8E91 0x8E92 0x8E93 0x8E94 +0x8E95 0x8E99 0x8E9A 0x8E9C 0x8E9D 0x8E9E 0x8EA1 0x8EA5 0x8EA6 0x8EAA 0x8EAB 0x8EAC 0x8EAD 0x8EAF 0x8EB0 0x8EB1 +0x8EB2 0x8EBA 0x8EBC 0x8EBE 0x8EC0 0x8EC1 0x8EC5 0x8EC6 0x8EC8 0x8ECA 0x8ECB 0x8ECC 0x8ECD 0x8ECE 0x8ECF 0x8ED1 +0x8ED2 0x8ED4 0x8EDA 0x8EDB 0x8EDD 0x8EDF 0x8EE2 0x8EE3 0x8EE4 0x8EE8 0x8EEB 0x8EF1 0x8EF2 0x8EF8 0x8EF9 0x8EFA +0x8EFB 0x8EFC 0x8EFD 0x8EFE 0x8EFF 0x8F00 0x8F03 0x8F04 0x8F05 0x8F07 0x8F08 0x8F09 0x8F0A 0x8F0B 0x8F0C 0x8F12 +0x8F13 0x8F14 0x8F15 0x8F17 0x8F19 0x8F1B 0x8F1C 0x8F1D 0x8F1E 0x8F1F 0x8F25 0x8F26 0x8F27 0x8F29 0x8F2A 0x8F2C +0x8F2D 0x8F2E 0x8F2F 0x8F33 0x8F36 0x8F38 0x8F39 0x8F3B 0x8F3C 0x8F3E 0x8F3F 0x8F40 0x8F42 0x8F44 0x8F45 0x8F46 +0x8F49 0x8F4C 0x8F4D 0x8F4E 0x8F54 0x8F57 0x8F58 0x8F5C 0x8F5D 0x8F5F 0x8F61 0x8F62 0x8F63 0x8F64 0x8F66 0x8F67 +0x8F68 0x8F69 0x8F6A 0x8F6B 0x8F6C 0x8F6D 0x8F6E 0x8F6F 0x8F70 0x8F71 0x8F72 0x8F73 0x8F74 0x8F75 0x8F76 0x8F77 +0x8F78 0x8F79 0x8F7A 0x8F7B 0x8F7C 0x8F7D 0x8F7E 0x8F7F 0x8F80 0x8F81 0x8F82 0x8F83 0x8F84 0x8F85 0x8F86 0x8F87 +0x8F88 0x8F89 0x8F8A 0x8F8B 0x8F8C 0x8F8D 0x8F8E 0x8F8F 0x8F90 0x8F91 0x8F92 0x8F93 0x8F94 0x8F95 0x8F96 0x8F97 +0x8F98 0x8F99 0x8F9A 0x8F9B 0x8F9C 0x8F9E 0x8F9F 0x8FA3 0x8FA6 0x8FA7 0x8FA8 0x8FA9 0x8FAB 0x8FAD 0x8FAE 0x8FAF +0x8FB0 0x8FB1 0x8FB2 0x8FB4 0x8FB5 0x8FB6 0x8FB7 0x8FB9 0x8FBA 0x8FBB 0x8FBC 0x8FBD 0x8FBE 0x8FBF 0x8FC0 0x8FC1 +0x8FC2 0x8FC4 0x8FC5 0x8FC6 0x8FC7 0x8FC8 0x8FC9 0x8FCB 0x8FCC 0x8FCD 0x8FCE 0x8FD0 0x8FD1 0x8FD2 0x8FD3 0x8FD4 +0x8FD5 0x8FD6 0x8FD7 0x8FD8 0x8FD9 0x8FDA 0x8FDB 0x8FDC 0x8FDD 0x8FDE 0x8FDF 0x8FE0 0x8FE1 0x8FE2 0x8FE3 0x8FE4 +0x8FE5 0x8FE6 0x8FE8 0x8FE9 0x8FEA 0x8FEB 0x8FED 0x8FEE 0x8FEF 0x8FF0 0x8FF2 0x8FF3 0x8FF4 0x8FF5 0x8FF6 0x8FF7 +0x8FF8 0x8FF9 0x8FFA 0x8FFB 0x8FFC 0x8FFD 0x8FFE 0x8FFF 0x9000 0x9001 0x9002 0x9003 0x9004 0x9005 0x9006 0x9008 +0x9009 0x900A 0x900B 0x900C 0x900D 0x900E 0x900F 0x9010 0x9011 0x9012 0x9013 0x9014 0x9015 0x9016 0x9017 0x9019 +0x901A 0x901B 0x901C 0x901D 0x901E 0x901F 0x9020 0x9021 0x9022 0x9023 0x9024 0x9026 0x9027 0x902D 0x902E 0x902F +0x9031 0x9032 0x9034 0x9035 0x9036 0x9038 0x9039 0x903B 0x903C 0x903D 0x903E 0x903F 0x9041 0x9042 0x9044 0x9045 +0x9046 0x9047 0x9049 0x904A 0x904B 0x904D 0x904E 0x904F 0x9050 0x9051 0x9052 0x9053 0x9054 0x9055 0x9056 0x9057 +0x9058 0x9059 0x905B 0x905C 0x905D 0x905E 0x9060 0x9061 0x9062 0x9063 0x9065 0x9067 0x9068 0x9069 0x906B 0x906D +0x906E 0x906F 0x9070 0x9072 0x9073 0x9074 0x9075 0x9076 0x9077 0x9078 0x9079 0x907A 0x907B 0x907C 0x907D 0x907E +0x907F 0x9080 0x9081 0x9082 0x9083 0x9084 0x9085 0x9086 0x9087 0x9088 0x9089 0x908A 0x908B 0x908D 0x908F 0x9090 +0x9091 0x9093 0x9094 0x9095 0x9097 0x9098 0x9099 0x909B 0x909D 0x909E 0x909F 0x90A0 0x90A1 0x90A2 0x90A3 0x90A5 +0x90A6 0x90A7 0x90A8 0x90AA 0x90AC 0x90AE 0x90AF 0x90B0 0x90B1 0x90B2 0x90B3 0x90B4 0x90B5 0x90B6 0x90B8 0x90B9 +0x90BA 0x90BB 0x90BD 0x90BE 0x90BF 0x90C1 0x90C3 0x90C4 0x90C5 0x90C7 0x90C8 0x90CA 0x90CE 0x90CF 0x90D0 0x90D1 +0x90D3 0x90D7 0x90DA 0x90DB 0x90DC 0x90DD 0x90DE 0x90DF 0x90E1 0x90E2 0x90E4 0x90E6 0x90E7 0x90E8 0x90EA 0x90EB +0x90EC 0x90ED 0x90EF 0x90F4 0x90F5 0x90F7 0x90F8 0x90FD 0x90FE 0x90FF 0x9100 0x9102 0x9103 0x9104 0x9105 0x9106 +0x9109 0x910C 0x9111 0x9112 0x9114 0x9115 0x9116 0x9117 0x9118 0x9119 0x911A 0x911C 0x911E 0x9120 0x9122 0x9123 +0x9127 0x9129 0x912B 0x912D 0x912E 0x912F 0x9130 0x9131 0x9132 0x9133 0x9134 0x9136 0x9139 0x913A 0x9142 0x9143 +0x9145 0x9146 0x9147 0x9148 0x9149 0x914A 0x914B 0x914C 0x914D 0x914E 0x914F 0x9150 0x9152 0x9154 0x9155 0x9156 +0x9157 0x9158 0x915A 0x915C 0x915D 0x915E 0x9161 0x9162 0x9163 0x9164 0x9165 0x9166 0x9169 0x916A 0x916C 0x916E +0x916F 0x9170 0x9171 0x9172 0x9173 0x9174 0x9175 0x9176 0x9177 0x9178 0x9179 0x917A 0x917D 0x917E 0x917F 0x9181 +0x9182 0x9183 0x9184 0x9185 0x9187 0x9189 0x918B 0x918C 0x918D 0x9190 0x9191 0x9192 0x9196 0x9197 0x919A 0x919B +0x919C 0x919E 0x91A1 0x91A2 0x91A3 0x91A4 0x91A8 0x91AA 0x91AB 0x91AC 0x91AD 0x91AE 0x91AF 0x91B1 0x91B2 0x91B4 +0x91B5 0x91B8 0x91BA 0x91BE 0x91C0 0x91C1 0x91C3 0x91C5 0x91C6 0x91C7 0x91C8 0x91C9 0x91CA 0x91CB 0x91CC 0x91CD +0x91CE 0x91CF 0x91D0 0x91D1 0x91D2 0x91D3 0x91D4 0x91D5 0x91D6 0x91D7 0x91D8 0x91D9 0x91DA 0x91DB 0x91DC 0x91DD +0x91DF 0x91E1 0x91E2 0x91E3 0x91E4 0x91E6 0x91E7 0x91E8 0x91E9 0x91EA 0x91EB 0x91EC 0x91ED 0x91EE 0x91F1 0x91F3 +0x91F4 0x91F5 0x91F6 0x91F7 0x91F8 0x91F9 0x91FA 0x91FC 0x91FD 0x91FE 0x91FF 0x9200 0x9201 0x9202 0x9203 0x9204 +0x9205 0x9206 0x9207 0x9208 0x9209 0x920A 0x920C 0x920D 0x920E 0x920F 0x9210 0x9211 0x9212 0x9214 0x9215 0x9216 +0x9217 0x9219 0x921A 0x921C 0x921E 0x9223 0x9224 0x9225 0x9226 0x9227 0x9229 0x922A 0x922C 0x922D 0x922E 0x9230 +0x9231 0x9232 0x9233 0x9234 0x9236 0x9237 0x9238 0x9239 0x923A 0x923D 0x923E 0x923F 0x9240 0x9244 0x9245 0x9246 +0x9248 0x9249 0x924A 0x924B 0x924C 0x924D 0x924E 0x924F 0x9250 0x9251 0x9252 0x9253 0x9254 0x9255 0x9256 0x9257 +0x925A 0x925B 0x925D 0x925E 0x9260 0x9261 0x9262 0x9263 0x9264 0x9265 0x9266 0x9267 0x9268 0x926C 0x926D 0x926E +0x926F 0x9270 0x9271 0x9272 0x9273 0x9274 0x9276 0x9277 0x9278 0x9279 0x927A 0x927B 0x927C 0x927D 0x927E 0x927F +0x9280 0x9282 0x9283 0x9285 0x9286 0x9287 0x9288 0x928A 0x928B 0x928C 0x928D 0x928E 0x9291 0x9293 0x9294 0x9295 +0x9296 0x9297 0x9298 0x9299 0x929A 0x929B 0x929C 0x929D 0x92A0 0x92A1 0x92A2 0x92A3 0x92A4 0x92A5 0x92A6 0x92A7 +0x92A8 0x92A9 0x92AA 0x92AB 0x92AC 0x92AD 0x92AE 0x92B1 0x92B2 0x92B3 0x92B6 0x92B7 0x92B9 0x92BB 0x92BC 0x92C1 +0x92C2 0x92C3 0x92C5 0x92C6 0x92C7 0x92C8 0x92C9 0x92CC 0x92CF 0x92D0 0x92D2 0x92D5 0x92D7 0x92D9 0x92DD 0x92DF +0x92E3 0x92E4 0x92E5 0x92E6 0x92E7 0x92E8 0x92E9 0x92EA 0x92EC 0x92ED 0x92EE 0x92EF 0x92F0 0x92F1 0x92F2 0x92F3 +0x92F6 0x92F8 0x92F9 0x92FA 0x92FC 0x9300 0x9301 0x9302 0x9304 0x9306 0x9307 0x9308 0x930F 0x9310 0x9312 0x9315 +0x9318 0x9319 0x931A 0x931B 0x931E 0x931F 0x9320 0x9321 0x9322 0x9323 0x9324 0x9326 0x9327 0x9328 0x9329 0x932A +0x932B 0x932C 0x932E 0x932F 0x9332 0x9333 0x9335 0x9336 0x9338 0x933A 0x933B 0x933C 0x933E 0x9340 0x9341 0x9343 +0x9344 0x9345 0x9346 0x9347 0x9348 0x9349 0x934A 0x934B 0x934D 0x9351 0x9352 0x9354 0x9355 0x9356 0x9358 0x9359 +0x935A 0x935B 0x935C 0x935E 0x9360 0x9364 0x9365 0x9369 0x936A 0x936C 0x936D 0x936E 0x9370 0x9375 0x9376 0x937A +0x937C 0x937E 0x9382 0x9384 0x9385 0x9387 0x938A 0x938C 0x938F 0x9393 0x9394 0x9396 0x9397 0x9398 0x939A 0x939B +0x939D 0x93A1 0x93A2 0x93A3 0x93A4 0x93A6 0x93A7 0x93A9 0x93AA 0x93AC 0x93AD 0x93AE 0x93AF 0x93B0 0x93B2 0x93B3 +0x93B5 0x93B6 0x93B7 0x93B8 0x93B9 0x93BF 0x93C2 0x93C3 0x93C4 0x93C7 0x93C8 0x93CA 0x93CB 0x93CC 0x93CD 0x93CF +0x93D0 0x93D1 0x93D6 0x93D7 0x93D8 0x93DC 0x93DD 0x93DE 0x93DF 0x93E1 0x93E2 0x93E4 0x93E5 0x93E6 0x93E8 0x93F0 +0x93F1 0x93F5 0x93F6 0x93F7 0x93F9 0x93FA 0x93FB 0x93FD 0x9403 0x9404 0x9407 0x940B 0x940D 0x940E 0x940F 0x9410 +0x9412 0x9413 0x9414 0x9418 0x9419 0x941A 0x941D 0x9420 0x9421 0x9424 0x9425 0x9426 0x9427 0x9428 0x9429 0x942B +0x942E 0x942F 0x9431 0x9432 0x9433 0x9435 0x9436 0x9438 0x943A 0x943D 0x943E 0x943F 0x9440 0x9441 0x9442 0x9444 +0x944A 0x944C 0x9451 0x9452 0x9453 0x9454 0x9455 0x945A 0x945B 0x945E 0x9460 0x9462 0x9463 0x9464 0x9465 0x946A +0x946B 0x946D 0x9470 0x9471 0x9472 0x9473 0x9474 0x9475 0x9476 0x9477 0x9478 0x9479 0x947C 0x947D 0x947E 0x947F +0x9480 0x9481 0x9482 0x9483 0x9485 0x9486 0x9487 0x9488 0x9489 0x948A 0x948B 0x948C 0x948D 0x948E 0x948F 0x9490 +0x9491 0x9492 0x9493 0x9494 0x9495 0x9496 0x9497 0x9498 0x9499 0x949A 0x949B 0x949C 0x949D 0x949E 0x949F 0x94A0 +0x94A1 0x94A2 0x94A3 0x94A4 0x94A5 0x94A6 0x94A7 0x94A8 0x94A9 0x94AA 0x94AB 0x94AC 0x94AD 0x94AE 0x94AF 0x94B0 +0x94B1 0x94B2 0x94B3 0x94B4 0x94B5 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BB 0x94BC 0x94BD 0x94BE 0x94BF 0x94C0 +0x94C1 0x94C2 0x94C3 0x94C4 0x94C5 0x94C6 0x94C7 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC 0x94CD 0x94CE 0x94CF 0x94D0 +0x94D1 0x94D2 0x94D3 0x94D4 0x94D5 0x94D6 0x94D7 0x94D8 0x94D9 0x94DA 0x94DB 0x94DC 0x94DD 0x94DE 0x94DF 0x94E0 +0x94E1 0x94E2 0x94E3 0x94E4 0x94E5 0x94E6 0x94E7 0x94E8 0x94E9 0x94EA 0x94EB 0x94EC 0x94ED 0x94EE 0x94EF 0x94F0 +0x94F1 0x94F2 0x94F3 0x94F4 0x94F5 0x94F6 0x94F7 0x94F8 0x94F9 0x94FA 0x94FB 0x94FC 0x94FD 0x94FE 0x94FF 0x9500 +0x9501 0x9502 0x9503 0x9504 0x9505 0x9506 0x9507 0x9508 0x9509 0x950A 0x950B 0x950C 0x950D 0x950E 0x950F 0x9510 +0x9511 0x9512 0x9513 0x9514 0x9515 0x9516 0x9517 0x9518 0x9519 0x951A 0x951B 0x951C 0x951D 0x951E 0x951F 0x9520 +0x9521 0x9522 0x9523 0x9524 0x9525 0x9526 0x9527 0x9528 0x9529 0x952A 0x952B 0x952C 0x952D 0x952E 0x952F 0x9530 +0x9531 0x9532 0x9533 0x9534 0x9535 0x9536 0x9537 0x9538 0x9539 0x953A 0x953B 0x953C 0x953D 0x953E 0x953F 0x9540 +0x9541 0x9542 0x9543 0x9544 0x9545 0x9546 0x9547 0x9548 0x9549 0x954A 0x954B 0x954C 0x954D 0x954E 0x954F 0x9550 +0x9551 0x9552 0x9553 0x9554 0x9555 0x9556 0x9557 0x9558 0x9559 0x955A 0x955B 0x955C 0x955D 0x955E 0x955F 0x9560 +0x9561 0x9562 0x9563 0x9564 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C 0x956D 0x956E 0x956F 0x9570 +0x9571 0x9572 0x9573 0x9574 0x9575 0x9576 0x9577 0x9578 0x957A 0x957B 0x957C 0x957D 0x957F 0x9580 0x9581 0x9582 +0x9583 0x9586 0x9587 0x9588 0x9589 0x958A 0x958B 0x958C 0x958D 0x958E 0x958F 0x9590 0x9591 0x9592 0x9593 0x9594 +0x9596 0x9598 0x9599 0x959B 0x959C 0x959E 0x959F 0x95A0 0x95A1 0x95A2 0x95A3 0x95A4 0x95A5 0x95A7 0x95A8 0x95A9 +0x95AA 0x95AB 0x95AC 0x95AD 0x95AE 0x95B0 0x95B1 0x95B2 0x95B5 0x95B6 0x95B7 0x95B9 0x95BA 0x95BB 0x95BC 0x95BD +0x95BE 0x95BF 0x95C0 0x95C3 0x95C5 0x95C6 0x95C7 0x95C8 0x95C9 0x95CA 0x95CB 0x95CC 0x95CD 0x95D0 0x95D1 0x95D2 +0x95D3 0x95D4 0x95D5 0x95D6 0x95D8 0x95DA 0x95DB 0x95DC 0x95DE 0x95DF 0x95E0 0x95E1 0x95E2 0x95E3 0x95E4 0x95E5 +0x95E8 0x95E9 0x95EA 0x95EB 0x95EC 0x95ED 0x95EE 0x95EF 0x95F0 0x95F1 0x95F2 0x95F3 0x95F4 0x95F5 0x95F6 0x95F7 +0x95F8 0x95F9 0x95FA 0x95FB 0x95FC 0x95FD 0x95FE 0x95FF 0x9600 0x9601 0x9602 0x9603 0x9604 0x9605 0x9606 0x9607 +0x9608 0x9609 0x960A 0x960B 0x960C 0x960D 0x960E 0x960F 0x9610 0x9611 0x9612 0x9613 0x9614 0x9615 0x9616 0x9617 +0x9618 0x9619 0x961A 0x961B 0x961C 0x961D 0x961E 0x961F 0x9620 0x9621 0x9622 0x9623 0x9624 0x9627 0x9628 0x962A +0x962C 0x962D 0x962E 0x962F 0x9630 0x9631 0x9632 0x9633 0x9634 0x9635 0x9636 0x9639 0x963A 0x963B 0x963C 0x963D +0x963F 0x9640 0x9641 0x9642 0x9644 0x9645 0x9646 0x9647 0x9648 0x9649 0x964B 0x964C 0x964D 0x964E 0x964F 0x9650 +0x9651 0x9654 0x9655 0x9658 0x965B 0x965C 0x965D 0x965E 0x965F 0x9661 0x9662 0x9663 0x9664 0x9665 0x9666 0x9667 +0x9668 0x9669 0x966A 0x966C 0x9670 0x9672 0x9673 0x9674 0x9675 0x9676 0x9677 0x9678 0x967A 0x967D 0x9683 0x9684 +0x9685 0x9686 0x9688 0x9689 0x968A 0x968B 0x968D 0x968E 0x968F 0x9690 0x9691 0x9694 0x9695 0x9697 0x9698 0x9699 +0x969B 0x969C 0x96A0 0x96A3 0x96A4 0x96A7 0x96A8 0x96A9 0x96AA 0x96AE 0x96B0 0x96B1 0x96B2 0x96B3 0x96B4 0x96B6 +0x96B7 0x96B8 0x96B9 0x96BA 0x96BB 0x96BC 0x96BD 0x96BE 0x96C0 0x96C1 0x96C3 0x96C4 0x96C5 0x96C6 0x96C7 0x96C9 +0x96CA 0x96CB 0x96CC 0x96CD 0x96CE 0x96CF 0x96D1 0x96D2 0x96D4 0x96D5 0x96D6 0x96D8 0x96D9 0x96DB 0x96DC 0x96DE +0x96E0 0x96E2 0x96E3 0x96E8 0x96E9 0x96EA 0x96EB 0x96EF 0x96F0 0x96F1 0x96F2 0x96F3 0x96F6 0x96F7 0x96F9 0x96FB +0x96FE 0x9700 0x9701 0x9702 0x9704 0x9705 0x9706 0x9707 0x9708 0x9709 0x970A 0x970D 0x970E 0x970F 0x9711 0x9713 +0x9716 0x9719 0x971C 0x971E 0x9721 0x9722 0x9724 0x9726 0x9727 0x9728 0x972A 0x972D 0x9730 0x9732 0x9738 0x9739 +0x973D 0x973E 0x9742 0x9744 0x9746 0x9748 0x9749 0x974D 0x974F 0x9751 0x9752 0x9753 0x9754 0x9756 0x9758 0x9759 +0x975A 0x975B 0x975C 0x975D 0x975E 0x9760 0x9761 0x9762 0x9764 0x9765 0x9766 0x9767 0x9768 0x9769 0x976A 0x976B +0x976C 0x976D 0x976E 0x9770 0x9771 0x9772 0x9773 0x9774 0x9776 0x9777 0x9778 0x9779 0x977A 0x977B 0x977C 0x977D +0x977F 0x9780 0x9781 0x9784 0x9785 0x9786 0x978B 0x978C 0x978D 0x978E 0x978F 0x9790 0x9791 0x9792 0x9794 0x9798 +0x979C 0x97A0 0x97A1 0x97A3 0x97A6 0x97A7 0x97A8 0x97AB 0x97AC 0x97AD 0x97AE 0x97AF 0x97B2 0x97B3 0x97B4 0x97BD +0x97BE 0x97BF 0x97C1 0x97C2 0x97C3 0x97C6 0x97C8 0x97C9 0x97CB 0x97CC 0x97CD 0x97D3 0x97D9 0x97DB 0x97DC 0x97DE +0x97E1 0x97E6 0x97E7 0x97E8 0x97E9 0x97EA 0x97EB 0x97EC 0x97ED 0x97EE 0x97F1 0x97F2 0x97F3 0x97F5 0x97F6 0x97F9 +0x97FB 0x97FE 0x97FF 0x9800 0x9801 0x9802 0x9803 0x9804 0x9805 0x9806 0x9807 0x9808 0x980A 0x980C 0x980D 0x980E +0x980F 0x9810 0x9811 0x9812 0x9813 0x9814 0x9816 0x9817 0x9818 0x981A 0x981C 0x9820 0x9821 0x9824 0x9826 0x982B +0x982C 0x982D 0x982E 0x9830 0x9832 0x9834 0x9835 0x9837 0x9838 0x9839 0x983B 0x983C 0x983D 0x9846 0x984B 0x984C +0x984D 0x984E 0x984F 0x9851 0x9852 0x9853 0x9854 0x9855 0x9857 0x9858 0x9859 0x985A 0x985B 0x985E 0x9862 0x9863 +0x9865 0x9867 0x9869 0x986B 0x986C 0x986F 0x9870 0x9871 0x9872 0x9873 0x9874 0x9875 0x9876 0x9877 0x9878 0x9879 +0x987A 0x987B 0x987C 0x987D 0x987E 0x987F 0x9880 0x9881 0x9882 0x9883 0x9884 0x9885 0x9886 0x9887 0x9888 0x9889 +0x988A 0x988B 0x988C 0x988D 0x988E 0x988F 0x9890 0x9891 0x9892 0x9893 0x9894 0x9895 0x9896 0x9897 0x9898 0x9899 +0x989A 0x989B 0x989C 0x989D 0x989E 0x989F 0x98A0 0x98A1 0x98A2 0x98A3 0x98A4 0x98A5 0x98A6 0x98A7 0x98A8 0x98A9 +0x98AA 0x98AC 0x98AD 0x98AE 0x98AF 0x98B1 0x98B2 0x98B3 0x98B6 0x98B8 0x98BA 0x98BB 0x98BC 0x98BD 0x98BE 0x98BF +0x98C0 0x98C1 0x98C2 0x98C3 0x98C4 0x98C6 0x98C7 0x98C8 0x98C9 0x98CB 0x98CC 0x98CE 0x98CF 0x98D0 0x98D1 0x98D2 +0x98D3 0x98D4 0x98D5 0x98D6 0x98D7 0x98D8 0x98D9 0x98DA 0x98DB 0x98DC 0x98DE 0x98DF 0x98E0 0x98E1 0x98E2 0x98E3 +0x98E5 0x98E7 0x98E8 0x98E9 0x98EA 0x98EB 0x98ED 0x98EE 0x98EF 0x98F2 0x98F4 0x98F6 0x98F9 0x98FA 0x98FC 0x98FD +0x98FE 0x98FF 0x9900 0x9902 0x9903 0x9904 0x9905 0x9907 0x9908 0x9909 0x990A 0x990C 0x990D 0x990E 0x990F 0x9910 +0x9911 0x9912 0x9913 0x9914 0x9915 0x9916 0x9917 0x9918 0x991A 0x991B 0x991C 0x991D 0x991E 0x991F 0x9920 0x9921 +0x9924 0x9928 0x992C 0x992E 0x9931 0x9932 0x9933 0x9935 0x9936 0x9937 0x9938 0x993A 0x993C 0x993D 0x993E 0x993F +0x9941 0x9942 0x9943 0x9945 0x9948 0x9949 0x994A 0x994B 0x994C 0x994D 0x9950 0x9951 0x9952 0x9954 0x9955 0x9957 +0x9958 0x995C 0x995E 0x9962 0x9963 0x9964 0x9965 0x9966 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x996D 0x996E +0x996F 0x9970 0x9971 0x9972 0x9973 0x9974 0x9975 0x9976 0x9977 0x9978 0x9979 0x997A 0x997B 0x997C 0x997D 0x997E +0x997F 0x9980 0x9981 0x9982 0x9983 0x9984 0x9985 0x9986 0x9987 0x9988 0x9989 0x998A 0x998B 0x998C 0x998D 0x998E +0x998F 0x9990 0x9991 0x9992 0x9993 0x9994 0x9995 0x9996 0x9997 0x9998 0x9999 0x999D 0x999E 0x99A5 0x99A7 0x99A8 +0x99AC 0x99AD 0x99AE 0x99AF 0x99B0 0x99B1 0x99B2 0x99B3 0x99B4 0x99B5 0x99B9 0x99BA 0x99BB 0x99BC 0x99BD 0x99C1 +0x99C2 0x99C3 0x99C4 0x99C5 0x99C6 0x99C7 0x99C8 0x99C9 0x99CB 0x99CC 0x99CD 0x99CE 0x99CF 0x99D0 0x99D1 0x99D2 +0x99D3 0x99D4 0x99D5 0x99D6 0x99D7 0x99D8 0x99D9 0x99DB 0x99DC 0x99DD 0x99DF 0x99E1 0x99E2 0x99E3 0x99E4 0x99E5 +0x99E7 0x99E9 0x99EA 0x99EC 0x99ED 0x99EE 0x99F0 0x99F1 0x99F2 0x99F8 0x99FB 0x99FC 0x99FF 0x9A01 0x9A02 0x9A03 +0x9A04 0x9A05 0x9A06 0x9A08 0x9A0A 0x9A0C 0x9A0D 0x9A0E 0x9A0F 0x9A11 0x9A12 0x9A13 0x9A16 0x9A19 0x9A1E 0x9A20 +0x9A24 0x9A27 0x9A28 0x9A2B 0x9A2D 0x9A2E 0x9A2F 0x9A30 0x9A31 0x9A35 0x9A36 0x9A37 0x9A38 0x9A3E 0x9A40 0x9A41 +0x9A42 0x9A43 0x9A44 0x9A45 0x9A4A 0x9A4C 0x9A4D 0x9A4E 0x9A4F 0x9A50 0x9A52 0x9A55 0x9A57 0x9A5A 0x9A5B 0x9A5F +0x9A62 0x9A63 0x9A64 0x9A65 0x9A66 0x9A69 0x9A6A 0x9A6B 0x9A6C 0x9A6D 0x9A6E 0x9A6F 0x9A70 0x9A71 0x9A72 0x9A73 +0x9A74 0x9A75 0x9A76 0x9A77 0x9A78 0x9A79 0x9A7A 0x9A7B 0x9A7C 0x9A7D 0x9A7E 0x9A7F 0x9A80 0x9A81 0x9A82 0x9A83 +0x9A84 0x9A85 0x9A86 0x9A87 0x9A88 0x9A89 0x9A8A 0x9A8B 0x9A8C 0x9A8D 0x9A8E 0x9A8F 0x9A90 0x9A91 0x9A92 0x9A93 +0x9A94 0x9A95 0x9A96 0x9A97 0x9A98 0x9A99 0x9A9A 0x9A9B 0x9A9C 0x9A9D 0x9A9E 0x9A9F 0x9AA0 0x9AA1 0x9AA2 0x9AA3 +0x9AA4 0x9AA5 0x9AA6 0x9AA7 0x9AA8 0x9AAB 0x9AAD 0x9AAF 0x9AB0 0x9AB1 0x9AB3 0x9AB4 0x9AB6 0x9AB7 0x9AB8 0x9AB9 +0x9ABA 0x9ABB 0x9ABC 0x9ABE 0x9ABF 0x9AC0 0x9AC1 0x9AC2 0x9AC3 0x9AC4 0x9AC5 0x9AC6 0x9AC7 0x9AC8 0x9ACA 0x9ACB +0x9ACC 0x9ACD 0x9ACE 0x9ACF 0x9AD0 0x9AD1 0x9AD2 0x9AD3 0x9AD4 0x9AD5 0x9AD6 0x9AD8 0x9AD9 0x9ADC 0x9ADD 0x9ADE +0x9ADF 0x9AE1 0x9AE2 0x9AE3 0x9AE5 0x9AE6 0x9AE7 0x9AEA 0x9AEB 0x9AEC 0x9AED 0x9AEE 0x9AEF 0x9AF1 0x9AF2 0x9AF3 +0x9AF4 0x9AF6 0x9AF7 0x9AF9 0x9AFA 0x9AFB 0x9AFC 0x9AFD 0x9AFE 0x9B01 0x9B03 0x9B04 0x9B05 0x9B06 0x9B08 0x9B0A +0x9B0B 0x9B0C 0x9B0D 0x9B0E 0x9B0F 0x9B10 0x9B11 0x9B12 0x9B13 0x9B15 0x9B16 0x9B17 0x9B18 0x9B19 0x9B1A 0x9B1E +0x9B1F 0x9B20 0x9B22 0x9B23 0x9B24 0x9B25 0x9B27 0x9B28 0x9B29 0x9B2A 0x9B2B 0x9B2E 0x9B2F 0x9B31 0x9B32 0x9B33 +0x9B35 0x9B36 0x9B37 0x9B39 0x9B3A 0x9B3B 0x9B3C 0x9B3E 0x9B3F 0x9B41 0x9B42 0x9B43 0x9B44 0x9B45 0x9B46 0x9B47 +0x9B48 0x9B49 0x9B4A 0x9B4B 0x9B4C 0x9B4D 0x9B4E 0x9B4F 0x9B51 0x9B52 0x9B54 0x9B55 0x9B56 0x9B58 0x9B59 0x9B5A +0x9B5B 0x9B5C 0x9B5F 0x9B60 0x9B61 0x9B62 0x9B64 0x9B66 0x9B67 0x9B68 0x9B69 0x9B6C 0x9B6F 0x9B70 0x9B71 0x9B74 +0x9B75 0x9B76 0x9B77 0x9B7A 0x9B7B 0x9B7C 0x9B7D 0x9B7E 0x9B80 0x9B81 0x9B82 0x9B83 0x9B84 0x9B85 0x9B86 0x9B87 +0x9B88 0x9B8A 0x9B8B 0x9B8D 0x9B8E 0x9B90 0x9B91 0x9B92 0x9B93 0x9B95 0x9B96 0x9B97 0x9B9A 0x9B9B 0x9B9C 0x9B9D +0x9B9E 0x9B9F 0x9BA0 0x9BA1 0x9BA2 0x9BA3 0x9BA4 0x9BA5 0x9BA6 0x9BA8 0x9BAA 0x9BAB 0x9BAD 0x9BAE 0x9BAF 0x9BB0 +0x9BB3 0x9BB4 0x9BB5 0x9BB6 0x9BB8 0x9BB9 0x9BBA 0x9BBD 0x9BBF 0x9BC0 0x9BC1 0x9BC3 0x9BC4 0x9BC6 0x9BC7 0x9BC8 +0x9BC9 0x9BCA 0x9BCF 0x9BD1 0x9BD2 0x9BD3 0x9BD4 0x9BD5 0x9BD6 0x9BD7 0x9BD9 0x9BDA 0x9BDB 0x9BDC 0x9BDD 0x9BDE +0x9BE0 0x9BE1 0x9BE2 0x9BE3 0x9BE4 0x9BE5 0x9BE6 0x9BE7 0x9BE8 0x9BEA 0x9BEB 0x9BEC 0x9BED 0x9BF0 0x9BF1 0x9BF2 +0x9BF4 0x9BF5 0x9BF6 0x9BF7 0x9BF8 0x9BFB 0x9BFD 0x9BFF 0x9C01 0x9C02 0x9C03 0x9C04 0x9C05 0x9C06 0x9C07 0x9C08 +0x9C09 0x9C0A 0x9C0B 0x9C0C 0x9C0D 0x9C0E 0x9C0F 0x9C10 0x9C12 0x9C13 0x9C14 0x9C15 0x9C17 0x9C1B 0x9C1C 0x9C1D +0x9C1F 0x9C20 0x9C21 0x9C23 0x9C24 0x9C25 0x9C27 0x9C28 0x9C29 0x9C2D 0x9C2E 0x9C2F 0x9C30 0x9C31 0x9C32 0x9C33 +0x9C35 0x9C36 0x9C37 0x9C39 0x9C3A 0x9C3B 0x9C3C 0x9C3E 0x9C40 0x9C42 0x9C45 0x9C46 0x9C47 0x9C48 0x9C49 0x9C4A +0x9C4B 0x9C4D 0x9C52 0x9C54 0x9C56 0x9C57 0x9C58 0x9C59 0x9C5A 0x9C5D 0x9C5F 0x9C60 0x9C63 0x9C64 0x9C65 0x9C66 +0x9C67 0x9C68 0x9C6D 0x9C6E 0x9C6F 0x9C72 0x9C74 0x9C75 0x9C76 0x9C77 0x9C78 0x9C7A 0x9C7C 0x9C7D 0x9C7E 0x9C7F +0x9C80 0x9C81 0x9C82 0x9C83 0x9C84 0x9C85 0x9C86 0x9C87 0x9C88 0x9C89 0x9C8A 0x9C8B 0x9C8C 0x9C8D 0x9C8E 0x9C8F +0x9C90 0x9C91 0x9C92 0x9C93 0x9C94 0x9C95 0x9C96 0x9C97 0x9C98 0x9C99 0x9C9A 0x9C9B 0x9C9C 0x9C9D 0x9C9E 0x9C9F +0x9CA0 0x9CA1 0x9CA2 0x9CA3 0x9CA4 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAA 0x9CAB 0x9CAC 0x9CAD 0x9CAE 0x9CAF +0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 0x9CB6 0x9CB7 0x9CB8 0x9CB9 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CBE 0x9CBF +0x9CC0 0x9CC1 0x9CC2 0x9CC3 0x9CC4 0x9CC5 0x9CC6 0x9CC7 0x9CC8 0x9CC9 0x9CCA 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF +0x9CD0 0x9CD1 0x9CD2 0x9CD3 0x9CD4 0x9CD5 0x9CD6 0x9CD7 0x9CD8 0x9CD9 0x9CDA 0x9CDB 0x9CDC 0x9CDD 0x9CDE 0x9CDF +0x9CE0 0x9CE1 0x9CE2 0x9CE3 0x9CE4 0x9CE5 0x9CE6 0x9CE7 0x9CE9 0x9CEA 0x9CEB 0x9CEC 0x9CED 0x9CF0 0x9CF1 0x9CF2 +0x9CF3 0x9CF4 0x9CF5 0x9CF6 0x9CF7 0x9CF9 0x9CFA 0x9CFB 0x9CFC 0x9CFD 0x9CFE 0x9CFF 0x9D00 0x9D02 0x9D03 0x9D04 +0x9D05 0x9D06 0x9D07 0x9D08 0x9D09 0x9D0E 0x9D10 0x9D12 0x9D14 0x9D15 0x9D1B 0x9D1C 0x9D1D 0x9D1E 0x9D1F 0x9D23 +0x9D26 0x9D28 0x9D2A 0x9D2B 0x9D2C 0x9D2F 0x9D30 0x9D33 0x9D34 0x9D37 0x9D3B 0x9D3D 0x9D3E 0x9D3F 0x9D41 0x9D42 +0x9D43 0x9D44 0x9D46 0x9D48 0x9D4F 0x9D50 0x9D51 0x9D52 0x9D53 0x9D59 0x9D5C 0x9D5D 0x9D5E 0x9D5F 0x9D60 0x9D61 +0x9D64 0x9D6A 0x9D6B 0x9D6C 0x9D6E 0x9D6F 0x9D70 0x9D72 0x9D77 0x9D7A 0x9D7E 0x9D84 0x9D86 0x9D87 0x9D89 0x9D8A +0x9D8F 0x9D92 0x9D93 0x9D96 0x9D98 0x9D9A 0x9DA0 0x9DA1 0x9DA4 0x9DA5 0x9DA9 0x9DAA 0x9DAB 0x9DAC 0x9DAF 0x9DB1 +0x9DB2 0x9DB4 0x9DB5 0x9DB8 0x9DB9 0x9DBA 0x9DBB 0x9DBC 0x9DBF 0x9DC0 0x9DC1 0x9DC2 0x9DC3 0x9DC4 0x9DC6 0x9DC8 +0x9DC9 0x9DCA 0x9DCF 0x9DD3 0x9DD6 0x9DD7 0x9DD9 0x9DDA 0x9DDF 0x9DE5 0x9DE6 0x9DEB 0x9DED 0x9DEF 0x9DF2 0x9DF3 +0x9DF4 0x9DF8 0x9DF9 0x9DFA 0x9DFD 0x9DFF 0x9E02 0x9E07 0x9E0A 0x9E0C 0x9E0F 0x9E11 0x9E15 0x9E18 0x9E19 0x9E1A +0x9E1B 0x9E1D 0x9E1E 0x9E1F 0x9E20 0x9E21 0x9E22 0x9E23 0x9E24 0x9E25 0x9E26 0x9E27 0x9E28 0x9E29 0x9E2A 0x9E2B +0x9E2C 0x9E2D 0x9E2E 0x9E2F 0x9E30 0x9E31 0x9E32 0x9E33 0x9E34 0x9E35 0x9E36 0x9E37 0x9E38 0x9E39 0x9E3A 0x9E3B +0x9E3C 0x9E3D 0x9E3E 0x9E3F 0x9E40 0x9E41 0x9E42 0x9E43 0x9E44 0x9E45 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4A 0x9E4B +0x9E4C 0x9E4D 0x9E4E 0x9E4F 0x9E50 0x9E51 0x9E52 0x9E53 0x9E54 0x9E55 0x9E56 0x9E57 0x9E58 0x9E59 0x9E5A 0x9E5B +0x9E5C 0x9E5D 0x9E5E 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E63 0x9E64 0x9E65 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B +0x9E6C 0x9E6D 0x9E6E 0x9E6F 0x9E70 0x9E71 0x9E72 0x9E73 0x9E74 0x9E75 0x9E78 0x9E79 0x9E7A 0x9E7C 0x9E7D 0x9E7E +0x9E7F 0x9E80 0x9E81 0x9E82 0x9E83 0x9E86 0x9E87 0x9E88 0x9E89 0x9E8A 0x9E8B 0x9E8C 0x9E8D 0x9E8E 0x9E90 0x9E91 +0x9E92 0x9E93 0x9E94 0x9E95 0x9E96 0x9E97 0x9E99 0x9E9A 0x9E9B 0x9E9C 0x9E9D 0x9E9F 0x9EA0 0x9EA1 0x9EA4 0x9EA5 +0x9EA6 0x9EA7 0x9EA8 0x9EA9 0x9EAA 0x9EAB 0x9EAC 0x9EAD 0x9EAE 0x9EAF 0x9EB0 0x9EB1 0x9EB2 0x9EB3 0x9EB4 0x9EB5 +0x9EB6 0x9EB7 0x9EB8 0x9EB9 0x9EBA 0x9EBB 0x9EBC 0x9EBD 0x9EBE 0x9EBF 0x9EC0 0x9EC1 0x9EC2 0x9EC3 0x9EC4 0x9EC5 +0x9EC6 0x9EC7 0x9EC8 0x9EC9 0x9ECA 0x9ECB 0x9ECC 0x9ECD 0x9ECE 0x9ECF 0x9ED0 0x9ED1 0x9ED2 0x9ED3 0x9ED4 0x9ED5 +0x9ED6 0x9ED7 0x9ED8 0x9ED9 0x9EDA 0x9EDB 0x9EDC 0x9EDD 0x9EDE 0x9EDF 0x9EE0 0x9EE1 0x9EE2 0x9EE3 0x9EE4 0x9EE5 +0x9EE6 0x9EE7 0x9EE8 0x9EE9 0x9EEA 0x9EEB 0x9EEC 0x9EED 0x9EEE 0x9EEF 0x9EF0 0x9EF1 0x9EF2 0x9EF3 0x9EF4 0x9EF5 +0x9EF6 0x9EF7 0x9EF8 0x9EF9 0x9EFA 0x9EFB 0x9EFC 0x9EFD 0x9EFE 0x9EFF 0x9F00 0x9F01 0x9F02 0x9F03 0x9F04 0x9F05 +0x9F06 0x9F07 0x9F08 0x9F09 0x9F0A 0x9F0B 0x9F0C 0x9F0D 0x9F0E 0x9F0F 0x9F10 0x9F11 0x9F12 0x9F13 0x9F14 0x9F15 +0x9F16 0x9F17 0x9F18 0x9F19 0x9F1A 0x9F1B 0x9F1C 0x9F1D 0x9F1E 0x9F1F 0x9F20 0x9F21 0x9F22 0x9F23 0x9F24 0x9F25 +0x9F26 0x9F27 0x9F28 0x9F29 0x9F2A 0x9F2B 0x9F2C 0x9F2D 0x9F2E 0x9F2F 0x9F30 0x9F31 0x9F32 0x9F33 0x9F34 0x9F35 +0x9F36 0x9F37 0x9F38 0x9F39 0x9F3A 0x9F3B 0x9F3C 0x9F3D 0x9F3E 0x9F3F 0x9F40 0x9F41 0x9F42 0x9F43 0x9F44 0x9F45 +0x9F46 0x9F47 0x9F48 0x9F49 0x9F4A 0x9F4B 0x9F4C 0x9F4D 0x9F4E 0x9F4F 0x9F50 0x9F51 0x9F52 0x9F53 0x9F54 0x9F55 +0x9F56 0x9F57 0x9F58 0x9F59 0x9F5A 0x9F5B 0x9F5C 0x9F5D 0x9F5E 0x9F5F 0x9F60 0x9F61 0x9F62 0x9F63 0x9F64 0x9F65 +0x9F66 0x9F67 0x9F68 0x9F69 0x9F6A 0x9F6B 0x9F6C 0x9F6D 0x9F6E 0x9F6F 0x9F70 0x9F71 0x9F72 0x9F73 0x9F74 0x9F75 +0x9F76 0x9F77 0x9F78 0x9F79 0x9F7A 0x9F7B 0x9F7C 0x9F7D 0x9F7E 0x9F7F 0x9F80 0x9F81 0x9F82 0x9F83 0x9F84 0x9F85 +0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A 0x9F8B 0x9F8C 0x9F8D 0x9F8E 0x9F8F 0x9F90 0x9F91 0x9F92 0x9F93 0x9F94 0x9F95 +0x9F96 0x9F97 0x9F98 0x9F99 0x9F9A 0x9F9B 0x9F9C 0x9F9D 0x9F9E 0x9F9F 0x9FA0 0x9FA1 0x9FA2 0x9FA3 0x9FA4 0x9FA5 +0x9FB0 0x9FB1 0x9FBF 0x9FCD 0x9FCE 0x9FCF 0x9FD4 0x9FEB 0x9FEC 0x9FED 0x9FFD 0xAC00 0xAC01 0xAC02 0xAC03 0xAC04 +0xAC05 0xAC06 0xAC07 0xAC08 0xAC09 0xAC0A 0xAC0B 0xAC0C 0xAC0D 0xAC0E 0xAC0F 0xAC10 0xAC11 0xAC12 0xAC13 0xAC14 +0xAC15 0xAC16 0xAC17 0xAC18 0xAC19 0xAC1A 0xAC1B 0xAC1C 0xAC1D 0xAC1E 0xAC1F 0xAC20 0xAC21 0xAC22 0xAC23 0xAC24 +0xAC25 0xAC26 0xAC27 0xAC28 0xAC29 0xAC2A 0xAC2B 0xAC2C 0xAC2D 0xAC2E 0xAC2F 0xAC30 0xAC31 0xAC32 0xAC33 0xAC34 +0xAC35 0xAC36 0xAC37 0xAC38 0xAC39 0xAC3A 0xAC3B 0xAC3C 0xAC3D 0xAC3E 0xAC3F 0xAC40 0xAC41 0xAC42 0xAC43 0xAC44 +0xAC45 0xAC46 0xAC47 0xAC48 0xAC49 0xAC4A 0xAC4B 0xAC4C 0xAC4D 0xAC4E 0xAC4F 0xAC50 0xAC51 0xAC52 0xAC53 0xAC54 +0xAC55 0xAC56 0xAC57 0xAC58 0xAC59 0xAC5A 0xAC5B 0xAC5C 0xAC5D 0xAC5E 0xAC5F 0xAC60 0xAC61 0xAC62 0xAC63 0xAC64 +0xAC65 0xAC66 0xAC67 0xAC68 0xAC69 0xAC6A 0xAC6B 0xAC6C 0xAC6D 0xAC6E 0xAC6F 0xAC70 0xAC71 0xAC72 0xAC73 0xAC74 +0xAC75 0xAC76 0xAC77 0xAC78 0xAC79 0xAC7A 0xAC7B 0xAC7C 0xAC7D 0xAC7E 0xAC7F 0xAC80 0xAC81 0xAC82 0xAC83 0xAC84 +0xAC85 0xAC86 0xAC87 0xAC88 0xAC89 0xAC8A 0xAC8B 0xAC8C 0xAC8D 0xAC8E 0xAC8F 0xAC90 0xAC91 0xAC92 0xAC93 0xAC94 +0xAC95 0xAC96 0xAC97 0xAC98 0xAC99 0xAC9A 0xAC9B 0xAC9C 0xAC9D 0xAC9E 0xAC9F 0xACA0 0xACA1 0xACA2 0xACA3 0xACA4 +0xACA5 0xACA6 0xACA7 0xACA8 0xACA9 0xACAA 0xACAB 0xACAC 0xACAD 0xACAE 0xACAF 0xACB0 0xACB1 0xACB2 0xACB3 0xACB4 +0xACB5 0xACB6 0xACB7 0xACB8 0xACB9 0xACBA 0xACBB 0xACBC 0xACBD 0xACBE 0xACBF 0xACC0 0xACC1 0xACC2 0xACC3 0xACC4 +0xACC5 0xACC6 0xACC7 0xACC8 0xACC9 0xACCA 0xACCB 0xACCC 0xACCD 0xACCE 0xACCF 0xACD0 0xACD1 0xACD2 0xACD3 0xACD4 +0xACD5 0xACD6 0xACD7 0xACD8 0xACD9 0xACDA 0xACDB 0xACDC 0xACDD 0xACDE 0xACDF 0xACE0 0xACE1 0xACE2 0xACE3 0xACE4 +0xACE7 0xACE8 0xACE9 0xACEA 0xACEB 0xACEC 0xACEE 0xACEF 0xACF0 0xACF1 0xACF2 0xACF3 0xACF4 0xACF5 0xACF6 0xACF7 +0xACF9 0xACFA 0xACFB 0xACFC 0xACFD 0xAD00 0xAD03 0xAD04 0xAD06 0xAD0C 0xAD0D 0xAD0E 0xAD0F 0xAD10 0xAD11 0xAD12 +0xAD18 0xAD19 0xAD1C 0xAD1F 0xAD20 0xAD22 0xAD28 0xAD29 0xAD2A 0xAD2B 0xAD2C 0xAD2D 0xAD34 0xAD35 0xAD38 0xAD3B +0xAD3C 0xAD3E 0xAD44 0xAD45 0xAD46 0xAD47 0xAD48 0xAD49 0xAD50 0xAD51 0xAD54 0xAD57 0xAD58 0xAD60 0xAD61 0xAD62 +0xAD63 0xAD64 0xAD65 0xAD6C 0xAD6D 0xAD70 0xAD73 0xAD74 0xAD75 0xAD76 0xAD78 0xAD7B 0xAD7C 0xAD7D 0xAD7E 0xAD7F +0xAD80 0xAD81 0xAD82 0xAD83 0xAD86 0xAD88 0xAD89 0xAD8C 0xAD8F 0xAD90 0xAD98 0xAD99 0xAD9A 0xAD9B 0xAD9C 0xAD9D +0xADA4 0xADA5 0xADA8 0xADAB 0xADAC 0xADB4 0xADB5 0xADB6 0xADB7 0xADB8 0xADB9 0xADC0 0xADC1 0xADC4 0xADC7 0xADC8 +0xADCA 0xADD0 0xADD1 0xADD2 0xADD3 0xADD4 0xADD5 0xADDC 0xADDD 0xADE0 0xADE4 0xADE8 0xADEC 0xADED 0xADEE 0xADEF +0xADF0 0xADF1 0xADF8 0xADF9 0xADFA 0xADFB 0xADFC 0xADFD 0xADFE 0xADFF 0xAE00 0xAE01 0xAE02 0xAE03 0xAE04 0xAE05 +0xAE06 0xAE07 0xAE08 0xAE09 0xAE0A 0xAE0B 0xAE0C 0xAE0D 0xAE0E 0xAE0F 0xAE11 0xAE12 0xAE13 0xAE14 0xAE15 0xAE18 +0xAE1C 0xAE20 0xAE24 0xAE25 0xAE26 0xAE27 0xAE28 0xAE29 0xAE30 0xAE31 0xAE32 0xAE33 0xAE34 0xAE35 0xAE36 0xAE37 +0xAE38 0xAE39 0xAE3A 0xAE3B 0xAE3C 0xAE3D 0xAE3E 0xAE3F 0xAE40 0xAE41 0xAE42 0xAE43 0xAE44 0xAE45 0xAE46 0xAE47 +0xAE48 0xAE49 0xAE4A 0xAE4B 0xAE4C 0xAE4D 0xAE4E 0xAE50 0xAE53 0xAE54 0xAE56 0xAE5C 0xAE5D 0xAE5E 0xAE5F 0xAE60 +0xAE61 0xAE62 0xAE63 0xAE65 0xAE68 0xAE69 0xAE6A 0xAE6C 0xAE6F 0xAE70 0xAE73 0xAE76 0xAE78 0xAE79 0xAE7A 0xAE7B +0xAE7C 0xAE7D 0xAE81 0xAE84 0xAE85 0xAE86 0xAE88 0xAE8B 0xAE8C 0xAE8D 0xAE94 0xAE95 0xAE96 0xAE97 0xAE98 0xAE99 +0xAEA0 0xAEA1 0xAEA4 0xAEB0 0xAEB1 0xAEB2 0xAEB3 0xAEB4 0xAEB5 0xAEBC 0xAEBD 0xAEBE 0xAEC0 0xAEC2 0xAEC3 0xAEC4 +0xAECC 0xAECD 0xAECE 0xAECF 0xAED0 0xAED1 0xAED2 0xAED3 0xAED5 0xAED8 0xAED9 0xAEDA 0xAEDC 0xAEDF 0xAEE0 0xAEE8 +0xAEE9 0xAEEA 0xAEEB 0xAEEC 0xAEED 0xAEF1 0xAEF4 0xAEF5 0xAEF8 0xAEFB 0xAEFC 0xAF04 0xAF05 0xAF06 0xAF07 0xAF08 +0xAF09 0xAF0D 0xAF10 0xAF11 0xAF17 0xAF20 0xAF21 0xAF22 0xAF23 0xAF24 0xAF25 0xAF2C 0xAF2D 0xAF30 0xAF31 0xAF32 +0xAF33 0xAF34 0xAF36 0xAF38 0xAF3B 0xAF3C 0xAF3D 0xAF3E 0xAF3F 0xAF40 0xAF41 0xAF42 0xAF43 0xAF45 0xAF47 0xAF48 +0xAF49 0xAF4C 0xAF4F 0xAF50 0xAF58 0xAF59 0xAF5A 0xAF5B 0xAF5C 0xAF5D 0xAF64 0xAF65 0xAF68 0xAF6B 0xAF6C 0xAF74 +0xAF75 0xAF76 0xAF77 0xAF78 0xAF79 0xAF80 0xAF81 0xAF84 0xAF87 0xAF88 0xAF90 0xAF91 0xAF92 0xAF93 0xAF94 0xAF95 +0xAF9C 0xAF9D 0xAFA0 0xAFA3 0xAFA4 0xAFAC 0xAFAD 0xAFAE 0xAFAF 0xAFB0 0xAFB1 0xAFB2 0xAFB8 0xAFB9 0xAFBC 0xAFBF +0xAFC0 0xAFC1 0xAFC7 0xAFC8 0xAFC9 0xAFCA 0xAFCB 0xAFCC 0xAFCD 0xAFCE 0xAFCF 0xAFD4 0xAFD5 0xAFD8 0xAFDB 0xAFDC +0xAFE4 0xAFE5 0xAFE6 0xAFE7 0xAFE8 0xAFE9 0xAFF0 0xAFF1 0xAFF4 0xAFF7 0xAFF8 0xB000 0xB001 0xB002 0xB003 0xB004 +0xB005 0xB00C 0xB00D 0xB010 0xB013 0xB014 0xB01C 0xB01D 0xB01E 0xB01F 0xB020 0xB021 0xB028 0xB029 0xB02C 0xB030 +0xB038 0xB039 0xB03A 0xB03B 0xB03C 0xB03D 0xB044 0xB045 0xB048 0xB04A 0xB04B 0xB04C 0xB04D 0xB04E 0xB053 0xB054 +0xB055 0xB056 0xB057 0xB058 0xB059 0xB05A 0xB05B 0xB05D 0xB05F 0xB060 0xB061 0xB064 0xB067 0xB068 0xB06B 0xB070 +0xB071 0xB072 0xB073 0xB074 0xB075 0xB07C 0xB07D 0xB080 0xB083 0xB084 0xB08B 0xB08C 0xB08D 0xB08E 0xB08F 0xB090 +0xB091 0xB095 0xB098 0xB099 0xB09A 0xB09B 0xB09C 0xB09F 0xB0A0 0xB0A1 0xB0A2 0xB0A4 0xB0A8 0xB0A9 0xB0AA 0xB0AB +0xB0AC 0xB0AD 0xB0AE 0xB0AF 0xB0B0 0xB0B1 0xB0B2 0xB0B3 0xB0B4 0xB0B5 0xB0B8 0xB0BB 0xB0BC 0xB0C4 0xB0C5 0xB0C6 +0xB0C7 0xB0C8 0xB0C9 0xB0CE 0xB0D0 0xB0D1 0xB0D4 0xB0D7 0xB0D8 0xB0E0 0xB0E1 0xB0E2 0xB0E3 0xB0E4 0xB0E5 0xB0E6 +0xB0E7 0xB0E9 0xB0EC 0xB0ED 0xB0F0 0xB0FC 0xB0FD 0xB0FE 0xB0FF 0xB100 0xB101 0xB108 0xB109 0xB10A 0xB10B 0xB10C +0xB10F 0xB110 0xB111 0xB112 0xB113 0xB117 0xB118 0xB119 0xB11A 0xB11B 0xB11C 0xB11D 0xB11E 0xB11F 0xB120 0xB121 +0xB122 0xB123 0xB124 0xB125 0xB128 0xB12B 0xB12C 0xB134 0xB135 0xB136 0xB137 0xB138 0xB139 0xB13C 0xB13D 0xB13E +0xB13F 0xB140 0xB141 0xB143 0xB144 0xB147 0xB148 0xB14B 0xB150 0xB151 0xB152 0xB153 0xB154 0xB155 0xB156 0xB157 +0xB158 0xB159 0xB15A 0xB15B 0xB15C 0xB15D 0xB160 0xB163 0xB164 0xB16C 0xB16D 0xB16E 0xB16F 0xB170 0xB171 0xB178 +0xB179 0xB17A 0xB17B 0xB17C 0xB17E 0xB17F 0xB180 0xB181 0xB182 0xB188 0xB189 0xB18A 0xB18B 0xB18C 0xB18D 0xB18E +0xB18F 0xB190 0xB191 0xB192 0xB193 0xB194 0xB195 0xB198 0xB19B 0xB19C 0xB1A4 0xB1A5 0xB1A6 0xB1A7 0xB1A8 0xB1A9 +0xB1B0 0xB1B4 0xB1B8 0xB1C0 0xB1C1 0xB1C2 0xB1C3 0xB1C4 0xB1C5 0xB1CC 0xB1CD 0xB1D0 0xB1D3 0xB1D4 0xB1DC 0xB1DD +0xB1DE 0xB1DF 0xB1E0 0xB1E1 0xB1E6 0xB1E8 0xB1E9 0xB1EC 0xB1EF 0xB1F0 0xB1F8 0xB1F9 0xB1FA 0xB1FB 0xB1FC 0xB1FD +0xB204 0xB205 0xB208 0xB20B 0xB20C 0xB20D 0xB210 0xB213 0xB214 0xB215 0xB216 0xB217 0xB218 0xB219 0xB21B 0xB21D +0xB21E 0xB220 0xB221 0xB224 0xB227 0xB228 0xB230 0xB231 0xB232 0xB233 0xB234 0xB235 0xB23C 0xB23D 0xB240 0xB243 +0xB244 0xB24C 0xB24D 0xB24E 0xB24F 0xB250 0xB251 0xB258 0xB259 0xB25C 0xB25F 0xB260 0xB268 0xB269 0xB26A 0xB26B +0xB26C 0xB26D 0xB26F 0xB274 0xB275 0xB278 0xB27B 0xB27C 0xB284 0xB285 0xB286 0xB287 0xB288 0xB289 0xB28A 0xB28B +0xB290 0xB291 0xB294 0xB297 0xB298 0xB299 0xB29A 0xB29C 0xB2A0 0xB2A1 0xB2A2 0xB2A3 0xB2A4 0xB2A5 0xB2A6 0xB2A7 +0xB2AA 0xB2AB 0xB2AC 0xB2AD 0xB2B0 0xB2B3 0xB2B4 0xB2BC 0xB2BD 0xB2BE 0xB2BF 0xB2C0 0xB2C1 0xB2C8 0xB2C9 0xB2CC +0xB2CF 0xB2D0 0xB2D1 0xB2D2 0xB2D3 0xB2D4 0xB2D8 0xB2D9 0xB2DA 0xB2DB 0xB2DC 0xB2DD 0xB2DE 0xB2E0 0xB2E2 0xB2E3 +0xB2E4 0xB2E5 0xB2E6 0xB2E8 0xB2EB 0xB2EC 0xB2ED 0xB2EE 0xB2EF 0xB2F0 0xB2F2 0xB2F3 0xB2F4 0xB2F5 0xB2F6 0xB2F7 +0xB2F8 0xB2F9 0xB2FA 0xB2FB 0xB2FC 0xB2FD 0xB2FE 0xB2FF 0xB300 0xB301 0xB304 0xB307 0xB308 0xB310 0xB311 0xB312 +0xB313 0xB314 0xB315 0xB316 0xB319 0xB31C 0xB31D 0xB320 0xB324 0xB327 0xB32C 0xB32D 0xB32E 0xB32F 0xB330 0xB331 +0xB338 0xB33C 0xB348 0xB349 0xB34A 0xB34B 0xB34C 0xB34D 0xB34E 0xB354 0xB355 0xB356 0xB358 0xB359 0xB35B 0xB35C +0xB35E 0xB35F 0xB364 0xB365 0xB366 0xB367 0xB368 0xB369 0xB36A 0xB36B 0xB36D 0xB36E 0xB36F 0xB370 0xB371 0xB374 +0xB377 0xB378 0xB380 0xB381 0xB382 0xB383 0xB384 0xB385 0xB386 0xB38A 0xB38C 0xB38D 0xB38F 0xB390 0xB393 0xB394 +0xB398 0xB39C 0xB39D 0xB39E 0xB39F 0xB3A0 0xB3A1 0xB3A8 0xB3A9 0xB3AC 0xB3B0 0xB3B8 0xB3B9 0xB3BA 0xB3BB 0xB3BC +0xB3BD 0xB3C4 0xB3C5 0xB3C6 0xB3C7 0xB3C8 0xB3CB 0xB3CC 0xB3CE 0xB3CF 0xB3D0 0xB3D3 0xB3D4 0xB3D5 0xB3D6 0xB3D7 +0xB3D8 0xB3D9 0xB3DA 0xB3DB 0xB3DC 0xB3DD 0xB3DE 0xB3DF 0xB3E0 0xB3E1 0xB3E4 0xB3E8 0xB3F0 0xB3F1 0xB3F2 0xB3F3 +0xB3F4 0xB3F5 0xB3FC 0xB400 0xB403 0xB404 0xB40C 0xB40D 0xB40E 0xB40F 0xB410 0xB411 0xB418 0xB419 0xB41C 0xB41F +0xB420 0xB424 0xB428 0xB429 0xB42A 0xB42B 0xB42C 0xB42D 0xB434 0xB435 0xB438 0xB43B 0xB43C 0xB444 0xB445 0xB446 +0xB447 0xB448 0xB449 0xB44F 0xB450 0xB451 0xB452 0xB454 0xB457 0xB458 0xB459 0xB45A 0xB45B 0xB460 0xB461 0xB462 +0xB463 0xB464 0xB465 0xB46A 0xB46C 0xB46D 0xB470 0xB473 0xB474 0xB47C 0xB47D 0xB47E 0xB47F 0xB480 0xB481 0xB488 +0xB489 0xB48C 0xB48F 0xB490 0xB498 0xB499 0xB49A 0xB49B 0xB49C 0xB49D 0xB4A4 0xB4A5 0xB4A8 0xB4AB 0xB4AC 0xB4B4 +0xB4B5 0xB4B6 0xB4B7 0xB4B8 0xB4B9 0xB4C0 0xB4C1 0xB4C4 0xB4C8 0xB4D0 0xB4D1 0xB4D2 0xB4D3 0xB4D4 0xB4D5 0xB4DC +0xB4DD 0xB4DE 0xB4DF 0xB4E0 0xB4E3 0xB4E4 0xB4E5 0xB4E6 0xB4E7 0xB4E8 0xB4EC 0xB4ED 0xB4EE 0xB4EF 0xB4F0 0xB4F1 +0xB4F8 0xB4F9 0xB4FA 0xB4FC 0xB4FF 0xB500 0xB508 0xB509 0xB50A 0xB50B 0xB50C 0xB50D 0xB511 0xB514 0xB515 0xB516 +0xB518 0xB51B 0xB51C 0xB524 0xB525 0xB526 0xB527 0xB528 0xB529 0xB52A 0xB52B 0xB52D 0xB52E 0xB52F 0xB530 0xB531 +0xB532 0xB534 0xB537 0xB538 0xB539 0xB53A 0xB53B 0xB53F 0xB540 0xB541 0xB542 0xB543 0xB544 0xB545 0xB54B 0xB54C +0xB54D 0xB54E 0xB550 0xB553 0xB554 0xB55C 0xB55D 0xB55E 0xB55F 0xB560 0xB561 0xB567 0xB568 0xB569 0xB56C 0xB570 +0xB578 0xB579 0xB57A 0xB57B 0xB57C 0xB57D 0xB584 0xB585 0xB588 0xB594 0xB595 0xB596 0xB597 0xB598 0xB599 0xB5A0 +0xB5A1 0xB5A4 0xB5A7 0xB5A8 0xB5AA 0xB5AB 0xB5AF 0xB5B0 0xB5B1 0xB5B2 0xB5B3 0xB5B4 0xB5B5 0xB5BB 0xB5BC 0xB5BD +0xB5BE 0xB5C0 0xB5C3 0xB5C4 0xB5CC 0xB5CD 0xB5CE 0xB5CF 0xB5D0 0xB5D1 0xB5D8 0xB5D9 0xB5DC 0xB5DF 0xB5E8 0xB5E9 +0xB5EA 0xB5EB 0xB5EC 0xB5ED 0xB5F4 0xB5F5 0xB5F8 0xB604 0xB605 0xB606 0xB607 0xB608 0xB609 0xB610 0xB611 0xB612 +0xB614 0xB617 0xB618 0xB619 0xB61A 0xB61F 0xB620 0xB621 0xB622 0xB623 0xB624 0xB625 0xB62C 0xB62D 0xB630 0xB634 +0xB63C 0xB63D 0xB63E 0xB63F 0xB640 0xB641 0xB647 0xB648 0xB649 0xB64C 0xB64F 0xB650 0xB658 0xB659 0xB65A 0xB65B +0xB65C 0xB65D 0xB664 0xB665 0xB668 0xB66B 0xB66C 0xB674 0xB675 0xB676 0xB677 0xB678 0xB679 0xB680 0xB681 0xB690 +0xB691 0xB692 0xB693 0xB694 0xB695 0xB69C 0xB69D 0xB6A0 0xB6A3 0xB6A4 0xB6A6 0xB6A7 0xB6AB 0xB6AC 0xB6AD 0xB6AE +0xB6AF 0xB6B0 0xB6B1 0xB6B5 0xB6B8 0xB6BC 0xB6BF 0xB6C8 0xB6C9 0xB6CA 0xB6CB 0xB6CC 0xB6CD 0xB6D4 0xB6D8 0xB6DB +0xB6DC 0xB6E4 0xB6E5 0xB6E6 0xB6E7 0xB6E8 0xB6E9 0xB6F0 0xB6F4 0xB6F7 0xB6F8 0xB700 0xB701 0xB702 0xB703 0xB704 +0xB705 0xB70C 0xB70D 0xB710 0xB714 0xB71C 0xB71D 0xB71E 0xB71F 0xB720 0xB721 0xB728 0xB729 0xB72A 0xB72B 0xB72C +0xB72F 0xB730 0xB732 0xB733 0xB737 0xB738 0xB739 0xB73A 0xB73B 0xB73C 0xB73D 0xB73E 0xB743 0xB744 0xB745 0xB748 +0xB74C 0xB754 0xB755 0xB756 0xB757 0xB758 0xB759 0xB760 0xB761 0xB764 0xB767 0xB768 0xB770 0xB771 0xB772 0xB773 +0xB774 0xB775 0xB77B 0xB77C 0xB77D 0xB780 0xB783 0xB784 0xB788 0xB78C 0xB78D 0xB78E 0xB78F 0xB790 0xB791 0xB792 +0xB793 0xB794 0xB795 0xB796 0xB797 0xB798 0xB799 0xB79C 0xB79F 0xB7A0 0xB7A8 0xB7A9 0xB7AA 0xB7AB 0xB7AC 0xB7AD +0xB7B0 0xB7B1 0xB7B2 0xB7B4 0xB7B5 0xB7B8 0xB7BB 0xB7BC 0xB7C4 0xB7C5 0xB7C6 0xB7C7 0xB7C8 0xB7C9 0xB7D0 0xB7D4 +0xB7E0 0xB7E1 0xB7E2 0xB7E3 0xB7E4 0xB7E5 0xB7EC 0xB7ED 0xB7F0 0xB7F2 0xB7F3 0xB7F4 0xB7FC 0xB7FD 0xB7FE 0xB7FF +0xB800 0xB801 0xB802 0xB804 0xB806 0xB807 0xB808 0xB809 0xB80C 0xB80F 0xB810 0xB818 0xB819 0xB81A 0xB81B 0xB81C +0xB81D 0xB821 0xB822 0xB823 0xB824 0xB825 0xB828 0xB82B 0xB82C 0xB830 0xB834 0xB835 0xB836 0xB837 0xB838 0xB839 +0xB83C 0xB83E 0xB840 0xB841 0xB844 0xB847 0xB848 0xB850 0xB851 0xB852 0xB853 0xB854 0xB855 0xB85C 0xB85D 0xB860 +0xB863 0xB864 0xB868 0xB86B 0xB86C 0xB86D 0xB86E 0xB86F 0xB870 0xB871 0xB874 0xB876 0xB877 0xB878 0xB879 0xB87C +0xB880 0xB888 0xB889 0xB88A 0xB88B 0xB88C 0xB88D 0xB894 0xB895 0xB896 0xB897 0xB898 0xB89B 0xB89C 0xB8A4 0xB8A5 +0xB8A6 0xB8A7 0xB8A8 0xB8A9 0xB8B0 0xB8B1 0xB8B4 0xB8B5 0xB8B7 0xB8B8 0xB8C0 0xB8C1 0xB8C2 0xB8C3 0xB8C4 0xB8C5 +0xB8CC 0xB8CD 0xB8CE 0xB8CF 0xB8D0 0xB8D3 0xB8D4 0xB8DC 0xB8DD 0xB8DE 0xB8DF 0xB8E0 0xB8E1 0xB8E8 0xB8E9 0xB8EC +0xB8EF 0xB8F0 0xB8F3 0xB8F8 0xB8F9 0xB8FA 0xB8FB 0xB8FC 0xB8FD 0xB900 0xB902 0xB904 0xB905 0xB908 0xB90B 0xB90C +0xB914 0xB915 0xB916 0xB917 0xB918 0xB919 0xB920 0xB921 0xB924 0xB928 0xB930 0xB931 0xB932 0xB933 0xB934 0xB935 +0xB93C 0xB93D 0xB940 0xB943 0xB944 0xB94C 0xB94D 0xB94E 0xB94F 0xB950 0xB951 0xB958 0xB959 0xB95C 0xB95F 0xB960 +0xB968 0xB969 0xB96A 0xB96B 0xB96C 0xB96D 0xB974 0xB975 0xB978 0xB97B 0xB97C 0xB97D 0xB980 0xB984 0xB985 0xB986 +0xB987 0xB988 0xB989 0xB98A 0xB98B 0xB98D 0xB98E 0xB98F 0xB990 0xB991 0xB994 0xB998 0xB99E 0xB9A0 0xB9A1 0xB9A2 +0xB9A3 0xB9A4 0xB9A5 0xB9AC 0xB9AD 0xB9AE 0xB9AF 0xB9B0 0xB9B3 0xB9B4 0xB9BC 0xB9BD 0xB9BE 0xB9BF 0xB9C0 0xB9C1 +0xB9C2 0xB9C4 0xB9C6 0xB9C8 0xB9C9 0xB9CA 0xB9CB 0xB9CC 0xB9CD 0xB9CE 0xB9CF 0xB9D0 0xB9D1 0xB9D2 0xB9D4 0xB9D8 +0xB9D9 0xB9DA 0xB9DB 0xB9DC 0xB9DD 0xB9DE 0xB9DF 0xB9E0 0xB9E1 0xB9E2 0xB9E3 0xB9E4 0xB9E5 0xB9E6 0xB9E7 0xB9E8 +0xB9EB 0xB9EC 0xB9ED 0xB9F4 0xB9F5 0xB9F6 0xB9F7 0xB9F8 0xB9F9 0xB9FA 0xB9FB 0xB9FC 0xB9FD 0xB9FE 0xB9FF 0xBA00 +0xBA01 0xBA02 0xBA03 0xBA04 0xBA05 0xBA06 0xBA07 0xBA08 0xBA10 0xBA11 0xBA12 0xBA13 0xBA14 0xBA15 0xBA18 0xBA1C +0xBA1D 0xBA1E 0xBA1F 0xBA20 0xBA2C 0xBA2D 0xBA2E 0xBA2F 0xBA30 0xBA31 0xBA32 0xBA33 0xBA34 0xBA35 0xBA36 0xBA37 +0xBA38 0xBA39 0xBA3A 0xBA3B 0xBA3C 0xBA3D 0xBA3E 0xBA3F 0xBA40 0xBA41 0xBA42 0xBA43 0xBA44 0xBA45 0xBA46 0xBA47 +0xBA48 0xBA49 0xBA4A 0xBA4B 0xBA4C 0xBA4D 0xBA4E 0xBA4F 0xBA50 0xBA51 0xBA52 0xBA53 0xBA54 0xBA55 0xBA56 0xBA57 +0xBA58 0xBA59 0xBA5A 0xBA5B 0xBA5C 0xBA60 0xBA64 0xBA65 0xBA66 0xBA67 0xBA68 0xBA69 0xBA6A 0xBA6B 0xBA6C 0xBA6D +0xBA6E 0xBA6F 0xBA70 0xBA71 0xBA72 0xBA73 0xBA74 0xBA75 0xBA76 0xBA77 0xBA78 0xBA79 0xBA7A 0xBA7B 0xBA7C 0xBA7D +0xBA7E 0xBA7F 0xBA80 0xBA81 0xBA82 0xBA83 0xBA84 0xBA85 0xBA86 0xBA87 0xBA89 0xBA8C 0xBA8D 0xBA8E 0xBA8F 0xBA90 +0xBA93 0xBA94 0xBA9C 0xBA9D 0xBA9E 0xBA9F 0xBAA0 0xBAA1 0xBAA2 0xBAA3 0xBAA4 0xBAA5 0xBAA6 0xBAA7 0xBAA8 0xBAA9 +0xBAAA 0xBAAB 0xBAAC 0xBAAD 0xBAAE 0xBAAF 0xBAB0 0xBAB1 0xBAB2 0xBAB3 0xBAB4 0xBAB5 0xBAB6 0xBAB7 0xBAB8 0xBAB9 +0xBABA 0xBABB 0xBABC 0xBABD 0xBABF 0xBAC3 0xBAC4 0xBAC5 0xBAC6 0xBAC8 0xBACB 0xBACC 0xBAD4 0xBAD5 0xBAD6 0xBAD7 +0xBAD8 0xBAD9 0xBAE0 0xBAE4 0xBAE8 0xBAF0 0xBAF1 0xBAF2 0xBAF3 0xBAF4 0xBAF5 0xBAFC 0xBAFD 0xBAFE 0xBB00 0xBB03 +0xBB04 0xBB0C 0xBB0D 0xBB0E 0xBB0F 0xBB10 0xBB11 0xBB18 0xBB19 0xBB1C 0xBB1F 0xBB20 0xBB28 0xBB29 0xBB2A 0xBB2B +0xBB2C 0xBB2D 0xBB34 0xBB35 0xBB36 0xBB38 0xBB3A 0xBB3B 0xBB3C 0xBB3D 0xBB3E 0xBB40 0xBB44 0xBB45 0xBB46 0xBB47 +0xBB48 0xBB49 0xBB4B 0xBB4D 0xBB4F 0xBB50 0xBB51 0xBB54 0xBB57 0xBB58 0xBB60 0xBB61 0xBB62 0xBB63 0xBB64 0xBB65 +0xBB6C 0xBB6D 0xBB6E 0xBB70 0xBB74 0xBB7C 0xBB7D 0xBB7E 0xBB7F 0xBB80 0xBB81 0xBB88 0xBB89 0xBB8A 0xBB8C 0xBB90 +0xBB98 0xBB99 0xBB9A 0xBB9B 0xBB9C 0xBB9D 0xBBA4 0xBBA5 0xBBA6 0xBBA8 0xBBAB 0xBBAC 0xBBB4 0xBBB5 0xBBB6 0xBBB7 +0xBBB8 0xBBB9 0xBBC0 0xBBC1 0xBBC3 0xBBC4 0xBBC7 0xBBC8 0xBBC9 0xBBCA 0xBBCB 0xBBCC 0xBBCD 0xBBCE 0xBBCF 0xBBD0 +0xBBD1 0xBBD2 0xBBD3 0xBBD4 0xBBD5 0xBBD9 0xBBDC 0xBBDD 0xBBDE 0xBBE0 0xBBE4 0xBBEC 0xBBED 0xBBEE 0xBBEF 0xBBF0 +0xBBF1 0xBBF2 0xBBF8 0xBBF9 0xBBFC 0xBBFF 0xBC00 0xBC01 0xBC02 0xBC03 0xBC04 0xBC05 0xBC06 0xBC07 0xBC08 0xBC09 +0xBC0A 0xBC0B 0xBC0C 0xBC0D 0xBC0E 0xBC0F 0xBC10 0xBC11 0xBC14 0xBC15 0xBC16 0xBC17 0xBC18 0xBC1B 0xBC1C 0xBC1D +0xBC1E 0xBC1F 0xBC20 0xBC23 0xBC24 0xBC25 0xBC26 0xBC27 0xBC28 0xBC29 0xBC2B 0xBC2C 0xBC2D 0xBC2F 0xBC30 0xBC31 +0xBC32 0xBC33 0xBC34 0xBC35 0xBC36 0xBC37 0xBC38 0xBC39 0xBC3A 0xBC3B 0xBC3C 0xBC3D 0xBC3E 0xBC3F 0xBC40 0xBC41 +0xBC42 0xBC43 0xBC44 0xBC45 0xBC46 0xBC49 0xBC4C 0xBC4D 0xBC4E 0xBC50 0xBC54 0xBC5C 0xBC5D 0xBC5E 0xBC5F 0xBC60 +0xBC61 0xBC67 0xBC68 0xBC69 0xBC6A 0xBC6B 0xBC6C 0xBC6F 0xBC70 0xBC77 0xBC78 0xBC79 0xBC7A 0xBC7B 0xBC7C 0xBC7D +0xBC84 0xBC85 0xBC86 0xBC88 0xBC8B 0xBC8C 0xBC8D 0xBC8E 0xBC90 0xBC94 0xBC95 0xBC96 0xBC97 0xBC98 0xBC99 0xBC9A +0xBC9C 0xBC9D 0xBC9F 0xBCA0 0xBCA1 0xBCA2 0xBCA3 0xBCA4 0xBCA7 0xBCA8 0xBCB0 0xBCB1 0xBCB2 0xBCB3 0xBCB4 0xBCB5 +0xBCB8 0xBCB9 0xBCBC 0xBCBD 0xBCC0 0xBCC3 0xBCC4 0xBCC8 0xBCCC 0xBCCD 0xBCCE 0xBCCF 0xBCD0 0xBCD1 0xBCD2 0xBCD3 +0xBCD4 0xBCD5 0xBCD8 0xBCD9 0xBCDC 0xBCE0 0xBCE8 0xBCE9 0xBCEA 0xBCEB 0xBCEC 0xBCED 0xBCF4 0xBCF5 0xBCF6 0xBCF7 +0xBCF8 0xBCFB 0xBCFC 0xBCFD 0xBCFE 0xBCFF 0xBD04 0xBD05 0xBD06 0xBD07 0xBD08 0xBD09 0xBD0A 0xBD0B 0xBD0D 0xBD0F +0xBD10 0xBD11 0xBD14 0xBD17 0xBD18 0xBD20 0xBD21 0xBD22 0xBD23 0xBD24 0xBD25 0xBD2C 0xBD30 0xBD33 0xBD34 0xBD3C +0xBD3D 0xBD3E 0xBD3F 0xBD40 0xBD41 0xBD48 0xBD49 0xBD4A 0xBD4C 0xBD4F 0xBD50 0xBD58 0xBD59 0xBD5A 0xBD5B 0xBD5C +0xBD5D 0xBD64 0xBD65 0xBD68 0xBD6C 0xBD74 0xBD75 0xBD76 0xBD77 0xBD78 0xBD79 0xBD80 0xBD81 0xBD82 0xBD84 0xBD87 +0xBD88 0xBD89 0xBD8A 0xBD8B 0xBD8E 0xBD90 0xBD91 0xBD92 0xBD93 0xBD94 0xBD95 0xBD96 0xBD97 0xBD98 0xBD99 0xBD9A +0xBD9B 0xBD9C 0xBD9D 0xBDA0 0xBDA3 0xBDA4 0xBDAC 0xBDAD 0xBDAE 0xBDAF 0xBDB0 0xBDB1 0xBDB4 0xBDB8 0xBDB9 0xBDBC +0xBDBF 0xBDC0 0xBDC1 0xBDC8 0xBDC9 0xBDCA 0xBDCB 0xBDCC 0xBDCD 0xBDD4 0xBDD5 0xBDD8 0xBDDB 0xBDDC 0xBDE4 0xBDE5 +0xBDE6 0xBDE7 0xBDE8 0xBDE9 0xBDF0 0xBDF1 0xBDF2 0xBDF4 0xBDF7 0xBDF8 0xBE00 0xBE01 0xBE02 0xBE03 0xBE04 0xBE05 +0xBE0C 0xBE0D 0xBE10 0xBE13 0xBE14 0xBE15 0xBE17 0xBE18 0xBE1B 0xBE1C 0xBE1D 0xBE1E 0xBE1F 0xBE20 0xBE21 0xBE22 +0xBE23 0xBE25 0xBE27 0xBE28 0xBE29 0xBE2C 0xBE30 0xBE38 0xBE39 0xBE3A 0xBE3B 0xBE3C 0xBE3D 0xBE44 0xBE45 0xBE46 +0xBE47 0xBE48 0xBE49 0xBE4A 0xBE4B 0xBE4C 0xBE4E 0xBE54 0xBE55 0xBE56 0xBE57 0xBE58 0xBE59 0xBE5A 0xBE5B 0xBE5C +0xBE5D 0xBE5F 0xBE60 0xBE61 0xBE62 0xBE63 0xBE64 0xBE65 0xBE66 0xBE67 0xBE68 0xBE69 0xBE6A 0xBE70 0xBE71 0xBE72 +0xBE73 0xBE74 0xBE75 0xBE76 0xBE79 0xBE7B 0xBE7C 0xBE7D 0xBE7E 0xBE7F 0xBE80 0xBE83 0xBE84 0xBE8C 0xBE8D 0xBE8E +0xBE8F 0xBE90 0xBE91 0xBE92 0xBE93 0xBE94 0xBE95 0xBE96 0xBE98 0xBE99 0xBE9C 0xBEA8 0xBEA9 0xBEAA 0xBEAB 0xBEAC +0xBEAD 0xBEAE 0xBEB4 0xBEB5 0xBEB6 0xBEB7 0xBEB8 0xBEBB 0xBEBC 0xBEC4 0xBEC5 0xBEC6 0xBEC7 0xBEC8 0xBEC9 0xBECA +0xBECB 0xBECC 0xBECD 0xBECE 0xBED0 0xBED1 0xBED4 0xBED7 0xBED8 0xBED9 0xBEE0 0xBEE1 0xBEE2 0xBEE3 0xBEE4 0xBEE5 +0xBEE6 0xBEEC 0xBEED 0xBEEE 0xBEEF 0xBEF0 0xBEF3 0xBEF4 0xBEFC 0xBEFD 0xBEFE 0xBEFF 0xBF00 0xBF01 0xBF02 0xBF03 +0xBF04 0xBF05 0xBF06 0xBF08 0xBF09 0xBF0C 0xBF0F 0xBF10 0xBF18 0xBF19 0xBF1A 0xBF1B 0xBF1C 0xBF1D 0xBF1F 0xBF21 +0xBF24 0xBF25 0xBF26 0xBF27 0xBF28 0xBF2B 0xBF2C 0xBF34 0xBF35 0xBF36 0xBF37 0xBF38 0xBF39 0xBF3A 0xBF3B 0xBF3C +0xBF3D 0xBF3E 0xBF40 0xBF41 0xBF44 0xBF47 0xBF48 0xBF50 0xBF51 0xBF52 0xBF53 0xBF54 0xBF55 0xBF59 0xBF5B 0xBF5C +0xBF60 0xBF63 0xBF78 0xBF7F 0xBF94 0xBF98 0xBF9B 0xBFA4 0xBFA5 0xBFAC 0xBFB0 0xBFB1 0xBFB4 0xBFC0 0xBFC1 0xBFC2 +0xBFC3 0xBFC4 0xBFC5 0xBFCC 0xBFCD 0xBFD0 0xBFD3 0xBFD4 0xBFD5 0xBFDC 0xBFDD 0xBFDF 0xBFE1 0xBFE5 0xBFE8 0xBFEF +0xC004 0xC020 0xC021 0xC03C 0xC03D 0xC040 0xC043 0xC044 0xC051 0xC058 0xC059 0xC05C 0xC05F 0xC060 0xC068 0xC069 +0xC06A 0xC06B 0xC06C 0xC06D 0xC074 0xC090 0xC091 0xC094 0xC097 0xC098 0xC0A0 0xC0A1 0xC0A2 0xC0A3 0xC0A4 0xC0A5 +0xC0A6 0xC0A7 0xC0AB 0xC0AC 0xC0AD 0xC0AE 0xC0AF 0xC0B0 0xC0B1 0xC0B2 0xC0B3 0xC0B4 0xC0B5 0xC0B6 0xC0B7 0xC0B8 +0xC0B9 0xC0BA 0xC0BB 0xC0BC 0xC0BD 0xC0BE 0xC0BF 0xC0C0 0xC0C1 0xC0C2 0xC0C3 0xC0C4 0xC0C5 0xC0C6 0xC0C7 0xC0C8 +0xC0C9 0xC0CA 0xC0CB 0xC0CC 0xC0CF 0xC0D0 0xC0D2 0xC0D8 0xC0D9 0xC0DA 0xC0DB 0xC0DC 0xC0DD 0xC0E3 0xC0E4 0xC0E5 +0xC0E8 0xC0EB 0xC0EC 0xC0F4 0xC0F5 0xC0F6 0xC0F7 0xC0F8 0xC0F9 0xC0FB 0xC0FE 0xC0FF 0xC100 0xC101 0xC104 0xC108 +0xC10A 0xC110 0xC111 0xC112 0xC113 0xC114 0xC115 0xC11C 0xC11D 0xC11E 0xC11F 0xC120 0xC123 0xC124 0xC125 0xC126 +0xC127 0xC128 0xC12A 0xC12C 0xC12D 0xC12E 0xC12F 0xC130 0xC131 0xC134 0xC136 0xC138 0xC139 0xC13C 0xC13F 0xC140 +0xC148 0xC149 0xC14A 0xC14B 0xC14C 0xC14D 0xC14E 0xC151 0xC152 0xC154 0xC155 0xC156 0xC157 0xC158 0xC15B 0xC15C +0xC15F 0xC160 0xC164 0xC165 0xC166 0xC167 0xC168 0xC169 0xC170 0xC171 0xC173 0xC174 0xC178 0xC180 0xC181 0xC182 +0xC183 0xC184 0xC185 0xC18A 0xC18C 0xC18D 0xC18E 0xC18F 0xC190 0xC193 0xC194 0xC195 0xC196 0xC197 0xC198 0xC19C +0xC19D 0xC19E 0xC19F 0xC1A0 0xC1A1 0xC1A3 0xC1A5 0xC1A6 0xC1A8 0xC1A9 0xC1AC 0xC1B0 0xC1B8 0xC1B9 0xC1BA 0xC1BB +0xC1BC 0xC1BD 0xC1C4 0xC1C5 0xC1C8 0xC1CB 0xC1CC 0xC1D4 0xC1D5 0xC1D6 0xC1D7 0xC1D8 0xC1D9 0xC1E0 0xC1E1 0xC1E4 +0xC1E7 0xC1E8 0xC1F0 0xC1F1 0xC1F2 0xC1F3 0xC1F4 0xC1F5 0xC1FC 0xC1FD 0xC200 0xC203 0xC204 0xC20C 0xC20D 0xC20E +0xC20F 0xC210 0xC211 0xC216 0xC218 0xC219 0xC21C 0xC21F 0xC220 0xC221 0xC224 0xC227 0xC228 0xC229 0xC22A 0xC22B +0xC22C 0xC22D 0xC22E 0xC22F 0xC231 0xC232 0xC233 0xC234 0xC235 0xC238 0xC23B 0xC23C 0xC244 0xC245 0xC246 0xC247 +0xC248 0xC249 0xC250 0xC251 0xC254 0xC257 0xC258 0xC260 0xC261 0xC262 0xC263 0xC264 0xC265 0xC26C 0xC26D 0xC270 +0xC273 0xC274 0xC27C 0xC27D 0xC27E 0xC27F 0xC280 0xC281 0xC286 0xC288 0xC289 0xC28C 0xC28F 0xC290 0xC298 0xC299 +0xC29A 0xC29B 0xC29C 0xC29D 0xC2A4 0xC2A5 0xC2A8 0xC2AB 0xC2AC 0xC2AD 0xC2AE 0xC2AF 0xC2B0 0xC2B2 0xC2B3 0xC2B4 +0xC2B5 0xC2B6 0xC2B7 0xC2B8 0xC2B9 0xC2BA 0xC2BB 0xC2BC 0xC2BD 0xC2BE 0xC2BF 0xC2C0 0xC2C1 0xC2C4 0xC2C8 0xC2D0 +0xC2D1 0xC2D2 0xC2D3 0xC2D4 0xC2D5 0xC2DC 0xC2DD 0xC2DE 0xC2E0 0xC2E2 0xC2E3 0xC2E4 0xC2E5 0xC2E6 0xC2E8 0xC2EB +0xC2EC 0xC2ED 0xC2EE 0xC2EF 0xC2F0 0xC2F1 0xC2F3 0xC2F4 0xC2F6 0xC2F8 0xC2F9 0xC2FB 0xC2FC 0xC2FF 0xC300 0xC301 +0xC302 0xC308 0xC309 0xC30A 0xC30B 0xC30C 0xC30D 0xC30E 0xC311 0xC313 0xC314 0xC315 0xC316 0xC317 0xC318 0xC31B +0xC31C 0xC324 0xC325 0xC326 0xC327 0xC328 0xC329 0xC32A 0xC32B 0xC32C 0xC32D 0xC32E 0xC32F 0xC330 0xC331 0xC334 +0xC337 0xC338 0xC340 0xC341 0xC342 0xC343 0xC344 0xC345 0xC34C 0xC34D 0xC34E 0xC34F 0xC350 0xC353 0xC354 0xC35C +0xC35D 0xC35E 0xC35F 0xC360 0xC361 0xC362 0xC363 0xC364 0xC365 0xC366 0xC367 0xC368 0xC369 0xC36A 0xC36C 0xC36F +0xC370 0xC372 0xC378 0xC379 0xC37A 0xC37B 0xC37C 0xC37D 0xC382 0xC384 0xC385 0xC386 0xC387 0xC388 0xC38B 0xC38C +0xC394 0xC395 0xC396 0xC397 0xC398 0xC399 0xC39A 0xC39B 0xC39C 0xC39D 0xC39E 0xC39F 0xC3A0 0xC3A1 0xC3A4 0xC3A7 +0xC3A8 0xC3B0 0xC3B1 0xC3B2 0xC3B3 0xC3B4 0xC3B5 0xC3BC 0xC3BD 0xC3BE 0xC3BF 0xC3C0 0xC3C3 0xC3C4 0xC3CC 0xC3CD +0xC3CE 0xC3CF 0xC3D0 0xC3D1 0xC3D2 0xC3D3 0xC3D4 0xC3D5 0xC3D6 0xC3D7 0xC3D8 0xC3D9 0xC3DA 0xC3DC 0xC3DF 0xC3E0 +0xC3E2 0xC3E8 0xC3E9 0xC3EA 0xC3EB 0xC3EC 0xC3ED 0xC3F1 0xC3F4 0xC3F5 0xC3F8 0xC3FB 0xC3FC 0xC404 0xC405 0xC406 +0xC407 0xC408 0xC409 0xC40B 0xC410 0xC411 0xC414 0xC417 0xC418 0xC420 0xC421 0xC422 0xC423 0xC424 0xC425 0xC42C +0xC42D 0xC430 0xC433 0xC434 0xC43C 0xC43D 0xC43E 0xC43F 0xC440 0xC441 0xC448 0xC449 0xC44C 0xC44F 0xC450 0xC458 +0xC459 0xC45A 0xC45B 0xC45C 0xC45D 0xC464 0xC465 0xC468 0xC46B 0xC46C 0xC474 0xC475 0xC476 0xC477 0xC478 0xC479 +0xC47A 0xC47B 0xC47C 0xC47D 0xC47E 0xC47F 0xC480 0xC481 0xC484 0xC487 0xC488 0xC490 0xC491 0xC492 0xC493 0xC494 +0xC495 0xC49C 0xC49D 0xC4A0 0xC4A3 0xC4A4 0xC4AC 0xC4AD 0xC4AE 0xC4AF 0xC4B0 0xC4B1 0xC4B8 0xC4B9 0xC4BC 0xC4BF +0xC4C0 0xC4C8 0xC4C9 0xC4CA 0xC4CB 0xC4CC 0xC4CD 0xC4D3 0xC4D4 0xC4D5 0xC4D8 0xC4DB 0xC4DC 0xC4E4 0xC4E5 0xC4E6 +0xC4E7 0xC4E8 0xC4E9 0xC4F0 0xC4F1 0xC4F4 0xC4F7 0xC4F8 0xC4FA 0xC4FF 0xC500 0xC501 0xC502 0xC503 0xC504 0xC505 +0xC50C 0xC50D 0xC510 0xC514 0xC51C 0xC51D 0xC51E 0xC51F 0xC520 0xC521 0xC528 0xC529 0xC52B 0xC52C 0xC52F 0xC530 +0xC531 0xC538 0xC539 0xC53A 0xC53B 0xC53C 0xC53D 0xC53F 0xC540 0xC543 0xC544 0xC545 0xC546 0xC547 0xC548 0xC549 +0xC54A 0xC54B 0xC54C 0xC54D 0xC54E 0xC54F 0xC550 0xC551 0xC552 0xC553 0xC554 0xC555 0xC556 0xC557 0xC558 0xC559 +0xC55A 0xC55B 0xC55C 0xC55D 0xC55E 0xC55F 0xC560 0xC561 0xC562 0xC563 0xC564 0xC565 0xC566 0xC567 0xC568 0xC569 +0xC56A 0xC56B 0xC56C 0xC56D 0xC56E 0xC56F 0xC570 0xC571 0xC572 0xC573 0xC574 0xC575 0xC576 0xC577 0xC578 0xC579 +0xC57A 0xC57B 0xC57C 0xC57D 0xC57E 0xC57F 0xC580 0xC581 0xC582 0xC583 0xC584 0xC585 0xC586 0xC587 0xC588 0xC589 +0xC58A 0xC58B 0xC58C 0xC58D 0xC58E 0xC58F 0xC590 0xC591 0xC592 0xC593 0xC594 0xC595 0xC596 0xC597 0xC598 0xC599 +0xC59A 0xC59B 0xC59C 0xC59D 0xC59E 0xC59F 0xC5A0 0xC5A1 0xC5A2 0xC5A3 0xC5A4 0xC5A5 0xC5A6 0xC5A7 0xC5A8 0xC5A9 +0xC5AA 0xC5AB 0xC5AC 0xC5AD 0xC5AE 0xC5AF 0xC5B0 0xC5B1 0xC5B2 0xC5B3 0xC5B4 0xC5B5 0xC5B6 0xC5B7 0xC5B8 0xC5B9 +0xC5BA 0xC5BB 0xC5BC 0xC5BD 0xC5BE 0xC5BF 0xC5C0 0xC5C1 0xC5C2 0xC5C3 0xC5C4 0xC5C5 0xC5C6 0xC5C7 0xC5C8 0xC5C9 +0xC5CA 0xC5CB 0xC5CC 0xC5CD 0xC5CE 0xC5CF 0xC5D0 0xC5D1 0xC5D4 0xC5D7 0xC5D8 0xC5E0 0xC5E1 0xC5E2 0xC5E3 0xC5E4 +0xC5E5 0xC5E6 0xC5E7 0xC5E8 0xC5E9 0xC5EA 0xC5EB 0xC5EC 0xC5ED 0xC5EE 0xC5EF 0xC5F0 0xC5F1 0xC5F2 0xC5F3 0xC5F4 +0xC5F5 0xC5F6 0xC5F7 0xC5F8 0xC5F9 0xC5FA 0xC5FB 0xC5FC 0xC5FD 0xC5FE 0xC5FF 0xC600 0xC601 0xC602 0xC603 0xC604 +0xC605 0xC606 0xC607 0xC608 0xC609 0xC60C 0xC60F 0xC610 0xC618 0xC619 0xC61A 0xC61B 0xC61C 0xC61D 0xC620 0xC624 +0xC625 0xC626 0xC628 0xC629 0xC62A 0xC62B 0xC62C 0xC62D 0xC62E 0xC62F 0xC630 0xC631 0xC632 0xC633 0xC634 0xC635 +0xC636 0xC637 0xC638 0xC639 0xC63A 0xC63B 0xC63C 0xC63D 0xC63E 0xC63F 0xC640 0xC641 0xC644 0xC647 0xC648 0xC64E +0xC650 0xC651 0xC652 0xC653 0xC654 0xC655 0xC658 0xC659 0xC65C 0xC65D 0xC660 0xC661 0xC662 0xC663 0xC664 0xC66C +0xC66D 0xC66E 0xC66F 0xC670 0xC671 0xC678 0xC679 0xC67C 0xC67F 0xC680 0xC682 0xC688 0xC689 0xC68A 0xC68B 0xC68C +0xC68D 0xC692 0xC694 0xC695 0xC698 0xC699 0xC69A 0xC69B 0xC69C 0xC69D 0xC6A4 0xC6A5 0xC6A6 0xC6A7 0xC6A8 0xC6A9 +0xC6AC 0xC6B0 0xC6B1 0xC6B2 0xC6B3 0xC6B4 0xC6B5 0xC6B6 0xC6B7 0xC6B8 0xC6B9 0xC6BA 0xC6BB 0xC6BC 0xC6BE 0xC6BF +0xC6C0 0xC6C1 0xC6C2 0xC6C3 0xC6C4 0xC6C5 0xC6C6 0xC6C7 0xC6C8 0xC6C9 0xC6CA 0xC6CB 0xC6CC 0xC6CD 0xC6D0 0xC6D1 +0xC6D2 0xC6D3 0xC6D4 0xC6D8 0xC6DC 0xC6DD 0xC6DE 0xC6DF 0xC6E0 0xC6E1 0xC6E4 0xC6E5 0xC6E8 0xC6E9 0xC6EC 0xC6EF +0xC6F0 0xC6F8 0xC6F9 0xC6FA 0xC6FB 0xC6FC 0xC6FD 0xC701 0xC704 0xC705 0xC708 0xC70B 0xC70C 0xC70E 0xC713 0xC714 +0xC715 0xC716 0xC717 0xC718 0xC719 0xC71C 0xC71D 0xC720 0xC721 0xC724 0xC727 0xC728 0xC730 0xC731 0xC732 0xC733 +0xC734 0xC735 0xC736 0xC737 0xC738 0xC739 0xC73C 0xC73D 0xC73E 0xC73F 0xC740 0xC741 0xC742 0xC743 0xC744 0xC745 +0xC746 0xC747 0xC748 0xC749 0xC74A 0xC74B 0xC74C 0xC74D 0xC74E 0xC74F 0xC750 0xC751 0xC752 0xC753 0xC754 0xC755 +0xC756 0xC757 0xC758 0xC759 0xC75C 0xC75F 0xC760 0xC766 0xC768 0xC769 0xC76A 0xC76B 0xC76C 0xC76D 0xC774 0xC775 +0xC776 0xC777 0xC778 0xC779 0xC77A 0xC77B 0xC77C 0xC77D 0xC77E 0xC77F 0xC780 0xC781 0xC782 0xC783 0xC784 0xC785 +0xC786 0xC787 0xC788 0xC789 0xC78A 0xC78B 0xC78C 0xC78D 0xC78E 0xC78F 0xC790 0xC791 0xC793 0xC794 0xC796 0xC797 +0xC798 0xC799 0xC79A 0xC7A0 0xC7A1 0xC7A2 0xC7A3 0xC7A4 0xC7A5 0xC7A6 0xC7A7 0xC7A9 0xC7AA 0xC7AB 0xC7AC 0xC7AD +0xC7B0 0xC7B2 0xC7B3 0xC7B4 0xC7BC 0xC7BD 0xC7BE 0xC7BF 0xC7C0 0xC7C1 0xC7C2 0xC7C8 0xC7C9 0xC7CC 0xC7CE 0xC7CF +0xC7D0 0xC7D8 0xC7D9 0xC7DA 0xC7DB 0xC7DC 0xC7DD 0xC7E4 0xC7E5 0xC7E8 0xC7EB 0xC7EC 0xC7F4 0xC7F5 0xC7F6 0xC7F7 +0xC7F8 0xC7F9 0xC800 0xC801 0xC802 0xC804 0xC806 0xC807 0xC808 0xC809 0xC80A 0xC80B 0xC810 0xC811 0xC812 0xC813 +0xC814 0xC815 0xC816 0xC819 0xC81B 0xC81C 0xC81D 0xC820 0xC823 0xC824 0xC82C 0xC82D 0xC82E 0xC82F 0xC830 0xC831 +0xC832 0xC836 0xC838 0xC839 0xC83C 0xC83F 0xC840 0xC841 0xC842 0xC843 0xC847 0xC848 0xC849 0xC84A 0xC84B 0xC84C +0xC84D 0xC84E 0xC851 0xC853 0xC854 0xC855 0xC858 0xC85C 0xC864 0xC865 0xC866 0xC867 0xC868 0xC869 0xC870 0xC871 +0xC874 0xC877 0xC878 0xC87A 0xC880 0xC881 0xC882 0xC883 0xC884 0xC885 0xC886 0xC887 0xC88B 0xC88C 0xC88D 0xC890 +0xC892 0xC893 0xC894 0xC895 0xC896 0xC89C 0xC89D 0xC89E 0xC89F 0xC8A0 0xC8A1 0xC8A6 0xC8A8 0xC8A9 0xC8AC 0xC8AF +0xC8B0 0xC8B8 0xC8B9 0xC8BA 0xC8BB 0xC8BC 0xC8BD 0xC8C4 0xC8C5 0xC8C8 0xC8CB 0xC8CC 0xC8D4 0xC8D5 0xC8D6 0xC8D7 +0xC8D8 0xC8D9 0xC8E0 0xC8E1 0xC8E4 0xC8E7 0xC8E8 0xC8F0 0xC8F1 0xC8F2 0xC8F3 0xC8F4 0xC8F5 0xC8FB 0xC8FC 0xC8FD +0xC900 0xC903 0xC904 0xC905 0xC906 0xC908 0xC90C 0xC90D 0xC90E 0xC90F 0xC910 0xC911 0xC917 0xC918 0xC919 0xC91C +0xC91F 0xC920 0xC928 0xC929 0xC92A 0xC92B 0xC92C 0xC92D 0xC934 0xC935 0xC938 0xC93B 0xC93C 0xC944 0xC945 0xC946 +0xC947 0xC948 0xC949 0xC950 0xC951 0xC954 0xC957 0xC958 0xC960 0xC961 0xC962 0xC963 0xC964 0xC965 0xC96C 0xC96D +0xC970 0xC974 0xC97C 0xC97D 0xC97E 0xC97F 0xC980 0xC981 0xC988 0xC989 0xC98C 0xC98F 0xC990 0xC991 0xC992 0xC994 +0xC998 0xC999 0xC99A 0xC99B 0xC99C 0xC99D 0xC99E 0xC9A4 0xC9A5 0xC9A8 0xC9AC 0xC9B4 0xC9B5 0xC9B6 0xC9B7 0xC9B8 +0xC9B9 0xC9C0 0xC9C1 0xC9C4 0xC9C7 0xC9C8 0xC9CA 0xC9CF 0xC9D0 0xC9D1 0xC9D2 0xC9D3 0xC9D4 0xC9D5 0xC9D6 0xC9D7 +0xC9D8 0xC9D9 0xC9DA 0xC9DB 0xC9DC 0xC9DD 0xC9DE 0xC9E0 0xC9E2 0xC9E3 0xC9E4 0xC9E7 0xC9E8 0xC9EC 0xC9ED 0xC9EE +0xC9EF 0xC9F0 0xC9F1 0xC9F2 0xC9F7 0xC9F8 0xC9F9 0xC9FA 0xC9FB 0xC9FC 0xC9FF 0xCA00 0xCA08 0xCA09 0xCA0A 0xCA0B +0xCA0C 0xCA0D 0xCA0E 0xCA0F 0xCA10 0xCA11 0xCA12 0xCA13 0xCA14 0xCA15 0xCA18 0xCA1A 0xCA1C 0xCA24 0xCA25 0xCA26 +0xCA27 0xCA28 0xCA29 0xCA2D 0xCA30 0xCA31 0xCA32 0xCA33 0xCA34 0xCA37 0xCA38 0xCA40 0xCA41 0xCA42 0xCA43 0xCA44 +0xCA45 0xCA46 0xCA47 0xCA48 0xCA49 0xCA4A 0xCA4B 0xCA4C 0xCA4D 0xCA50 0xCA53 0xCA54 0xCA57 0xCA58 0xCA5B 0xCA5C +0xCA5D 0xCA5E 0xCA5F 0xCA60 0xCA61 0xCA67 0xCA68 0xCA69 0xCA6A 0xCA6B 0xCA6C 0xCA6F 0xCA70 0xCA78 0xCA79 0xCA7A +0xCA7B 0xCA7C 0xCA7D 0xCA7E 0xCA7F 0xCA80 0xCA81 0xCA82 0xCA83 0xCA84 0xCA85 0xCA88 0xCA8B 0xCA8C 0xCA94 0xCA95 +0xCA96 0xCA97 0xCA98 0xCA99 0xCAA0 0xCAA1 0xCAA2 0xCAA3 0xCAA4 0xCAA7 0xCAA8 0xCAB0 0xCAB1 0xCAB2 0xCAB3 0xCAB4 +0xCAB5 0xCAB6 0xCAB7 0xCAB8 0xCAB9 0xCABA 0xCABB 0xCABC 0xCABD 0xCABE 0xCAC0 0xCAC3 0xCAC4 0xCAC6 0xCACC 0xCACD +0xCACE 0xCACF 0xCAD0 0xCAD1 0xCAD2 0xCAD3 0xCAD7 0xCAD8 0xCAD9 0xCADC 0xCADF 0xCAE0 0xCAE8 0xCAE9 0xCAEA 0xCAEB +0xCAEC 0xCAED 0xCAF4 0xCAF5 0xCAF8 0xCAFB 0xCAFC 0xCB08 0xCB10 0xCB11 0xCB14 0xCB17 0xCB18 0xCB20 0xCB21 0xCB22 +0xCB23 0xCB24 0xCB25 0xCB26 0xCB27 0xCB28 0xCB29 0xCB2A 0xCB2B 0xCB2C 0xCB2D 0xCB30 0xCB32 0xCB34 0xCB3C 0xCB3D +0xCB3F 0xCB40 0xCB41 0xCB48 0xCB49 0xCB4A 0xCB4C 0xCB4F 0xCB50 0xCB52 0xCB58 0xCB59 0xCB5A 0xCB5B 0xCB5C 0xCB5D +0xCB64 0xCB65 0xCB68 0xCB6B 0xCB6C 0xCB74 0xCB75 0xCB77 0xCB78 0xCB79 0xCB80 0xCB81 0xCB84 0xCB87 0xCB88 0xCB90 +0xCB91 0xCB92 0xCB93 0xCB94 0xCB95 0xCB9C 0xCB9D 0xCBA0 0xCBA3 0xCBA4 0xCBAC 0xCBAD 0xCBAF 0xCBB1 0xCBB8 0xCBB9 +0xCBBC 0xCBC0 0xCBC8 0xCBC9 0xCBCA 0xCBCB 0xCBCC 0xCBCD 0xCBD4 0xCBD5 0xCBD8 0xCBDB 0xCBDC 0xCBE4 0xCBE5 0xCBE6 +0xCBE7 0xCBE8 0xCBE9 0xCBEA 0xCBF0 0xCBF1 0xCBF4 0xCBF8 0xCC00 0xCC01 0xCC02 0xCC03 0xCC04 0xCC05 0xCC06 0xCC0C +0xCC0D 0xCC10 0xCC13 0xCC14 0xCC1C 0xCC1D 0xCC1E 0xCC1F 0xCC20 0xCC21 0xCC22 0xCC26 0xCC27 0xCC28 0xCC29 0xCC2C +0xCC2E 0xCC2F 0xCC30 0xCC31 0xCC38 0xCC39 0xCC3A 0xCC3B 0xCC3C 0xCC3D 0xCC3E 0xCC3F 0xCC42 0xCC44 0xCC45 0xCC48 +0xCC4B 0xCC4C 0xCC54 0xCC55 0xCC56 0xCC57 0xCC58 0xCC59 0xCC5B 0xCC5E 0xCC60 0xCC61 0xCC64 0xCC66 0xCC68 0xCC70 +0xCC71 0xCC72 0xCC73 0xCC74 0xCC75 0xCC7A 0xCC7C 0xCC7D 0xCC91 0xCC98 0xCC99 0xCC9C 0xCC9F 0xCCA0 0xCCA7 0xCCA8 +0xCCA9 0xCCAA 0xCCAB 0xCCAC 0xCCAD 0xCCAE 0xCCB2 0xCCB4 0xCCB5 0xCCB8 0xCCBB 0xCCBC 0xCCC3 0xCCC4 0xCCC5 0xCCC6 +0xCCC7 0xCCC8 0xCCC9 0xCCCA 0xCCD0 0xCCD1 0xCCD4 0xCCD7 0xCCD8 0xCCE0 0xCCE1 0xCCE2 0xCCE3 0xCCE4 0xCCE5 0xCCEC +0xCCED 0xCCF0 0xCCF4 0xCCFC 0xCCFD 0xCCFE 0xCCFF 0xCD00 0xCD01 0xCD08 0xCD09 0xCD0C 0xCD0F 0xCD10 0xCD18 0xCD19 +0xCD1A 0xCD1B 0xCD1C 0xCD1D 0xCD23 0xCD24 0xCD25 0xCD28 0xCD2B 0xCD2C 0xCD34 0xCD35 0xCD36 0xCD37 0xCD38 0xCD39 +0xCD40 0xCD44 0xCD50 0xCD51 0xCD52 0xCD53 0xCD54 0xCD55 0xCD5C 0xCD5D 0xCD60 0xCD63 0xCD64 0xCD6C 0xCD6D 0xCD6E +0xCD6F 0xCD70 0xCD71 0xCD78 0xCD79 0xCD7C 0xCD80 0xCD88 0xCD89 0xCD8A 0xCD8B 0xCD8C 0xCD8D 0xCD94 0xCD95 0xCD98 +0xCD9B 0xCD9C 0xCDA4 0xCDA5 0xCDA6 0xCDA7 0xCDA8 0xCDA9 0xCDB0 0xCDB1 0xCDB4 0xCDB7 0xCDB8 0xCDC0 0xCDC1 0xCDC2 +0xCDC3 0xCDC4 0xCDC5 0xCDCC 0xCDCD 0xCDD0 0xCDD4 0xCDDC 0xCDDD 0xCDDE 0xCDDF 0xCDE0 0xCDE1 0xCDE8 0xCDE9 0xCDEC +0xCDEF 0xCDF0 0xCDF8 0xCDF9 0xCDFA 0xCDFB 0xCDFC 0xCDFD 0xCE04 0xCE05 0xCE08 0xCE0C 0xCE14 0xCE15 0xCE16 0xCE17 +0xCE18 0xCE19 0xCE20 0xCE21 0xCE24 0xCE27 0xCE28 0xCE29 0xCE2C 0xCE30 0xCE31 0xCE32 0xCE33 0xCE34 0xCE35 0xCE3C +0xCE3D 0xCE40 0xCE44 0xCE4C 0xCE4D 0xCE4E 0xCE4F 0xCE50 0xCE51 0xCE58 0xCE59 0xCE5C 0xCE5F 0xCE60 0xCE61 0xCE62 +0xCE68 0xCE69 0xCE6A 0xCE6B 0xCE6C 0xCE6D 0xCE6E 0xCE70 0xCE72 0xCE74 0xCE75 0xCE78 0xCE7B 0xCE7C 0xCE84 0xCE85 +0xCE86 0xCE87 0xCE88 0xCE89 0xCE8D 0xCE8E 0xCE90 0xCE91 0xCE94 0xCE97 0xCE98 0xCEA0 0xCEA1 0xCEA2 0xCEA3 0xCEA4 +0xCEA5 0xCEA8 0xCEA9 0xCEAA 0xCEAC 0xCEAD 0xCEB0 0xCEB4 0xCEBC 0xCEBD 0xCEBE 0xCEBF 0xCEC0 0xCEC1 0xCEC4 0xCEC8 +0xCEC9 0xCECC 0xCED8 0xCED9 0xCEDA 0xCEDB 0xCEDC 0xCEDD 0xCEE4 0xCEE5 0xCEE8 0xCEEB 0xCEEC 0xCEF4 0xCEF5 0xCEF6 +0xCEF7 0xCEF8 0xCEF9 0xCEFB 0xCEFD 0xCEFE 0xCF00 0xCF01 0xCF04 0xCF07 0xCF08 0xCF10 0xCF11 0xCF12 0xCF13 0xCF14 +0xCF15 0xCF18 0xCF19 0xCF1A 0xCF1C 0xCF1D 0xCF20 0xCF23 0xCF24 0xCF2C 0xCF2D 0xCF2E 0xCF2F 0xCF30 0xCF31 0xCF38 +0xCF39 0xCF3C 0xCF40 0xCF48 0xCF49 0xCF4A 0xCF4B 0xCF4C 0xCF4D 0xCF54 0xCF55 0xCF58 0xCF5B 0xCF5C 0xCF64 0xCF65 +0xCF66 0xCF67 0xCF68 0xCF69 0xCF6A 0xCF6E 0xCF70 0xCF71 0xCF74 0xCF78 0xCF80 0xCF81 0xCF82 0xCF83 0xCF84 0xCF85 +0xCF8C 0xCF8D 0xCF90 0xCF93 0xCF94 0xCF9C 0xCF9D 0xCF9E 0xCF9F 0xCFA0 0xCFA1 0xCFA8 0xCFA9 0xCFAC 0xCFB0 0xCFB8 +0xCFB9 0xCFBA 0xCFBB 0xCFBC 0xCFBD 0xCFC4 0xCFC5 0xCFC8 0xCFCC 0xCFD4 0xCFD5 0xCFD6 0xCFD7 0xCFD8 0xCFD9 0xCFE0 +0xCFE1 0xCFE4 0xCFE7 0xCFE8 0xCFF0 0xCFF1 0xCFF2 0xCFF3 0xCFF4 0xCFF5 0xCFFA 0xCFFC 0xCFFD 0xD000 0xD003 0xD004 +0xD00C 0xD00D 0xD00E 0xD00F 0xD010 0xD011 0xD018 0xD019 0xD01C 0xD020 0xD028 0xD029 0xD02A 0xD02B 0xD02C 0xD02D +0xD034 0xD035 0xD038 0xD03B 0xD03C 0xD044 0xD045 0xD046 0xD047 0xD048 0xD049 0xD050 0xD051 0xD054 0xD058 0xD060 +0xD061 0xD062 0xD063 0xD064 0xD065 0xD068 0xD06C 0xD06D 0xD070 0xD072 0xD074 0xD076 0xD07C 0xD07D 0xD07E 0xD07F +0xD080 0xD081 0xD084 0xD088 0xD089 0xD08C 0xD090 0xD098 0xD099 0xD09A 0xD09B 0xD09C 0xD09D 0xD0A4 0xD0A5 0xD0A8 +0xD0AB 0xD0AC 0xD0B4 0xD0B5 0xD0B6 0xD0B7 0xD0B8 0xD0B9 0xD0BE 0xD0C0 0xD0C1 0xD0C4 0xD0C7 0xD0C8 0xD0C9 0xD0CA +0xD0CF 0xD0D0 0xD0D1 0xD0D2 0xD0D3 0xD0D4 0xD0D5 0xD0DA 0xD0DC 0xD0DD 0xD0E0 0xD0E2 0xD0E3 0xD0E4 0xD0E5 0xD0EC +0xD0ED 0xD0EE 0xD0EF 0xD0F0 0xD0F1 0xD0F6 0xD0F8 0xD0F9 0xD0FC 0xD100 0xD108 0xD109 0xD10A 0xD10B 0xD10C 0xD10D +0xD114 0xD115 0xD118 0xD11A 0xD124 0xD125 0xD126 0xD127 0xD128 0xD129 0xD130 0xD131 0xD134 0xD137 0xD138 0xD139 +0xD13A 0xD13B 0xD140 0xD141 0xD142 0xD143 0xD144 0xD145 0xD14C 0xD14D 0xD150 0xD153 0xD154 0xD15C 0xD15D 0xD15E +0xD15F 0xD160 0xD161 0xD166 0xD168 0xD169 0xD16C 0xD16F 0xD170 0xD178 0xD179 0xD17A 0xD17B 0xD17C 0xD17D 0xD184 +0xD185 0xD188 0xD18C 0xD194 0xD195 0xD196 0xD197 0xD198 0xD199 0xD1A0 0xD1A1 0xD1A4 0xD1A7 0xD1A8 0xD1B0 0xD1B1 +0xD1B2 0xD1B3 0xD1B4 0xD1B5 0xD1B7 0xD1B8 0xD1B9 0xD1BA 0xD1BC 0xD1BD 0xD1C0 0xD1C4 0xD1CC 0xD1CD 0xD1CE 0xD1CF +0xD1D0 0xD1D1 0xD1D8 0xD1E8 0xD1E9 0xD1EA 0xD1EB 0xD1EC 0xD1ED 0xD1F4 0xD1F5 0xD1F8 0xD1FB 0xD1FC 0xD204 0xD205 +0xD206 0xD207 0xD208 0xD209 0xD210 0xD211 0xD214 0xD218 0xD220 0xD221 0xD222 0xD223 0xD224 0xD225 0xD22C 0xD22D +0xD230 0xD233 0xD234 0xD236 0xD23C 0xD23D 0xD23E 0xD23F 0xD240 0xD241 0xD248 0xD249 0xD24C 0xD24F 0xD250 0xD254 +0xD258 0xD259 0xD25A 0xD25B 0xD25C 0xD25D 0xD264 0xD265 0xD268 0xD26B 0xD26C 0xD274 0xD275 0xD276 0xD277 0xD278 +0xD279 0xD280 0xD281 0xD284 0xD287 0xD288 0xD290 0xD291 0xD292 0xD293 0xD294 0xD295 0xD29C 0xD29D 0xD2A0 0xD2A4 +0xD2AC 0xD2AD 0xD2AE 0xD2AF 0xD2B0 0xD2B1 0xD2B8 0xD2B9 0xD2BB 0xD2BC 0xD2BF 0xD2C0 0xD2C1 0xD2C2 0xD2C4 0xD2C8 +0xD2C9 0xD2CA 0xD2CB 0xD2CC 0xD2CD 0xD2D1 0xD2D4 0xD2D5 0xD2D8 0xD2DC 0xD2E0 0xD2E4 0xD2E5 0xD2E6 0xD2E7 0xD2E8 +0xD2E9 0xD2F0 0xD2F1 0xD2F4 0xD2F7 0xD2F8 0xD300 0xD301 0xD302 0xD303 0xD304 0xD305 0xD308 0xD30A 0xD30C 0xD30D +0xD30E 0xD310 0xD311 0xD313 0xD314 0xD316 0xD31C 0xD31D 0xD31E 0xD31F 0xD320 0xD321 0xD323 0xD324 0xD325 0xD326 +0xD328 0xD329 0xD32C 0xD32F 0xD330 0xD338 0xD339 0xD33A 0xD33B 0xD33C 0xD33D 0xD341 0xD344 0xD345 0xD348 0xD34C +0xD354 0xD355 0xD356 0xD357 0xD358 0xD359 0xD35D 0xD360 0xD361 0xD364 0xD370 0xD371 0xD372 0xD373 0xD374 0xD375 +0xD37C 0xD37D 0xD380 0xD383 0xD384 0xD38C 0xD38D 0xD38E 0xD38F 0xD390 0xD391 0xD395 0xD396 0xD398 0xD399 0xD39C +0xD39F 0xD3A0 0xD3A8 0xD3A9 0xD3AA 0xD3AB 0xD3AC 0xD3AD 0xD3B2 0xD3B4 0xD3B5 0xD3B8 0xD3B9 0xD3BB 0xD3BC 0xD3C4 +0xD3C5 0xD3C6 0xD3C7 0xD3C8 0xD3C9 0xD3D0 0xD3D1 0xD3D4 0xD3D7 0xD3D8 0xD3E0 0xD3E1 0xD3E2 0xD3E3 0xD3E4 0xD3E5 +0xD3EC 0xD3ED 0xD3EE 0xD3F0 0xD3F3 0xD3F4 0xD3FC 0xD3FD 0xD3FE 0xD3FF 0xD400 0xD401 0xD404 0xD405 0xD406 0xD408 +0xD409 0xD40C 0xD410 0xD418 0xD419 0xD41A 0xD41B 0xD41C 0xD41D 0xD424 0xD440 0xD441 0xD444 0xD448 0xD450 0xD451 +0xD452 0xD453 0xD454 0xD455 0xD45C 0xD45D 0xD460 0xD463 0xD464 0xD46C 0xD46D 0xD46E 0xD46F 0xD470 0xD471 0xD478 +0xD479 0xD47C 0xD47F 0xD480 0xD482 0xD488 0xD489 0xD48A 0xD48B 0xD48C 0xD48D 0xD494 0xD495 0xD498 0xD49B 0xD49C +0xD4A4 0xD4A5 0xD4A6 0xD4A7 0xD4A8 0xD4A9 0xD4B0 0xD4B1 0xD4B4 0xD4B8 0xD4C0 0xD4C1 0xD4C2 0xD4C3 0xD4C4 0xD4C5 +0xD4CC 0xD4CD 0xD4D0 0xD4D4 0xD4DC 0xD4DD 0xD4DE 0xD4DF 0xD4E0 0xD4E1 0xD4E8 0xD4E9 0xD4EC 0xD4EF 0xD4F0 0xD4F8 +0xD4F9 0xD4FA 0xD4FB 0xD4FC 0xD4FD 0xD504 0xD505 0xD508 0xD50B 0xD50C 0xD510 0xD514 0xD515 0xD516 0xD517 0xD518 +0xD519 0xD520 0xD521 0xD524 0xD528 0xD530 0xD531 0xD532 0xD533 0xD534 0xD535 0xD53C 0xD53D 0xD540 0xD543 0xD544 +0xD54C 0xD54D 0xD54E 0xD54F 0xD550 0xD551 0xD555 0xD556 0xD558 0xD559 0xD55C 0xD55F 0xD560 0xD561 0xD563 0xD564 +0xD565 0xD567 0xD568 0xD569 0xD56A 0xD56B 0xD56C 0xD56D 0xD56E 0xD570 0xD571 0xD572 0xD573 0xD574 0xD575 0xD578 +0xD57B 0xD57C 0xD584 0xD585 0xD586 0xD587 0xD588 0xD589 0xD58B 0xD58D 0xD58F 0xD590 0xD591 0xD594 0xD598 0xD5A0 +0xD5A1 0xD5A2 0xD5A3 0xD5A4 0xD5A5 0xD5AB 0xD5AC 0xD5AD 0xD5BC 0xD5BD 0xD5BE 0xD5BF 0xD5C0 0xD5C1 0xD5C8 0xD5C9 +0xD5CC 0xD5CF 0xD5D0 0xD5D1 0xD5D2 0xD5D5 0xD5D7 0xD5D8 0xD5D9 0xD5DA 0xD5DB 0xD5DC 0xD5DD 0xD5E0 0xD5E1 0xD5E2 +0xD5E3 0xD5E4 0xD5E5 0xD5E8 0xD5EB 0xD5EC 0xD5F4 0xD5F5 0xD5F6 0xD5F7 0xD5F8 0xD5F9 0xD5FE 0xD5FF 0xD600 0xD601 +0xD604 0xD607 0xD608 0xD610 0xD611 0xD612 0xD613 0xD614 0xD615 0xD61C 0xD61D 0xD620 0xD624 0xD62C 0xD62D 0xD62E +0xD62F 0xD630 0xD631 0xD638 0xD639 0xD63B 0xD63C 0xD63D 0xD63F 0xD640 0xD641 0xD644 0xD645 0xD647 0xD648 0xD649 +0xD64A 0xD64B 0xD64C 0xD64D 0xD651 0xD654 0xD655 0xD658 0xD65B 0xD65C 0xD660 0xD664 0xD665 0xD666 0xD667 0xD668 +0xD669 0xD670 0xD671 0xD674 0xD677 0xD678 0xD680 0xD681 0xD682 0xD683 0xD684 0xD685 0xD68C 0xD68D 0xD690 0xD693 +0xD694 0xD69C 0xD69D 0xD69E 0xD69F 0xD6A0 0xD6A1 0xD6A8 0xD6A9 0xD6AC 0xD6AF 0xD6B0 0xD6B8 0xD6B9 0xD6BA 0xD6BB +0xD6BC 0xD6BD 0xD6C4 0xD6C5 0xD6C8 0xD6CB 0xD6CC 0xD6CD 0xD6CE 0xD6D0 0xD6D1 0xD6D2 0xD6D3 0xD6D4 0xD6D5 0xD6D6 +0xD6D7 0xD6D8 0xD6D9 0xD6DC 0xD6DD 0xD6E0 0xD6E1 0xD6E4 0xD6E8 0xD6F0 0xD6F1 0xD6F2 0xD6F3 0xD6F4 0xD6F5 0xD6FC +0xD6FD 0xD700 0xD703 0xD704 0xD70C 0xD70D 0xD70E 0xD70F 0xD710 0xD711 0xD718 0xD719 0xD71C 0xD71F 0xD720 0xD728 +0xD729 0xD72A 0xD72B 0xD72C 0xD72D 0xD734 0xD735 0xD738 0xD73A 0xD73B 0xD73C 0xD743 0xD744 0xD745 0xD746 0xD747 +0xD748 0xD749 0xD74D 0xD750 0xD751 0xD752 0xD754 0xD755 0xD756 0xD757 0xD758 0xD759 0xD75D 0xD75F 0xD760 0xD761 +0xD762 0xD763 0xD764 0xD765 0xD768 0xD769 0xD76A 0xD76B 0xD76C 0xD76D 0xD770 0xD773 0xD774 0xD77C 0xD77D 0xD77E +0xD77F 0xD780 0xD781 0xD788 0xD789 0xD78A 0xD78B 0xD78C 0xD78D 0xD78E 0xD78F 0xD790 0xD797 0xD798 0xD799 0xD79A +0xD79B 0xD79C 0xD79D 0xD79E 0xD7A0 0xD7A1 0xD7A2 0xD7A3 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE007 +0xE008 0xE009 0xE00A 0xE00B 0xE00C 0xE00D 0xE020 0xE021 0xE022 0xE023 0xE030 0xE031 0xE032 0xE033 0xE040 0xE041 +0xE042 0xE043 0xE044 0xE045 0xE050 0xE051 0xE052 0xE053 0xE054 0xE055 0xE056 0xE057 0xE058 0xE059 0xE05A 0xE05B +0xE05C 0xE05D 0xE070 0xE071 0xE072 0xE073 0xE080 0xE081 0xE082 0xE083 0xE090 0xE091 0xE092 0xE093 0xE094 0xE095 +0xE09D 0xE0A0 0xE0A1 0xE0A2 0xE0A3 0xE0B0 0xE0B1 0xE0B2 0xE0B3 0xF000 0xF001 0xF007 0xF020 0xF021 0xF022 0xF023 +0xF024 0xF025 0xF026 0xF027 0xF028 0xF029 0xF02A 0xF030 0xF031 0xF032 0xF033 0xF034 0xF035 0xF036 0xF037 0xF038 +0xF039 0xF03A 0xF03B 0xF03C 0xF03D 0xF8FF 0xFE10 0xFE11 0xFE12 0xFE13 0xFE14 0xFE15 0xFE16 0xFE17 0xFE18 0xFE19 +0xFE30 0xFE31 0xFE33 0xFE34 0xFE35 0xFE36 0xFE37 0xFE38 0xFE39 0xFE3A 0xFE3B 0xFE3C 0xFE3D 0xFE3E 0xFE3F 0xFE40 +0xFE41 0xFE42 0xFE43 0xFE44 0xFE49 0xFE4A 0xFE4B 0xFE4C 0xFE4D 0xFE4E 0xFE4F 0xFE50 0xFE51 0xFE52 0xFE54 0xFE55 +0xFE56 0xFE57 0xFE59 0xFE5A 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0xFE5F 0xFE60 0xFE61 0xFE62 0xFE63 0xFE64 0xFE65 0xFE66 +0xFE68 0xFE69 0xFE6A 0xFE6B 0xFF01 0xFF02 0xFF03 0xFF04 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C +0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C +0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C +0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C +0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C +0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C +0xFF5D 0xFF5E 0xFF5F 0xFF60 0xFF61 0xFF62 0xFF63 0xFF64 0xFF65 0xFF66 0xFF67 0xFF68 0xFF69 0xFF6A 0xFF6B 0xFF6C +0xFF6D 0xFF6E 0xFF6F 0xFF70 0xFF71 0xFF72 0xFF73 0xFF74 0xFF75 0xFF76 0xFF77 0xFF78 0xFF79 0xFF7A 0xFF7B 0xFF7C +0xFF7D 0xFF7E 0xFF7F 0xFF80 0xFF81 0xFF82 0xFF83 0xFF84 0xFF85 0xFF86 0xFF87 0xFF88 0xFF89 0xFF8A 0xFF8B 0xFF8C +0xFF8D 0xFF8E 0xFF8F 0xFF90 0xFF91 0xFF92 0xFF93 0xFF94 0xFF95 0xFF96 0xFF97 0xFF98 0xFF99 0xFF9A 0xFF9B 0xFF9C +0xFF9D 0xFF9E 0xFF9F 0xFFE0 0xFFE1 0xFFE2 0xFFE3 0xFFE4 0xFFE5 0xFFE9 0xFFEB 0xFFFC 0xFFFD 0xFFFE diff --git a/resources/fonts/fusion/font_fusion_ja_8x8.frf b/resources/fonts/fusion/font_fusion_ja_8x8.frf new file mode 100644 index 000000000..da8314fbd Binary files /dev/null and b/resources/fonts/fusion/font_fusion_ja_8x8.frf differ diff --git a/resources/fonts/fusion/font_fusion_ja_8x8.pbm b/resources/fonts/fusion/font_fusion_ja_8x8.pbm new file mode 100644 index 000000000..9fe2c7898 Binary files /dev/null and b/resources/fonts/fusion/font_fusion_ja_8x8.pbm differ diff --git a/resources/fonts/fusion/font_fusion_ja_8x8.txt b/resources/fonts/fusion/font_fusion_ja_8x8.txt new file mode 100644 index 000000000..cd88777dd --- /dev/null +++ b/resources/fonts/fusion/font_fusion_ja_8x8.txt @@ -0,0 +1,1379 @@ +0x0020 0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F +0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F +0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F +0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F +0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F +0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E 0x00A1 +0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00AF 0x00B0 0x00B1 0x00B2 +0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00B8 0x00B9 0x00BA 0x00BB 0x00BC 0x00BD 0x00BE 0x00BF 0x00C0 0x00C1 0x00C2 +0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 +0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 +0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 +0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0100 0x0101 0x0102 +0x0103 0x0104 0x0105 0x0106 0x0107 0x0108 0x0109 0x010A 0x010B 0x010C 0x010D 0x010E 0x010F 0x0110 0x0111 0x0112 +0x0113 0x0114 0x0115 0x0116 0x0117 0x0118 0x0119 0x011A 0x011B 0x011C 0x011D 0x011E 0x011F 0x0120 0x0121 0x0122 +0x0123 0x0124 0x0125 0x0126 0x0127 0x0128 0x0129 0x012A 0x012B 0x012C 0x012D 0x012E 0x012F 0x0130 0x0131 0x0132 +0x0133 0x0134 0x0135 0x0136 0x0137 0x0138 0x0139 0x013A 0x013B 0x013C 0x013D 0x013E 0x013F 0x0140 0x0141 0x0142 +0x0143 0x0144 0x0145 0x0146 0x0147 0x0148 0x0149 0x014A 0x014B 0x014C 0x014D 0x014E 0x014F 0x0150 0x0151 0x0152 +0x0153 0x0154 0x0155 0x0156 0x0157 0x0158 0x0159 0x015A 0x015B 0x015C 0x015D 0x015E 0x015F 0x0160 0x0161 0x0162 +0x0163 0x0164 0x0165 0x0166 0x0167 0x0168 0x0169 0x016A 0x016B 0x016C 0x016D 0x016E 0x016F 0x0170 0x0171 0x0172 +0x0173 0x0174 0x0175 0x0176 0x0177 0x0178 0x0179 0x017A 0x017B 0x017C 0x017D 0x017E 0x017F 0x0192 0x0197 0x01A0 +0x01A1 0x01AC 0x01AF 0x01B0 0x01C0 0x01C1 0x01C2 0x01C3 0x01CD 0x01CE 0x01CF 0x01D0 0x01D1 0x01D2 0x01D3 0x01D4 +0x01D5 0x01D6 0x01D7 0x01D8 0x01D9 0x01DA 0x01DB 0x01DC 0x01DE 0x01DF 0x01E0 0x01E1 0x01E2 0x01E3 0x01E6 0x01E7 +0x01E8 0x01E9 0x01EA 0x01EB 0x01EC 0x01ED 0x01F0 0x01F4 0x01F5 0x01F8 0x01F9 0x01FA 0x01FB 0x01FC 0x01FD 0x01FE +0x01FF 0x0218 0x0219 0x021A 0x021B 0x021E 0x021F 0x0221 0x0226 0x0227 0x0228 0x0229 0x022A 0x022B 0x022C 0x022D +0x022E 0x022F 0x0230 0x0231 0x0232 0x0233 0x0235 0x0236 0x0237 0x0244 0x2010 0x2011 0x2012 0x2013 0x2014 0x2015 +0x2016 0x2017 0x2018 0x2019 0x201A 0x201C 0x201D 0x201E 0x2020 0x2021 0x2022 0x2023 0x2025 0x2026 0x2027 0x2030 +0x2031 0x2032 0x2033 0x2034 0x2035 0x2037 0x2038 0x2039 0x203A 0x203B 0x203C 0x203E 0x203F 0x2044 0x2103 0x2109 +0x2160 0x2161 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 0x216A 0x216B 0x2170 0x2171 0x2172 0x2173 +0x2174 0x2175 0x2176 0x2177 0x2178 0x2179 0x2181 0x2182 0x2190 0x2191 0x2192 0x2193 0x2194 0x2195 0x2196 0x2197 +0x2198 0x2199 0x219A 0x219B 0x21BA 0x21BB 0x21D0 0x21D1 0x21D2 0x21D3 0x21D4 0x21D5 0x21D6 0x21D7 0x21D8 0x21D9 +0x21DA 0x21DB 0x21E0 0x21E1 0x21E2 0x21E3 0x21E4 0x21E5 0x21E6 0x21E7 0x21E8 0x21E9 0x21EA 0x21EB 0x21EC 0x21ED +0x21EE 0x21EF 0x21F0 0x21F1 0x21F2 0x21F3 0x21FD 0x21FE 0x21FF 0x2200 0x2202 0x2203 0x2207 0x2208 0x220B 0x2211 +0x2212 0x221A 0x221D 0x221E 0x221F 0x2220 0x2225 0x2227 0x2228 0x2229 0x222A 0x222B 0x222C 0x222E 0x2234 0x2235 +0x223D 0x2252 0x2260 0x2261 0x2266 0x2267 0x226A 0x226B 0x2282 0x2283 0x2286 0x2287 0x22A5 0x22BF 0x2460 0x2461 +0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 0x246A 0x246B 0x246C 0x246D 0x246E 0x246F 0x2470 0x2471 +0x2472 0x2473 0x2500 0x2501 0x2502 0x2503 0x2504 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C 0x250D +0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C 0x251D +0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C 0x252D +0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C 0x253D +0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0x254C 0x254D +0x254E 0x254F 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D +0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x256D +0x256E 0x256F 0x2570 0x2571 0x2572 0x2573 0x2574 0x2575 0x2576 0x2577 0x2578 0x2579 0x257A 0x257B 0x257C 0x257D +0x257E 0x257F 0x2580 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 0x2589 0x258A 0x258B 0x258C 0x258D +0x258E 0x258F 0x2590 0x2591 0x2592 0x2593 0x2594 0x2595 0x2596 0x2597 0x2598 0x2599 0x259A 0x259B 0x259C 0x259D +0x259E 0x259F 0x25A0 0x25A1 0x25A2 0x25A3 0x25A4 0x25A5 0x25A6 0x25A7 0x25A8 0x25A9 0x25AA 0x25AB 0x25AC 0x25AD +0x25AE 0x25AF 0x25B0 0x25B1 0x25B2 0x25B3 0x25B4 0x25B5 0x25B6 0x25B7 0x25B8 0x25B9 0x25BA 0x25BB 0x25BC 0x25BD +0x25BE 0x25BF 0x25C0 0x25C1 0x25C2 0x25C3 0x25C4 0x25C5 0x25C6 0x25C7 0x25C8 0x25C9 0x25CA 0x25CB 0x25CC 0x25CD +0x25CE 0x25CF 0x25D0 0x25D1 0x25D2 0x25D3 0x25D4 0x25D5 0x25D6 0x25D7 0x25D8 0x25D9 0x25DA 0x25DB 0x25DC 0x25DD +0x25DE 0x25DF 0x25E0 0x25E1 0x25E2 0x25E3 0x25E4 0x25E5 0x25E6 0x25E7 0x25E8 0x25E9 0x25EA 0x25EB 0x25EC 0x25ED +0x25EE 0x25EF 0x25F0 0x25F1 0x25F2 0x25F3 0x25F4 0x25F5 0x25F6 0x25F7 0x25F8 0x25F9 0x25FA 0x25FB 0x25FC 0x25FD +0x25FE 0x25FF 0x2600 0x2602 0x2604 0x2605 0x2606 0x2609 0x260A 0x260B 0x260C 0x260D 0x260E 0x260F 0x2616 0x2617 +0x262D 0x262E 0x262F 0x2630 0x2631 0x2632 0x2633 0x2634 0x2635 0x2636 0x2637 0x2639 0x263A 0x263B 0x263C 0x263D +0x263E 0x2640 0x2641 0x2642 0x2660 0x2661 0x2662 0x2663 0x2664 0x2665 0x2666 0x2667 0x2668 0x2669 0x266A 0x266B +0x266C 0x266D 0x266E 0x266F 0x2680 0x2681 0x2682 0x2683 0x2684 0x2685 0x2686 0x2687 0x2688 0x2689 0x268A 0x268B +0x268C 0x268D 0x268E 0x268F 0x2694 0x2698 0x2699 0x26AA 0x26AB 0x26AC 0x26C9 0x26CA 0x26F6 0x2800 0x2801 0x2802 +0x2803 0x2804 0x2805 0x2806 0x2807 0x2808 0x2809 0x280A 0x280B 0x280C 0x280D 0x280E 0x280F 0x2810 0x2811 0x2812 +0x2813 0x2814 0x2815 0x2816 0x2817 0x2818 0x2819 0x281A 0x281B 0x281C 0x281D 0x281E 0x281F 0x2820 0x2821 0x2822 +0x2823 0x2824 0x2825 0x2826 0x2827 0x2828 0x2829 0x282A 0x282B 0x282C 0x282D 0x282E 0x282F 0x2830 0x2831 0x2832 +0x2833 0x2834 0x2835 0x2836 0x2837 0x2838 0x2839 0x283A 0x283B 0x283C 0x283D 0x283E 0x283F 0x2840 0x2841 0x2842 +0x2843 0x2844 0x2845 0x2846 0x2847 0x2848 0x2849 0x284A 0x284B 0x284C 0x284D 0x284E 0x284F 0x2850 0x2851 0x2852 +0x2853 0x2854 0x2855 0x2856 0x2857 0x2858 0x2859 0x285A 0x285B 0x285C 0x285D 0x285E 0x285F 0x2860 0x2861 0x2862 +0x2863 0x2864 0x2865 0x2866 0x2867 0x2868 0x2869 0x286A 0x286B 0x286C 0x286D 0x286E 0x286F 0x2870 0x2871 0x2872 +0x2873 0x2874 0x2875 0x2876 0x2877 0x2878 0x2879 0x287A 0x287B 0x287C 0x287D 0x287E 0x287F 0x2880 0x2881 0x2882 +0x2883 0x2884 0x2885 0x2886 0x2887 0x2888 0x2889 0x288A 0x288B 0x288C 0x288D 0x288E 0x288F 0x2890 0x2891 0x2892 +0x2893 0x2894 0x2895 0x2896 0x2897 0x2898 0x2899 0x289A 0x289B 0x289C 0x289D 0x289E 0x289F 0x28A0 0x28A1 0x28A2 +0x28A3 0x28A4 0x28A5 0x28A6 0x28A7 0x28A8 0x28A9 0x28AA 0x28AB 0x28AC 0x28AD 0x28AE 0x28AF 0x28B0 0x28B1 0x28B2 +0x28B3 0x28B4 0x28B5 0x28B6 0x28B7 0x28B8 0x28B9 0x28BA 0x28BB 0x28BC 0x28BD 0x28BE 0x28BF 0x28C0 0x28C1 0x28C2 +0x28C3 0x28C4 0x28C5 0x28C6 0x28C7 0x28C8 0x28C9 0x28CA 0x28CB 0x28CC 0x28CD 0x28CE 0x28CF 0x28D0 0x28D1 0x28D2 +0x28D3 0x28D4 0x28D5 0x28D6 0x28D7 0x28D8 0x28D9 0x28DA 0x28DB 0x28DC 0x28DD 0x28DE 0x28DF 0x28E0 0x28E1 0x28E2 +0x28E3 0x28E4 0x28E5 0x28E6 0x28E7 0x28E8 0x28E9 0x28EA 0x28EB 0x28EC 0x28ED 0x28EE 0x28EF 0x28F0 0x28F1 0x28F2 +0x28F3 0x28F4 0x28F5 0x28F6 0x28F7 0x28F8 0x28F9 0x28FA 0x28FB 0x28FC 0x28FD 0x28FE 0x28FF 0x3000 0x3001 0x3002 +0x3003 0x3004 0x3005 0x3006 0x3007 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0x3012 +0x3013 0x3014 0x3015 0x3016 0x3017 0x3018 0x3019 0x301A 0x301B 0x301C 0x301D 0x301E 0x301F 0x3020 0x3021 0x3022 +0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 0x3029 0x3036 0x3037 0x3038 0x3039 0x303A 0x303C 0x303E 0x303F 0x3041 +0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 +0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 +0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 +0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 +0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 +0x3092 0x3093 0x309B 0x309C 0x309D 0x309E 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA +0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA +0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA +0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA +0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA +0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x30FB 0x30FC 0x30FD 0x30FE +0x3105 0x3106 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 +0x3115 0x3116 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 +0x3125 0x3126 0x3127 0x3128 0x3129 0x312A 0x312B 0x312C 0x312D 0x312E 0x312F 0x3131 0x3132 0x3133 0x3134 0x3135 +0x3136 0x3137 0x3138 0x3139 0x313A 0x313B 0x313C 0x313D 0x313E 0x313F 0x3140 0x3141 0x3142 0x3143 0x3144 0x3145 +0x3146 0x3147 0x3148 0x3149 0x314A 0x314B 0x314C 0x314D 0x314E 0x314F 0x3150 0x3151 0x3152 0x3153 0x3154 0x3155 +0x3156 0x3157 0x3158 0x3159 0x315A 0x315B 0x315C 0x315D 0x315E 0x315F 0x3160 0x3161 0x3162 0x3163 0x3164 0x3220 +0x3221 0x3222 0x3223 0x3224 0x3225 0x3226 0x3227 0x3228 0x3229 0x3231 0x3232 0x3239 0x3268 0x3280 0x3281 0x3282 +0x3283 0x3284 0x3285 0x3286 0x3287 0x3288 0x3289 0x32A3 0x32A4 0x32A5 0x32A6 0x32A7 0x32A8 0x32FF 0x4E00 0x4E01 +0x4E02 0x4E03 0x4E04 0x4E05 0x4E06 0x4E07 0x4E08 0x4E09 0x4E0A 0x4E0B 0x4E0C 0x4E0D 0x4E0E 0x4E0F 0x4E10 0x4E11 +0x4E12 0x4E13 0x4E14 0x4E15 0x4E16 0x4E17 0x4E18 0x4E19 0x4E1A 0x4E1B 0x4E1C 0x4E1D 0x4E1E 0x4E1F 0x4E20 0x4E21 +0x4E22 0x4E23 0x4E24 0x4E25 0x4E26 0x4E27 0x4E28 0x4E29 0x4E2A 0x4E2B 0x4E2C 0x4E2D 0x4E2E 0x4E2F 0x4E30 0x4E31 +0x4E32 0x4E33 0x4E34 0x4E35 0x4E36 0x4E37 0x4E38 0x4E39 0x4E3A 0x4E3B 0x4E3C 0x4E3D 0x4E3E 0x4E3F 0x4E40 0x4E41 +0x4E42 0x4E43 0x4E44 0x4E45 0x4E46 0x4E47 0x4E48 0x4E49 0x4E4A 0x4E4B 0x4E4C 0x4E4D 0x4E4E 0x4E4F 0x4E50 0x4E51 +0x4E52 0x4E53 0x4E54 0x4E55 0x4E56 0x4E57 0x4E58 0x4E59 0x4E5A 0x4E5B 0x4E5C 0x4E5D 0x4E5E 0x4E5F 0x4E60 0x4E61 +0x4E62 0x4E63 0x4E64 0x4E65 0x4E66 0x4E67 0x4E68 0x4E69 0x4E6A 0x4E6B 0x4E6C 0x4E6D 0x4E6E 0x4E6F 0x4E70 0x4E71 +0x4E72 0x4E73 0x4E74 0x4E75 0x4E76 0x4E77 0x4E78 0x4E79 0x4E7A 0x4E7B 0x4E7C 0x4E7D 0x4E7E 0x4E7F 0x4E80 0x4E81 +0x4E82 0x4E83 0x4E84 0x4E85 0x4E86 0x4E87 0x4E88 0x4E89 0x4E8A 0x4E8B 0x4E8C 0x4E8D 0x4E8E 0x4E8F 0x4E90 0x4E91 +0x4E92 0x4E93 0x4E94 0x4E95 0x4E96 0x4E97 0x4E98 0x4E99 0x4E9A 0x4E9B 0x4E9C 0x4E9D 0x4E9E 0x4E9F 0x4EA0 0x4EA1 +0x4EA2 0x4EA3 0x4EA4 0x4EA5 0x4EA6 0x4EA7 0x4EA8 0x4EA9 0x4EAA 0x4EAB 0x4EAC 0x4EAD 0x4EAE 0x4EAF 0x4EB0 0x4EB1 +0x4EB2 0x4EB3 0x4EB4 0x4EB5 0x4EB6 0x4EB7 0x4EB8 0x4EB9 0x4EBA 0x4EBB 0x4EBC 0x4EBD 0x4EBE 0x4EBF 0x4EC0 0x4EC1 +0x4EC2 0x4EC3 0x4EC4 0x4EC5 0x4EC6 0x4EC7 0x4EC8 0x4EC9 0x4ECA 0x4ECB 0x4ECC 0x4ECD 0x4ECE 0x4ECF 0x4ED0 0x4ED1 +0x4ED2 0x4ED3 0x4ED4 0x4ED5 0x4ED6 0x4ED7 0x4ED8 0x4ED9 0x4EDA 0x4EDB 0x4EDC 0x4EDD 0x4EDE 0x4EDF 0x4EE0 0x4EE1 +0x4EE2 0x4EE3 0x4EE4 0x4EE5 0x4EE6 0x4EE7 0x4EE8 0x4EE9 0x4EEA 0x4EEB 0x4EEC 0x4EED 0x4EEE 0x4EEF 0x4EF0 0x4EF1 +0x4EF2 0x4EF3 0x4EF4 0x4EF5 0x4EF6 0x4EF7 0x4EF8 0x4EF9 0x4EFA 0x4EFB 0x4EFC 0x4EFD 0x4EFE 0x4EFF 0x4F00 0x4F01 +0x4F02 0x4F03 0x4F04 0x4F05 0x4F06 0x4F07 0x4F08 0x4F09 0x4F0A 0x4F0B 0x4F0C 0x4F0D 0x4F0E 0x4F0F 0x4F10 0x4F11 +0x4F12 0x4F13 0x4F14 0x4F15 0x4F16 0x4F17 0x4F18 0x4F19 0x4F1A 0x4F1B 0x4F1C 0x4F1D 0x4F1E 0x4F1F 0x4F20 0x4F21 +0x4F22 0x4F23 0x4F24 0x4F25 0x4F26 0x4F27 0x4F28 0x4F29 0x4F2A 0x4F2B 0x4F2C 0x4F2D 0x4F2E 0x4F2F 0x4F30 0x4F31 +0x4F32 0x4F33 0x4F34 0x4F35 0x4F36 0x4F37 0x4F38 0x4F39 0x4F3A 0x4F3B 0x4F3C 0x4F3D 0x4F3E 0x4F3F 0x4F40 0x4F41 +0x4F42 0x4F43 0x4F44 0x4F45 0x4F46 0x4F47 0x4F48 0x4F49 0x4F4A 0x4F4B 0x4F4C 0x4F4D 0x4F4E 0x4F4F 0x4F50 0x4F51 +0x4F52 0x4F53 0x4F54 0x4F55 0x4F56 0x4F57 0x4F58 0x4F59 0x4F5A 0x4F5B 0x4F5C 0x4F5D 0x4F5E 0x4F5F 0x4F60 0x4F61 +0x4F62 0x4F63 0x4F64 0x4F65 0x4F66 0x4F67 0x4F68 0x4F69 0x4F6A 0x4F6B 0x4F6C 0x4F6D 0x4F6E 0x4F6F 0x4F70 0x4F71 +0x4F72 0x4F73 0x4F74 0x4F75 0x4F76 0x4F77 0x4F78 0x4F79 0x4F7A 0x4F7B 0x4F7C 0x4F7D 0x4F7E 0x4F7F 0x4F80 0x4F81 +0x4F82 0x4F83 0x4F84 0x4F85 0x4F86 0x4F87 0x4F88 0x4F89 0x4F8A 0x4F8B 0x4F8C 0x4F8D 0x4F8E 0x4F8F 0x4F90 0x4F91 +0x4F92 0x4F93 0x4F94 0x4F95 0x4F96 0x4F97 0x4F98 0x4F99 0x4F9A 0x4F9B 0x4F9C 0x4F9D 0x4F9E 0x4F9F 0x4FA0 0x4FA1 +0x4FA2 0x4FA3 0x4FA4 0x4FA5 0x4FA6 0x4FA7 0x4FA8 0x4FA9 0x4FAA 0x4FAB 0x4FAC 0x4FAD 0x4FAE 0x4FAF 0x4FB0 0x4FB1 +0x4FB2 0x4FB3 0x4FB4 0x4FB5 0x4FB6 0x4FB7 0x4FB8 0x4FB9 0x4FBA 0x4FBB 0x4FBC 0x4FBD 0x4FBE 0x4FBF 0x4FC0 0x4FC1 +0x4FC2 0x4FC3 0x4FC4 0x4FC5 0x4FC6 0x4FC7 0x4FC8 0x4FC9 0x4FCA 0x4FCB 0x4FCC 0x4FCD 0x4FCE 0x4FCF 0x4FD0 0x4FD1 +0x4FD2 0x4FD3 0x4FD4 0x4FD5 0x4FD6 0x4FD7 0x4FD8 0x4FD9 0x4FDA 0x4FDB 0x4FDC 0x4FDD 0x4FDE 0x4FDF 0x4FE0 0x4FE1 +0x4FE2 0x4FE3 0x4FE4 0x4FE5 0x4FE6 0x4FE7 0x4FE8 0x4FE9 0x4FEA 0x4FEB 0x4FEC 0x4FED 0x4FEE 0x4FEF 0x4FF0 0x4FF1 +0x4FF2 0x4FF3 0x4FF4 0x4FF5 0x4FF6 0x4FF7 0x4FF8 0x4FF9 0x4FFA 0x4FFB 0x4FFC 0x4FFD 0x4FFE 0x4FFF 0x5000 0x5001 +0x5002 0x5003 0x5004 0x5005 0x5006 0x5007 0x5008 0x5009 0x500A 0x500B 0x500C 0x500D 0x500E 0x500F 0x5010 0x5011 +0x5012 0x5013 0x5014 0x5015 0x5016 0x5017 0x5018 0x5019 0x501A 0x501B 0x501C 0x501D 0x501E 0x501F 0x5020 0x5021 +0x5022 0x5023 0x5024 0x5025 0x5026 0x5027 0x5028 0x5029 0x502A 0x502B 0x502C 0x502D 0x502E 0x502F 0x5030 0x5031 +0x5033 0x5034 0x5035 0x5036 0x5037 0x5039 0x503A 0x503B 0x503C 0x503E 0x5040 0x5041 0x5043 0x5045 0x5046 0x5047 +0x5048 0x5049 0x504A 0x504B 0x504C 0x504D 0x504E 0x504F 0x5050 0x5051 0x5053 0x5055 0x5056 0x5057 0x505A 0x505B +0x505C 0x505D 0x505E 0x505F 0x5060 0x5061 0x5062 0x5063 0x5064 0x5065 0x5068 0x5069 0x506A 0x506B 0x506C 0x506D +0x506E 0x506F 0x5070 0x5072 0x5073 0x5074 0x5075 0x5076 0x5077 0x5078 0x507A 0x507B 0x507D 0x507E 0x507F 0x5080 +0x5082 0x5083 0x5085 0x5087 0x5088 0x5089 0x508B 0x508C 0x508D 0x508E 0x5091 0x5092 0x5094 0x5095 0x5096 0x5098 +0x5099 0x509A 0x509B 0x509C 0x509D 0x509E 0x50A2 0x50A3 0x50A4 0x50A5 0x50A7 0x50A8 0x50A9 0x50AC 0x50AD 0x50AE +0x50AF 0x50B0 0x50B1 0x50B2 0x50B3 0x50B4 0x50B5 0x50B6 0x50B7 0x50B8 0x50BA 0x50BB 0x50BD 0x50BE 0x50BF 0x50C1 +0x50C2 0x50C4 0x50C5 0x50C6 0x50C7 0x50C8 0x50C9 0x50CA 0x50CB 0x50CD 0x50CE 0x50CF 0x50D1 0x50D3 0x50D4 0x50D5 +0x50D6 0x50D7 0x50D9 0x50DA 0x50DB 0x50DC 0x50DD 0x50DE 0x50E0 0x50E3 0x50E4 0x50E5 0x50E6 0x50E7 0x50E8 0x50E9 +0x50EA 0x50EB 0x50EC 0x50ED 0x50EE 0x50EF 0x50F0 0x50F1 0x50F3 0x50F5 0x50F6 0x50F8 0x50F9 0x50FB 0x50FD 0x50FE +0x50FF 0x5100 0x5101 0x5102 0x5103 0x5104 0x5105 0x5106 0x5107 0x5108 0x5109 0x510A 0x510B 0x510C 0x510D 0x510E +0x5110 0x5111 0x5112 0x5113 0x5114 0x5115 0x5116 0x5117 0x5118 0x511A 0x511C 0x511F 0x5120 0x5121 0x5122 0x5124 +0x5125 0x5126 0x5129 0x512A 0x512D 0x512E 0x5130 0x5131 0x5132 0x5133 0x5134 0x5135 0x5137 0x5138 0x5139 0x513A +0x513B 0x513C 0x513D 0x513F 0x5140 0x5141 0x5142 0x5143 0x5144 0x5145 0x5146 0x5147 0x5148 0x5149 0x514A 0x514B +0x514C 0x514D 0x514E 0x514F 0x5150 0x5151 0x5152 0x5153 0x5154 0x5155 0x5156 0x5157 0x5159 0x515A 0x515B 0x515C +0x515D 0x515E 0x515F 0x5161 0x5162 0x5163 0x5165 0x5166 0x5167 0x5168 0x5169 0x516A 0x516B 0x516C 0x516D 0x516E +0x516F 0x5170 0x5171 0x5172 0x5173 0x5174 0x5175 0x5176 0x5177 0x5178 0x5179 0x517B 0x517C 0x517D 0x5180 0x5181 +0x5182 0x5183 0x5184 0x5185 0x5186 0x5187 0x5188 0x5189 0x518A 0x518B 0x518C 0x518D 0x518E 0x518F 0x5190 0x5191 +0x5192 0x5193 0x5194 0x5195 0x5196 0x5197 0x5198 0x5199 0x519A 0x519B 0x519C 0x519D 0x519E 0x51A0 0x51A2 0x51A4 +0x51A5 0x51A6 0x51A7 0x51A8 0x51A9 0x51AA 0x51AB 0x51AC 0x51AD 0x51AE 0x51AF 0x51B0 0x51B1 0x51B2 0x51B3 0x51B4 +0x51B5 0x51B6 0x51B7 0x51B9 0x51BB 0x51BC 0x51BD 0x51BE 0x51C0 0x51C3 0x51C4 0x51C5 0x51C6 0x51C7 0x51C8 0x51C9 +0x51CA 0x51CB 0x51CC 0x51CD 0x51CE 0x51CF 0x51D0 0x51D1 0x51D3 0x51D4 0x51D6 0x51D7 0x51D8 0x51D9 0x51DB 0x51DC +0x51DD 0x51DE 0x51E0 0x51E1 0x51E2 0x51E4 0x51E5 0x51E6 0x51E7 0x51E9 0x51EA 0x51EB 0x51ED 0x51EE 0x51EF 0x51F0 +0x51F1 0x51F3 0x51F4 0x51F5 0x51F6 0x51F7 0x51F8 0x51F9 0x51FA 0x51FB 0x51FC 0x51FD 0x51FE 0x51FF 0x5200 0x5201 +0x5202 0x5203 0x5204 0x5205 0x5206 0x5207 0x5208 0x5209 0x520A 0x520B 0x520C 0x520D 0x520E 0x5210 0x5211 0x5212 +0x5213 0x5214 0x5215 0x5216 0x5217 0x5218 0x5219 0x521A 0x521B 0x521C 0x521D 0x521E 0x5220 0x5221 0x5223 0x5224 +0x5225 0x5227 0x5228 0x5229 0x522A 0x522B 0x522C 0x522D 0x522E 0x5230 0x5231 0x5232 0x5233 0x5235 0x5236 0x5237 +0x5238 0x5239 0x523A 0x523B 0x523D 0x523F 0x5240 0x5241 0x5242 0x5243 0x5244 0x5245 0x5246 0x5247 0x5249 0x524A +0x524B 0x524C 0x524D 0x524E 0x524F 0x5250 0x5251 0x5252 0x5254 0x5255 0x5256 0x5257 0x525A 0x525B 0x525C 0x525D +0x525E 0x525F 0x5261 0x5262 0x5263 0x5264 0x5265 0x5267 0x5269 0x526A 0x526B 0x526C 0x526D 0x526E 0x526F 0x5270 +0x5271 0x5272 0x5273 0x5274 0x5275 0x5277 0x5278 0x527A 0x527B 0x527C 0x527D 0x527E 0x527F 0x5280 0x5281 0x5282 +0x5283 0x5284 0x5287 0x5288 0x5289 0x528A 0x528B 0x528C 0x528D 0x528F 0x5290 0x5291 0x5292 0x5293 0x5294 0x5296 +0x5297 0x5298 0x5299 0x529B 0x529C 0x529D 0x529E 0x529F 0x52A0 0x52A1 0x52A2 0x52A3 0x52A4 0x52A6 0x52A8 0x52A9 +0x52AA 0x52AB 0x52AC 0x52AD 0x52AE 0x52B1 0x52B2 0x52B3 0x52B4 0x52B5 0x52B9 0x52BB 0x52BC 0x52BE 0x52BF 0x52C0 +0x52C1 0x52C2 0x52C3 0x52C5 0x52C7 0x52C9 0x52CB 0x52CD 0x52D0 0x52D2 0x52D3 0x52D4 0x52D5 0x52D6 0x52D7 0x52D8 +0x52D9 0x52DA 0x52DB 0x52DD 0x52DE 0x52DF 0x52E0 0x52E2 0x52E3 0x52E4 0x52E5 0x52E6 0x52E7 0x52E9 0x52EB 0x52EF +0x52F0 0x52F1 0x52F2 0x52F3 0x52F4 0x52F5 0x52F7 0x52F8 0x52F9 0x52FA 0x52FB 0x52FC 0x52FD 0x52FE 0x52FF 0x5300 +0x5301 0x5302 0x5303 0x5304 0x5305 0x5306 0x5308 0x5309 0x530A 0x530B 0x530D 0x530E 0x530F 0x5310 0x5311 0x5312 +0x5315 0x5316 0x5317 0x5318 0x5319 0x531A 0x531B 0x531C 0x531D 0x531E 0x531F 0x5320 0x5321 0x5322 0x5323 0x5326 +0x5327 0x532A 0x532D 0x532E 0x532F 0x5330 0x5331 0x5333 0x5334 0x5337 0x5338 0x5339 0x533A 0x533B 0x533C 0x533D +0x533E 0x533F 0x5340 0x5341 0x5342 0x5343 0x5344 0x5345 0x5346 0x5347 0x5348 0x5349 0x534A 0x534B 0x534C 0x534D +0x534E 0x534F 0x5350 0x5351 0x5352 0x5353 0x5354 0x5355 0x5356 0x5357 0x5358 0x535A 0x535C 0x535D 0x535E 0x535F +0x5360 0x5361 0x5362 0x5363 0x5364 0x5365 0x5366 0x5367 0x5368 0x5369 0x536A 0x536B 0x536C 0x536D 0x536E 0x536F +0x5370 0x5371 0x5372 0x5373 0x5374 0x5375 0x5377 0x5378 0x5379 0x537A 0x537B 0x537C 0x537D 0x537F 0x5382 0x5383 +0x5384 0x5385 0x5386 0x5389 0x538A 0x538B 0x538C 0x538D 0x538E 0x538F 0x5390 0x5392 0x5393 0x5394 0x5395 0x5396 +0x5397 0x5398 0x5399 0x539A 0x539C 0x539D 0x539E 0x539F 0x53A0 0x53A2 0x53A3 0x53A4 0x53A5 0x53A6 0x53A7 0x53A8 +0x53A9 0x53AC 0x53AD 0x53AE 0x53B0 0x53B2 0x53B3 0x53B4 0x53B6 0x53B7 0x53B9 0x53BB 0x53BE 0x53BF 0x53C1 0x53C2 +0x53C3 0x53C4 0x53C6 0x53C7 0x53C8 0x53C9 0x53CA 0x53CB 0x53CC 0x53CD 0x53CE 0x53D1 0x53D2 0x53D4 0x53D5 0x53D6 +0x53D7 0x53D8 0x53D9 0x53DA 0x53DB 0x53DF 0x53E0 0x53E1 0x53E2 0x53E3 0x53E4 0x53E5 0x53E6 0x53E8 0x53E9 0x53EA +0x53EB 0x53EC 0x53ED 0x53EE 0x53EF 0x53F0 0x53F1 0x53F2 0x53F3 0x53F5 0x53F6 0x53F7 0x53F8 0x53F9 0x53FA 0x53FB +0x53FC 0x53FD 0x53FE 0x5401 0x5403 0x5404 0x5406 0x5407 0x5408 0x5409 0x540A 0x540B 0x540C 0x540D 0x540E 0x540F +0x5410 0x5411 0x5412 0x5413 0x5414 0x5415 0x5416 0x5417 0x5418 0x5419 0x541B 0x541C 0x541D 0x541E 0x541F 0x5420 +0x5421 0x5423 0x5424 0x5425 0x5426 0x5427 0x5428 0x5429 0x542A 0x542B 0x542C 0x542D 0x542E 0x542F 0x5430 0x5431 +0x5432 0x5433 0x5434 0x5435 0x5436 0x5437 0x5438 0x5439 0x543B 0x543C 0x543D 0x543E 0x543F 0x5440 0x5441 0x5442 +0x5443 0x5445 0x5446 0x5447 0x5448 0x5449 0x544A 0x544B 0x544E 0x544F 0x5450 0x5451 0x5452 0x5453 0x5454 0x5455 +0x5456 0x5457 0x5458 0x5459 0x545B 0x545C 0x545D 0x545F 0x5460 0x5461 0x5462 0x5463 0x5464 0x5465 0x5466 0x5467 +0x5468 0x546A 0x546B 0x546C 0x546F 0x5470 0x5471 0x5472 0x5473 0x5474 0x5475 0x5476 0x5477 0x5478 0x547A 0x547B +0x547C 0x547D 0x547E 0x547F 0x5480 0x5481 0x5482 0x5484 0x5486 0x5487 0x5488 0x5489 0x548B 0x548C 0x548D 0x548E +0x548F 0x5490 0x5491 0x5492 0x5493 0x5494 0x5495 0x5496 0x5497 0x5498 0x5499 0x549A 0x549B 0x549D 0x54A0 0x54A1 +0x54A2 0x54A3 0x54A4 0x54A5 0x54A6 0x54A7 0x54A8 0x54A9 0x54AA 0x54AB 0x54AC 0x54AD 0x54AE 0x54AF 0x54B0 0x54B1 +0x54B2 0x54B3 0x54B4 0x54B5 0x54B6 0x54B7 0x54B8 0x54B9 0x54BA 0x54BB 0x54BC 0x54BD 0x54BE 0x54BF 0x54C0 0x54C1 +0x54C2 0x54C3 0x54C4 0x54C5 0x54C6 0x54C7 0x54C8 0x54C9 0x54CA 0x54CB 0x54CC 0x54CD 0x54CE 0x54CF 0x54D0 0x54D1 +0x54D2 0x54D3 0x54D4 0x54D5 0x54D6 0x54D7 0x54D8 0x54D9 0x54DA 0x54DC 0x54DD 0x54DE 0x54DF 0x54E0 0x54E1 0x54E2 +0x54E4 0x54E5 0x54E6 0x54E7 0x54E8 0x54E9 0x54EA 0x54EB 0x54ED 0x54EE 0x54F1 0x54F2 0x54F3 0x54F7 0x54F8 0x54FA +0x54FB 0x54FC 0x54FD 0x54FF 0x5501 0x5503 0x5504 0x5505 0x5506 0x5507 0x5508 0x5509 0x550A 0x550B 0x550C 0x550E +0x550F 0x5510 0x5511 0x5512 0x5513 0x5514 0x5516 0x5517 0x551A 0x551B 0x551C 0x551D 0x551E 0x5520 0x5521 0x5522 +0x5523 0x5524 0x5525 0x5526 0x5527 0x552A 0x552C 0x552D 0x552E 0x552F 0x5530 0x5531 0x5532 0x5533 0x5534 0x5535 +0x5536 0x5537 0x5538 0x5539 0x553B 0x553C 0x553E 0x553F 0x5540 0x5541 0x5543 0x5544 0x5545 0x5546 0x5548 0x5549 +0x554A 0x554B 0x554C 0x554D 0x554E 0x554F 0x5550 0x5551 0x5552 0x5553 0x5555 0x5556 0x5557 0x5559 0x555B 0x555C +0x555D 0x555E 0x555F 0x5561 0x5562 0x5563 0x5564 0x5565 0x5566 0x5567 0x5569 0x556A 0x556B 0x556C 0x556D 0x556E +0x556F 0x5570 0x5571 0x5572 0x5574 0x5575 0x5576 0x5577 0x5578 0x5579 0x557B 0x557C 0x557D 0x557E 0x557F 0x5580 +0x5581 0x5582 0x5583 0x5584 0x5586 0x5587 0x5588 0x5589 0x558A 0x558B 0x558C 0x558D 0x558E 0x558F 0x5591 0x5592 +0x5593 0x5594 0x5595 0x5598 0x5599 0x559A 0x559C 0x559D 0x559E 0x559F 0x55A1 0x55A2 0x55A3 0x55A4 0x55A5 0x55A6 +0x55A7 0x55A8 0x55A9 0x55AA 0x55AB 0x55AC 0x55AD 0x55AE 0x55B0 0x55B1 0x55B2 0x55B3 0x55B5 0x55B6 0x55B7 0x55B9 +0x55BA 0x55BB 0x55BC 0x55BD 0x55BE 0x55BF 0x55C0 0x55C2 0x55C3 0x55C4 0x55C5 0x55C6 0x55C7 0x55C8 0x55C9 0x55CA +0x55CB 0x55CC 0x55CD 0x55CE 0x55CF 0x55D0 0x55D1 0x55D2 0x55D3 0x55D4 0x55D5 0x55D6 0x55D7 0x55D9 0x55DA 0x55DB +0x55DC 0x55DD 0x55DE 0x55DF 0x55E1 0x55E2 0x55E3 0x55E4 0x55E5 0x55E6 0x55E7 0x55E8 0x55E9 0x55EA 0x55EB 0x55EC +0x55EE 0x55EF 0x55F0 0x55F1 0x55F2 0x55F3 0x55F5 0x55F6 0x55F7 0x55F9 0x55FA 0x55FB 0x55FC 0x55FD 0x55FE 0x55FF +0x5600 0x5601 0x5602 0x5604 0x5605 0x5606 0x5608 0x5609 0x560C 0x560D 0x560E 0x560F 0x5610 0x5611 0x5612 0x5613 +0x5614 0x5615 0x5616 0x5617 0x5618 0x561A 0x561B 0x561C 0x561D 0x561E 0x561F 0x5621 0x5622 0x5623 0x5624 0x5625 +0x5627 0x5629 0x562A 0x562B 0x562C 0x562D 0x562E 0x562F 0x5630 0x5631 0x5632 0x5633 0x5634 0x5635 0x5636 0x5638 +0x5639 0x563A 0x563B 0x563D 0x563E 0x563F 0x5640 0x5641 0x5642 0x5643 0x5645 0x5646 0x5647 0x5648 0x5649 0x564A +0x564C 0x564D 0x564E 0x564F 0x5650 0x5652 0x5653 0x5654 0x5657 0x5658 0x5659 0x565A 0x565B 0x565C 0x565D 0x565E +0x5660 0x5662 0x5663 0x5664 0x5665 0x5666 0x5668 0x5669 0x566A 0x566B 0x566C 0x566D 0x566E 0x566F 0x5670 0x5671 +0x5672 0x5673 0x5674 0x5676 0x5677 0x5678 0x5679 0x567A 0x567B 0x567C 0x567E 0x567F 0x5680 0x5681 0x5682 0x5683 +0x5684 0x5685 0x5686 0x5687 0x5689 0x568A 0x568C 0x568D 0x568E 0x568F 0x5690 0x5692 0x5693 0x5694 0x5695 0x5697 +0x5698 0x5699 0x569A 0x569B 0x569C 0x569D 0x569F 0x56A0 0x56A1 0x56A2 0x56A3 0x56A4 0x56A5 0x56A6 0x56A7 0x56A8 +0x56AA 0x56AB 0x56AC 0x56AD 0x56AE 0x56AF 0x56B1 0x56B2 0x56B3 0x56B4 0x56B5 0x56B6 0x56B7 0x56B9 0x56BC 0x56BD +0x56BE 0x56BF 0x56C0 0x56C1 0x56C2 0x56C3 0x56C5 0x56C6 0x56C8 0x56C9 0x56CA 0x56CB 0x56CC 0x56CD 0x56CE 0x56D1 +0x56D2 0x56D3 0x56D4 0x56D6 0x56D7 0x56D8 0x56D9 0x56DA 0x56DB 0x56DC 0x56DD 0x56DE 0x56DF 0x56E0 0x56E1 0x56E2 +0x56E3 0x56E4 0x56E5 0x56E6 0x56E7 0x56E8 0x56E9 0x56EA 0x56EB 0x56EC 0x56ED 0x56EE 0x56EF 0x56F0 0x56F1 0x56F2 +0x56F3 0x56F4 0x56F5 0x56F6 0x56F7 0x56F8 0x56F9 0x56FA 0x56FB 0x56FC 0x56FD 0x56FE 0x56FF 0x5700 0x5701 0x5702 +0x5703 0x5704 0x5705 0x5706 0x5707 0x5708 0x5709 0x570A 0x570B 0x570C 0x570D 0x570E 0x570F 0x5710 0x5711 0x5712 +0x5713 0x5714 0x5715 0x5716 0x5717 0x5718 0x5719 0x571A 0x571B 0x571C 0x571D 0x571E 0x571F 0x5720 0x5721 0x5722 +0x5723 0x5724 0x5726 0x5727 0x5728 0x5729 0x572A 0x572B 0x572C 0x572D 0x572E 0x572F 0x5730 0x5732 0x5733 0x5734 +0x5737 0x5738 0x5739 0x573A 0x573B 0x573E 0x5740 0x5741 0x5742 0x5745 0x5747 0x5749 0x574A 0x574B 0x574C 0x574D +0x574E 0x574F 0x5750 0x5751 0x5752 0x5754 0x5757 0x575A 0x575B 0x575C 0x575D 0x575E 0x575F 0x5760 0x5761 0x5762 +0x5764 0x5765 0x5766 0x5768 0x5769 0x576A 0x576B 0x576C 0x576D 0x576E 0x576F 0x5770 0x5771 0x5772 0x5773 0x5774 +0x5775 0x5776 0x5777 0x577B 0x577C 0x577D 0x577F 0x5780 0x5782 0x5783 0x5784 0x5785 0x5786 0x5787 0x5788 0x5789 +0x578B 0x578C 0x578D 0x578E 0x578F 0x5792 0x5793 0x5794 0x5795 0x5797 0x5798 0x5799 0x579A 0x579B 0x579D 0x579E +0x579F 0x57A0 0x57A1 0x57A2 0x57A3 0x57A4 0x57A5 0x57A6 0x57A7 0x57A8 0x57A9 0x57AA 0x57AB 0x57AD 0x57AE 0x57AF +0x57B0 0x57B1 0x57B2 0x57B3 0x57B4 0x57B5 0x57B6 0x57B8 0x57B9 0x57BA 0x57BB 0x57BC 0x57BD 0x57BE 0x57BF 0x57C0 +0x57C1 0x57C2 0x57C3 0x57C6 0x57C7 0x57C8 0x57CB 0x57CC 0x57CE 0x57CF 0x57D0 0x57D2 0x57D3 0x57D4 0x57D5 0x57D6 +0x57D7 0x57D8 0x57D9 0x57DA 0x57DC 0x57DD 0x57DE 0x57DF 0x57E0 0x57E1 0x57E2 0x57E3 0x57E4 0x57E5 0x57E7 0x57E8 +0x57E9 0x57EA 0x57EB 0x57EC 0x57ED 0x57EE 0x57EF 0x57F0 0x57F1 0x57F2 0x57F3 0x57F4 0x57F5 0x57F6 0x57F7 0x57F8 +0x57F9 0x57FA 0x57FB 0x57FC 0x57FD 0x5800 0x5801 0x5802 0x5803 0x5804 0x5805 0x5806 0x5807 0x5808 0x5809 0x580A +0x580B 0x580C 0x580D 0x580E 0x5810 0x5811 0x5814 0x5815 0x5816 0x5817 0x5819 0x581B 0x581C 0x581D 0x581E 0x5820 +0x5821 0x5823 0x5824 0x5825 0x5827 0x5828 0x5829 0x582A 0x582C 0x582D 0x582E 0x582F 0x5830 0x5831 0x5832 0x5833 +0x5834 0x5835 0x5836 0x5837 0x5838 0x5839 0x583A 0x583B 0x583C 0x583D 0x583E 0x583F 0x5840 0x5841 0x5842 0x5843 +0x5844 0x5845 0x5846 0x5848 0x5849 0x584A 0x584B 0x584C 0x584D 0x584E 0x584F 0x5851 0x5852 0x5853 0x5854 0x5855 +0x5857 0x5858 0x5859 0x585A 0x585B 0x585D 0x585E 0x5861 0x5862 0x5863 0x5864 0x5865 0x5868 0x5869 0x586B 0x586C +0x586D 0x586E 0x586F 0x5870 0x5871 0x5872 0x5873 0x5874 0x5875 0x5876 0x5878 0x5879 0x587A 0x587B 0x587C 0x587D +0x587E 0x587F 0x5880 0x5881 0x5882 0x5883 0x5884 0x5885 0x5886 0x5887 0x5888 0x5889 0x588A 0x588B 0x588E 0x588F +0x5890 0x5891 0x5892 0x5893 0x5894 0x5895 0x5897 0x5898 0x5899 0x589A 0x589C 0x589D 0x589E 0x589F 0x58A0 0x58A1 +0x58A3 0x58A5 0x58A6 0x58A8 0x58A9 0x58AB 0x58AC 0x58AE 0x58AF 0x58B1 0x58B3 0x58B6 0x58B8 0x58B9 0x58BA 0x58BB +0x58BC 0x58BD 0x58BE 0x58BF 0x58C1 0x58C2 0x58C5 0x58C6 0x58C7 0x58C8 0x58C9 0x58CA 0x58CB 0x58CC 0x58CE 0x58CF +0x58D1 0x58D2 0x58D3 0x58D4 0x58D5 0x58D6 0x58D7 0x58D8 0x58D9 0x58DA 0x58DB 0x58DC 0x58DD 0x58DE 0x58DF 0x58E0 +0x58E2 0x58E3 0x58E4 0x58E5 0x58E7 0x58E8 0x58E9 0x58EA 0x58EB 0x58EC 0x58EE 0x58EF 0x58F0 0x58F1 0x58F2 0x58F3 +0x58F4 0x58F6 0x58F7 0x58F8 0x58F9 0x58FA 0x58FB 0x58FC 0x58FD 0x58FE 0x58FF 0x5902 0x5903 0x5904 0x5906 0x5907 +0x5909 0x590A 0x590B 0x590C 0x590D 0x590E 0x590F 0x5910 0x5912 0x5913 0x5914 0x5915 0x5916 0x5917 0x5918 0x5919 +0x591A 0x591B 0x591C 0x591F 0x5920 0x5922 0x5924 0x5925 0x5927 0x5928 0x5929 0x592A 0x592B 0x592C 0x592D 0x592E +0x592F 0x5930 0x5931 0x5932 0x5933 0x5934 0x5937 0x5938 0x5939 0x593A 0x593C 0x593D 0x593E 0x593F 0x5940 0x5941 +0x5942 0x5944 0x5945 0x5947 0x5948 0x5949 0x594A 0x594B 0x594C 0x594E 0x594F 0x5950 0x5951 0x5953 0x5954 0x5955 +0x5956 0x5957 0x5958 0x595A 0x595C 0x5960 0x5961 0x5962 0x5964 0x5965 0x5967 0x5968 0x5969 0x596A 0x596B 0x596C +0x596D 0x596E 0x5970 0x5971 0x5972 0x5973 0x5974 0x5976 0x5977 0x5978 0x5979 0x597B 0x597C 0x597D 0x597E 0x597F +0x5980 0x5981 0x5982 0x5983 0x5984 0x5985 0x5986 0x5987 0x5988 0x5989 0x598A 0x598D 0x598E 0x598F 0x5990 0x5992 +0x5993 0x5996 0x5997 0x5998 0x5999 0x599B 0x599D 0x599E 0x59A0 0x59A1 0x59A2 0x59A3 0x59A4 0x59A5 0x59A6 0x59A7 +0x59A8 0x59A9 0x59AA 0x59AB 0x59AC 0x59AD 0x59AE 0x59AF 0x59B1 0x59B2 0x59B3 0x59B4 0x59B5 0x59B6 0x59B8 0x59B9 +0x59BA 0x59BB 0x59BC 0x59BD 0x59BE 0x59C0 0x59C1 0x59C3 0x59C5 0x59C6 0x59C7 0x59C8 0x59C9 0x59CA 0x59CB 0x59CC +0x59CD 0x59CE 0x59CF 0x59D0 0x59D1 0x59D2 0x59D3 0x59D4 0x59D6 0x59D7 0x59D8 0x59D9 0x59DA 0x59DB 0x59DC 0x59DD +0x59DE 0x59E0 0x59E1 0x59E3 0x59E4 0x59E5 0x59E6 0x59E8 0x59E9 0x59EA 0x59EB 0x59EC 0x59ED 0x59EE 0x59F1 0x59F2 +0x59F3 0x59F4 0x59F5 0x59F6 0x59F7 0x59F8 0x59F9 0x59FA 0x59FB 0x59FC 0x59FD 0x59FE 0x59FF 0x5A00 0x5A01 0x5A03 +0x5A04 0x5A05 0x5A06 0x5A07 0x5A08 0x5A09 0x5A0A 0x5A0C 0x5A0D 0x5A0F 0x5A11 0x5A12 0x5A13 0x5A15 0x5A16 0x5A17 +0x5A18 0x5A19 0x5A1A 0x5A1B 0x5A1C 0x5A1E 0x5A1F 0x5A20 0x5A23 0x5A25 0x5A29 0x5A2B 0x5A2D 0x5A2E 0x5A2F 0x5A31 +0x5A32 0x5A33 0x5A34 0x5A35 0x5A36 0x5A37 0x5A38 0x5A39 0x5A3C 0x5A3E 0x5A3F 0x5A40 0x5A41 0x5A42 0x5A43 0x5A44 +0x5A46 0x5A47 0x5A48 0x5A49 0x5A4A 0x5A4B 0x5A4C 0x5A4D 0x5A50 0x5A51 0x5A52 0x5A53 0x5A55 0x5A56 0x5A57 0x5A58 +0x5A5A 0x5A5B 0x5A5C 0x5A5D 0x5A5E 0x5A5F 0x5A60 0x5A62 0x5A64 0x5A65 0x5A66 0x5A67 0x5A69 0x5A6A 0x5A6B 0x5A6C +0x5A6D 0x5A70 0x5A73 0x5A74 0x5A75 0x5A76 0x5A77 0x5A78 0x5A7A 0x5A7B 0x5A7C 0x5A7D 0x5A7F 0x5A82 0x5A83 0x5A84 +0x5A86 0x5A8A 0x5A8B 0x5A8C 0x5A8E 0x5A8F 0x5A90 0x5A92 0x5A93 0x5A94 0x5A95 0x5A96 0x5A97 0x5A9A 0x5A9B 0x5A9C +0x5A9D 0x5A9E 0x5A9F 0x5AA0 0x5AA2 0x5AA4 0x5AA5 0x5AA6 0x5AA7 0x5AA9 0x5AAA 0x5AAC 0x5AAD 0x5AAE 0x5AAF 0x5AB0 +0x5AB1 0x5AB2 0x5AB3 0x5AB4 0x5AB5 0x5AB6 0x5AB7 0x5AB8 0x5AB9 0x5ABA 0x5ABB 0x5ABC 0x5ABD 0x5ABE 0x5ABF 0x5AC0 +0x5AC1 0x5AC2 0x5AC4 0x5AC6 0x5AC7 0x5AC8 0x5AC9 0x5ACA 0x5ACB 0x5ACC 0x5ACD 0x5ACF 0x5AD0 0x5AD2 0x5AD4 0x5AD5 +0x5AD6 0x5AD7 0x5AD8 0x5AD9 0x5ADA 0x5ADB 0x5ADC 0x5ADD 0x5ADE 0x5ADF 0x5AE0 0x5AE1 0x5AE2 0x5AE3 0x5AE4 0x5AE5 +0x5AE6 0x5AE8 0x5AE9 0x5AEA 0x5AEB 0x5AEC 0x5AED 0x5AEE 0x5AF1 0x5AF2 0x5AF3 0x5AF4 0x5AF5 0x5AF6 0x5AF7 0x5AF8 +0x5AF9 0x5AFA 0x5AFB 0x5AFD 0x5AFF 0x5B00 0x5B01 0x5B02 0x5B03 0x5B05 0x5B07 0x5B08 0x5B09 0x5B0B 0x5B0C 0x5B0F +0x5B10 0x5B13 0x5B14 0x5B16 0x5B17 0x5B19 0x5B1A 0x5B1B 0x5B1D 0x5B1E 0x5B20 0x5B21 0x5B22 0x5B23 0x5B24 0x5B25 +0x5B26 0x5B27 0x5B28 0x5B2A 0x5B2C 0x5B2D 0x5B2E 0x5B2F 0x5B30 0x5B32 0x5B34 0x5B36 0x5B37 0x5B38 0x5B3C 0x5B3D +0x5B3E 0x5B3F 0x5B40 0x5B43 0x5B45 0x5B47 0x5B48 0x5B4B 0x5B4C 0x5B4D 0x5B4E 0x5B50 0x5B51 0x5B52 0x5B53 0x5B54 +0x5B55 0x5B56 0x5B57 0x5B58 0x5B59 0x5B5A 0x5B5B 0x5B5C 0x5B5D 0x5B5E 0x5B5F 0x5B62 0x5B63 0x5B64 0x5B65 0x5B66 +0x5B69 0x5B6A 0x5B6B 0x5B6C 0x5B6D 0x5B6E 0x5B70 0x5B71 0x5B72 0x5B73 0x5B75 0x5B77 0x5B78 0x5B7A 0x5B7B 0x5B7C +0x5B7D 0x5B7F 0x5B80 0x5B81 0x5B82 0x5B83 0x5B84 0x5B85 0x5B87 0x5B88 0x5B89 0x5B8B 0x5B8C 0x5B8D 0x5B8E 0x5B8F +0x5B90 0x5B92 0x5B93 0x5B95 0x5B96 0x5B97 0x5B98 0x5B99 0x5B9A 0x5B9B 0x5B9C 0x5B9D 0x5B9E 0x5B9F 0x5BA0 0x5BA1 +0x5BA2 0x5BA3 0x5BA4 0x5BA5 0x5BA6 0x5BA7 0x5BA8 0x5BAA 0x5BAB 0x5BAC 0x5BAD 0x5BAE 0x5BB0 0x5BB3 0x5BB4 0x5BB5 +0x5BB6 0x5BB8 0x5BB9 0x5BBD 0x5BBE 0x5BBF 0x5BC0 0x5BC1 0x5BC2 0x5BC3 0x5BC4 0x5BC5 0x5BC6 0x5BC7 0x5BC9 0x5BCA +0x5BCB 0x5BCC 0x5BCD 0x5BCE 0x5BD0 0x5BD1 0x5BD2 0x5BD3 0x5BD4 0x5BD6 0x5BD7 0x5BD8 0x5BD9 0x5BDB 0x5BDD 0x5BDE +0x5BDF 0x5BE0 0x5BE1 0x5BE2 0x5BE3 0x5BE4 0x5BE5 0x5BE6 0x5BE7 0x5BE8 0x5BE9 0x5BEA 0x5BEB 0x5BEC 0x5BEE 0x5BEF +0x5BF0 0x5BF1 0x5BF2 0x5BF3 0x5BF5 0x5BF6 0x5BF8 0x5BF9 0x5BFA 0x5BFB 0x5BFC 0x5BFE 0x5BFF 0x5C01 0x5C02 0x5C03 +0x5C04 0x5C05 0x5C06 0x5C07 0x5C08 0x5C09 0x5C0A 0x5C0B 0x5C0C 0x5C0D 0x5C0E 0x5C0F 0x5C10 0x5C11 0x5C12 0x5C13 +0x5C14 0x5C15 0x5C16 0x5C17 0x5C18 0x5C19 0x5C1A 0x5C1B 0x5C1C 0x5C1D 0x5C1F 0x5C20 0x5C22 0x5C23 0x5C24 0x5C25 +0x5C27 0x5C28 0x5C2A 0x5C2C 0x5C2D 0x5C30 0x5C31 0x5C33 0x5C34 0x5C35 0x5C36 0x5C37 0x5C38 0x5C39 0x5C3A 0x5C3B +0x5C3C 0x5C3D 0x5C3E 0x5C3F 0x5C40 0x5C41 0x5C42 0x5C43 0x5C44 0x5C45 0x5C46 0x5C47 0x5C48 0x5C49 0x5C4A 0x5C4B +0x5C4C 0x5C4D 0x5C4E 0x5C4F 0x5C50 0x5C51 0x5C53 0x5C54 0x5C55 0x5C56 0x5C58 0x5C59 0x5C5B 0x5C5C 0x5C5D 0x5C5E +0x5C60 0x5C61 0x5C62 0x5C63 0x5C64 0x5C65 0x5C66 0x5C67 0x5C68 0x5C69 0x5C6A 0x5C6C 0x5C6D 0x5C6E 0x5C6F 0x5C70 +0x5C71 0x5C72 0x5C73 0x5C74 0x5C75 0x5C76 0x5C79 0x5C7A 0x5C7B 0x5C7C 0x5C7E 0x5C7F 0x5C81 0x5C82 0x5C83 0x5C86 +0x5C88 0x5C89 0x5C8A 0x5C8B 0x5C8C 0x5C8D 0x5C8F 0x5C90 0x5C91 0x5C92 0x5C93 0x5C94 0x5C95 0x5C96 0x5C97 0x5C98 +0x5C99 0x5C9A 0x5C9B 0x5C9C 0x5C9D 0x5C9E 0x5C9F 0x5CA0 0x5CA1 0x5CA2 0x5CA3 0x5CA4 0x5CA5 0x5CA6 0x5CA7 0x5CA8 +0x5CA9 0x5CAA 0x5CAB 0x5CAC 0x5CAD 0x5CAE 0x5CAF 0x5CB0 0x5CB1 0x5CB3 0x5CB5 0x5CB6 0x5CB7 0x5CB8 0x5CBA 0x5CBB +0x5CBC 0x5CBD 0x5CBE 0x5CBF 0x5CC0 0x5CC1 0x5CC2 0x5CC3 0x5CC4 0x5CC5 0x5CC6 0x5CC7 0x5CC8 0x5CC9 0x5CCA 0x5CCB +0x5CCC 0x5CCE 0x5CCF 0x5CD0 0x5CD2 0x5CD3 0x5CD4 0x5CD6 0x5CD7 0x5CD8 0x5CD9 0x5CDA 0x5CDB 0x5CDE 0x5CDF 0x5CE0 +0x5CE1 0x5CE3 0x5CE4 0x5CE5 0x5CE6 0x5CE7 0x5CE8 0x5CE9 0x5CEA 0x5CEC 0x5CED 0x5CEE 0x5CEF 0x5CF0 0x5CF1 0x5CF4 +0x5CF6 0x5CF7 0x5CF8 0x5CF9 0x5CFA 0x5CFB 0x5CFD 0x5CFF 0x5D00 0x5D01 0x5D02 0x5D03 0x5D04 0x5D05 0x5D06 0x5D07 +0x5D0B 0x5D0C 0x5D0D 0x5D0E 0x5D0F 0x5D10 0x5D11 0x5D12 0x5D14 0x5D15 0x5D16 0x5D17 0x5D18 0x5D19 0x5D1A 0x5D1B +0x5D1D 0x5D1E 0x5D1F 0x5D20 0x5D21 0x5D22 0x5D23 0x5D24 0x5D25 0x5D26 0x5D27 0x5D28 0x5D29 0x5D2C 0x5D2D 0x5D2E +0x5D30 0x5D31 0x5D32 0x5D33 0x5D34 0x5D35 0x5D36 0x5D37 0x5D38 0x5D39 0x5D3A 0x5D3C 0x5D3D 0x5D3E 0x5D3F 0x5D40 +0x5D41 0x5D42 0x5D43 0x5D44 0x5D45 0x5D47 0x5D49 0x5D4A 0x5D4B 0x5D4C 0x5D4E 0x5D50 0x5D51 0x5D52 0x5D55 0x5D56 +0x5D58 0x5D59 0x5D5A 0x5D5B 0x5D5C 0x5D5D 0x5D5E 0x5D62 0x5D63 0x5D65 0x5D67 0x5D68 0x5D69 0x5D6B 0x5D6C 0x5D6F +0x5D71 0x5D72 0x5D73 0x5D74 0x5D76 0x5D77 0x5D79 0x5D7A 0x5D7C 0x5D7D 0x5D7E 0x5D7F 0x5D80 0x5D81 0x5D82 0x5D84 +0x5D85 0x5D86 0x5D87 0x5D88 0x5D89 0x5D8A 0x5D8B 0x5D8C 0x5D8D 0x5D90 0x5D92 0x5D93 0x5D94 0x5D95 0x5D97 0x5D99 +0x5D9A 0x5D9C 0x5D9D 0x5D9E 0x5D9F 0x5DA0 0x5DA1 0x5DA2 0x5DA6 0x5DA7 0x5DA8 0x5DA9 0x5DAA 0x5DAC 0x5DAD 0x5DAE +0x5DAF 0x5DB0 0x5DB1 0x5DB2 0x5DB4 0x5DB5 0x5DB7 0x5DB8 0x5DBA 0x5DBC 0x5DBD 0x5DC0 0x5DC2 0x5DC3 0x5DC5 0x5DC6 +0x5DC7 0x5DC9 0x5DCB 0x5DCC 0x5DCD 0x5DCF 0x5DD1 0x5DD2 0x5DD3 0x5DD4 0x5DD5 0x5DD6 0x5DD8 0x5DDB 0x5DDD 0x5DDE +0x5DDF 0x5DE0 0x5DE1 0x5DE2 0x5DE3 0x5DE4 0x5DE5 0x5DE6 0x5DE7 0x5DE8 0x5DE9 0x5DEA 0x5DEB 0x5DED 0x5DEE 0x5DEF +0x5DF0 0x5DF1 0x5DF2 0x5DF3 0x5DF4 0x5DF5 0x5DF7 0x5DF8 0x5DF9 0x5DFB 0x5DFD 0x5DFE 0x5DFF 0x5E00 0x5E01 0x5E02 +0x5E03 0x5E04 0x5E05 0x5E06 0x5E08 0x5E0A 0x5E0B 0x5E0C 0x5E0E 0x5E0F 0x5E10 0x5E11 0x5E14 0x5E15 0x5E16 0x5E17 +0x5E18 0x5E19 0x5E1A 0x5E1B 0x5E1C 0x5E1D 0x5E1F 0x5E20 0x5E21 0x5E22 0x5E23 0x5E24 0x5E25 0x5E26 0x5E27 0x5E28 +0x5E29 0x5E2B 0x5E2D 0x5E2E 0x5E2F 0x5E30 0x5E31 0x5E33 0x5E34 0x5E35 0x5E36 0x5E37 0x5E38 0x5E3B 0x5E3C 0x5E3D +0x5E3E 0x5E3F 0x5E40 0x5E41 0x5E42 0x5E43 0x5E44 0x5E45 0x5E47 0x5E48 0x5E4A 0x5E4B 0x5E4C 0x5E4D 0x5E4E 0x5E4F +0x5E53 0x5E54 0x5E55 0x5E56 0x5E57 0x5E58 0x5E59 0x5E5B 0x5E5C 0x5E5D 0x5E5E 0x5E5F 0x5E60 0x5E61 0x5E62 0x5E63 +0x5E64 0x5E66 0x5E67 0x5E68 0x5E69 0x5E6A 0x5E6B 0x5E6C 0x5E6D 0x5E6E 0x5E6F 0x5E70 0x5E72 0x5E73 0x5E74 0x5E75 +0x5E76 0x5E77 0x5E78 0x5E79 0x5E7A 0x5E7B 0x5E7C 0x5E7D 0x5E7E 0x5E7F 0x5E80 0x5E81 0x5E82 0x5E83 0x5E84 0x5E85 +0x5E86 0x5E87 0x5E88 0x5E89 0x5E8A 0x5E8B 0x5E8C 0x5E8D 0x5E8F 0x5E90 0x5E91 0x5E93 0x5E94 0x5E95 0x5E96 0x5E97 +0x5E99 0x5E9A 0x5E9B 0x5E9C 0x5E9D 0x5E9E 0x5E9F 0x5EA0 0x5EA2 0x5EA3 0x5EA4 0x5EA5 0x5EA6 0x5EA7 0x5EA8 0x5EAA +0x5EAB 0x5EAC 0x5EAD 0x5EAE 0x5EB0 0x5EB1 0x5EB2 0x5EB3 0x5EB4 0x5EB5 0x5EB6 0x5EB7 0x5EB8 0x5EB9 0x5EBC 0x5EBE +0x5EC1 0x5EC2 0x5EC3 0x5EC4 0x5EC5 0x5EC6 0x5EC7 0x5EC8 0x5EC9 0x5ECA 0x5ECB 0x5ECC 0x5ECD 0x5ECE 0x5ECF 0x5ED0 +0x5ED1 0x5ED2 0x5ED3 0x5ED4 0x5ED5 0x5ED6 0x5ED7 0x5ED8 0x5ED9 0x5EDA 0x5EDB 0x5EDC 0x5EDD 0x5EDE 0x5EDF 0x5EE0 +0x5EE1 0x5EE2 0x5EE3 0x5EE5 0x5EE6 0x5EE7 0x5EE8 0x5EE9 0x5EEA 0x5EEC 0x5EEE 0x5EEF 0x5EF0 0x5EF1 0x5EF2 0x5EF3 +0x5EF4 0x5EF6 0x5EF7 0x5EF8 0x5EFA 0x5EFB 0x5EFC 0x5EFE 0x5EFF 0x5F00 0x5F01 0x5F02 0x5F03 0x5F04 0x5F05 0x5F06 +0x5F07 0x5F08 0x5F09 0x5F0A 0x5F0B 0x5F0C 0x5F0D 0x5F0E 0x5F0F 0x5F10 0x5F11 0x5F12 0x5F13 0x5F14 0x5F15 0x5F16 +0x5F17 0x5F18 0x5F1A 0x5F1B 0x5F1C 0x5F1D 0x5F1F 0x5F20 0x5F22 0x5F23 0x5F24 0x5F25 0x5F26 0x5F27 0x5F28 0x5F29 +0x5F2A 0x5F2D 0x5F2E 0x5F2F 0x5F30 0x5F31 0x5F33 0x5F34 0x5F35 0x5F36 0x5F37 0x5F38 0x5F39 0x5F3A 0x5F3C 0x5F3E +0x5F40 0x5F41 0x5F43 0x5F44 0x5F45 0x5F46 0x5F48 0x5F49 0x5F4A 0x5F4B 0x5F4C 0x5F4E 0x5F4F 0x5F50 0x5F51 0x5F52 +0x5F53 0x5F54 0x5F55 0x5F56 0x5F57 0x5F58 0x5F59 0x5F5B 0x5F5C 0x5F5D 0x5F5E 0x5F5F 0x5F60 0x5F61 0x5F62 0x5F63 +0x5F64 0x5F65 0x5F66 0x5F67 0x5F68 0x5F69 0x5F6A 0x5F6B 0x5F6C 0x5F6D 0x5F6E 0x5F6F 0x5F70 0x5F71 0x5F72 0x5F73 +0x5F74 0x5F76 0x5F77 0x5F78 0x5F79 0x5F7B 0x5F7C 0x5F7D 0x5F7E 0x5F7F 0x5F80 0x5F81 0x5F82 0x5F83 0x5F84 0x5F85 +0x5F86 0x5F87 0x5F88 0x5F89 0x5F8A 0x5F8B 0x5F8C 0x5F90 0x5F91 0x5F92 0x5F93 0x5F95 0x5F96 0x5F97 0x5F98 0x5F99 +0x5F9B 0x5F9C 0x5F9E 0x5F9F 0x5FA0 0x5FA1 0x5FA5 0x5FA6 0x5FA7 0x5FA8 0x5FA9 0x5FAA 0x5FAB 0x5FAC 0x5FAD 0x5FAE +0x5FAF 0x5FB3 0x5FB4 0x5FB5 0x5FB7 0x5FB9 0x5FBC 0x5FBD 0x5FC3 0x5FC4 0x5FC5 0x5FC6 0x5FC9 0x5FCC 0x5FCD 0x5FCF +0x5FD0 0x5FD1 0x5FD2 0x5FD3 0x5FD6 0x5FD7 0x5FD8 0x5FD9 0x5FDC 0x5FDD 0x5FDE 0x5FDF 0x5FE0 0x5FE1 0x5FE3 0x5FE4 +0x5FE7 0x5FE8 0x5FEA 0x5FEB 0x5FED 0x5FEE 0x5FF0 0x5FF1 0x5FF3 0x5FF5 0x5FF8 0x5FFA 0x5FFB 0x5FFC 0x5FFD 0x5FFE +0x5FFF 0x6000 0x6001 0x6002 0x6003 0x6004 0x6005 0x6006 0x600A 0x600D 0x600E 0x600F 0x6010 0x6012 0x6014 0x6015 +0x6016 0x6017 0x6019 0x601B 0x601C 0x601D 0x6020 0x6021 0x6025 0x6026 0x6027 0x6028 0x6029 0x602A 0x602B 0x602F +0x6031 0x6033 0x6035 0x6039 0x603A 0x603B 0x603C 0x603F 0x6041 0x6042 0x6043 0x6046 0x6047 0x604A 0x604B 0x604D +0x604F 0x6050 0x6052 0x6053 0x6054 0x6055 0x6059 0x605A 0x605D 0x605F 0x6060 0x6062 0x6063 0x6064 0x6065 0x6067 +0x6068 0x6069 0x606A 0x606B 0x606C 0x606D 0x606F 0x6070 0x6073 0x6075 0x6076 0x6077 0x6078 0x6079 0x607A 0x607B +0x607C 0x607D 0x607F 0x6081 0x6083 0x6084 0x6085 0x6086 0x6088 0x6089 0x608B 0x608C 0x608D 0x6092 0x6094 0x6095 +0x6096 0x6097 0x609A 0x609B 0x609D 0x609E 0x609F 0x60A0 0x60A2 0x60A3 0x60A4 0x60A6 0x60A7 0x60A8 0x60A9 0x60AA +0x60AB 0x60AC 0x60AD 0x60AE 0x60AF 0x60B0 0x60B1 0x60B2 0x60B3 0x60B4 0x60B5 0x60B6 0x60B8 0x60BB 0x60BC 0x60BD +0x60BE 0x60C5 0x60C6 0x60C7 0x60CA 0x60CB 0x60CE 0x60D1 0x60D3 0x60D4 0x60D5 0x60D7 0x60D8 0x60D9 0x60DA 0x60DB +0x60DC 0x60DD 0x60DF 0x60E0 0x60E1 0x60E2 0x60E3 0x60E6 0x60E7 0x60E8 0x60E9 0x60EB 0x60EC 0x60ED 0x60EE 0x60EF +0x60F0 0x60F1 0x60F2 0x60F3 0x60F4 0x60F6 0x60F7 0x60F9 0x60FA 0x60FB 0x60FC 0x6100 0x6101 0x6103 0x6106 0x6108 +0x6109 0x610A 0x610D 0x610E 0x610F 0x6110 0x6112 0x6113 0x6114 0x6115 0x6116 0x611A 0x611B 0x611C 0x611F 0x6120 +0x6121 0x6123 0x6124 0x6126 0x6127 0x6128 0x612B 0x612C 0x612D 0x6130 0x6134 0x6137 0x613C 0x613D 0x613E 0x613F +0x6142 0x6144 0x6146 0x6147 0x6148 0x614A 0x614B 0x614C 0x614D 0x614E 0x6151 0x6153 0x6155 0x6158 0x6159 0x615A +0x615C 0x615D 0x615F 0x6160 0x6162 0x6163 0x6164 0x6165 0x6167 0x6168 0x616A 0x616B 0x616C 0x616D 0x616E 0x616F +0x6170 0x6171 0x6173 0x6174 0x6175 0x6176 0x6177 0x617C 0x617D 0x617E 0x6181 0x6182 0x6183 0x6187 0x618A 0x618B +0x618D 0x618E 0x618F 0x6190 0x6191 0x6192 0x6193 0x6194 0x6195 0x6196 0x6198 0x6199 0x619A 0x619D 0x61A4 0x61A7 +0x61A8 0x61A9 0x61AB 0x61AC 0x61AD 0x61AE 0x61AF 0x61B1 0x61B2 0x61B6 0x61B7 0x61B9 0x61BA 0x61BE 0x61C1 0x61C2 +0x61C3 0x61C6 0x61C7 0x61C8 0x61C9 0x61CA 0x61CB 0x61CC 0x61CD 0x61D0 0x61D1 0x61D2 0x61D4 0x61DE 0x61DF 0x61E3 +0x61E6 0x61E8 0x61F2 0x61F4 0x61F5 0x61F6 0x61F7 0x61F8 0x61FA 0x61FC 0x61FD 0x61FE 0x61FF 0x6200 0x6206 0x6207 +0x6208 0x6209 0x620A 0x620B 0x620C 0x620D 0x620E 0x620F 0x6210 0x6211 0x6212 0x6213 0x6214 0x6215 0x6216 0x6217 +0x6218 0x6219 0x621A 0x621B 0x621D 0x621E 0x621F 0x6221 0x6222 0x6223 0x6224 0x6225 0x6226 0x6227 0x6229 0x622A +0x622C 0x622D 0x622E 0x622F 0x6230 0x6231 0x6232 0x6233 0x6234 0x6236 0x6237 0x6238 0x623A 0x623B 0x623D 0x623E +0x623F 0x6240 0x6241 0x6242 0x6243 0x6245 0x6246 0x6247 0x6248 0x6249 0x624A 0x624B 0x624C 0x624D 0x624E 0x6250 +0x6251 0x6252 0x6253 0x6254 0x6255 0x6258 0x6259 0x625A 0x625B 0x625E 0x6260 0x6261 0x6263 0x6264 0x6265 0x6266 +0x6267 0x6268 0x6269 0x626A 0x626B 0x626C 0x626D 0x626E 0x626F 0x6270 0x6271 0x6273 0x6276 0x6279 0x627A 0x627C +0x627D 0x627E 0x627F 0x6280 0x6282 0x6283 0x6284 0x6286 0x6288 0x6289 0x628A 0x628C 0x628F 0x6291 0x6292 0x6293 +0x6294 0x6295 0x6296 0x6297 0x6298 0x629A 0x629B 0x629C 0x629E 0x629F 0x62A0 0x62A1 0x62A2 0x62A4 0x62A5 0x62A6 +0x62A8 0x62AB 0x62AC 0x62AE 0x62B1 0x62B5 0x62B6 0x62B9 0x62BA 0x62BB 0x62BC 0x62BD 0x62BF 0x62C2 0x62C3 0x62C4 +0x62C5 0x62C6 0x62C7 0x62C8 0x62C9 0x62CA 0x62CB 0x62CC 0x62CD 0x62CE 0x62CF 0x62D0 0x62D1 0x62D2 0x62D3 0x62D4 +0x62D6 0x62D7 0x62D8 0x62D9 0x62DA 0x62DB 0x62DC 0x62DD 0x62DF 0x62E0 0x62E1 0x62E2 0x62E3 0x62E4 0x62E5 0x62E6 +0x62E7 0x62E8 0x62E9 0x62EC 0x62ED 0x62EE 0x62EF 0x62F1 0x62F3 0x62F4 0x62F5 0x62F6 0x62F7 0x62FC 0x62FD 0x62FE +0x62FF 0x6301 0x6302 0x6307 0x6308 0x6309 0x630C 0x630E 0x6311 0x6313 0x6316 0x6319 0x631A 0x631B 0x631C 0x631D +0x631E 0x631F 0x6320 0x6321 0x6322 0x6323 0x6324 0x6325 0x6326 0x6327 0x6328 0x632A 0x632B 0x632F 0x6332 0x6335 +0x6339 0x633A 0x633B 0x633C 0x633D 0x633E 0x633F 0x6342 0x6343 0x6345 0x6346 0x6349 0x634B 0x634C 0x634D 0x634E +0x634F 0x6350 0x6355 0x6357 0x6358 0x635C 0x635E 0x635F 0x6361 0x6362 0x6363 0x6367 0x6368 0x6369 0x636B 0x636D +0x636E 0x636F 0x6371 0x6372 0x6376 0x6377 0x637A 0x637B 0x637D 0x637F 0x6380 0x6382 0x6383 0x6384 0x6387 0x6388 +0x6389 0x638A 0x638C 0x638E 0x638F 0x6390 0x6392 0x6396 0x6397 0x6398 0x6399 0x639B 0x639E 0x639F 0x63A0 0x63A1 +0x63A2 0x63A3 0x63A5 0x63A7 0x63A8 0x63A9 0x63AA 0x63AB 0x63AC 0x63AD 0x63AE 0x63AF 0x63B0 0x63B1 0x63B2 0x63B3 +0x63B4 0x63B5 0x63B7 0x63B8 0x63B9 0x63BA 0x63BB 0x63BC 0x63BE 0x63C0 0x63C3 0x63C4 0x63C5 0x63C6 0x63C8 0x63C9 +0x63CC 0x63CD 0x63CE 0x63CF 0x63D0 0x63D2 0x63D5 0x63D6 0x63DA 0x63DB 0x63DE 0x63E0 0x63E1 0x63E2 0x63E3 0x63E4 +0x63E6 0x63E9 0x63EA 0x63EC 0x63ED 0x63EE 0x63F2 0x63F3 0x63F4 0x63F6 0x63F7 0x63F8 0x63F9 0x63FA 0x63FB 0x63FC +0x63FD 0x63FE 0x63FF 0x6400 0x6401 0x6402 0x6405 0x6406 0x6407 0x640A 0x640B 0x640C 0x640D 0x640F 0x6410 0x6412 +0x6413 0x6414 0x6415 0x6416 0x6417 0x6419 0x641B 0x641C 0x641D 0x641E 0x6420 0x6421 0x6422 0x6423 0x6425 0x6426 +0x6427 0x6428 0x642A 0x642C 0x642D 0x6430 0x6432 0x6434 0x6435 0x6436 0x643A 0x643D 0x643E 0x643F 0x6440 0x6441 +0x6442 0x6443 0x6444 0x6445 0x6446 0x6447 0x6448 0x644A 0x644B 0x644E 0x644F 0x6451 0x6452 0x6454 0x6458 0x6459 +0x645B 0x645C 0x645E 0x645F 0x6460 0x6467 0x6469 0x646D 0x646F 0x6470 0x6471 0x6473 0x6474 0x6475 0x6476 0x6477 +0x6478 0x6479 0x647A 0x647B 0x647D 0x6482 0x6483 0x6484 0x6485 0x6487 0x6488 0x648D 0x648F 0x6490 0x6491 0x6492 +0x6493 0x6495 0x6496 0x6498 0x6499 0x649A 0x649D 0x649E 0x649F 0x64A2 0x64A3 0x64A4 0x64A5 0x64A9 0x64AB 0x64AC +0x64AD 0x64AE 0x64B0 0x64B2 0x64B3 0x64B4 0x64B5 0x64B7 0x64B8 0x64B9 0x64BA 0x64BB 0x64BC 0x64BE 0x64BF 0x64C0 +0x64C1 0x64C2 0x64C4 0x64C5 0x64C7 0x64CA 0x64CB 0x64CD 0x64CE 0x64D0 0x64D2 0x64D3 0x64D4 0x64D6 0x64D7 0x64D8 +0x64DA 0x64DD 0x64DE 0x64E0 0x64E1 0x64E2 0x64E3 0x64E4 0x64E5 0x64E6 0x64E7 0x64E9 0x64EC 0x64ED 0x64EF 0x64F0 +0x64F1 0x64F2 0x64F4 0x64F6 0x64F7 0x64F8 0x64FA 0x64FB 0x64FC 0x64FD 0x64FE 0x64FF 0x6500 0x6504 0x6505 0x6506 +0x6509 0x650F 0x6511 0x6512 0x6514 0x6516 0x6518 0x6519 0x651B 0x651C 0x651D 0x651E 0x6522 0x6523 0x6524 0x6525 +0x652A 0x652B 0x652C 0x652E 0x652F 0x6530 0x6534 0x6535 0x6536 0x6537 0x6538 0x6539 0x653A 0x653B 0x653D 0x653E +0x653F 0x6541 0x6543 0x6545 0x6548 0x6549 0x654C 0x654D 0x654E 0x654F 0x6551 0x6554 0x6555 0x6556 0x6557 0x6558 +0x6559 0x655B 0x655C 0x655D 0x655E 0x6560 0x6562 0x6563 0x6566 0x6569 0x656B 0x656C 0x656D 0x6570 0x6572 0x6574 +0x6575 0x6577 0x6578 0x6579 0x657E 0x6582 0x6583 0x6585 0x6586 0x6587 0x6588 0x6589 0x658B 0x658C 0x658E 0x658F +0x6590 0x6591 0x6593 0x6595 0x6597 0x6599 0x659B 0x659C 0x659D 0x659E 0x659F 0x65A0 0x65A1 0x65A2 0x65A4 0x65A5 +0x65A7 0x65A8 0x65A9 0x65AB 0x65AC 0x65AD 0x65AF 0x65B0 0x65B2 0x65B6 0x65B7 0x65B8 0x65B9 0x65BC 0x65BD 0x65C1 +0x65C2 0x65C3 0x65C4 0x65C5 0x65C6 0x65CB 0x65CC 0x65CE 0x65CF 0x65D0 0x65D2 0x65D6 0x65D7 0x65D9 0x65DB 0x65DE +0x65E0 0x65E1 0x65E2 0x65E3 0x65E5 0x65E6 0x65E7 0x65E8 0x65E9 0x65EC 0x65ED 0x65EE 0x65EF 0x65F0 0x65F1 0x65F2 +0x65F3 0x65F4 0x65F5 0x65F6 0x65F7 0x65F8 0x65FA 0x65FB 0x65FC 0x65FD 0x65FF 0x6600 0x6602 0x6603 0x6604 0x6605 +0x6606 0x6607 0x6608 0x6609 0x660A 0x660B 0x660C 0x660D 0x660E 0x660F 0x6610 0x6611 0x6612 0x6613 0x6614 0x6615 +0x6619 0x661A 0x661C 0x661D 0x661E 0x661F 0x6620 0x6621 0x6622 0x6623 0x6624 0x6625 0x6626 0x6627 0x6628 0x662A +0x662B 0x662D 0x662E 0x662F 0x6630 0x6631 0x6632 0x6633 0x6634 0x6635 0x6636 0x663A 0x663B 0x663C 0x663D 0x663E +0x663F 0x6641 0x6642 0x6643 0x6644 0x6645 0x6649 0x664A 0x664B 0x664C 0x664F 0x6650 0x6652 0x6653 0x6654 0x6655 +0x6656 0x6657 0x6659 0x665A 0x665B 0x665D 0x665E 0x665F 0x6661 0x6662 0x6664 0x6665 0x6666 0x6667 0x6668 0x6669 +0x666A 0x666B 0x666C 0x666E 0x666F 0x6670 0x6671 0x6673 0x6674 0x6676 0x6677 0x6678 0x6679 0x667A 0x667B 0x667E +0x6681 0x6682 0x6683 0x6684 0x6685 0x6687 0x6688 0x6689 0x668B 0x668C 0x668D 0x668E 0x6690 0x6691 0x6692 0x6695 +0x6696 0x6697 0x6698 0x669D 0x66A0 0x66A2 0x66A3 0x66A6 0x66A7 0x66A8 0x66AA 0x66AB 0x66AE 0x66B1 0x66B2 0x66B3 +0x66B4 0x66B5 0x66B6 0x66B8 0x66B9 0x66BB 0x66BC 0x66BE 0x66BF 0x66C1 0x66C4 0x66C6 0x66C7 0x66C8 0x66C9 0x66CC +0x66D6 0x66D9 0x66DA 0x66DB 0x66DC 0x66DD 0x66E0 0x66E3 0x66E6 0x66E8 0x66E9 0x66EC 0x66EF 0x66F0 0x66F1 0x66F2 +0x66F3 0x66F4 0x66F5 0x66F7 0x66F8 0x66F9 0x66FA 0x66FC 0x66FD 0x66FE 0x66FF 0x6700 0x6701 0x6703 0x6706 0x6708 +0x6709 0x670A 0x670B 0x670D 0x670F 0x6710 0x6711 0x6712 0x6713 0x6714 0x6715 0x6716 0x6717 0x6718 0x671B 0x671D +0x671E 0x671F 0x6723 0x6725 0x6726 0x6727 0x6728 0x6729 0x672A 0x672B 0x672C 0x672D 0x672E 0x672F 0x6730 0x6731 +0x6732 0x6733 0x6734 0x6735 0x6736 0x6737 0x6738 0x673A 0x673D 0x673F 0x6740 0x6741 0x6742 0x6743 0x6744 0x6745 +0x6746 0x6748 0x6749 0x674B 0x674C 0x674E 0x674F 0x6750 0x6751 0x6753 0x6755 0x6756 0x6757 0x6759 0x675C 0x675E +0x675F 0x6760 0x6761 0x6762 0x6763 0x6764 0x6765 0x6767 0x6768 0x6769 0x676A 0x676D 0x676E 0x676F 0x6770 0x6771 +0x6772 0x6773 0x6774 0x6775 0x6777 0x677A 0x677B 0x677C 0x677E 0x677F 0x6781 0x6784 0x6785 0x6787 0x6789 0x678B +0x678C 0x678D 0x678F 0x6790 0x6791 0x6792 0x6793 0x6795 0x6797 0x6798 0x6799 0x679A 0x679C 0x679D 0x679E 0x679F +0x67A0 0x67A1 0x67A2 0x67A3 0x67A5 0x67A6 0x67A7 0x67A8 0x67A9 0x67AA 0x67AB 0x67AD 0x67AF 0x67B0 0x67B1 0x67B2 +0x67B3 0x67B4 0x67B5 0x67B6 0x67B7 0x67B8 0x67B9 0x67BE 0x67C1 0x67C3 0x67C4 0x67C6 0x67C8 0x67CA 0x67CE 0x67CF +0x67D0 0x67D1 0x67D2 0x67D3 0x67D4 0x67D6 0x67D8 0x67D9 0x67DA 0x67DC 0x67DD 0x67DE 0x67E0 0x67E2 0x67E4 0x67E5 +0x67E7 0x67E9 0x67EC 0x67EE 0x67EF 0x67F0 0x67F1 0x67F3 0x67F4 0x67F5 0x67F6 0x67F7 0x67FA 0x67FB 0x67FD 0x67FE +0x67FF 0x6800 0x6802 0x6803 0x6804 0x6805 0x6807 0x6808 0x6809 0x680A 0x680B 0x680C 0x680E 0x680F 0x6810 0x6811 +0x6812 0x6813 0x6814 0x6816 0x6817 0x6818 0x681D 0x681E 0x681F 0x6821 0x6822 0x6829 0x682A 0x682B 0x682F 0x6832 +0x6833 0x6834 0x6837 0x6838 0x6839 0x683B 0x683C 0x683D 0x683E 0x683F 0x6840 0x6841 0x6842 0x6843 0x6844 0x6845 +0x6846 0x6848 0x6849 0x684A 0x684B 0x684C 0x684D 0x684E 0x6850 0x6851 0x6853 0x6854 0x6855 0x6859 0x685C 0x685D +0x685F 0x6860 0x6861 0x6862 0x6863 0x6864 0x6865 0x6866 0x6867 0x6868 0x6869 0x686A 0x686B 0x686C 0x686D 0x686F +0x6872 0x6874 0x6876 0x6877 0x6879 0x687E 0x687F 0x6881 0x6882 0x6883 0x6885 0x6886 0x6887 0x688C 0x688D 0x688F +0x6890 0x6893 0x6894 0x6897 0x6898 0x689B 0x689C 0x689D 0x689F 0x68A0 0x68A1 0x68A2 0x68A3 0x68A6 0x68A7 0x68A8 +0x68AD 0x68AF 0x68B0 0x68B1 0x68B2 0x68B3 0x68B4 0x68B5 0x68B6 0x68B9 0x68BA 0x68BC 0x68BD 0x68BE 0x68BF 0x68C0 +0x68C1 0x68C2 0x68C4 0x68C5 0x68C6 0x68C9 0x68CA 0x68CB 0x68CD 0x68D0 0x68D1 0x68D2 0x68D3 0x68D4 0x68D5 0x68D6 +0x68D7 0x68D8 0x68DA 0x68DF 0x68E0 0x68E1 0x68E3 0x68E4 0x68E7 0x68E8 0x68EA 0x68EB 0x68EC 0x68EE 0x68EF 0x68F0 +0x68F1 0x68F2 0x68F5 0x68F6 0x68F8 0x68F9 0x68FA 0x68FB 0x68FC 0x68FD 0x6900 0x6901 0x6904 0x6905 0x6906 0x6907 +0x6908 0x690B 0x690C 0x690D 0x690E 0x690F 0x6910 0x6911 0x6912 0x6913 0x6919 0x691A 0x691B 0x691C 0x691D 0x691F +0x6920 0x6921 0x6922 0x6923 0x6924 0x6925 0x6926 0x6927 0x6928 0x692A 0x692B 0x692D 0x6930 0x6934 0x6935 0x6936 +0x6938 0x6939 0x693D 0x693F 0x6940 0x6942 0x694A 0x6952 0x6953 0x6954 0x6955 0x6957 0x6959 0x695A 0x695B 0x695C +0x695D 0x695E 0x695F 0x6960 0x6961 0x6962 0x6963 0x6966 0x6968 0x6969 0x696A 0x696B 0x696C 0x696D 0x696E 0x696F +0x6971 0x6973 0x6974 0x6975 0x6977 0x6978 0x6979 0x697C 0x697D 0x697E 0x6980 0x6981 0x6982 0x6983 0x6984 0x6985 +0x6986 0x6987 0x6988 0x6989 0x698A 0x698D 0x698E 0x6991 0x6994 0x6995 0x6996 0x6998 0x699B 0x699C 0x69A0 0x69A3 +0x69A5 0x69A6 0x69A7 0x69A8 0x69AA 0x69AB 0x69AD 0x69AE 0x69B0 0x69B1 0x69B2 0x69B4 0x69B7 0x69BB 0x69BC 0x69BE +0x69BF 0x69C1 0x69C3 0x69C5 0x69C7 0x69CA 0x69CB 0x69CC 0x69CD 0x69CE 0x69CF 0x69D0 0x69D1 0x69D3 0x69D4 0x69D8 +0x69D9 0x69DA 0x69DB 0x69DC 0x69DD 0x69DE 0x69DF 0x69E0 0x69E4 0x69E5 0x69E7 0x69E8 0x69EA 0x69EB 0x69ED 0x69F1 +0x69F2 0x69F3 0x69F9 0x69FA 0x69FB 0x69FC 0x69FD 0x69FE 0x69FF 0x6A01 0x6A02 0x6A05 0x6A0A 0x6A0B 0x6A0C 0x6A11 +0x6A12 0x6A13 0x6A14 0x6A17 0x6A18 0x6A19 0x6A1B 0x6A1E 0x6A1F 0x6A21 0x6A22 0x6A23 0x6A28 0x6A29 0x6A2A 0x6A2B +0x6A2E 0x6A2F 0x6A31 0x6A33 0x6A35 0x6A36 0x6A38 0x6A39 0x6A3A 0x6A3D 0x6A3E 0x6A3F 0x6A44 0x6A47 0x6A48 0x6A4B +0x6A50 0x6A51 0x6A52 0x6A53 0x6A58 0x6A59 0x6A5A 0x6A5B 0x6A5E 0x6A5F 0x6A61 0x6A62 0x6A65 0x6A66 0x6A6B 0x6A71 +0x6A72 0x6A74 0x6A78 0x6A79 0x6A7C 0x6A7D 0x6A7E 0x6A7F 0x6A80 0x6A81 0x6A84 0x6A87 0x6A89 0x6A8D 0x6A8E 0x6A90 +0x6A91 0x6A94 0x6A96 0x6A97 0x6A9C 0x6A9E 0x6A9F 0x6AA0 0x6AA2 0x6AA3 0x6AA8 0x6AA9 0x6AAA 0x6AAB 0x6AAC 0x6AAE +0x6AAF 0x6AB3 0x6AB4 0x6AB5 0x6AB8 0x6ABB 0x6AC1 0x6AC2 0x6AC3 0x6AC6 0x6AC8 0x6ACD 0x6AD1 0x6AD3 0x6ADA 0x6ADB +0x6ADD 0x6ADE 0x6ADF 0x6AE5 0x6AE7 0x6AE8 0x6AEA 0x6AEB 0x6AEC 0x6AF1 0x6AF3 0x6AF6 0x6AF8 0x6AFA 0x6AFB 0x6AFC +0x6B02 0x6B04 0x6B05 0x6B09 0x6B0A 0x6B0C 0x6B0F 0x6B10 0x6B12 0x6B13 0x6B16 0x6B17 0x6B1D 0x6B1E 0x6B1F 0x6B20 +0x6B21 0x6B22 0x6B23 0x6B24 0x6B27 0x6B2C 0x6B32 0x6B37 0x6B38 0x6B39 0x6B3A 0x6B3B 0x6B3D 0x6B3E 0x6B3F 0x6B43 +0x6B45 0x6B46 0x6B47 0x6B49 0x6B4C 0x6B4E 0x6B50 0x6B53 0x6B54 0x6B58 0x6B59 0x6B5B 0x6B5C 0x6B5F 0x6B61 0x6B62 +0x6B63 0x6B64 0x6B65 0x6B66 0x6B67 0x6B69 0x6B6A 0x6B6C 0x6B6F 0x6B72 0x6B73 0x6B74 0x6B77 0x6B78 0x6B79 0x6B7A +0x6B7B 0x6B7C 0x6B7F 0x6B80 0x6B81 0x6B82 0x6B83 0x6B84 0x6B86 0x6B87 0x6B89 0x6B8A 0x6B8B 0x6B8D 0x6B92 0x6B93 +0x6B95 0x6B96 0x6B98 0x6B9A 0x6B9B 0x6B9E 0x6BA1 0x6BA2 0x6BA3 0x6BA4 0x6BAA 0x6BAB 0x6BAD 0x6BAE 0x6BAF 0x6BB1 +0x6BB2 0x6BB3 0x6BB4 0x6BB5 0x6BB7 0x6BBA 0x6BBB 0x6BBC 0x6BBD 0x6BBF 0x6BC0 0x6BC1 0x6BC2 0x6BC5 0x6BC6 0x6BCB +0x6BCC 0x6BCD 0x6BCE 0x6BCF 0x6BD0 0x6BD1 0x6BD2 0x6BD3 0x6BD4 0x6BD5 0x6BD6 0x6BD7 0x6BD8 0x6BD9 0x6BDA 0x6BDB +0x6BDF 0x6BE1 0x6BEA 0x6BEB 0x6BEC 0x6BEF 0x6BF3 0x6BF4 0x6BF5 0x6BF7 0x6BF9 0x6BFD 0x6BFF 0x6C02 0x6C05 0x6C06 +0x6C07 0x6C08 0x6C09 0x6C0A 0x6C0C 0x6C0D 0x6C0F 0x6C10 0x6C11 0x6C13 0x6C14 0x6C15 0x6C16 0x6C17 0x6C18 0x6C19 +0x6C1A 0x6C1B 0x6C1C 0x6C1D 0x6C1E 0x6C1F 0x6C20 0x6C21 0x6C22 0x6C23 0x6C24 0x6C25 0x6C26 0x6C27 0x6C28 0x6C29 +0x6C2A 0x6C2B 0x6C2C 0x6C2D 0x6C2E 0x6C2F 0x6C30 0x6C31 0x6C32 0x6C33 0x6C34 0x6C35 0x6C36 0x6C37 0x6C38 0x6C39 +0x6C3A 0x6C3B 0x6C3C 0x6C3D 0x6C3E 0x6C3F 0x6C40 0x6C41 0x6C42 0x6C43 0x6C46 0x6C47 0x6C48 0x6C49 0x6C4A 0x6C4B +0x6C4D 0x6C4E 0x6C4F 0x6C50 0x6C54 0x6C55 0x6C57 0x6C59 0x6C5A 0x6C5B 0x6C5C 0x6C5D 0x6C5E 0x6C5F 0x6C60 0x6C61 +0x6C62 0x6C64 0x6C67 0x6C68 0x6C69 0x6C6A 0x6C6B 0x6C6D 0x6C70 0x6C72 0x6C73 0x6C74 0x6C76 0x6C78 0x6C79 0x6C7A +0x6C7D 0x6C7E 0x6C81 0x6C82 0x6C83 0x6C84 0x6C85 0x6C86 0x6C87 0x6C88 0x6C89 0x6C8C 0x6C8D 0x6C8F 0x6C90 0x6C92 +0x6C93 0x6C94 0x6C95 0x6C96 0x6C98 0x6C99 0x6C9A 0x6C9B 0x6C9C 0x6C9F 0x6CA1 0x6CA2 0x6CA3 0x6CA4 0x6CA5 0x6CA6 +0x6CA7 0x6CA8 0x6CA9 0x6CAA 0x6CAB 0x6CAC 0x6CAD 0x6CAE 0x6CB1 0x6CB2 0x6CB3 0x6CB5 0x6CB8 0x6CB9 0x6CBA 0x6CBB +0x6CBC 0x6CBD 0x6CBE 0x6CBF 0x6CC1 0x6CC2 0x6CC3 0x6CC4 0x6CC5 0x6CC6 0x6CC7 0x6CC9 0x6CCA 0x6CCC 0x6CD0 0x6CD3 +0x6CD4 0x6CD5 0x6CD6 0x6CD7 0x6CD9 0x6CDA 0x6CDB 0x6CDC 0x6CDD 0x6CDE 0x6CE0 0x6CE1 0x6CE2 0x6CE3 0x6CE5 0x6CE8 +0x6CEA 0x6CEB 0x6CEE 0x6CEF 0x6CF0 0x6CF1 0x6CF3 0x6CF5 0x6CF6 0x6CF7 0x6CF8 0x6CFA 0x6CFB 0x6CFC 0x6CFD 0x6CFE +0x6D01 0x6D04 0x6D05 0x6D07 0x6D08 0x6D0B 0x6D0C 0x6D0D 0x6D0E 0x6D10 0x6D11 0x6D12 0x6D13 0x6D16 0x6D17 0x6D18 +0x6D19 0x6D1A 0x6D1B 0x6D1E 0x6D1F 0x6D22 0x6D23 0x6D25 0x6D27 0x6D28 0x6D29 0x6D2A 0x6D2B 0x6D2D 0x6D2E 0x6D31 +0x6D32 0x6D33 0x6D34 0x6D35 0x6D36 0x6D38 0x6D39 0x6D3A 0x6D3B 0x6D3C 0x6D3D 0x6D3E 0x6D3F 0x6D41 0x6D43 0x6D44 +0x6D45 0x6D46 0x6D47 0x6D48 0x6D49 0x6D4A 0x6D4B 0x6D4D 0x6D4E 0x6D4F 0x6D50 0x6D51 0x6D52 0x6D53 0x6D54 0x6D55 +0x6D59 0x6D5A 0x6D5B 0x6D5C 0x6D5E 0x6D5F 0x6D60 0x6D61 0x6D63 0x6D64 0x6D65 0x6D66 0x6D69 0x6D6A 0x6D6C 0x6D6D +0x6D6E 0x6D6F 0x6D70 0x6D72 0x6D74 0x6D77 0x6D78 0x6D79 0x6D7B 0x6D7C 0x6D7F 0x6D82 0x6D84 0x6D85 0x6D87 0x6D88 +0x6D89 0x6D8A 0x6D8C 0x6D8D 0x6D8E 0x6D8F 0x6D90 0x6D91 0x6D93 0x6D94 0x6D95 0x6D97 0x6D98 0x6D99 0x6D9A 0x6D9B +0x6D9C 0x6D9D 0x6D9E 0x6D9F 0x6DA0 0x6DA1 0x6DA2 0x6DA3 0x6DA4 0x6DA6 0x6DA7 0x6DA8 0x6DA9 0x6DAA 0x6DAB 0x6DAD +0x6DAE 0x6DAF 0x6DB2 0x6DB4 0x6DB5 0x6DB7 0x6DB8 0x6DBC 0x6DBF 0x6DC0 0x6DC3 0x6DC4 0x6DC5 0x6DC6 0x6DC7 0x6DCB +0x6DCC 0x6DCD 0x6DCF 0x6DD1 0x6DD2 0x6DD5 0x6DD6 0x6DD8 0x6DD9 0x6DDA 0x6DDC 0x6DDD 0x6DDE 0x6DDF 0x6DE0 0x6DE1 +0x6DE4 0x6DE5 0x6DE6 0x6DE8 0x6DE9 0x6DEA 0x6DEB 0x6DEC 0x6DEE 0x6DEF 0x6DF1 0x6DF3 0x6DF4 0x6DF5 0x6DF6 0x6DF7 +0x6DF8 0x6DF9 0x6DFA 0x6DFB 0x6DFC 0x6DFD 0x6E05 0x6E07 0x6E08 0x6E09 0x6E0A 0x6E0B 0x6E0C 0x6E0D 0x6E0E 0x6E10 +0x6E11 0x6E13 0x6E14 0x6E15 0x6E16 0x6E17 0x6E19 0x6E1A 0x6E1B 0x6E1D 0x6E1F 0x6E20 0x6E21 0x6E22 0x6E23 0x6E24 +0x6E25 0x6E26 0x6E29 0x6E2B 0x6E2C 0x6E2D 0x6E2E 0x6E2F 0x6E30 0x6E32 0x6E34 0x6E36 0x6E38 0x6E3A 0x6E3C 0x6E3D +0x6E3E 0x6E43 0x6E44 0x6E49 0x6E4A 0x6E4B 0x6E4D 0x6E4E 0x6E51 0x6E53 0x6E54 0x6E56 0x6E58 0x6E5B 0x6E5C 0x6E5D +0x6E5E 0x6E5F 0x6E61 0x6E62 0x6E63 0x6E66 0x6E67 0x6E68 0x6E69 0x6E6A 0x6E6B 0x6E6E 0x6E6F 0x6E72 0x6E73 0x6E74 +0x6E76 0x6E7A 0x6E7B 0x6E7E 0x6E7F 0x6E80 0x6E81 0x6E82 0x6E83 0x6E85 0x6E86 0x6E87 0x6E88 0x6E89 0x6E8C 0x6E8D +0x6E8E 0x6E8F 0x6E90 0x6E96 0x6E98 0x6E9A 0x6E9C 0x6E9D 0x6E9E 0x6E9F 0x6EA0 0x6EA2 0x6EA5 0x6EA6 0x6EA7 0x6EAA +0x6EAB 0x6EAE 0x6EAF 0x6EB1 0x6EB2 0x6EB3 0x6EB4 0x6EB5 0x6EB6 0x6EB7 0x6EB9 0x6EBA 0x6EBB 0x6EBC 0x6EBD 0x6EC1 +0x6EC2 0x6EC3 0x6EC4 0x6EC5 0x6EC6 0x6EC7 0x6EC8 0x6EC9 0x6ECB 0x6ECC 0x6ECD 0x6ECE 0x6ECF 0x6ED1 0x6ED3 0x6ED4 +0x6ED5 0x6ED7 0x6ED8 0x6ED9 0x6EDA 0x6EDD 0x6EDE 0x6EDF 0x6EE0 0x6EE1 0x6EE2 0x6EE4 0x6EE5 0x6EE6 0x6EE7 0x6EE8 +0x6EE9 0x6EEA 0x6EEB 0x6EEC 0x6EEE 0x6EEF 0x6EF2 0x6EF4 0x6EF7 0x6EF8 0x6EF9 0x6EFB 0x6EFE 0x6EFF 0x6F01 0x6F02 +0x6F06 0x6F08 0x6F09 0x6F0A 0x6F0B 0x6F0C 0x6F0D 0x6F0F 0x6F11 0x6F13 0x6F14 0x6F15 0x6F16 0x6F1A 0x6F20 0x6F22 +0x6F23 0x6F24 0x6F25 0x6F26 0x6F27 0x6F29 0x6F2A 0x6F2B 0x6F2C 0x6F2D 0x6F2F 0x6F30 0x6F31 0x6F32 0x6F33 0x6F34 +0x6F35 0x6F36 0x6F37 0x6F38 0x6F39 0x6F3B 0x6F3C 0x6F3E 0x6F3F 0x6F41 0x6F45 0x6F46 0x6F47 0x6F4A 0x6F4B 0x6F4D +0x6F4F 0x6F51 0x6F54 0x6F55 0x6F56 0x6F57 0x6F58 0x6F59 0x6F5A 0x6F5B 0x6F5C 0x6F5E 0x6F5F 0x6F60 0x6F62 0x6F63 +0x6F64 0x6F66 0x6F69 0x6F6D 0x6F6E 0x6F6F 0x6F70 0x6F72 0x6F74 0x6F75 0x6F76 0x6F77 0x6F78 0x6F7A 0x6F7C 0x6F7D +0x6F7E 0x6F7F 0x6F80 0x6F81 0x6F82 0x6F84 0x6F86 0x6F87 0x6F88 0x6F89 0x6F8C 0x6F8D 0x6F8E 0x6F90 0x6F91 0x6F92 +0x6F94 0x6F97 0x6F9B 0x6F9C 0x6FA0 0x6FA1 0x6FA3 0x6FA4 0x6FA5 0x6FA6 0x6FA7 0x6FA8 0x6FA9 0x6FAA 0x6FAB 0x6FAD +0x6FAE 0x6FAF 0x6FB1 0x6FB3 0x6FB4 0x6FB6 0x6FB9 0x6FBC 0x6FBD 0x6FBE 0x6FC0 0x6FC1 0x6FC2 0x6FC3 0x6FC6 0x6FC7 +0x6FC9 0x6FCA 0x6FCB 0x6FD1 0x6FD2 0x6FD4 0x6FD5 0x6FD8 0x6FDA 0x6FDB 0x6FDC 0x6FDE 0x6FDF 0x6FE0 0x6FE1 0x6FE4 +0x6FE8 0x6FE9 0x6FEB 0x6FEC 0x6FEE 0x6FEF 0x6FF0 0x6FF1 0x6FF3 0x6FF6 0x6FFA 0x6FFC 0x6FFE 0x7001 0x7002 0x7005 +0x7006 0x7009 0x700B 0x700C 0x700D 0x700F 0x7011 0x7014 0x7015 0x7018 0x701A 0x701B 0x701C 0x701D 0x701E 0x701F +0x7020 0x7021 0x7023 0x7026 0x7027 0x7028 0x702C 0x702F 0x7030 0x7031 0x7032 0x7035 0x7037 0x7039 0x703C 0x703E +0x7043 0x7044 0x7048 0x704C 0x704F 0x7050 0x7051 0x7054 0x7055 0x7058 0x705D 0x705E 0x7060 0x7063 0x7064 0x7065 +0x7067 0x7069 0x706B 0x706C 0x706D 0x706F 0x7070 0x7074 0x7075 0x7076 0x7078 0x707A 0x707C 0x707D 0x707E 0x707F +0x7080 0x7081 0x7085 0x7086 0x7089 0x708A 0x708C 0x708E 0x7092 0x7094 0x7095 0x7096 0x7098 0x7099 0x709A 0x709C +0x709D 0x709E 0x709F 0x70A1 0x70A3 0x70A4 0x70A9 0x70AB 0x70AC 0x70AD 0x70AE 0x70AF 0x70B0 0x70B1 0x70B3 0x70B5 +0x70B7 0x70B8 0x70B9 0x70BA 0x70BB 0x70BC 0x70BD 0x70C0 0x70C1 0x70C2 0x70C3 0x70C7 0x70C8 0x70CA 0x70CB 0x70CE +0x70CF 0x70D3 0x70D4 0x70D8 0x70D9 0x70DA 0x70DB 0x70DC 0x70DD 0x70DF 0x70E0 0x70E4 0x70E6 0x70E7 0x70E8 0x70E9 +0x70EB 0x70EC 0x70ED 0x70EF 0x70F1 0x70F4 0x70F6 0x70F7 0x70F9 0x70FA 0x70FB 0x70FD 0x7104 0x7106 0x7109 0x710A +0x710C 0x7110 0x7113 0x7114 0x7115 0x7116 0x7117 0x7118 0x7119 0x711A 0x711C 0x711E 0x7120 0x7121 0x7122 0x7126 +0x712E 0x712F 0x7130 0x7131 0x7136 0x713A 0x713C 0x713F 0x7140 0x7141 0x7143 0x7145 0x7146 0x7147 0x7149 0x714A +0x714B 0x714C 0x714E 0x714F 0x7150 0x7151 0x7152 0x7153 0x7155 0x7156 0x7159 0x715A 0x715C 0x715E 0x715F 0x7162 +0x7163 0x7164 0x7165 0x7166 0x7167 0x7168 0x7169 0x716C 0x716E 0x7172 0x7173 0x7174 0x7178 0x717A 0x717D 0x717F +0x7180 0x7184 0x7185 0x7187 0x7188 0x7189 0x718A 0x718F 0x7190 0x7192 0x7194 0x7195 0x7197 0x7198 0x7199 0x719B +0x719C 0x719F 0x71A0 0x71A2 0x71A5 0x71A8 0x71AC 0x71AF 0x71B0 0x71B1 0x71B2 0x71B3 0x71B5 0x71B9 0x71BA 0x71BB +0x71BE 0x71C0 0x71C1 0x71C3 0x71C4 0x71C8 0x71C9 0x71CA 0x71CB 0x71CE 0x71CF 0x71D0 0x71D2 0x71D4 0x71D5 0x71D6 +0x71D7 0x71D9 0x71DA 0x71DC 0x71DF 0x71E0 0x71E1 0x71E5 0x71E6 0x71E7 0x71EC 0x71ED 0x71EE 0x71F4 0x71F5 0x71F6 +0x71F8 0x71F9 0x71FB 0x71FC 0x71FE 0x71FF 0x7200 0x7201 0x7206 0x7207 0x720C 0x720D 0x7210 0x7213 0x7214 0x7215 +0x721A 0x721B 0x721D 0x721F 0x7228 0x722A 0x722B 0x722C 0x722D 0x7230 0x7231 0x7232 0x7235 0x7236 0x7237 0x7238 +0x7239 0x723A 0x723B 0x723C 0x723D 0x723E 0x723F 0x7240 0x7241 0x7242 0x7246 0x7247 0x7248 0x724B 0x724C 0x724D +0x7252 0x7256 0x7258 0x7259 0x725A 0x725B 0x725D 0x725E 0x725F 0x7260 0x7261 0x7262 0x7263 0x7264 0x7265 0x7266 +0x7267 0x7269 0x726E 0x726F 0x7272 0x7274 0x7275 0x7277 0x7278 0x7279 0x727A 0x727B 0x727D 0x727E 0x727F 0x7280 +0x7281 0x7282 0x7284 0x7287 0x728A 0x728B 0x728D 0x728F 0x7292 0x7296 0x7297 0x729B 0x729F 0x72A0 0x72A1 0x72A2 +0x72A7 0x72A8 0x72AC 0x72AD 0x72AE 0x72AF 0x72B0 0x72B2 0x72B4 0x72B6 0x72B7 0x72B8 0x72B9 0x72BC 0x72C0 0x72C1 +0x72C2 0x72C3 0x72C4 0x72C6 0x72C8 0x72C9 0x72CD 0x72CE 0x72D0 0x72D2 0x72D3 0x72D7 0x72D9 0x72DB 0x72DD 0x72DE +0x72DF 0x72E0 0x72E1 0x72E2 0x72E8 0x72E9 0x72EC 0x72ED 0x72EE 0x72EF 0x72F0 0x72F1 0x72F2 0x72F3 0x72F4 0x72F7 +0x72F8 0x72F9 0x72FA 0x72FB 0x72FC 0x72FD 0x7301 0x7303 0x7304 0x7306 0x7307 0x730A 0x730B 0x730E 0x7313 0x7314 +0x7315 0x7316 0x7317 0x7319 0x731B 0x731C 0x731D 0x731E 0x731F 0x7321 0x7322 0x7325 0x7329 0x732A 0x732B 0x732C +0x732E 0x732F 0x7330 0x7331 0x7334 0x7336 0x7337 0x7338 0x7339 0x733A 0x733B 0x733E 0x733F 0x7341 0x7343 0x7344 +0x7345 0x7347 0x734D 0x734E 0x734F 0x7350 0x7352 0x7355 0x7357 0x735A 0x735B 0x7360 0x7362 0x7363 0x7364 0x7368 +0x736A 0x736B 0x736C 0x736D 0x736E 0x736F 0x7370 0x7372 0x7374 0x7375 0x7377 0x7378 0x737A 0x737B 0x737C 0x737E +0x7380 0x7381 0x7383 0x7384 0x7386 0x7387 0x7389 0x738A 0x738B 0x738E 0x738F 0x7391 0x7392 0x7393 0x7394 0x7395 +0x7396 0x7397 0x7398 0x7399 0x739A 0x739B 0x739E 0x739F 0x73A0 0x73A1 0x73A2 0x73A4 0x73A5 0x73A6 0x73A7 0x73A8 +0x73A9 0x73AB 0x73AD 0x73AE 0x73AF 0x73B0 0x73B1 0x73B2 0x73B3 0x73B5 0x73B6 0x73B7 0x73B9 0x73BA 0x73BB 0x73BC +0x73BD 0x73BF 0x73C0 0x73C2 0x73C3 0x73C4 0x73C5 0x73C7 0x73C8 0x73C9 0x73CA 0x73CB 0x73CC 0x73CD 0x73CE 0x73CF +0x73D0 0x73D1 0x73D2 0x73D5 0x73D6 0x73D7 0x73D9 0x73DB 0x73DD 0x73DE 0x73E0 0x73E1 0x73E2 0x73E3 0x73E4 0x73E5 +0x73E6 0x73E7 0x73E8 0x73E9 0x73EA 0x73EB 0x73ED 0x73EE 0x73F0 0x73F1 0x73F2 0x73F5 0x73F6 0x73F7 0x73F8 0x73F9 +0x73FA 0x73FD 0x73FE 0x7400 0x7401 0x7402 0x7403 0x7404 0x7405 0x7406 0x7407 0x7408 0x7409 0x740A 0x740D 0x740E +0x740F 0x7410 0x7413 0x7414 0x7415 0x741A 0x741B 0x741E 0x741F 0x7420 0x7421 0x7422 0x7424 0x7425 0x7426 0x7428 +0x742A 0x742B 0x742C 0x742D 0x742E 0x742F 0x7430 0x7431 0x7432 0x7433 0x7434 0x7435 0x7436 0x7437 0x7438 0x743A +0x743C 0x743F 0x7440 0x7441 0x7442 0x7443 0x7444 0x7445 0x7446 0x744A 0x744B 0x744C 0x7451 0x7452 0x7453 0x7454 +0x7455 0x7456 0x7457 0x7459 0x745A 0x745B 0x745C 0x745D 0x745E 0x745F 0x7460 0x7462 0x7463 0x7464 0x7465 0x7467 +0x7468 0x7469 0x746A 0x746C 0x746D 0x746F 0x7470 0x7471 0x7472 0x7473 0x7476 0x7477 0x7478 0x747D 0x747E 0x7480 +0x7481 0x7482 0x7483 0x7486 0x7487 0x7488 0x7489 0x748A 0x748B 0x748E 0x748F 0x7490 0x7492 0x7495 0x7497 0x7498 +0x749C 0x749E 0x749F 0x74A0 0x74A1 0x74A2 0x74A3 0x74A4 0x74A5 0x74A6 0x74A7 0x74A8 0x74A9 0x74AA 0x74AB 0x74AC +0x74AE 0x74B0 0x74B1 0x74B2 0x74B5 0x74B8 0x74B9 0x74BA 0x74BD 0x74BF 0x74C0 0x74C5 0x74C6 0x74C8 0x74CA 0x74CC +0x74CF 0x74D2 0x74D3 0x74D4 0x74D6 0x74D8 0x74DA 0x74DB 0x74DC 0x74DE 0x74E0 0x74E2 0x74E3 0x74E4 0x74E6 0x74E7 +0x74E9 0x74EE 0x74EF 0x74F0 0x74F1 0x74F2 0x74F4 0x74F6 0x74F7 0x74F8 0x74FB 0x74FF 0x7501 0x7503 0x7504 0x7505 +0x7507 0x750C 0x750D 0x750E 0x750F 0x7511 0x7513 0x7515 0x7516 0x7517 0x7518 0x7519 0x751A 0x751B 0x751C 0x751D +0x751E 0x751F 0x7521 0x7522 0x7523 0x7525 0x7526 0x7528 0x7529 0x752A 0x752B 0x752C 0x752D 0x752E 0x752F 0x7530 +0x7531 0x7532 0x7533 0x7534 0x7535 0x7537 0x7538 0x7539 0x753A 0x753B 0x753C 0x753D 0x753E 0x753F 0x7540 0x7544 +0x7545 0x7546 0x7547 0x7548 0x7549 0x754A 0x754B 0x754C 0x754D 0x754E 0x754F 0x7551 0x7553 0x7554 0x7556 0x7559 +0x755A 0x755B 0x755C 0x755D 0x755F 0x7560 0x7562 0x7563 0x7564 0x7565 0x7566 0x7567 0x7569 0x756A 0x756B 0x756C +0x756D 0x756F 0x7570 0x7572 0x7573 0x7574 0x7575 0x7576 0x7577 0x7578 0x7579 0x757A 0x757D 0x757E 0x757F 0x7580 +0x7581 0x7582 0x7583 0x7584 0x7586 0x7587 0x7589 0x758A 0x758B 0x758C 0x758D 0x758E 0x758F 0x7590 0x7591 0x7592 +0x7594 0x7595 0x7596 0x7597 0x7598 0x7599 0x759A 0x759D 0x759F 0x75A0 0x75A1 0x75A2 0x75A3 0x75A4 0x75A5 0x75A7 +0x75AA 0x75AB 0x75AC 0x75AD 0x75AE 0x75AF 0x75B0 0x75B1 0x75B2 0x75B3 0x75B4 0x75B5 0x75B6 0x75B8 0x75B9 0x75BA +0x75BB 0x75BC 0x75BD 0x75BE 0x75BF 0x75C0 0x75C1 0x75C2 0x75C3 0x75C4 0x75C5 0x75C7 0x75C8 0x75C9 0x75CA 0x75CB +0x75CC 0x75CD 0x75CE 0x75CF 0x75D0 0x75D1 0x75D2 0x75D3 0x75D4 0x75D5 0x75D6 0x75D7 0x75D8 0x75D9 0x75DA 0x75DB +0x75DD 0x75DE 0x75DF 0x75E0 0x75E1 0x75E2 0x75E3 0x75E4 0x75E6 0x75E7 0x75E8 0x75E9 0x75EA 0x75EB 0x75ED 0x75EF +0x75F0 0x75F1 0x75F2 0x75F3 0x75F4 0x75F5 0x75F6 0x75F7 0x75F8 0x75F9 0x75FA 0x75FB 0x75FC 0x75FD 0x75FE 0x75FF +0x7600 0x7601 0x7602 0x7603 0x7604 0x7605 0x7606 0x7608 0x7609 0x760A 0x760B 0x760C 0x760D 0x760F 0x7610 0x7611 +0x7613 0x7614 0x7615 0x7616 0x7617 0x7618 0x7619 0x761A 0x761B 0x761C 0x761D 0x761E 0x761F 0x7620 0x7621 0x7622 +0x7623 0x7624 0x7625 0x7626 0x7627 0x7628 0x7629 0x762A 0x762B 0x762D 0x762E 0x762F 0x7630 0x7631 0x7632 0x7633 +0x7634 0x7635 0x7638 0x763A 0x763B 0x763C 0x763D 0x763E 0x763F 0x7640 0x7642 0x7643 0x7646 0x7647 0x7648 0x7649 +0x764C 0x764D 0x764E 0x7650 0x7652 0x7653 0x7654 0x7656 0x7657 0x7658 0x7659 0x765A 0x765C 0x765E 0x765F 0x7660 +0x7661 0x7662 0x7663 0x7664 0x7665 0x7666 0x7667 0x7668 0x7669 0x766A 0x766B 0x766C 0x766D 0x766E 0x766F 0x7670 +0x7671 0x7672 0x7675 0x7676 0x7678 0x7679 0x767A 0x767B 0x767C 0x767D 0x767E 0x767F 0x7680 0x7681 0x7682 0x7683 +0x7684 0x7686 0x7687 0x7688 0x7689 0x768A 0x768B 0x768E 0x768F 0x7690 0x7691 0x7692 0x7693 0x7695 0x7696 0x7699 +0x769A 0x769B 0x769C 0x769D 0x769E 0x76A4 0x76A6 0x76AA 0x76AB 0x76AD 0x76AE 0x76AF 0x76B0 0x76B1 0x76B2 0x76B4 +0x76B5 0x76B6 0x76B7 0x76B8 0x76B9 0x76BA 0x76BB 0x76BD 0x76BE 0x76BF 0x76C2 0x76C3 0x76C4 0x76C5 0x76C6 0x76C8 +0x76C9 0x76CA 0x76CC 0x76CD 0x76CE 0x76CF 0x76D0 0x76D1 0x76D2 0x76D3 0x76D4 0x76D6 0x76D7 0x76D8 0x76DA 0x76DB +0x76DC 0x76DD 0x76DE 0x76DF 0x76E1 0x76E3 0x76E4 0x76E5 0x76E6 0x76E7 0x76E8 0x76E9 0x76EA 0x76EC 0x76ED 0x76EE +0x76EF 0x76F0 0x76F1 0x76F2 0x76F3 0x76F4 0x76F5 0x76F7 0x76F8 0x76F9 0x76FA 0x76FB 0x76FC 0x76FE 0x7701 0x7704 +0x7707 0x7708 0x7709 0x770A 0x770B 0x770C 0x770D 0x7712 0x7715 0x7719 0x771A 0x771B 0x771C 0x771E 0x771F 0x7720 +0x7722 0x7724 0x7725 0x7726 0x7728 0x7729 0x772C 0x772D 0x772F 0x7735 0x7736 0x7737 0x7738 0x773A 0x773C 0x773D +0x773E 0x7740 0x7741 0x7743 0x7744 0x7746 0x7747 0x774D 0x774E 0x774F 0x7750 0x7751 0x7752 0x775A 0x775B 0x775C +0x775E 0x7761 0x7762 0x7763 0x7765 0x7766 0x7768 0x7769 0x776A 0x776B 0x776C 0x7779 0x777A 0x777D 0x777E 0x777F +0x7780 0x7784 0x7785 0x7786 0x7787 0x778B 0x778C 0x778D 0x778E 0x778F 0x7791 0x7792 0x7793 0x7798 0x779A 0x779C +0x779E 0x779F 0x77A0 0x77A2 0x77A4 0x77A5 0x77A7 0x77A9 0x77AA 0x77AB 0x77AC 0x77AD 0x77B0 0x77B3 0x77B5 0x77B6 +0x77B7 0x77B9 0x77BB 0x77BC 0x77BD 0x77BF 0x77C7 0x77CB 0x77CD 0x77CE 0x77D3 0x77D7 0x77DA 0x77DB 0x77DC 0x77DE +0x77E2 0x77E3 0x77E5 0x77E7 0x77E9 0x77EB 0x77EC 0x77ED 0x77EE 0x77EF 0x77F0 0x77F3 0x77F4 0x77F6 0x77F7 0x77F8 +0x77F9 0x77FA 0x77FB 0x77FC 0x77FD 0x77FE 0x77FF 0x7800 0x7801 0x7802 0x7803 0x7804 0x7805 0x7806 0x7807 0x7808 +0x7809 0x780C 0x780D 0x780E 0x780F 0x7810 0x7811 0x7812 0x7813 0x7814 0x7815 0x7816 0x7817 0x7818 0x781A 0x781C +0x781D 0x781F 0x7820 0x7821 0x7822 0x7823 0x7825 0x7826 0x7827 0x7828 0x7829 0x782A 0x782B 0x782C 0x782D 0x782E +0x782F 0x7830 0x7831 0x7832 0x7833 0x7834 0x7835 0x7837 0x7838 0x7839 0x783A 0x783B 0x783C 0x783E 0x783F 0x7840 +0x7841 0x7843 0x7845 0x7847 0x7848 0x7849 0x784A 0x784B 0x784C 0x784D 0x784E 0x784F 0x7850 0x7852 0x7853 0x7854 +0x7855 0x7856 0x7857 0x7859 0x785A 0x785C 0x785D 0x785E 0x7860 0x7862 0x7864 0x7865 0x7866 0x7868 0x7869 0x786A +0x786B 0x786C 0x786D 0x786E 0x786F 0x7870 0x7871 0x7872 0x7874 0x7875 0x7877 0x7879 0x787B 0x787C 0x787E 0x787F +0x7880 0x7881 0x7883 0x7884 0x7885 0x7886 0x7887 0x7888 0x7889 0x788C 0x788D 0x788E 0x788F 0x7891 0x7893 0x7894 +0x7895 0x7896 0x7897 0x7898 0x789A 0x789B 0x789C 0x789F 0x78A1 0x78A3 0x78A5 0x78A7 0x78A8 0x78A9 0x78AA 0x78AD +0x78AF 0x78B0 0x78B1 0x78B2 0x78B3 0x78B4 0x78B5 0x78B6 0x78B8 0x78B9 0x78BA 0x78BB 0x78BC 0x78BE 0x78C1 0x78C5 +0x78C6 0x78C8 0x78C9 0x78CA 0x78CB 0x78CE 0x78CF 0x78D0 0x78D1 0x78D4 0x78D5 0x78D8 0x78D9 0x78DA 0x78DC 0x78E0 +0x78E1 0x78E2 0x78E3 0x78E7 0x78E8 0x78EC 0x78EF 0x78F2 0x78F4 0x78F5 0x78F7 0x78F9 0x78FA 0x78FB 0x78FD 0x78FE +0x7901 0x7903 0x7904 0x7905 0x7906 0x7907 0x790C 0x790E 0x7910 0x7911 0x7912 0x7913 0x7916 0x7919 0x791E 0x7921 +0x7924 0x7926 0x792A 0x792B 0x792C 0x7931 0x7933 0x7934 0x7935 0x793A 0x793B 0x793C 0x793D 0x793E 0x7940 0x7941 +0x7942 0x7943 0x7945 0x7946 0x7947 0x7948 0x7949 0x794A 0x794B 0x794E 0x794F 0x7950 0x7953 0x7955 0x7956 0x7957 +0x795A 0x795B 0x795C 0x795D 0x795E 0x795F 0x7960 0x7962 0x7965 0x7967 0x7968 0x7969 0x796B 0x796D 0x796F 0x7972 +0x7977 0x7978 0x797A 0x797C 0x797E 0x797F 0x7980 0x7981 0x7984 0x7985 0x798A 0x798B 0x798D 0x798E 0x798F 0x7991 +0x7992 0x7994 0x7995 0x7998 0x799A 0x799B 0x799D 0x799F 0x79A0 0x79A1 0x79A4 0x79A5 0x79A6 0x79A7 0x79A9 0x79AA +0x79AE 0x79B0 0x79B1 0x79B3 0x79B8 0x79B9 0x79BA 0x79BB 0x79BD 0x79BE 0x79BF 0x79C0 0x79C1 0x79C2 0x79C3 0x79C6 +0x79C8 0x79C9 0x79CA 0x79CB 0x79CD 0x79CF 0x79D1 0x79D2 0x79D5 0x79D8 0x79DD 0x79DE 0x79DF 0x79E1 0x79E3 0x79E4 +0x79E6 0x79E7 0x79E9 0x79EB 0x79EC 0x79ED 0x79EF 0x79F0 0x79F8 0x79FB 0x79FD 0x79FE 0x7A00 0x7A02 0x7A03 0x7A04 +0x7A05 0x7A06 0x7A08 0x7A09 0x7A0B 0x7A0C 0x7A0D 0x7A0E 0x7A11 0x7A14 0x7A16 0x7A17 0x7A18 0x7A19 0x7A1A 0x7A1C +0x7A1E 0x7A1F 0x7A20 0x7A23 0x7A26 0x7A2E 0x7A31 0x7A32 0x7A33 0x7A36 0x7A37 0x7A39 0x7A3B 0x7A3C 0x7A3D 0x7A3E +0x7A3F 0x7A40 0x7A42 0x7A43 0x7A44 0x7A46 0x7A47 0x7A49 0x7A4B 0x7A4C 0x7A4D 0x7A4E 0x7A4F 0x7A50 0x7A51 0x7A57 +0x7A59 0x7A5C 0x7A5E 0x7A5F 0x7A60 0x7A61 0x7A62 0x7A63 0x7A66 0x7A68 0x7A69 0x7A6B 0x7A6D 0x7A70 0x7A74 0x7A75 +0x7A76 0x7A77 0x7A78 0x7A79 0x7A7A 0x7A7D 0x7A7F 0x7A80 0x7A81 0x7A83 0x7A84 0x7A85 0x7A86 0x7A88 0x7A8A 0x7A8D +0x7A8E 0x7A91 0x7A92 0x7A93 0x7A95 0x7A96 0x7A97 0x7A98 0x7A9C 0x7A9D 0x7A9F 0x7AA0 0x7AA3 0x7AA5 0x7AA6 0x7AA8 +0x7AA9 0x7AAA 0x7AAC 0x7AAD 0x7AAE 0x7AAF 0x7AB0 0x7AB3 0x7AB5 0x7AB6 0x7AB8 0x7ABA 0x7ABE 0x7ABF 0x7AC3 0x7AC4 +0x7AC5 0x7AC7 0x7AC8 0x7ACA 0x7ACB 0x7ACD 0x7ACF 0x7AD1 0x7AD2 0x7AD3 0x7AD5 0x7AD6 0x7AD7 0x7AD8 0x7AD9 0x7ADA +0x7ADC 0x7ADD 0x7ADE 0x7ADF 0x7AE0 0x7AE1 0x7AE2 0x7AE3 0x7AE5 0x7AE6 0x7AEA 0x7AEB 0x7AED 0x7AEF 0x7AF0 0x7AF6 +0x7AF7 0x7AF8 0x7AF9 0x7AFA 0x7AFD 0x7AFF 0x7B02 0x7B03 0x7B04 0x7B06 0x7B08 0x7B0A 0x7B0B 0x7B0F 0x7B11 0x7B14 +0x7B15 0x7B18 0x7B19 0x7B1B 0x7B1E 0x7B20 0x7B24 0x7B25 0x7B26 0x7B28 0x7B2A 0x7B2B 0x7B2C 0x7B2D 0x7B2E 0x7B2F +0x7B31 0x7B33 0x7B35 0x7B36 0x7B38 0x7B39 0x7B3A 0x7B3C 0x7B3E 0x7B40 0x7B45 0x7B46 0x7B47 0x7B48 0x7B49 0x7B4A +0x7B4B 0x7B4C 0x7B4D 0x7B4E 0x7B4F 0x7B50 0x7B51 0x7B52 0x7B54 0x7B56 0x7B58 0x7B5A 0x7B5B 0x7B5C 0x7B5D 0x7B60 +0x7B62 0x7B64 0x7B65 0x7B66 0x7B67 0x7B69 0x7B6C 0x7B6E 0x7B6F 0x7B70 0x7B71 0x7B72 0x7B74 0x7B75 0x7B76 0x7B77 +0x7B79 0x7B7A 0x7B7B 0x7B7C 0x7B7D 0x7B7E 0x7B7F 0x7B80 0x7B84 0x7B85 0x7B86 0x7B87 0x7B8B 0x7B8D 0x7B8E 0x7B8F +0x7B90 0x7B92 0x7B93 0x7B94 0x7B95 0x7B96 0x7B97 0x7B98 0x7B99 0x7B9A 0x7B9C 0x7B9D 0x7B9F 0x7BA0 0x7BA1 0x7BA2 +0x7BA3 0x7BA6 0x7BA7 0x7BA8 0x7BA9 0x7BAA 0x7BAB 0x7BAC 0x7BAD 0x7BB1 0x7BB4 0x7BB8 0x7BC0 0x7BC1 0x7BC4 0x7BC6 +0x7BC7 0x7BC9 0x7BCB 0x7BCC 0x7BCF 0x7BD1 0x7BD2 0x7BD3 0x7BD4 0x7BD9 0x7BDA 0x7BDB 0x7BDD 0x7BE0 0x7BE1 0x7BE2 +0x7BE4 0x7BE5 0x7BE6 0x7BE9 0x7BEA 0x7BED 0x7BEE 0x7BEF 0x7BF0 0x7BF1 0x7BF2 0x7BF3 0x7BF6 0x7BF7 0x7BFC 0x7BFE +0x7C00 0x7C03 0x7C07 0x7C09 0x7C0B 0x7C0C 0x7C0D 0x7C0F 0x7C11 0x7C12 0x7C13 0x7C14 0x7C15 0x7C16 0x7C17 0x7C1D +0x7C1E 0x7C1F 0x7C20 0x7C21 0x7C23 0x7C26 0x7C27 0x7C29 0x7C2A 0x7C2B 0x7C30 0x7C37 0x7C38 0x7C39 0x7C3D 0x7C3E +0x7C3F 0x7C40 0x7C41 0x7C43 0x7C4C 0x7C4D 0x7C4F 0x7C50 0x7C53 0x7C54 0x7C56 0x7C57 0x7C58 0x7C59 0x7C5B 0x7C5C +0x7C5D 0x7C5F 0x7C60 0x7C63 0x7C64 0x7C65 0x7C69 0x7C6A 0x7C6C 0x7C6E 0x7C72 0x7C73 0x7C74 0x7C75 0x7C78 0x7C79 +0x7C7B 0x7C7C 0x7C7D 0x7C7E 0x7C81 0x7C82 0x7C83 0x7C84 0x7C89 0x7C8B 0x7C8D 0x7C90 0x7C91 0x7C92 0x7C95 0x7C97 +0x7C98 0x7C9B 0x7C9C 0x7C9D 0x7C9E 0x7C9F 0x7CA1 0x7CA2 0x7CA4 0x7CA5 0x7CA6 0x7CA7 0x7CA8 0x7CAA 0x7CAB 0x7CAC +0x7CAD 0x7CAE 0x7CB1 0x7CB2 0x7CB3 0x7CB5 0x7CB9 0x7CBA 0x7CBC 0x7CBD 0x7CBE 0x7CBF 0x7CC0 0x7CC1 0x7CC2 0x7CC4 +0x7CC5 0x7CC7 0x7CC8 0x7CC9 0x7CCA 0x7CCC 0x7CCD 0x7CCE 0x7CD2 0x7CD5 0x7CD6 0x7CD7 0x7CD8 0x7CD9 0x7CDC 0x7CDD +0x7CDE 0x7CDF 0x7CE0 0x7CE2 0x7CE7 0x7CE8 0x7CEC 0x7CED 0x7CEF 0x7CF0 0x7CF2 0x7CF4 0x7CF5 0x7CF6 0x7CF8 0x7CF9 +0x7CFA 0x7CFB 0x7CFE 0x7D00 0x7D02 0x7D03 0x7D04 0x7D05 0x7D06 0x7D07 0x7D08 0x7D09 0x7D0A 0x7D0B 0x7D0D 0x7D10 +0x7D11 0x7D13 0x7D14 0x7D15 0x7D16 0x7D17 0x7D18 0x7D19 0x7D1A 0x7D1B 0x7D1C 0x7D1D 0x7D1E 0x7D20 0x7D21 0x7D22 +0x7D27 0x7D2B 0x7D2C 0x7D2E 0x7D2F 0x7D30 0x7D31 0x7D32 0x7D33 0x7D35 0x7D39 0x7D3A 0x7D3C 0x7D3F 0x7D40 0x7D42 +0x7D43 0x7D44 0x7D45 0x7D46 0x7D4B 0x7D4C 0x7D4E 0x7D4F 0x7D50 0x7D53 0x7D55 0x7D56 0x7D5A 0x7D5B 0x7D5C 0x7D5D +0x7D5E 0x7D61 0x7D62 0x7D63 0x7D66 0x7D68 0x7D6A 0x7D6E 0x7D70 0x7D71 0x7D72 0x7D73 0x7D75 0x7D76 0x7D77 0x7D79 +0x7D7A 0x7D7D 0x7D7F 0x7D81 0x7D83 0x7D84 0x7D86 0x7D88 0x7D89 0x7D8C 0x7D8E 0x7D8F 0x7D91 0x7D93 0x7D96 0x7D99 +0x7D9A 0x7D9B 0x7D9C 0x7D9D 0x7D9E 0x7D9F 0x7DA0 0x7DA1 0x7DA2 0x7DA3 0x7DA6 0x7DA7 0x7DAA 0x7DAB 0x7DAC 0x7DAD +0x7DAE 0x7DAF 0x7DB0 0x7DB1 0x7DB2 0x7DB3 0x7DB4 0x7DB5 0x7DB7 0x7DB8 0x7DB9 0x7DBA 0x7DBB 0x7DBD 0x7DBE 0x7DBF +0x7DC1 0x7DC4 0x7DC7 0x7DC8 0x7DCA 0x7DCB 0x7DCC 0x7DCF 0x7DD1 0x7DD2 0x7DD3 0x7DD4 0x7DD5 0x7DD6 0x7DD7 0x7DD8 +0x7DD9 0x7DDA 0x7DDC 0x7DDD 0x7DDE 0x7DE0 0x7DE1 0x7DE3 0x7DE4 0x7DE6 0x7DE8 0x7DE9 0x7DEA 0x7DEC 0x7DEF 0x7DF1 +0x7DF2 0x7DF4 0x7DF6 0x7DF9 0x7DFB 0x7DFC 0x7E01 0x7E04 0x7E05 0x7E08 0x7E09 0x7E0A 0x7E0B 0x7E10 0x7E11 0x7E12 +0x7E15 0x7E17 0x7E1B 0x7E1D 0x7E1E 0x7E1F 0x7E20 0x7E21 0x7E22 0x7E23 0x7E26 0x7E27 0x7E29 0x7E2B 0x7E2D 0x7E2E +0x7E2F 0x7E31 0x7E32 0x7E33 0x7E34 0x7E35 0x7E36 0x7E37 0x7E39 0x7E3A 0x7E3B 0x7E3D 0x7E3E 0x7E3F 0x7E41 0x7E43 +0x7E44 0x7E45 0x7E46 0x7E47 0x7E48 0x7E4A 0x7E4B 0x7E4D 0x7E4E 0x7E51 0x7E52 0x7E54 0x7E55 0x7E56 0x7E59 0x7E5A +0x7E5D 0x7E5E 0x7E61 0x7E62 0x7E66 0x7E67 0x7E69 0x7E6A 0x7E6B 0x7E6D 0x7E6E 0x7E6F 0x7E70 0x7E73 0x7E76 0x7E79 +0x7E7B 0x7E7C 0x7E7D 0x7E7E 0x7E7F 0x7E81 0x7E82 0x7E83 0x7E86 0x7E87 0x7E88 0x7E89 0x7E8A 0x7E8C 0x7E8D 0x7E8E +0x7E8F 0x7E90 0x7E92 0x7E93 0x7E94 0x7E95 0x7E96 0x7E98 0x7E9A 0x7E9B 0x7E9C 0x7E9F 0x7EA0 0x7EA1 0x7EA2 0x7EA3 +0x7EA4 0x7EA5 0x7EA6 0x7EA7 0x7EA8 0x7EA9 0x7EAA 0x7EAB 0x7EAC 0x7EAD 0x7EAE 0x7EAF 0x7EB0 0x7EB1 0x7EB2 0x7EB3 +0x7EB4 0x7EB5 0x7EB6 0x7EB7 0x7EB8 0x7EB9 0x7EBA 0x7EBB 0x7EBC 0x7EBD 0x7EBE 0x7EBF 0x7EC0 0x7EC1 0x7EC2 0x7EC3 +0x7EC4 0x7EC5 0x7EC6 0x7EC7 0x7EC8 0x7EC9 0x7ECA 0x7ECB 0x7ECC 0x7ECD 0x7ECE 0x7ECF 0x7ED0 0x7ED1 0x7ED2 0x7ED3 +0x7ED4 0x7ED5 0x7ED6 0x7ED7 0x7ED8 0x7ED9 0x7EDA 0x7EDB 0x7EDC 0x7EDD 0x7EDE 0x7EDF 0x7EE0 0x7EE1 0x7EE2 0x7EE3 +0x7EE4 0x7EE5 0x7EE6 0x7EE7 0x7EE8 0x7EE9 0x7EEA 0x7EEB 0x7EEC 0x7EED 0x7EEE 0x7EEF 0x7EF0 0x7EF1 0x7EF2 0x7EF3 +0x7EF4 0x7EF5 0x7EF6 0x7EF7 0x7EF8 0x7EF9 0x7EFA 0x7EFB 0x7EFC 0x7EFD 0x7EFE 0x7EFF 0x7F00 0x7F01 0x7F02 0x7F03 +0x7F04 0x7F05 0x7F06 0x7F07 0x7F08 0x7F09 0x7F0A 0x7F0B 0x7F0C 0x7F0D 0x7F0E 0x7F0F 0x7F10 0x7F11 0x7F12 0x7F13 +0x7F14 0x7F15 0x7F16 0x7F17 0x7F18 0x7F19 0x7F1A 0x7F1B 0x7F1C 0x7F1D 0x7F1E 0x7F1F 0x7F20 0x7F21 0x7F22 0x7F23 +0x7F24 0x7F25 0x7F26 0x7F27 0x7F28 0x7F29 0x7F2A 0x7F2B 0x7F2C 0x7F2D 0x7F2E 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 +0x7F34 0x7F35 0x7F36 0x7F38 0x7F39 0x7F3A 0x7F3D 0x7F42 0x7F43 0x7F44 0x7F45 0x7F48 0x7F49 0x7F4C 0x7F4D 0x7F4E +0x7F4F 0x7F50 0x7F51 0x7F52 0x7F53 0x7F54 0x7F55 0x7F57 0x7F58 0x7F5A 0x7F5B 0x7F5C 0x7F5D 0x7F5E 0x7F5F 0x7F60 +0x7F61 0x7F62 0x7F63 0x7F65 0x7F66 0x7F67 0x7F68 0x7F69 0x7F6A 0x7F6B 0x7F6C 0x7F6D 0x7F6E 0x7F70 0x7F71 0x7F72 +0x7F73 0x7F74 0x7F75 0x7F76 0x7F77 0x7F78 0x7F79 0x7F7D 0x7F7E 0x7F81 0x7F82 0x7F83 0x7F85 0x7F86 0x7F87 0x7F88 +0x7F8A 0x7F8B 0x7F8C 0x7F8E 0x7F91 0x7F93 0x7F94 0x7F95 0x7F96 0x7F97 0x7F9A 0x7F9D 0x7F9E 0x7F9F 0x7FA1 0x7FA3 +0x7FA4 0x7FA5 0x7FA7 0x7FA8 0x7FA9 0x7FAE 0x7FAF 0x7FB0 0x7FB1 0x7FB2 0x7FB4 0x7FB6 0x7FB8 0x7FB9 0x7FBC 0x7FBD +0x7FBF 0x7FC0 0x7FC1 0x7FC2 0x7FC3 0x7FC5 0x7FC6 0x7FC8 0x7FCA 0x7FCB 0x7FCC 0x7FCE 0x7FD2 0x7FD4 0x7FD5 0x7FD8 +0x7FD9 0x7FDA 0x7FDB 0x7FDF 0x7FE0 0x7FE1 0x7FE5 0x7FE6 0x7FE7 0x7FE9 0x7FEB 0x7FEC 0x7FEE 0x7FEF 0x7FF0 0x7FF1 +0x7FF3 0x7FF7 0x7FF9 0x7FFA 0x7FFB 0x7FFC 0x7FFD 0x7FFE 0x8000 0x8001 0x8002 0x8003 0x8004 0x8005 0x8006 0x8007 +0x8008 0x8009 0x800B 0x800C 0x800D 0x800E 0x800F 0x8010 0x8011 0x8012 0x8014 0x8015 0x8016 0x8017 0x8018 0x8019 +0x801C 0x8020 0x8021 0x8022 0x8024 0x8025 0x8026 0x8027 0x8028 0x8029 0x802A 0x802C 0x802D 0x802E 0x8030 0x8031 +0x8032 0x8033 0x8035 0x8036 0x8037 0x8038 0x803B 0x803D 0x803F 0x8042 0x8043 0x8046 0x804A 0x804B 0x804C 0x804D +0x804F 0x8050 0x8051 0x8052 0x8054 0x8056 0x8058 0x805A 0x805E 0x805F 0x8061 0x8062 0x8064 0x8068 0x8069 0x806A +0x806F 0x8070 0x8071 0x8072 0x8073 0x8074 0x8075 0x8076 0x8077 0x8079 0x807D 0x807E 0x807F 0x8080 0x8083 0x8084 +0x8085 0x8086 0x8087 0x8089 0x808B 0x808C 0x808F 0x8090 0x8093 0x8096 0x8098 0x8099 0x809A 0x809B 0x809C 0x809D +0x809F 0x80A0 0x80A1 0x80A2 0x80A4 0x80A5 0x80A9 0x80AA 0x80AB 0x80AC 0x80AD 0x80AE 0x80AF 0x80B1 0x80B2 0x80B4 +0x80B7 0x80B8 0x80BA 0x80BC 0x80BD 0x80BE 0x80BF 0x80C0 0x80C1 0x80C2 0x80C3 0x80C4 0x80C6 0x80C8 0x80CC 0x80CD +0x80CE 0x80D4 0x80D6 0x80D7 0x80D9 0x80DA 0x80DB 0x80DC 0x80DD 0x80DE 0x80E0 0x80E1 0x80E3 0x80E4 0x80E5 0x80E7 +0x80E8 0x80E9 0x80EA 0x80EB 0x80EC 0x80ED 0x80EF 0x80F0 0x80F1 0x80F2 0x80F3 0x80F4 0x80F6 0x80F8 0x80FA 0x80FC +0x80FD 0x80FE 0x80FF 0x8102 0x8105 0x8106 0x8107 0x8108 0x8109 0x810A 0x810D 0x810E 0x810F 0x8110 0x8111 0x8112 +0x8113 0x8114 0x8116 0x8117 0x8118 0x811A 0x811B 0x811D 0x811E 0x811F 0x8122 0x8123 0x8124 0x8126 0x8127 0x8129 +0x812B 0x812C 0x812F 0x8130 0x8131 0x8132 0x8133 0x8136 0x8137 0x8138 0x8139 0x813E 0x813F 0x8146 0x8148 0x814A +0x814B 0x814C 0x814E 0x8150 0x8151 0x8152 0x8153 0x8154 0x8155 0x8156 0x8158 0x8159 0x815A 0x815F 0x8160 0x8161 +0x8165 0x8166 0x8167 0x8168 0x8169 0x816B 0x816D 0x816E 0x816F 0x8170 0x8171 0x8173 0x8174 0x8178 0x8179 0x817A +0x817B 0x817C 0x817D 0x817E 0x817F 0x8180 0x8182 0x8183 0x8188 0x818A 0x818D 0x818E 0x818F 0x8191 0x8193 0x8195 +0x8196 0x8198 0x8199 0x819A 0x819B 0x819C 0x819D 0x819E 0x81A0 0x81A2 0x81A3 0x81A4 0x81A5 0x81A6 0x81A8 0x81A9 +0x81AA 0x81B0 0x81B3 0x81B5 0x81B6 0x81B8 0x81BA 0x81BB 0x81BD 0x81BE 0x81BF 0x81C0 0x81C1 0x81C2 0x81C3 0x81C6 +0x81C8 0x81C9 0x81CA 0x81CC 0x81CD 0x81CF 0x81D1 0x81D3 0x81D8 0x81D9 0x81DA 0x81DC 0x81DF 0x81E0 0x81E2 0x81E3 +0x81E5 0x81E7 0x81E8 0x81EA 0x81EC 0x81ED 0x81F3 0x81F4 0x81FA 0x81FB 0x81FC 0x81FE 0x81FF 0x8200 0x8201 0x8202 +0x8204 0x8205 0x8206 0x8207 0x8208 0x8209 0x820A 0x820B 0x820C 0x820D 0x820E 0x8210 0x8212 0x8214 0x8216 0x8217 +0x8218 0x821B 0x821C 0x821E 0x821F 0x8220 0x8221 0x8222 0x8223 0x8225 0x8226 0x8228 0x8229 0x822A 0x822B 0x822C +0x822D 0x822E 0x822F 0x8230 0x8231 0x8232 0x8233 0x8234 0x8235 0x8236 0x8237 0x8238 0x8239 0x823A 0x823B 0x823E +0x8240 0x8244 0x8245 0x8247 0x8249 0x824B 0x824E 0x824F 0x8258 0x8259 0x825A 0x825D 0x825F 0x8262 0x8264 0x8266 +0x8268 0x826A 0x826B 0x826E 0x826F 0x8270 0x8271 0x8272 0x8273 0x8274 0x8276 0x8277 0x8278 0x8279 0x827A 0x827D +0x827E 0x827F 0x8280 0x8282 0x8283 0x8284 0x8288 0x828A 0x828B 0x828D 0x828E 0x828F 0x8291 0x8292 0x8297 0x8298 +0x8299 0x829A 0x829C 0x829D 0x829F 0x82A0 0x82A1 0x82A3 0x82A4 0x82A5 0x82A6 0x82A7 0x82A8 0x82A9 0x82AA 0x82AB +0x82AC 0x82AD 0x82AE 0x82AF 0x82B0 0x82B1 0x82B3 0x82B4 0x82B5 0x82B6 0x82B7 0x82B8 0x82B9 0x82BB 0x82BC 0x82BD +0x82BE 0x82BF 0x82C1 0x82C4 0x82C5 0x82C7 0x82C8 0x82C9 0x82CA 0x82CB 0x82CC 0x82CD 0x82CE 0x82CF 0x82D1 0x82D2 +0x82D3 0x82D4 0x82D5 0x82D6 0x82D7 0x82D8 0x82D9 0x82DB 0x82DC 0x82DD 0x82DE 0x82DF 0x82E0 0x82E1 0x82E3 0x82E4 +0x82E5 0x82E6 0x82E7 0x82E8 0x82EB 0x82EF 0x82F1 0x82F3 0x82F4 0x82F6 0x82F7 0x82F9 0x82FA 0x82FB 0x82FD 0x82FE +0x8300 0x8301 0x8302 0x8303 0x8304 0x8305 0x8306 0x8307 0x8308 0x8309 0x830B 0x830C 0x830D 0x830E 0x830F 0x8311 +0x8313 0x8314 0x8315 0x8316 0x8317 0x8318 0x831A 0x831B 0x831C 0x831D 0x8322 0x8323 0x8327 0x8328 0x8329 0x832B +0x832C 0x832D 0x832F 0x8331 0x8332 0x8333 0x8334 0x8335 0x8336 0x8338 0x8339 0x833A 0x833C 0x833D 0x8340 0x8341 +0x8343 0x8344 0x8345 0x8346 0x8347 0x8349 0x834A 0x834E 0x834F 0x8350 0x8351 0x8352 0x8353 0x8354 0x8356 0x8358 +0x8359 0x835A 0x835B 0x835C 0x835D 0x835E 0x835F 0x8360 0x8361 0x8363 0x8364 0x8365 0x8366 0x8367 0x8368 0x8369 +0x836A 0x836B 0x836C 0x836D 0x836E 0x836F 0x8373 0x8375 0x8377 0x8378 0x837A 0x837B 0x837C 0x837D 0x8380 0x8382 +0x8385 0x8386 0x8387 0x8389 0x838A 0x838E 0x8392 0x8393 0x8395 0x8396 0x8398 0x8399 0x839A 0x839B 0x839C 0x839D +0x839E 0x839F 0x83A0 0x83A2 0x83A3 0x83A6 0x83A7 0x83A8 0x83A9 0x83AA 0x83AB 0x83AF 0x83B0 0x83B1 0x83B2 0x83B3 +0x83B4 0x83B5 0x83B6 0x83B7 0x83B8 0x83B9 0x83BA 0x83BC 0x83BD 0x83BF 0x83C0 0x83C1 0x83C2 0x83C5 0x83C7 0x83C8 +0x83C9 0x83CA 0x83CC 0x83CD 0x83CE 0x83CF 0x83D1 0x83D3 0x83D4 0x83D6 0x83D8 0x83DC 0x83DD 0x83DF 0x83E0 0x83E1 +0x83E5 0x83E9 0x83EA 0x83EB 0x83EF 0x83F0 0x83F1 0x83F2 0x83F4 0x83F5 0x83F7 0x83F8 0x83F9 0x83FB 0x83FC 0x83FD +0x83FE 0x83FF 0x8401 0x8403 0x8404 0x8406 0x8407 0x840A 0x840B 0x840C 0x840D 0x840E 0x840F 0x8411 0x8413 0x8418 +0x841A 0x841C 0x841D 0x8420 0x8422 0x8423 0x8424 0x8425 0x8426 0x8427 0x8428 0x8429 0x842A 0x842C 0x8431 0x8433 +0x8434 0x8435 0x8438 0x8439 0x843C 0x843D 0x8446 0x8447 0x8449 0x844E 0x8451 0x8452 0x8453 0x8456 0x8457 0x8459 +0x845A 0x845B 0x845C 0x8460 0x8461 0x8462 0x8463 0x8464 0x8466 0x8469 0x846B 0x846C 0x846D 0x846E 0x846F 0x8470 +0x8471 0x8473 0x8474 0x8475 0x8476 0x8477 0x8478 0x8479 0x847A 0x8482 0x8484 0x8487 0x8488 0x8489 0x848B 0x848C +0x848D 0x848E 0x8490 0x8493 0x8494 0x8497 0x8499 0x849C 0x849D 0x849E 0x849F 0x84A1 0x84A8 0x84AD 0x84AF 0x84B1 +0x84B2 0x84B4 0x84B8 0x84B9 0x84BA 0x84BB 0x84BC 0x84BD 0x84BE 0x84BF 0x84C0 0x84C1 0x84C2 0x84C4 0x84C6 0x84C7 +0x84C9 0x84CA 0x84CB 0x84CD 0x84CF 0x84D0 0x84D1 0x84D3 0x84D6 0x84D9 0x84DA 0x84DD 0x84DF 0x84E0 0x84E2 0x84E3 +0x84E5 0x84E6 0x84EA 0x84EC 0x84EE 0x84EF 0x84F0 0x84F3 0x84F4 0x84F7 0x84FC 0x84FD 0x84FF 0x8500 0x8503 0x8504 +0x8506 0x8508 0x850A 0x850C 0x8511 0x8513 0x8514 0x8515 0x8517 0x8518 0x851A 0x851E 0x851F 0x8521 0x8523 0x8525 +0x8526 0x852B 0x852C 0x852D 0x852F 0x8534 0x8535 0x8537 0x8538 0x8539 0x853A 0x853B 0x853C 0x853D 0x853F 0x8540 +0x8541 0x8543 0x8546 0x8548 0x8549 0x854A 0x854B 0x854E 0x8552 0x8553 0x8555 0x8556 0x8557 0x8558 0x8559 0x855A +0x855E 0x8562 0x8563 0x8564 0x8565 0x8568 0x8569 0x856A 0x856D 0x8570 0x8572 0x8574 0x8577 0x8579 0x857A 0x857B +0x857E 0x8580 0x8581 0x8584 0x8585 0x8586 0x8587 0x8588 0x858A 0x858C 0x858F 0x8590 0x8591 0x8594 0x8597 0x8598 +0x8599 0x859B 0x859C 0x859F 0x85A0 0x85A2 0x85A4 0x85A6 0x85A8 0x85A9 0x85AA 0x85AB 0x85AC 0x85AE 0x85AF 0x85B0 +0x85B3 0x85B4 0x85B6 0x85B7 0x85B8 0x85B9 0x85BA 0x85BE 0x85BF 0x85C1 0x85C2 0x85C9 0x85CD 0x85CE 0x85CF 0x85D0 +0x85D3 0x85D5 0x85DC 0x85DD 0x85DF 0x85E0 0x85E4 0x85E5 0x85E6 0x85E8 0x85E9 0x85EA 0x85ED 0x85F4 0x85F6 0x85F7 +0x85F9 0x85FA 0x85FB 0x85FE 0x85FF 0x8600 0x8602 0x8604 0x8605 0x8606 0x8607 0x860A 0x860B 0x8611 0x8613 0x8616 +0x8617 0x8618 0x861A 0x861E 0x8621 0x8622 0x8626 0x8627 0x8629 0x862D 0x862F 0x8630 0x8635 0x8638 0x863A 0x863C +0x863F 0x8649 0x864D 0x864E 0x864F 0x8650 0x8651 0x8652 0x8653 0x8654 0x8655 0x8656 0x8659 0x865A 0x865B 0x865C +0x865E 0x865F 0x8661 0x8662 0x8663 0x8664 0x8667 0x866B 0x866C 0x866D 0x866E 0x866F 0x8670 0x8671 0x8673 0x8674 +0x8677 0x8678 0x8679 0x867A 0x867B 0x867C 0x867D 0x867E 0x867F 0x8680 0x8681 0x8682 0x8683 0x8684 0x8685 0x8686 +0x8687 0x868A 0x868B 0x868C 0x868D 0x868E 0x8690 0x8691 0x8693 0x8694 0x8695 0x8696 0x8697 0x8698 0x8699 0x869A +0x869C 0x869D 0x869E 0x86A1 0x86A2 0x86A3 0x86A4 0x86A5 0x86A7 0x86A8 0x86A9 0x86AA 0x86AB 0x86AC 0x86AF 0x86B0 +0x86B1 0x86B2 0x86B3 0x86B4 0x86B5 0x86B6 0x86B7 0x86B8 0x86B9 0x86BA 0x86C0 0x86C1 0x86C2 0x86C3 0x86C4 0x86C5 +0x86C6 0x86C7 0x86C8 0x86C9 0x86CA 0x86CB 0x86CD 0x86CE 0x86CF 0x86D0 0x86D1 0x86D4 0x86D8 0x86D9 0x86DB 0x86DE +0x86DF 0x86E4 0x86E9 0x86EC 0x86ED 0x86EE 0x86EF 0x86F0 0x86F1 0x86F2 0x86F3 0x86F4 0x86F8 0x86F9 0x86FA 0x86FB +0x86FE 0x8700 0x8702 0x8703 0x8705 0x8706 0x8707 0x8708 0x8709 0x870A 0x870D 0x870E 0x8710 0x8711 0x8712 0x8713 +0x8715 0x8717 0x8718 0x871A 0x871C 0x871E 0x8721 0x8722 0x8723 0x8725 0x8729 0x872E 0x8730 0x8731 0x8734 0x8737 +0x873B 0x873D 0x873E 0x873F 0x8740 0x8742 0x8744 0x8747 0x8748 0x8749 0x874B 0x874C 0x874E 0x8753 0x8755 0x8757 +0x8758 0x8759 0x875C 0x875F 0x8760 0x8763 0x8764 0x8765 0x8766 0x8768 0x876A 0x876E 0x8770 0x8772 0x8774 0x8776 +0x8778 0x877B 0x877C 0x877D 0x877E 0x877F 0x8780 0x8782 0x8783 0x8784 0x8785 0x8786 0x8788 0x878B 0x878D 0x8793 +0x8797 0x879E 0x879F 0x87A0 0x87A2 0x87A3 0x87A8 0x87AB 0x87AC 0x87AD 0x87AE 0x87AF 0x87B1 0x87B3 0x87B5 0x87BA +0x87BB 0x87BD 0x87BF 0x87C0 0x87C4 0x87C6 0x87C7 0x87C8 0x87CA 0x87CB 0x87CE 0x87CF 0x87D0 0x87D1 0x87D2 0x87D3 +0x87DB 0x87E0 0x87E2 0x87E3 0x87E5 0x87E7 0x87EA 0x87EB 0x87EC 0x87EE 0x87EF 0x87F2 0x87F3 0x87F6 0x87F7 0x87F9 +0x87FB 0x87FE 0x87FF 0x8801 0x8803 0x8804 0x8805 0x8806 0x880A 0x880B 0x880D 0x880E 0x880F 0x8810 0x8811 0x8813 +0x8814 0x8815 0x8816 0x881B 0x881F 0x8821 0x8822 0x8823 0x8827 0x8828 0x882D 0x8831 0x8832 0x8835 0x8836 0x8839 +0x883B 0x883C 0x8840 0x8842 0x8843 0x8844 0x8845 0x8846 0x884A 0x884C 0x884D 0x884E 0x8852 0x8853 0x8854 0x8855 +0x8856 0x8857 0x8859 0x885A 0x885B 0x885D 0x885E 0x8860 0x8861 0x8862 0x8863 0x8864 0x8865 0x8868 0x8869 0x886B +0x886C 0x886E 0x8870 0x8872 0x8875 0x8877 0x8879 0x887D 0x887E 0x887F 0x8881 0x8882 0x8884 0x8885 0x8886 0x8888 +0x888B 0x888D 0x8892 0x8893 0x8896 0x8897 0x8899 0x889C 0x889E 0x88A2 0x88A4 0x88AA 0x88AB 0x88AD 0x88AE 0x88AF +0x88B0 0x88B1 0x88B4 0x88B5 0x88B7 0x88BA 0x88BC 0x88BF 0x88C0 0x88C1 0x88C2 0x88C3 0x88C4 0x88C5 0x88C6 0x88C7 +0x88C8 0x88C9 0x88CA 0x88CB 0x88CE 0x88CF 0x88D1 0x88D2 0x88D4 0x88D5 0x88D8 0x88D9 0x88DB 0x88DC 0x88DD 0x88DF +0x88E1 0x88E2 0x88E3 0x88E4 0x88E5 0x88E8 0x88EC 0x88EF 0x88F0 0x88F1 0x88F2 0x88F3 0x88F4 0x88F5 0x88F8 0x88F9 +0x88FB 0x88FC 0x88FD 0x88FE 0x8902 0x8904 0x8907 0x890A 0x890C 0x890E 0x8910 0x8912 0x8913 0x8914 0x8915 0x8918 +0x8919 0x891A 0x891B 0x891D 0x891E 0x891F 0x8921 0x8925 0x8926 0x892A 0x892B 0x892F 0x8930 0x8932 0x8933 0x8934 +0x8935 0x8936 0x8938 0x893B 0x893D 0x8940 0x8941 0x8943 0x8944 0x8947 0x8948 0x894C 0x894D 0x894F 0x8955 0x8956 +0x895A 0x895C 0x895D 0x895E 0x895F 0x8960 0x8964 0x8966 0x896A 0x896B 0x896C 0x896D 0x896F 0x8972 0x8974 0x8976 +0x8977 0x897B 0x897E 0x897F 0x8980 0x8981 0x8983 0x8985 0x8986 0x8987 0x8988 0x898A 0x898B 0x898E 0x898F 0x8993 +0x8996 0x8997 0x8998 0x8999 0x899A 0x899C 0x89A1 0x89A4 0x89A5 0x89A6 0x89A7 0x89A9 0x89AA 0x89AC 0x89AF 0x89B2 +0x89B3 0x89B7 0x89BA 0x89BC 0x89BD 0x89BF 0x89C0 0x89C1 0x89C2 0x89C3 0x89C4 0x89C5 0x89C6 0x89C7 0x89C8 0x89C9 +0x89CA 0x89CB 0x89CC 0x89CD 0x89CE 0x89CF 0x89D0 0x89D1 0x89D2 0x89D4 0x89D6 0x89DA 0x89DC 0x89DD 0x89DE 0x89DF +0x89E3 0x89E5 0x89E6 0x89E7 0x89EB 0x89ED 0x89EF 0x89F1 0x89F3 0x89F4 0x89F6 0x89F8 0x89FC 0x89FF 0x8A00 0x8A01 +0x8A02 0x8A03 0x8A04 0x8A07 0x8A08 0x8A0A 0x8A0C 0x8A0E 0x8A0F 0x8A10 0x8A11 0x8A12 0x8A13 0x8A15 0x8A16 0x8A17 +0x8A18 0x8A1A 0x8A1B 0x8A1D 0x8A1F 0x8A22 0x8A23 0x8A25 0x8A29 0x8A2A 0x8A2B 0x8A2D 0x8A31 0x8A33 0x8A34 0x8A36 +0x8A38 0x8A3A 0x8A3B 0x8A3C 0x8A3E 0x8A40 0x8A41 0x8A46 0x8A48 0x8A4E 0x8A50 0x8A51 0x8A52 0x8A54 0x8A55 0x8A56 +0x8A57 0x8A58 0x8A5B 0x8A5D 0x8A5E 0x8A5F 0x8A60 0x8A61 0x8A62 0x8A63 0x8A66 0x8A68 0x8A69 0x8A6A 0x8A6B 0x8A6C +0x8A6D 0x8A6E 0x8A70 0x8A71 0x8A72 0x8A73 0x8A75 0x8A77 0x8A79 0x8A7A 0x8A7B 0x8A7C 0x8A7F 0x8A81 0x8A82 0x8A84 +0x8A85 0x8A86 0x8A87 0x8A89 0x8A8A 0x8A8C 0x8A8D 0x8A91 0x8A92 0x8A93 0x8A95 0x8A98 0x8A9A 0x8A9E 0x8AA0 0x8AA1 +0x8AA3 0x8AA4 0x8AA5 0x8AA6 0x8AA7 0x8AA8 0x8AA9 0x8AAA 0x8AAC 0x8AAD 0x8AB0 0x8AB2 0x8AB6 0x8AB9 0x8ABC 0x8ABE +0x8ABF 0x8AC2 0x8AC4 0x8AC7 0x8AC9 0x8ACB 0x8ACC 0x8ACD 0x8ACF 0x8AD1 0x8AD2 0x8AD3 0x8AD4 0x8AD6 0x8AD7 0x8ADA +0x8ADB 0x8ADC 0x8ADD 0x8ADE 0x8ADF 0x8AE0 0x8AE1 0x8AE2 0x8AE4 0x8AE6 0x8AE7 0x8AEA 0x8AEB 0x8AED 0x8AEE 0x8AF1 +0x8AF2 0x8AF3 0x8AF4 0x8AF6 0x8AF7 0x8AF8 0x8AFA 0x8AFC 0x8AFE 0x8AFF 0x8B00 0x8B01 0x8B02 0x8B04 0x8B05 0x8B07 +0x8B0A 0x8B0B 0x8B0C 0x8B0E 0x8B0F 0x8B10 0x8B14 0x8B16 0x8B17 0x8B19 0x8B1A 0x8B1B 0x8B1D 0x8B1E 0x8B20 0x8B21 +0x8B22 0x8B26 0x8B28 0x8B2B 0x8B2C 0x8B2D 0x8B2E 0x8B33 0x8B37 0x8B39 0x8B3E 0x8B41 0x8B46 0x8B49 0x8B4A 0x8B4C +0x8B4E 0x8B4F 0x8B53 0x8B56 0x8B58 0x8B59 0x8B5A 0x8B5B 0x8B5C 0x8B5E 0x8B5F 0x8B60 0x8B63 0x8B66 0x8B69 0x8B6A +0x8B6B 0x8B6C 0x8B6D 0x8B6F 0x8B70 0x8B71 0x8B72 0x8B74 0x8B77 0x8B78 0x8B7D 0x8B7F 0x8B80 0x8B83 0x8B85 0x8B86 +0x8B8A 0x8B8B 0x8B8C 0x8B8E 0x8B90 0x8B92 0x8B93 0x8B94 0x8B95 0x8B96 0x8B99 0x8B9A 0x8B9C 0x8B9E 0x8B9F 0x8BA0 +0x8BA1 0x8BA2 0x8BA3 0x8BA4 0x8BA5 0x8BA6 0x8BA7 0x8BA8 0x8BA9 0x8BAA 0x8BAB 0x8BAC 0x8BAD 0x8BAE 0x8BAF 0x8BB0 +0x8BB1 0x8BB2 0x8BB3 0x8BB4 0x8BB5 0x8BB6 0x8BB7 0x8BB8 0x8BB9 0x8BBA 0x8BBB 0x8BBC 0x8BBD 0x8BBE 0x8BBF 0x8BC0 +0x8BC1 0x8BC2 0x8BC3 0x8BC4 0x8BC5 0x8BC6 0x8BC7 0x8BC8 0x8BC9 0x8BCA 0x8BCB 0x8BCC 0x8BCD 0x8BCE 0x8BCF 0x8BD0 +0x8BD1 0x8BD2 0x8BD3 0x8BD4 0x8BD5 0x8BD6 0x8BD7 0x8BD8 0x8BD9 0x8BDA 0x8BDB 0x8BDC 0x8BDD 0x8BDE 0x8BDF 0x8BE0 +0x8BE1 0x8BE2 0x8BE3 0x8BE4 0x8BE5 0x8BE6 0x8BE7 0x8BE8 0x8BE9 0x8BEA 0x8BEB 0x8BEC 0x8BED 0x8BEE 0x8BEF 0x8BF0 +0x8BF1 0x8BF2 0x8BF3 0x8BF4 0x8BF5 0x8BF6 0x8BF7 0x8BF8 0x8BF9 0x8BFA 0x8BFB 0x8BFC 0x8BFD 0x8BFE 0x8BFF 0x8C00 +0x8C01 0x8C02 0x8C03 0x8C04 0x8C05 0x8C06 0x8C07 0x8C08 0x8C09 0x8C0A 0x8C0B 0x8C0C 0x8C0D 0x8C0E 0x8C0F 0x8C10 +0x8C11 0x8C12 0x8C13 0x8C14 0x8C15 0x8C16 0x8C17 0x8C18 0x8C19 0x8C1A 0x8C1B 0x8C1C 0x8C1D 0x8C1E 0x8C1F 0x8C20 +0x8C21 0x8C22 0x8C23 0x8C24 0x8C25 0x8C26 0x8C27 0x8C28 0x8C29 0x8C2A 0x8C2B 0x8C2C 0x8C2D 0x8C2E 0x8C2F 0x8C30 +0x8C31 0x8C32 0x8C33 0x8C34 0x8C35 0x8C36 0x8C37 0x8C3A 0x8C3C 0x8C3F 0x8C41 0x8C46 0x8C47 0x8C48 0x8C49 0x8C4A +0x8C4C 0x8C4E 0x8C50 0x8C54 0x8C55 0x8C57 0x8C5A 0x8C61 0x8C62 0x8C68 0x8C6A 0x8C6B 0x8C6C 0x8C6D 0x8C6E 0x8C73 +0x8C76 0x8C78 0x8C79 0x8C7A 0x8C7C 0x8C82 0x8C85 0x8C86 0x8C89 0x8C8A 0x8C8C 0x8C8D 0x8C8E 0x8C90 0x8C92 0x8C93 +0x8C94 0x8C98 0x8C99 0x8C9D 0x8C9E 0x8C9F 0x8CA0 0x8CA1 0x8CA2 0x8CA7 0x8CA8 0x8CA9 0x8CAA 0x8CAB 0x8CAC 0x8CAD +0x8CAE 0x8CAF 0x8CB0 0x8CB2 0x8CB3 0x8CB4 0x8CB6 0x8CB7 0x8CB8 0x8CBA 0x8CBB 0x8CBC 0x8CBD 0x8CBF 0x8CC0 0x8CC1 +0x8CC2 0x8CC3 0x8CC4 0x8CC5 0x8CC7 0x8CC8 0x8CCA 0x8CCD 0x8CCE 0x8CCF 0x8CD1 0x8CD2 0x8CD3 0x8CD5 0x8CD9 0x8CDA +0x8CDB 0x8CDC 0x8CDE 0x8CE0 0x8CE1 0x8CE2 0x8CE3 0x8CE4 0x8CE6 0x8CE7 0x8CE8 0x8CEA 0x8CEB 0x8CEC 0x8CED 0x8CF0 +0x8CF1 0x8CF4 0x8CF5 0x8CF8 0x8CFA 0x8CFB 0x8CFC 0x8CFD 0x8CFE 0x8D04 0x8D05 0x8D07 0x8D08 0x8D0A 0x8D0B 0x8D0D +0x8D0F 0x8D10 0x8D13 0x8D14 0x8D16 0x8D17 0x8D1B 0x8D1C 0x8D1D 0x8D1E 0x8D1F 0x8D20 0x8D21 0x8D22 0x8D23 0x8D24 +0x8D25 0x8D26 0x8D27 0x8D28 0x8D29 0x8D2A 0x8D2B 0x8D2C 0x8D2D 0x8D2E 0x8D2F 0x8D30 0x8D31 0x8D32 0x8D33 0x8D34 +0x8D35 0x8D36 0x8D37 0x8D38 0x8D39 0x8D3A 0x8D3B 0x8D3C 0x8D3D 0x8D3E 0x8D3F 0x8D40 0x8D41 0x8D42 0x8D43 0x8D44 +0x8D45 0x8D46 0x8D47 0x8D48 0x8D49 0x8D4A 0x8D4B 0x8D4C 0x8D4D 0x8D4E 0x8D4F 0x8D50 0x8D51 0x8D52 0x8D53 0x8D54 +0x8D55 0x8D56 0x8D57 0x8D58 0x8D59 0x8D5A 0x8D5B 0x8D5C 0x8D5D 0x8D5E 0x8D5F 0x8D60 0x8D61 0x8D62 0x8D63 0x8D64 +0x8D66 0x8D67 0x8D69 0x8D6A 0x8D6B 0x8D6C 0x8D6D 0x8D70 0x8D71 0x8D73 0x8D74 0x8D75 0x8D76 0x8D77 0x8D81 0x8D84 +0x8D85 0x8D8A 0x8D8B 0x8D91 0x8D94 0x8D95 0x8D96 0x8D99 0x8D9F 0x8DA3 0x8DA8 0x8DAF 0x8DB1 0x8DB2 0x8DB3 0x8DB4 +0x8DB5 0x8DB8 0x8DBA 0x8DBC 0x8DBE 0x8DBF 0x8DC2 0x8DC3 0x8DC4 0x8DC5 0x8DC6 0x8DCB 0x8DCC 0x8DCE 0x8DCF 0x8DD0 +0x8DD1 0x8DD6 0x8DD7 0x8DDA 0x8DDB 0x8DDD 0x8DDE 0x8DDF 0x8DE1 0x8DE3 0x8DE4 0x8DE6 0x8DE8 0x8DE9 0x8DEA 0x8DEB +0x8DEC 0x8DEF 0x8DF0 0x8DF1 0x8DF3 0x8DF5 0x8DF6 0x8DF7 0x8DF8 0x8DF9 0x8DFA 0x8DFB 0x8DFC 0x8DFD 0x8DFF 0x8E04 +0x8E05 0x8E08 0x8E09 0x8E0A 0x8E0C 0x8E0E 0x8E0F 0x8E10 0x8E12 0x8E14 0x8E16 0x8E1C 0x8E1D 0x8E1E 0x8E1F 0x8E21 +0x8E22 0x8E23 0x8E26 0x8E27 0x8E29 0x8E2A 0x8E2B 0x8E2C 0x8E2D 0x8E2E 0x8E2F 0x8E30 0x8E31 0x8E34 0x8E35 0x8E36 +0x8E39 0x8E3A 0x8E3C 0x8E3D 0x8E40 0x8E41 0x8E42 0x8E44 0x8E45 0x8E47 0x8E48 0x8E49 0x8E4A 0x8E4B 0x8E4C 0x8E4D +0x8E4F 0x8E50 0x8E51 0x8E52 0x8E53 0x8E54 0x8E55 0x8E59 0x8E5A 0x8E5C 0x8E5F 0x8E60 0x8E61 0x8E62 0x8E63 0x8E64 +0x8E66 0x8E67 0x8E69 0x8E6C 0x8E6D 0x8E6F 0x8E70 0x8E72 0x8E74 0x8E76 0x8E7A 0x8E7B 0x8E7C 0x8E7D 0x8E7E 0x8E7F +0x8E80 0x8E81 0x8E82 0x8E84 0x8E85 0x8E87 0x8E89 0x8E8A 0x8E8B 0x8E8D 0x8E8F 0x8E90 0x8E91 0x8E92 0x8E93 0x8E94 +0x8E95 0x8E99 0x8E9A 0x8E9C 0x8E9D 0x8E9E 0x8EA1 0x8EA5 0x8EA6 0x8EAA 0x8EAB 0x8EAC 0x8EAD 0x8EAF 0x8EB0 0x8EB1 +0x8EB2 0x8EBA 0x8EBC 0x8EBE 0x8EC0 0x8EC1 0x8EC5 0x8EC6 0x8EC8 0x8ECA 0x8ECB 0x8ECC 0x8ECD 0x8ECE 0x8ECF 0x8ED1 +0x8ED2 0x8ED4 0x8EDA 0x8EDB 0x8EDD 0x8EDF 0x8EE2 0x8EE3 0x8EE4 0x8EE8 0x8EEB 0x8EF1 0x8EF2 0x8EF8 0x8EF9 0x8EFA +0x8EFB 0x8EFC 0x8EFD 0x8EFE 0x8EFF 0x8F00 0x8F03 0x8F04 0x8F05 0x8F07 0x8F08 0x8F09 0x8F0A 0x8F0B 0x8F0C 0x8F12 +0x8F13 0x8F14 0x8F15 0x8F17 0x8F19 0x8F1B 0x8F1C 0x8F1D 0x8F1E 0x8F1F 0x8F25 0x8F26 0x8F27 0x8F29 0x8F2A 0x8F2C +0x8F2D 0x8F2E 0x8F2F 0x8F33 0x8F36 0x8F38 0x8F39 0x8F3B 0x8F3C 0x8F3E 0x8F3F 0x8F40 0x8F42 0x8F44 0x8F45 0x8F46 +0x8F49 0x8F4C 0x8F4D 0x8F4E 0x8F54 0x8F57 0x8F58 0x8F5C 0x8F5D 0x8F5F 0x8F61 0x8F62 0x8F63 0x8F64 0x8F66 0x8F67 +0x8F68 0x8F69 0x8F6A 0x8F6B 0x8F6C 0x8F6D 0x8F6E 0x8F6F 0x8F70 0x8F71 0x8F72 0x8F73 0x8F74 0x8F75 0x8F76 0x8F77 +0x8F78 0x8F79 0x8F7A 0x8F7B 0x8F7C 0x8F7D 0x8F7E 0x8F7F 0x8F80 0x8F81 0x8F82 0x8F83 0x8F84 0x8F85 0x8F86 0x8F87 +0x8F88 0x8F89 0x8F8A 0x8F8B 0x8F8C 0x8F8D 0x8F8E 0x8F8F 0x8F90 0x8F91 0x8F92 0x8F93 0x8F94 0x8F95 0x8F96 0x8F97 +0x8F98 0x8F99 0x8F9A 0x8F9B 0x8F9C 0x8F9E 0x8F9F 0x8FA3 0x8FA6 0x8FA7 0x8FA8 0x8FA9 0x8FAB 0x8FAD 0x8FAE 0x8FAF +0x8FB0 0x8FB1 0x8FB2 0x8FB4 0x8FB5 0x8FB6 0x8FB7 0x8FB9 0x8FBA 0x8FBB 0x8FBC 0x8FBD 0x8FBE 0x8FBF 0x8FC0 0x8FC1 +0x8FC2 0x8FC4 0x8FC5 0x8FC6 0x8FC7 0x8FC8 0x8FC9 0x8FCB 0x8FCC 0x8FCD 0x8FCE 0x8FD0 0x8FD1 0x8FD2 0x8FD3 0x8FD4 +0x8FD5 0x8FD6 0x8FD7 0x8FD8 0x8FD9 0x8FDA 0x8FDB 0x8FDC 0x8FDD 0x8FDE 0x8FDF 0x8FE0 0x8FE1 0x8FE2 0x8FE3 0x8FE4 +0x8FE5 0x8FE6 0x8FE8 0x8FE9 0x8FEA 0x8FEB 0x8FED 0x8FEE 0x8FEF 0x8FF0 0x8FF2 0x8FF3 0x8FF4 0x8FF5 0x8FF6 0x8FF7 +0x8FF8 0x8FF9 0x8FFA 0x8FFB 0x8FFC 0x8FFD 0x8FFE 0x8FFF 0x9000 0x9001 0x9002 0x9003 0x9004 0x9005 0x9006 0x9008 +0x9009 0x900A 0x900B 0x900C 0x900D 0x900E 0x900F 0x9010 0x9011 0x9012 0x9013 0x9014 0x9015 0x9016 0x9017 0x9019 +0x901A 0x901B 0x901C 0x901D 0x901E 0x901F 0x9020 0x9021 0x9022 0x9023 0x9024 0x9026 0x9027 0x902D 0x902E 0x902F +0x9031 0x9032 0x9034 0x9035 0x9036 0x9038 0x9039 0x903B 0x903C 0x903D 0x903E 0x903F 0x9041 0x9042 0x9044 0x9045 +0x9046 0x9047 0x9049 0x904A 0x904B 0x904D 0x904E 0x904F 0x9050 0x9051 0x9052 0x9053 0x9054 0x9055 0x9056 0x9057 +0x9058 0x9059 0x905B 0x905C 0x905D 0x905E 0x9060 0x9061 0x9062 0x9063 0x9065 0x9067 0x9068 0x9069 0x906B 0x906D +0x906E 0x906F 0x9070 0x9072 0x9073 0x9074 0x9075 0x9076 0x9077 0x9078 0x9079 0x907A 0x907B 0x907C 0x907D 0x907E +0x907F 0x9080 0x9081 0x9082 0x9083 0x9084 0x9085 0x9086 0x9087 0x9088 0x9089 0x908A 0x908B 0x908D 0x908F 0x9090 +0x9091 0x9093 0x9094 0x9095 0x9097 0x9098 0x9099 0x909B 0x909D 0x909E 0x909F 0x90A0 0x90A1 0x90A2 0x90A3 0x90A5 +0x90A6 0x90A7 0x90A8 0x90AA 0x90AC 0x90AE 0x90AF 0x90B0 0x90B1 0x90B2 0x90B3 0x90B4 0x90B5 0x90B6 0x90B8 0x90B9 +0x90BA 0x90BB 0x90BD 0x90BE 0x90BF 0x90C1 0x90C3 0x90C4 0x90C5 0x90C7 0x90C8 0x90CA 0x90CE 0x90CF 0x90D0 0x90D1 +0x90D3 0x90D7 0x90DA 0x90DB 0x90DC 0x90DD 0x90DE 0x90DF 0x90E1 0x90E2 0x90E4 0x90E6 0x90E7 0x90E8 0x90EA 0x90EB +0x90EC 0x90ED 0x90EF 0x90F4 0x90F5 0x90F7 0x90F8 0x90FD 0x90FE 0x90FF 0x9100 0x9102 0x9103 0x9104 0x9105 0x9106 +0x9109 0x910C 0x9111 0x9112 0x9114 0x9115 0x9116 0x9117 0x9118 0x9119 0x911A 0x911C 0x911E 0x9120 0x9122 0x9123 +0x9127 0x9129 0x912B 0x912D 0x912E 0x912F 0x9130 0x9131 0x9132 0x9133 0x9134 0x9136 0x9139 0x913A 0x9142 0x9143 +0x9145 0x9146 0x9147 0x9148 0x9149 0x914A 0x914B 0x914C 0x914D 0x914E 0x914F 0x9150 0x9152 0x9154 0x9155 0x9156 +0x9157 0x9158 0x915A 0x915C 0x915D 0x915E 0x9161 0x9162 0x9163 0x9164 0x9165 0x9166 0x9169 0x916A 0x916C 0x916E +0x916F 0x9170 0x9171 0x9172 0x9173 0x9174 0x9175 0x9176 0x9177 0x9178 0x9179 0x917A 0x917D 0x917E 0x917F 0x9181 +0x9182 0x9183 0x9184 0x9185 0x9187 0x9189 0x918B 0x918C 0x918D 0x9190 0x9191 0x9192 0x9196 0x9197 0x919A 0x919B +0x919C 0x919E 0x91A1 0x91A2 0x91A3 0x91A4 0x91A8 0x91AA 0x91AB 0x91AC 0x91AD 0x91AE 0x91AF 0x91B1 0x91B2 0x91B4 +0x91B5 0x91B8 0x91BA 0x91BE 0x91C0 0x91C1 0x91C3 0x91C5 0x91C6 0x91C7 0x91C8 0x91C9 0x91CA 0x91CB 0x91CC 0x91CD +0x91CE 0x91CF 0x91D0 0x91D1 0x91D2 0x91D3 0x91D4 0x91D5 0x91D6 0x91D7 0x91D8 0x91D9 0x91DA 0x91DB 0x91DC 0x91DD +0x91DF 0x91E1 0x91E2 0x91E3 0x91E4 0x91E6 0x91E7 0x91E8 0x91E9 0x91EA 0x91EB 0x91EC 0x91ED 0x91EE 0x91F1 0x91F3 +0x91F4 0x91F5 0x91F6 0x91F7 0x91F8 0x91F9 0x91FA 0x91FC 0x91FD 0x91FE 0x91FF 0x9200 0x9201 0x9202 0x9203 0x9204 +0x9205 0x9206 0x9207 0x9208 0x9209 0x920A 0x920C 0x920D 0x920E 0x920F 0x9210 0x9211 0x9212 0x9214 0x9215 0x9216 +0x9217 0x9219 0x921A 0x921C 0x921E 0x9223 0x9224 0x9225 0x9226 0x9227 0x9229 0x922A 0x922C 0x922D 0x922E 0x9230 +0x9231 0x9232 0x9233 0x9234 0x9236 0x9237 0x9238 0x9239 0x923A 0x923D 0x923E 0x923F 0x9240 0x9244 0x9245 0x9246 +0x9248 0x9249 0x924A 0x924B 0x924C 0x924D 0x924E 0x924F 0x9250 0x9251 0x9252 0x9253 0x9254 0x9255 0x9256 0x9257 +0x925A 0x925B 0x925D 0x925E 0x9260 0x9261 0x9262 0x9263 0x9264 0x9265 0x9266 0x9267 0x9268 0x926C 0x926D 0x926E +0x926F 0x9270 0x9271 0x9272 0x9273 0x9274 0x9276 0x9277 0x9278 0x9279 0x927A 0x927B 0x927C 0x927D 0x927E 0x927F +0x9280 0x9282 0x9283 0x9285 0x9286 0x9287 0x9288 0x928A 0x928B 0x928C 0x928D 0x928E 0x9291 0x9293 0x9294 0x9295 +0x9296 0x9297 0x9298 0x9299 0x929A 0x929B 0x929C 0x929D 0x92A0 0x92A1 0x92A2 0x92A3 0x92A4 0x92A5 0x92A6 0x92A7 +0x92A8 0x92A9 0x92AA 0x92AB 0x92AC 0x92AD 0x92AE 0x92B1 0x92B2 0x92B3 0x92B6 0x92B7 0x92B9 0x92BB 0x92BC 0x92C1 +0x92C2 0x92C3 0x92C5 0x92C6 0x92C7 0x92C8 0x92C9 0x92CC 0x92CF 0x92D0 0x92D2 0x92D5 0x92D7 0x92D9 0x92DD 0x92DF +0x92E3 0x92E4 0x92E5 0x92E6 0x92E7 0x92E8 0x92E9 0x92EA 0x92EC 0x92ED 0x92EE 0x92EF 0x92F0 0x92F1 0x92F2 0x92F3 +0x92F6 0x92F8 0x92F9 0x92FA 0x92FC 0x9300 0x9301 0x9302 0x9304 0x9306 0x9307 0x9308 0x930F 0x9310 0x9312 0x9315 +0x9318 0x9319 0x931A 0x931B 0x931E 0x931F 0x9320 0x9321 0x9322 0x9323 0x9324 0x9326 0x9327 0x9328 0x9329 0x932A +0x932B 0x932C 0x932E 0x932F 0x9332 0x9333 0x9335 0x9336 0x9338 0x933A 0x933B 0x933C 0x933E 0x9340 0x9341 0x9343 +0x9344 0x9345 0x9346 0x9347 0x9348 0x9349 0x934A 0x934B 0x934D 0x9351 0x9352 0x9354 0x9355 0x9356 0x9358 0x9359 +0x935A 0x935B 0x935C 0x935E 0x9360 0x9364 0x9365 0x9369 0x936A 0x936C 0x936D 0x936E 0x9370 0x9375 0x9376 0x937A +0x937C 0x937E 0x9382 0x9384 0x9385 0x9387 0x938A 0x938C 0x938F 0x9393 0x9394 0x9396 0x9397 0x9398 0x939A 0x939B +0x939D 0x93A1 0x93A2 0x93A3 0x93A4 0x93A6 0x93A7 0x93A9 0x93AA 0x93AC 0x93AD 0x93AE 0x93AF 0x93B0 0x93B2 0x93B3 +0x93B5 0x93B6 0x93B7 0x93B8 0x93B9 0x93BF 0x93C2 0x93C3 0x93C4 0x93C7 0x93C8 0x93CA 0x93CB 0x93CC 0x93CD 0x93CF +0x93D0 0x93D1 0x93D6 0x93D7 0x93D8 0x93DC 0x93DD 0x93DE 0x93DF 0x93E1 0x93E2 0x93E4 0x93E5 0x93E6 0x93E8 0x93F0 +0x93F1 0x93F5 0x93F6 0x93F7 0x93F9 0x93FA 0x93FB 0x93FD 0x9403 0x9404 0x9407 0x940B 0x940D 0x940E 0x940F 0x9410 +0x9412 0x9413 0x9414 0x9418 0x9419 0x941A 0x941D 0x9420 0x9421 0x9424 0x9425 0x9426 0x9427 0x9428 0x9429 0x942B +0x942E 0x942F 0x9431 0x9432 0x9433 0x9435 0x9436 0x9438 0x943A 0x943D 0x943E 0x943F 0x9440 0x9441 0x9442 0x9444 +0x944A 0x944C 0x9451 0x9452 0x9453 0x9454 0x9455 0x945A 0x945B 0x945E 0x9460 0x9462 0x9463 0x9464 0x9465 0x946A +0x946B 0x946D 0x9470 0x9471 0x9472 0x9473 0x9474 0x9475 0x9476 0x9477 0x9478 0x9479 0x947C 0x947D 0x947E 0x947F +0x9480 0x9481 0x9482 0x9483 0x9485 0x9486 0x9487 0x9488 0x9489 0x948A 0x948B 0x948C 0x948D 0x948E 0x948F 0x9490 +0x9491 0x9492 0x9493 0x9494 0x9495 0x9496 0x9497 0x9498 0x9499 0x949A 0x949B 0x949C 0x949D 0x949E 0x949F 0x94A0 +0x94A1 0x94A2 0x94A3 0x94A4 0x94A5 0x94A6 0x94A7 0x94A8 0x94A9 0x94AA 0x94AB 0x94AC 0x94AD 0x94AE 0x94AF 0x94B0 +0x94B1 0x94B2 0x94B3 0x94B4 0x94B5 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BB 0x94BC 0x94BD 0x94BE 0x94BF 0x94C0 +0x94C1 0x94C2 0x94C3 0x94C4 0x94C5 0x94C6 0x94C7 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC 0x94CD 0x94CE 0x94CF 0x94D0 +0x94D1 0x94D2 0x94D3 0x94D4 0x94D5 0x94D6 0x94D7 0x94D8 0x94D9 0x94DA 0x94DB 0x94DC 0x94DD 0x94DE 0x94DF 0x94E0 +0x94E1 0x94E2 0x94E3 0x94E4 0x94E5 0x94E6 0x94E7 0x94E8 0x94E9 0x94EA 0x94EB 0x94EC 0x94ED 0x94EE 0x94EF 0x94F0 +0x94F1 0x94F2 0x94F3 0x94F4 0x94F5 0x94F6 0x94F7 0x94F8 0x94F9 0x94FA 0x94FB 0x94FC 0x94FD 0x94FE 0x94FF 0x9500 +0x9501 0x9502 0x9503 0x9504 0x9505 0x9506 0x9507 0x9508 0x9509 0x950A 0x950B 0x950C 0x950D 0x950E 0x950F 0x9510 +0x9511 0x9512 0x9513 0x9514 0x9515 0x9516 0x9517 0x9518 0x9519 0x951A 0x951B 0x951C 0x951D 0x951E 0x951F 0x9520 +0x9521 0x9522 0x9523 0x9524 0x9525 0x9526 0x9527 0x9528 0x9529 0x952A 0x952B 0x952C 0x952D 0x952E 0x952F 0x9530 +0x9531 0x9532 0x9533 0x9534 0x9535 0x9536 0x9537 0x9538 0x9539 0x953A 0x953B 0x953C 0x953D 0x953E 0x953F 0x9540 +0x9541 0x9542 0x9543 0x9544 0x9545 0x9546 0x9547 0x9548 0x9549 0x954A 0x954B 0x954C 0x954D 0x954E 0x954F 0x9550 +0x9551 0x9552 0x9553 0x9554 0x9555 0x9556 0x9557 0x9558 0x9559 0x955A 0x955B 0x955C 0x955D 0x955E 0x955F 0x9560 +0x9561 0x9562 0x9563 0x9564 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C 0x956D 0x956E 0x956F 0x9570 +0x9571 0x9572 0x9573 0x9574 0x9575 0x9576 0x9577 0x9578 0x957A 0x957B 0x957C 0x957D 0x957F 0x9580 0x9581 0x9582 +0x9583 0x9586 0x9587 0x9588 0x9589 0x958A 0x958B 0x958C 0x958D 0x958E 0x958F 0x9590 0x9591 0x9592 0x9593 0x9594 +0x9596 0x9598 0x9599 0x959B 0x959C 0x959E 0x959F 0x95A0 0x95A1 0x95A2 0x95A3 0x95A4 0x95A5 0x95A7 0x95A8 0x95A9 +0x95AA 0x95AB 0x95AC 0x95AD 0x95AE 0x95B0 0x95B1 0x95B2 0x95B5 0x95B6 0x95B7 0x95B9 0x95BA 0x95BB 0x95BC 0x95BD +0x95BE 0x95BF 0x95C0 0x95C3 0x95C5 0x95C6 0x95C7 0x95C8 0x95C9 0x95CA 0x95CB 0x95CC 0x95CD 0x95D0 0x95D1 0x95D2 +0x95D3 0x95D4 0x95D5 0x95D6 0x95D8 0x95DA 0x95DB 0x95DC 0x95DE 0x95DF 0x95E0 0x95E1 0x95E2 0x95E3 0x95E4 0x95E5 +0x95E8 0x95E9 0x95EA 0x95EB 0x95EC 0x95ED 0x95EE 0x95EF 0x95F0 0x95F1 0x95F2 0x95F3 0x95F4 0x95F5 0x95F6 0x95F7 +0x95F8 0x95F9 0x95FA 0x95FB 0x95FC 0x95FD 0x95FE 0x95FF 0x9600 0x9601 0x9602 0x9603 0x9604 0x9605 0x9606 0x9607 +0x9608 0x9609 0x960A 0x960B 0x960C 0x960D 0x960E 0x960F 0x9610 0x9611 0x9612 0x9613 0x9614 0x9615 0x9616 0x9617 +0x9618 0x9619 0x961A 0x961B 0x961C 0x961D 0x961E 0x961F 0x9620 0x9621 0x9622 0x9623 0x9624 0x9627 0x9628 0x962A +0x962C 0x962D 0x962E 0x962F 0x9630 0x9631 0x9632 0x9633 0x9634 0x9635 0x9636 0x9639 0x963A 0x963B 0x963C 0x963D +0x963F 0x9640 0x9641 0x9642 0x9644 0x9645 0x9646 0x9647 0x9648 0x9649 0x964B 0x964C 0x964D 0x964E 0x964F 0x9650 +0x9651 0x9654 0x9655 0x9658 0x965B 0x965C 0x965D 0x965E 0x965F 0x9661 0x9662 0x9663 0x9664 0x9665 0x9666 0x9667 +0x9668 0x9669 0x966A 0x966C 0x9670 0x9672 0x9673 0x9674 0x9675 0x9676 0x9677 0x9678 0x967A 0x967D 0x9683 0x9684 +0x9685 0x9686 0x9688 0x9689 0x968A 0x968B 0x968D 0x968E 0x968F 0x9690 0x9691 0x9694 0x9695 0x9697 0x9698 0x9699 +0x969B 0x969C 0x96A0 0x96A3 0x96A4 0x96A7 0x96A8 0x96A9 0x96AA 0x96AE 0x96B0 0x96B1 0x96B2 0x96B3 0x96B4 0x96B6 +0x96B7 0x96B8 0x96B9 0x96BA 0x96BB 0x96BC 0x96BD 0x96BE 0x96C0 0x96C1 0x96C3 0x96C4 0x96C5 0x96C6 0x96C7 0x96C9 +0x96CA 0x96CB 0x96CC 0x96CD 0x96CE 0x96CF 0x96D1 0x96D2 0x96D4 0x96D5 0x96D6 0x96D8 0x96D9 0x96DB 0x96DC 0x96DE +0x96E0 0x96E2 0x96E3 0x96E8 0x96E9 0x96EA 0x96EB 0x96EF 0x96F0 0x96F1 0x96F2 0x96F3 0x96F6 0x96F7 0x96F9 0x96FB +0x96FE 0x9700 0x9701 0x9702 0x9704 0x9705 0x9706 0x9707 0x9708 0x9709 0x970A 0x970D 0x970E 0x970F 0x9711 0x9713 +0x9716 0x9719 0x971C 0x971E 0x9721 0x9722 0x9724 0x9726 0x9727 0x9728 0x972A 0x972D 0x9730 0x9732 0x9738 0x9739 +0x973D 0x973E 0x9742 0x9744 0x9746 0x9748 0x9749 0x974D 0x974F 0x9751 0x9752 0x9753 0x9754 0x9756 0x9758 0x9759 +0x975A 0x975B 0x975C 0x975D 0x975E 0x9760 0x9761 0x9762 0x9764 0x9765 0x9766 0x9767 0x9768 0x9769 0x976A 0x976B +0x976C 0x976D 0x976E 0x9770 0x9771 0x9772 0x9773 0x9774 0x9776 0x9777 0x9778 0x9779 0x977A 0x977B 0x977C 0x977D +0x977F 0x9780 0x9781 0x9784 0x9785 0x9786 0x978B 0x978C 0x978D 0x978E 0x978F 0x9790 0x9791 0x9792 0x9794 0x9798 +0x979C 0x97A0 0x97A1 0x97A3 0x97A6 0x97A7 0x97A8 0x97AB 0x97AC 0x97AD 0x97AE 0x97AF 0x97B2 0x97B3 0x97B4 0x97BD +0x97BE 0x97BF 0x97C1 0x97C2 0x97C3 0x97C6 0x97C8 0x97C9 0x97CB 0x97CC 0x97CD 0x97D3 0x97D9 0x97DB 0x97DC 0x97DE +0x97E1 0x97E6 0x97E7 0x97E8 0x97E9 0x97EA 0x97EB 0x97EC 0x97ED 0x97EE 0x97F1 0x97F2 0x97F3 0x97F5 0x97F6 0x97F9 +0x97FB 0x97FE 0x97FF 0x9800 0x9801 0x9802 0x9803 0x9804 0x9805 0x9806 0x9807 0x9808 0x980A 0x980C 0x980D 0x980E +0x980F 0x9810 0x9811 0x9812 0x9813 0x9814 0x9816 0x9817 0x9818 0x981A 0x981C 0x9820 0x9821 0x9824 0x9826 0x982B +0x982C 0x982D 0x982E 0x9830 0x9832 0x9834 0x9835 0x9837 0x9838 0x9839 0x983B 0x983C 0x983D 0x9846 0x984B 0x984C +0x984D 0x984E 0x984F 0x9851 0x9852 0x9853 0x9854 0x9855 0x9857 0x9858 0x9859 0x985A 0x985B 0x985E 0x9862 0x9863 +0x9865 0x9867 0x9869 0x986B 0x986C 0x986F 0x9870 0x9871 0x9872 0x9873 0x9874 0x9875 0x9876 0x9877 0x9878 0x9879 +0x987A 0x987B 0x987C 0x987D 0x987E 0x987F 0x9880 0x9881 0x9882 0x9883 0x9884 0x9885 0x9886 0x9887 0x9888 0x9889 +0x988A 0x988B 0x988C 0x988D 0x988E 0x988F 0x9890 0x9891 0x9892 0x9893 0x9894 0x9895 0x9896 0x9897 0x9898 0x9899 +0x989A 0x989B 0x989C 0x989D 0x989E 0x989F 0x98A0 0x98A1 0x98A2 0x98A3 0x98A4 0x98A5 0x98A6 0x98A7 0x98A8 0x98A9 +0x98AA 0x98AC 0x98AD 0x98AE 0x98AF 0x98B1 0x98B2 0x98B3 0x98B6 0x98B8 0x98BA 0x98BB 0x98BC 0x98BD 0x98BE 0x98BF +0x98C0 0x98C1 0x98C2 0x98C3 0x98C4 0x98C6 0x98C7 0x98C8 0x98C9 0x98CB 0x98CC 0x98CE 0x98CF 0x98D0 0x98D1 0x98D2 +0x98D3 0x98D4 0x98D5 0x98D6 0x98D7 0x98D8 0x98D9 0x98DA 0x98DB 0x98DC 0x98DE 0x98DF 0x98E0 0x98E1 0x98E2 0x98E3 +0x98E5 0x98E7 0x98E8 0x98E9 0x98EA 0x98EB 0x98ED 0x98EE 0x98EF 0x98F2 0x98F4 0x98F6 0x98F9 0x98FA 0x98FC 0x98FD +0x98FE 0x98FF 0x9900 0x9902 0x9903 0x9904 0x9905 0x9907 0x9908 0x9909 0x990A 0x990C 0x990D 0x990E 0x990F 0x9910 +0x9911 0x9912 0x9913 0x9914 0x9915 0x9916 0x9917 0x9918 0x991A 0x991B 0x991C 0x991D 0x991E 0x991F 0x9920 0x9921 +0x9924 0x9928 0x992C 0x992E 0x9931 0x9932 0x9933 0x9935 0x9936 0x9937 0x9938 0x993A 0x993C 0x993D 0x993E 0x993F +0x9941 0x9942 0x9943 0x9945 0x9948 0x9949 0x994A 0x994B 0x994C 0x994D 0x9950 0x9951 0x9952 0x9954 0x9955 0x9957 +0x9958 0x995C 0x995E 0x9962 0x9963 0x9964 0x9965 0x9966 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x996D 0x996E +0x996F 0x9970 0x9971 0x9972 0x9973 0x9974 0x9975 0x9976 0x9977 0x9978 0x9979 0x997A 0x997B 0x997C 0x997D 0x997E +0x997F 0x9980 0x9981 0x9982 0x9983 0x9984 0x9985 0x9986 0x9987 0x9988 0x9989 0x998A 0x998B 0x998C 0x998D 0x998E +0x998F 0x9990 0x9991 0x9992 0x9993 0x9994 0x9995 0x9996 0x9997 0x9998 0x9999 0x999D 0x999E 0x99A5 0x99A7 0x99A8 +0x99AC 0x99AD 0x99AE 0x99AF 0x99B0 0x99B1 0x99B2 0x99B3 0x99B4 0x99B5 0x99B9 0x99BA 0x99BB 0x99BC 0x99BD 0x99C1 +0x99C2 0x99C3 0x99C4 0x99C5 0x99C6 0x99C7 0x99C8 0x99C9 0x99CB 0x99CC 0x99CD 0x99CE 0x99CF 0x99D0 0x99D1 0x99D2 +0x99D3 0x99D4 0x99D5 0x99D6 0x99D7 0x99D8 0x99D9 0x99DB 0x99DC 0x99DD 0x99DF 0x99E1 0x99E2 0x99E3 0x99E4 0x99E5 +0x99E7 0x99E9 0x99EA 0x99EC 0x99ED 0x99EE 0x99F0 0x99F1 0x99F2 0x99F8 0x99FB 0x99FC 0x99FF 0x9A01 0x9A02 0x9A03 +0x9A04 0x9A05 0x9A06 0x9A08 0x9A0A 0x9A0C 0x9A0D 0x9A0E 0x9A0F 0x9A11 0x9A12 0x9A13 0x9A16 0x9A19 0x9A1E 0x9A20 +0x9A24 0x9A27 0x9A28 0x9A2B 0x9A2D 0x9A2E 0x9A2F 0x9A30 0x9A31 0x9A35 0x9A36 0x9A37 0x9A38 0x9A3E 0x9A40 0x9A41 +0x9A42 0x9A43 0x9A44 0x9A45 0x9A4A 0x9A4C 0x9A4D 0x9A4E 0x9A4F 0x9A50 0x9A52 0x9A55 0x9A57 0x9A5A 0x9A5B 0x9A5F +0x9A62 0x9A63 0x9A64 0x9A65 0x9A66 0x9A69 0x9A6A 0x9A6B 0x9A6C 0x9A6D 0x9A6E 0x9A6F 0x9A70 0x9A71 0x9A72 0x9A73 +0x9A74 0x9A75 0x9A76 0x9A77 0x9A78 0x9A79 0x9A7A 0x9A7B 0x9A7C 0x9A7D 0x9A7E 0x9A7F 0x9A80 0x9A81 0x9A82 0x9A83 +0x9A84 0x9A85 0x9A86 0x9A87 0x9A88 0x9A89 0x9A8A 0x9A8B 0x9A8C 0x9A8D 0x9A8E 0x9A8F 0x9A90 0x9A91 0x9A92 0x9A93 +0x9A94 0x9A95 0x9A96 0x9A97 0x9A98 0x9A99 0x9A9A 0x9A9B 0x9A9C 0x9A9D 0x9A9E 0x9A9F 0x9AA0 0x9AA1 0x9AA2 0x9AA3 +0x9AA4 0x9AA5 0x9AA6 0x9AA7 0x9AA8 0x9AAB 0x9AAD 0x9AAF 0x9AB0 0x9AB1 0x9AB3 0x9AB4 0x9AB6 0x9AB7 0x9AB8 0x9AB9 +0x9ABA 0x9ABB 0x9ABC 0x9ABE 0x9ABF 0x9AC0 0x9AC1 0x9AC2 0x9AC3 0x9AC4 0x9AC5 0x9AC6 0x9AC7 0x9AC8 0x9ACA 0x9ACB +0x9ACC 0x9ACD 0x9ACE 0x9ACF 0x9AD0 0x9AD1 0x9AD2 0x9AD3 0x9AD4 0x9AD5 0x9AD6 0x9AD8 0x9AD9 0x9ADC 0x9ADD 0x9ADE +0x9ADF 0x9AE1 0x9AE2 0x9AE3 0x9AE5 0x9AE6 0x9AE7 0x9AEA 0x9AEB 0x9AEC 0x9AED 0x9AEE 0x9AEF 0x9AF1 0x9AF2 0x9AF3 +0x9AF4 0x9AF6 0x9AF7 0x9AF9 0x9AFA 0x9AFB 0x9AFC 0x9AFD 0x9AFE 0x9B01 0x9B03 0x9B04 0x9B05 0x9B06 0x9B08 0x9B0A +0x9B0B 0x9B0C 0x9B0D 0x9B0E 0x9B0F 0x9B10 0x9B11 0x9B12 0x9B13 0x9B15 0x9B16 0x9B17 0x9B18 0x9B19 0x9B1A 0x9B1E +0x9B1F 0x9B20 0x9B22 0x9B23 0x9B24 0x9B25 0x9B27 0x9B28 0x9B29 0x9B2A 0x9B2B 0x9B2E 0x9B2F 0x9B31 0x9B32 0x9B33 +0x9B35 0x9B36 0x9B37 0x9B39 0x9B3A 0x9B3B 0x9B3C 0x9B3E 0x9B3F 0x9B41 0x9B42 0x9B43 0x9B44 0x9B45 0x9B46 0x9B47 +0x9B48 0x9B49 0x9B4A 0x9B4B 0x9B4C 0x9B4D 0x9B4E 0x9B4F 0x9B51 0x9B52 0x9B54 0x9B55 0x9B56 0x9B58 0x9B59 0x9B5A +0x9B5B 0x9B5C 0x9B5F 0x9B60 0x9B61 0x9B62 0x9B64 0x9B66 0x9B67 0x9B68 0x9B69 0x9B6C 0x9B6F 0x9B70 0x9B71 0x9B74 +0x9B75 0x9B76 0x9B77 0x9B7A 0x9B7B 0x9B7C 0x9B7D 0x9B7E 0x9B80 0x9B81 0x9B82 0x9B83 0x9B84 0x9B85 0x9B86 0x9B87 +0x9B88 0x9B8A 0x9B8B 0x9B8D 0x9B8E 0x9B90 0x9B91 0x9B92 0x9B93 0x9B95 0x9B96 0x9B97 0x9B9A 0x9B9B 0x9B9C 0x9B9D +0x9B9E 0x9B9F 0x9BA0 0x9BA1 0x9BA2 0x9BA3 0x9BA4 0x9BA5 0x9BA6 0x9BA8 0x9BAA 0x9BAB 0x9BAD 0x9BAE 0x9BAF 0x9BB0 +0x9BB3 0x9BB4 0x9BB5 0x9BB6 0x9BB8 0x9BB9 0x9BBA 0x9BBD 0x9BBF 0x9BC0 0x9BC1 0x9BC3 0x9BC4 0x9BC6 0x9BC7 0x9BC8 +0x9BC9 0x9BCA 0x9BCF 0x9BD1 0x9BD2 0x9BD3 0x9BD4 0x9BD5 0x9BD6 0x9BD7 0x9BD9 0x9BDA 0x9BDB 0x9BDC 0x9BDD 0x9BDE +0x9BE0 0x9BE1 0x9BE2 0x9BE3 0x9BE4 0x9BE5 0x9BE6 0x9BE7 0x9BE8 0x9BEA 0x9BEB 0x9BEC 0x9BED 0x9BF0 0x9BF1 0x9BF2 +0x9BF4 0x9BF5 0x9BF6 0x9BF7 0x9BF8 0x9BFB 0x9BFD 0x9BFF 0x9C01 0x9C02 0x9C03 0x9C04 0x9C05 0x9C06 0x9C07 0x9C08 +0x9C09 0x9C0A 0x9C0B 0x9C0C 0x9C0D 0x9C0E 0x9C0F 0x9C10 0x9C12 0x9C13 0x9C14 0x9C15 0x9C17 0x9C1B 0x9C1C 0x9C1D +0x9C1F 0x9C20 0x9C21 0x9C23 0x9C24 0x9C25 0x9C27 0x9C28 0x9C29 0x9C2D 0x9C2E 0x9C2F 0x9C30 0x9C31 0x9C32 0x9C33 +0x9C35 0x9C36 0x9C37 0x9C39 0x9C3A 0x9C3B 0x9C3C 0x9C3E 0x9C40 0x9C42 0x9C45 0x9C46 0x9C47 0x9C48 0x9C49 0x9C4A +0x9C4B 0x9C4D 0x9C52 0x9C54 0x9C56 0x9C57 0x9C58 0x9C59 0x9C5A 0x9C5D 0x9C5F 0x9C60 0x9C63 0x9C64 0x9C65 0x9C66 +0x9C67 0x9C68 0x9C6D 0x9C6E 0x9C6F 0x9C72 0x9C74 0x9C75 0x9C76 0x9C77 0x9C78 0x9C7A 0x9C7C 0x9C7D 0x9C7E 0x9C7F +0x9C80 0x9C81 0x9C82 0x9C83 0x9C84 0x9C85 0x9C86 0x9C87 0x9C88 0x9C89 0x9C8A 0x9C8B 0x9C8C 0x9C8D 0x9C8E 0x9C8F +0x9C90 0x9C91 0x9C92 0x9C93 0x9C94 0x9C95 0x9C96 0x9C97 0x9C98 0x9C99 0x9C9A 0x9C9B 0x9C9C 0x9C9D 0x9C9E 0x9C9F +0x9CA0 0x9CA1 0x9CA2 0x9CA3 0x9CA4 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAA 0x9CAB 0x9CAC 0x9CAD 0x9CAE 0x9CAF +0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 0x9CB6 0x9CB7 0x9CB8 0x9CB9 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CBE 0x9CBF +0x9CC0 0x9CC1 0x9CC2 0x9CC3 0x9CC4 0x9CC5 0x9CC6 0x9CC7 0x9CC8 0x9CC9 0x9CCA 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF +0x9CD0 0x9CD1 0x9CD2 0x9CD3 0x9CD4 0x9CD5 0x9CD6 0x9CD7 0x9CD8 0x9CD9 0x9CDA 0x9CDB 0x9CDC 0x9CDD 0x9CDE 0x9CDF +0x9CE0 0x9CE1 0x9CE2 0x9CE3 0x9CE4 0x9CE5 0x9CE6 0x9CE7 0x9CE9 0x9CEA 0x9CEB 0x9CEC 0x9CED 0x9CF0 0x9CF1 0x9CF2 +0x9CF3 0x9CF4 0x9CF5 0x9CF6 0x9CF7 0x9CF9 0x9CFA 0x9CFB 0x9CFC 0x9CFD 0x9CFE 0x9CFF 0x9D00 0x9D02 0x9D03 0x9D04 +0x9D05 0x9D06 0x9D07 0x9D08 0x9D09 0x9D0E 0x9D10 0x9D12 0x9D14 0x9D15 0x9D1B 0x9D1C 0x9D1D 0x9D1E 0x9D1F 0x9D23 +0x9D26 0x9D28 0x9D2A 0x9D2B 0x9D2C 0x9D2F 0x9D30 0x9D33 0x9D34 0x9D37 0x9D3B 0x9D3D 0x9D3E 0x9D3F 0x9D41 0x9D42 +0x9D43 0x9D44 0x9D46 0x9D48 0x9D4F 0x9D50 0x9D51 0x9D52 0x9D53 0x9D59 0x9D5C 0x9D5D 0x9D5E 0x9D5F 0x9D60 0x9D61 +0x9D64 0x9D6A 0x9D6B 0x9D6C 0x9D6E 0x9D6F 0x9D70 0x9D72 0x9D77 0x9D7A 0x9D7E 0x9D84 0x9D86 0x9D87 0x9D89 0x9D8A +0x9D8F 0x9D92 0x9D93 0x9D96 0x9D98 0x9D9A 0x9DA0 0x9DA1 0x9DA4 0x9DA5 0x9DA9 0x9DAA 0x9DAB 0x9DAC 0x9DAF 0x9DB1 +0x9DB2 0x9DB4 0x9DB5 0x9DB8 0x9DB9 0x9DBA 0x9DBB 0x9DBC 0x9DBF 0x9DC0 0x9DC1 0x9DC2 0x9DC3 0x9DC4 0x9DC6 0x9DC8 +0x9DC9 0x9DCA 0x9DCF 0x9DD3 0x9DD6 0x9DD7 0x9DD9 0x9DDA 0x9DDF 0x9DE5 0x9DE6 0x9DEB 0x9DED 0x9DEF 0x9DF2 0x9DF3 +0x9DF4 0x9DF8 0x9DF9 0x9DFA 0x9DFD 0x9DFF 0x9E02 0x9E07 0x9E0A 0x9E0C 0x9E0F 0x9E11 0x9E15 0x9E18 0x9E19 0x9E1A +0x9E1B 0x9E1D 0x9E1E 0x9E1F 0x9E20 0x9E21 0x9E22 0x9E23 0x9E24 0x9E25 0x9E26 0x9E27 0x9E28 0x9E29 0x9E2A 0x9E2B +0x9E2C 0x9E2D 0x9E2E 0x9E2F 0x9E30 0x9E31 0x9E32 0x9E33 0x9E34 0x9E35 0x9E36 0x9E37 0x9E38 0x9E39 0x9E3A 0x9E3B +0x9E3C 0x9E3D 0x9E3E 0x9E3F 0x9E40 0x9E41 0x9E42 0x9E43 0x9E44 0x9E45 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4A 0x9E4B +0x9E4C 0x9E4D 0x9E4E 0x9E4F 0x9E50 0x9E51 0x9E52 0x9E53 0x9E54 0x9E55 0x9E56 0x9E57 0x9E58 0x9E59 0x9E5A 0x9E5B +0x9E5C 0x9E5D 0x9E5E 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E63 0x9E64 0x9E65 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B +0x9E6C 0x9E6D 0x9E6E 0x9E6F 0x9E70 0x9E71 0x9E72 0x9E73 0x9E74 0x9E75 0x9E78 0x9E79 0x9E7A 0x9E7C 0x9E7D 0x9E7E +0x9E7F 0x9E80 0x9E81 0x9E82 0x9E83 0x9E86 0x9E87 0x9E88 0x9E89 0x9E8A 0x9E8B 0x9E8C 0x9E8D 0x9E8E 0x9E90 0x9E91 +0x9E92 0x9E93 0x9E94 0x9E95 0x9E96 0x9E97 0x9E99 0x9E9A 0x9E9B 0x9E9C 0x9E9D 0x9E9F 0x9EA0 0x9EA1 0x9EA4 0x9EA5 +0x9EA6 0x9EA7 0x9EA8 0x9EA9 0x9EAA 0x9EAB 0x9EAC 0x9EAD 0x9EAE 0x9EAF 0x9EB0 0x9EB1 0x9EB2 0x9EB3 0x9EB4 0x9EB5 +0x9EB6 0x9EB7 0x9EB8 0x9EB9 0x9EBA 0x9EBB 0x9EBC 0x9EBD 0x9EBE 0x9EBF 0x9EC0 0x9EC1 0x9EC2 0x9EC3 0x9EC4 0x9EC5 +0x9EC6 0x9EC7 0x9EC8 0x9EC9 0x9ECA 0x9ECB 0x9ECC 0x9ECD 0x9ECE 0x9ECF 0x9ED0 0x9ED1 0x9ED2 0x9ED3 0x9ED4 0x9ED5 +0x9ED6 0x9ED7 0x9ED8 0x9ED9 0x9EDA 0x9EDB 0x9EDC 0x9EDD 0x9EDE 0x9EDF 0x9EE0 0x9EE1 0x9EE2 0x9EE3 0x9EE4 0x9EE5 +0x9EE6 0x9EE7 0x9EE8 0x9EE9 0x9EEA 0x9EEB 0x9EEC 0x9EED 0x9EEE 0x9EEF 0x9EF0 0x9EF1 0x9EF2 0x9EF3 0x9EF4 0x9EF5 +0x9EF6 0x9EF7 0x9EF8 0x9EF9 0x9EFA 0x9EFB 0x9EFC 0x9EFD 0x9EFE 0x9EFF 0x9F00 0x9F01 0x9F02 0x9F03 0x9F04 0x9F05 +0x9F06 0x9F07 0x9F08 0x9F09 0x9F0A 0x9F0B 0x9F0C 0x9F0D 0x9F0E 0x9F0F 0x9F10 0x9F11 0x9F12 0x9F13 0x9F14 0x9F15 +0x9F16 0x9F17 0x9F18 0x9F19 0x9F1A 0x9F1B 0x9F1C 0x9F1D 0x9F1E 0x9F1F 0x9F20 0x9F21 0x9F22 0x9F23 0x9F24 0x9F25 +0x9F26 0x9F27 0x9F28 0x9F29 0x9F2A 0x9F2B 0x9F2C 0x9F2D 0x9F2E 0x9F2F 0x9F30 0x9F31 0x9F32 0x9F33 0x9F34 0x9F35 +0x9F36 0x9F37 0x9F38 0x9F39 0x9F3A 0x9F3B 0x9F3C 0x9F3D 0x9F3E 0x9F3F 0x9F40 0x9F41 0x9F42 0x9F43 0x9F44 0x9F45 +0x9F46 0x9F47 0x9F48 0x9F49 0x9F4A 0x9F4B 0x9F4C 0x9F4D 0x9F4E 0x9F4F 0x9F50 0x9F51 0x9F52 0x9F53 0x9F54 0x9F55 +0x9F56 0x9F57 0x9F58 0x9F59 0x9F5A 0x9F5B 0x9F5C 0x9F5D 0x9F5E 0x9F5F 0x9F60 0x9F61 0x9F62 0x9F63 0x9F64 0x9F65 +0x9F66 0x9F67 0x9F68 0x9F69 0x9F6A 0x9F6B 0x9F6C 0x9F6D 0x9F6E 0x9F6F 0x9F70 0x9F71 0x9F72 0x9F73 0x9F74 0x9F75 +0x9F76 0x9F77 0x9F78 0x9F79 0x9F7A 0x9F7B 0x9F7C 0x9F7D 0x9F7E 0x9F7F 0x9F80 0x9F81 0x9F82 0x9F83 0x9F84 0x9F85 +0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A 0x9F8B 0x9F8C 0x9F8D 0x9F8E 0x9F8F 0x9F90 0x9F91 0x9F92 0x9F93 0x9F94 0x9F95 +0x9F96 0x9F97 0x9F98 0x9F99 0x9F9A 0x9F9B 0x9F9C 0x9F9D 0x9F9E 0x9F9F 0x9FA0 0x9FA1 0x9FA2 0x9FA3 0x9FA4 0x9FA5 +0x9FB0 0x9FB1 0x9FBF 0x9FCD 0x9FCE 0x9FCF 0x9FD4 0x9FEB 0x9FEC 0x9FED 0x9FFD 0xAC00 0xAC01 0xAC02 0xAC03 0xAC04 +0xAC05 0xAC06 0xAC07 0xAC08 0xAC09 0xAC0A 0xAC0B 0xAC0C 0xAC0D 0xAC0E 0xAC0F 0xAC10 0xAC11 0xAC12 0xAC13 0xAC14 +0xAC15 0xAC16 0xAC17 0xAC18 0xAC19 0xAC1A 0xAC1B 0xAC1C 0xAC1D 0xAC1E 0xAC1F 0xAC20 0xAC21 0xAC22 0xAC23 0xAC24 +0xAC25 0xAC26 0xAC27 0xAC28 0xAC29 0xAC2A 0xAC2B 0xAC2C 0xAC2D 0xAC2E 0xAC2F 0xAC30 0xAC31 0xAC32 0xAC33 0xAC34 +0xAC35 0xAC36 0xAC37 0xAC38 0xAC39 0xAC3A 0xAC3B 0xAC3C 0xAC3D 0xAC3E 0xAC3F 0xAC40 0xAC41 0xAC42 0xAC43 0xAC44 +0xAC45 0xAC46 0xAC47 0xAC48 0xAC49 0xAC4A 0xAC4B 0xAC4C 0xAC4D 0xAC4E 0xAC4F 0xAC50 0xAC51 0xAC52 0xAC53 0xAC54 +0xAC55 0xAC56 0xAC57 0xAC58 0xAC59 0xAC5A 0xAC5B 0xAC5C 0xAC5D 0xAC5E 0xAC5F 0xAC60 0xAC61 0xAC62 0xAC63 0xAC64 +0xAC65 0xAC66 0xAC67 0xAC68 0xAC69 0xAC6A 0xAC6B 0xAC6C 0xAC6D 0xAC6E 0xAC6F 0xAC70 0xAC71 0xAC72 0xAC73 0xAC74 +0xAC75 0xAC76 0xAC77 0xAC78 0xAC79 0xAC7A 0xAC7B 0xAC7C 0xAC7D 0xAC7E 0xAC7F 0xAC80 0xAC81 0xAC82 0xAC83 0xAC84 +0xAC85 0xAC86 0xAC87 0xAC88 0xAC89 0xAC8A 0xAC8B 0xAC8C 0xAC8D 0xAC8E 0xAC8F 0xAC90 0xAC91 0xAC92 0xAC93 0xAC94 +0xAC95 0xAC96 0xAC97 0xAC98 0xAC99 0xAC9A 0xAC9B 0xAC9C 0xAC9D 0xAC9E 0xAC9F 0xACA0 0xACA1 0xACA2 0xACA3 0xACA4 +0xACA5 0xACA6 0xACA7 0xACA8 0xACA9 0xACAA 0xACAB 0xACAC 0xACAD 0xACAE 0xACAF 0xACB0 0xACB1 0xACB2 0xACB3 0xACB4 +0xACB5 0xACB6 0xACB7 0xACB8 0xACB9 0xACBA 0xACBB 0xACBC 0xACBD 0xACBE 0xACBF 0xACC0 0xACC1 0xACC2 0xACC3 0xACC4 +0xACC5 0xACC6 0xACC7 0xACC8 0xACC9 0xACCA 0xACCB 0xACCC 0xACCD 0xACCE 0xACCF 0xACD0 0xACD1 0xACD2 0xACD3 0xACD4 +0xACD5 0xACD6 0xACD7 0xACD8 0xACD9 0xACDA 0xACDB 0xACDC 0xACDD 0xACDE 0xACDF 0xACE0 0xACE1 0xACE2 0xACE3 0xACE4 +0xACE7 0xACE8 0xACE9 0xACEA 0xACEB 0xACEC 0xACEE 0xACEF 0xACF0 0xACF1 0xACF2 0xACF3 0xACF4 0xACF5 0xACF6 0xACF7 +0xACF9 0xACFA 0xACFB 0xACFC 0xACFD 0xAD00 0xAD03 0xAD04 0xAD06 0xAD0C 0xAD0D 0xAD0E 0xAD0F 0xAD10 0xAD11 0xAD12 +0xAD18 0xAD19 0xAD1C 0xAD1F 0xAD20 0xAD22 0xAD28 0xAD29 0xAD2A 0xAD2B 0xAD2C 0xAD2D 0xAD34 0xAD35 0xAD38 0xAD3B +0xAD3C 0xAD3E 0xAD44 0xAD45 0xAD46 0xAD47 0xAD48 0xAD49 0xAD50 0xAD51 0xAD54 0xAD57 0xAD58 0xAD60 0xAD61 0xAD62 +0xAD63 0xAD64 0xAD65 0xAD6C 0xAD6D 0xAD70 0xAD73 0xAD74 0xAD75 0xAD76 0xAD78 0xAD7B 0xAD7C 0xAD7D 0xAD7E 0xAD7F +0xAD80 0xAD81 0xAD82 0xAD83 0xAD86 0xAD88 0xAD89 0xAD8C 0xAD8F 0xAD90 0xAD98 0xAD99 0xAD9A 0xAD9B 0xAD9C 0xAD9D +0xADA4 0xADA5 0xADA8 0xADAB 0xADAC 0xADB4 0xADB5 0xADB6 0xADB7 0xADB8 0xADB9 0xADC0 0xADC1 0xADC4 0xADC7 0xADC8 +0xADCA 0xADD0 0xADD1 0xADD2 0xADD3 0xADD4 0xADD5 0xADDC 0xADDD 0xADE0 0xADE4 0xADE8 0xADEC 0xADED 0xADEE 0xADEF +0xADF0 0xADF1 0xADF8 0xADF9 0xADFA 0xADFB 0xADFC 0xADFD 0xADFE 0xADFF 0xAE00 0xAE01 0xAE02 0xAE03 0xAE04 0xAE05 +0xAE06 0xAE07 0xAE08 0xAE09 0xAE0A 0xAE0B 0xAE0C 0xAE0D 0xAE0E 0xAE0F 0xAE11 0xAE12 0xAE13 0xAE14 0xAE15 0xAE18 +0xAE1C 0xAE20 0xAE24 0xAE25 0xAE26 0xAE27 0xAE28 0xAE29 0xAE30 0xAE31 0xAE32 0xAE33 0xAE34 0xAE35 0xAE36 0xAE37 +0xAE38 0xAE39 0xAE3A 0xAE3B 0xAE3C 0xAE3D 0xAE3E 0xAE3F 0xAE40 0xAE41 0xAE42 0xAE43 0xAE44 0xAE45 0xAE46 0xAE47 +0xAE48 0xAE49 0xAE4A 0xAE4B 0xAE4C 0xAE4D 0xAE4E 0xAE50 0xAE53 0xAE54 0xAE56 0xAE5C 0xAE5D 0xAE5E 0xAE5F 0xAE60 +0xAE61 0xAE62 0xAE63 0xAE65 0xAE68 0xAE69 0xAE6A 0xAE6C 0xAE6F 0xAE70 0xAE73 0xAE76 0xAE78 0xAE79 0xAE7A 0xAE7B +0xAE7C 0xAE7D 0xAE81 0xAE84 0xAE85 0xAE86 0xAE88 0xAE8B 0xAE8C 0xAE8D 0xAE94 0xAE95 0xAE96 0xAE97 0xAE98 0xAE99 +0xAEA0 0xAEA1 0xAEA4 0xAEB0 0xAEB1 0xAEB2 0xAEB3 0xAEB4 0xAEB5 0xAEBC 0xAEBD 0xAEBE 0xAEC0 0xAEC2 0xAEC3 0xAEC4 +0xAECC 0xAECD 0xAECE 0xAECF 0xAED0 0xAED1 0xAED2 0xAED3 0xAED5 0xAED8 0xAED9 0xAEDA 0xAEDC 0xAEDF 0xAEE0 0xAEE8 +0xAEE9 0xAEEA 0xAEEB 0xAEEC 0xAEED 0xAEF1 0xAEF4 0xAEF5 0xAEF8 0xAEFB 0xAEFC 0xAF04 0xAF05 0xAF06 0xAF07 0xAF08 +0xAF09 0xAF0D 0xAF10 0xAF11 0xAF17 0xAF20 0xAF21 0xAF22 0xAF23 0xAF24 0xAF25 0xAF2C 0xAF2D 0xAF30 0xAF31 0xAF32 +0xAF33 0xAF34 0xAF36 0xAF38 0xAF3B 0xAF3C 0xAF3D 0xAF3E 0xAF3F 0xAF40 0xAF41 0xAF42 0xAF43 0xAF45 0xAF47 0xAF48 +0xAF49 0xAF4C 0xAF4F 0xAF50 0xAF58 0xAF59 0xAF5A 0xAF5B 0xAF5C 0xAF5D 0xAF64 0xAF65 0xAF68 0xAF6B 0xAF6C 0xAF74 +0xAF75 0xAF76 0xAF77 0xAF78 0xAF79 0xAF80 0xAF81 0xAF84 0xAF87 0xAF88 0xAF90 0xAF91 0xAF92 0xAF93 0xAF94 0xAF95 +0xAF9C 0xAF9D 0xAFA0 0xAFA3 0xAFA4 0xAFAC 0xAFAD 0xAFAE 0xAFAF 0xAFB0 0xAFB1 0xAFB2 0xAFB8 0xAFB9 0xAFBC 0xAFBF +0xAFC0 0xAFC1 0xAFC7 0xAFC8 0xAFC9 0xAFCA 0xAFCB 0xAFCC 0xAFCD 0xAFCE 0xAFCF 0xAFD4 0xAFD5 0xAFD8 0xAFDB 0xAFDC +0xAFE4 0xAFE5 0xAFE6 0xAFE7 0xAFE8 0xAFE9 0xAFF0 0xAFF1 0xAFF4 0xAFF7 0xAFF8 0xB000 0xB001 0xB002 0xB003 0xB004 +0xB005 0xB00C 0xB00D 0xB010 0xB013 0xB014 0xB01C 0xB01D 0xB01E 0xB01F 0xB020 0xB021 0xB028 0xB029 0xB02C 0xB030 +0xB038 0xB039 0xB03A 0xB03B 0xB03C 0xB03D 0xB044 0xB045 0xB048 0xB04A 0xB04B 0xB04C 0xB04D 0xB04E 0xB053 0xB054 +0xB055 0xB056 0xB057 0xB058 0xB059 0xB05A 0xB05B 0xB05D 0xB05F 0xB060 0xB061 0xB064 0xB067 0xB068 0xB06B 0xB070 +0xB071 0xB072 0xB073 0xB074 0xB075 0xB07C 0xB07D 0xB080 0xB083 0xB084 0xB08B 0xB08C 0xB08D 0xB08E 0xB08F 0xB090 +0xB091 0xB095 0xB098 0xB099 0xB09A 0xB09B 0xB09C 0xB09F 0xB0A0 0xB0A1 0xB0A2 0xB0A4 0xB0A8 0xB0A9 0xB0AA 0xB0AB +0xB0AC 0xB0AD 0xB0AE 0xB0AF 0xB0B0 0xB0B1 0xB0B2 0xB0B3 0xB0B4 0xB0B5 0xB0B8 0xB0BB 0xB0BC 0xB0C4 0xB0C5 0xB0C6 +0xB0C7 0xB0C8 0xB0C9 0xB0CE 0xB0D0 0xB0D1 0xB0D4 0xB0D7 0xB0D8 0xB0E0 0xB0E1 0xB0E2 0xB0E3 0xB0E4 0xB0E5 0xB0E6 +0xB0E7 0xB0E9 0xB0EC 0xB0ED 0xB0F0 0xB0FC 0xB0FD 0xB0FE 0xB0FF 0xB100 0xB101 0xB108 0xB109 0xB10A 0xB10B 0xB10C +0xB10F 0xB110 0xB111 0xB112 0xB113 0xB117 0xB118 0xB119 0xB11A 0xB11B 0xB11C 0xB11D 0xB11E 0xB11F 0xB120 0xB121 +0xB122 0xB123 0xB124 0xB125 0xB128 0xB12B 0xB12C 0xB134 0xB135 0xB136 0xB137 0xB138 0xB139 0xB13C 0xB13D 0xB13E +0xB13F 0xB140 0xB141 0xB143 0xB144 0xB147 0xB148 0xB14B 0xB150 0xB151 0xB152 0xB153 0xB154 0xB155 0xB156 0xB157 +0xB158 0xB159 0xB15A 0xB15B 0xB15C 0xB15D 0xB160 0xB163 0xB164 0xB16C 0xB16D 0xB16E 0xB16F 0xB170 0xB171 0xB178 +0xB179 0xB17A 0xB17B 0xB17C 0xB17E 0xB17F 0xB180 0xB181 0xB182 0xB188 0xB189 0xB18A 0xB18B 0xB18C 0xB18D 0xB18E +0xB18F 0xB190 0xB191 0xB192 0xB193 0xB194 0xB195 0xB198 0xB19B 0xB19C 0xB1A4 0xB1A5 0xB1A6 0xB1A7 0xB1A8 0xB1A9 +0xB1B0 0xB1B4 0xB1B8 0xB1C0 0xB1C1 0xB1C2 0xB1C3 0xB1C4 0xB1C5 0xB1CC 0xB1CD 0xB1D0 0xB1D3 0xB1D4 0xB1DC 0xB1DD +0xB1DE 0xB1DF 0xB1E0 0xB1E1 0xB1E6 0xB1E8 0xB1E9 0xB1EC 0xB1EF 0xB1F0 0xB1F8 0xB1F9 0xB1FA 0xB1FB 0xB1FC 0xB1FD +0xB204 0xB205 0xB208 0xB20B 0xB20C 0xB20D 0xB210 0xB213 0xB214 0xB215 0xB216 0xB217 0xB218 0xB219 0xB21B 0xB21D +0xB21E 0xB220 0xB221 0xB224 0xB227 0xB228 0xB230 0xB231 0xB232 0xB233 0xB234 0xB235 0xB23C 0xB23D 0xB240 0xB243 +0xB244 0xB24C 0xB24D 0xB24E 0xB24F 0xB250 0xB251 0xB258 0xB259 0xB25C 0xB25F 0xB260 0xB268 0xB269 0xB26A 0xB26B +0xB26C 0xB26D 0xB26F 0xB274 0xB275 0xB278 0xB27B 0xB27C 0xB284 0xB285 0xB286 0xB287 0xB288 0xB289 0xB28A 0xB28B +0xB290 0xB291 0xB294 0xB297 0xB298 0xB299 0xB29A 0xB29C 0xB2A0 0xB2A1 0xB2A2 0xB2A3 0xB2A4 0xB2A5 0xB2A6 0xB2A7 +0xB2AA 0xB2AB 0xB2AC 0xB2AD 0xB2B0 0xB2B3 0xB2B4 0xB2BC 0xB2BD 0xB2BE 0xB2BF 0xB2C0 0xB2C1 0xB2C8 0xB2C9 0xB2CC +0xB2CF 0xB2D0 0xB2D1 0xB2D2 0xB2D3 0xB2D4 0xB2D8 0xB2D9 0xB2DA 0xB2DB 0xB2DC 0xB2DD 0xB2DE 0xB2E0 0xB2E2 0xB2E3 +0xB2E4 0xB2E5 0xB2E6 0xB2E8 0xB2EB 0xB2EC 0xB2ED 0xB2EE 0xB2EF 0xB2F0 0xB2F2 0xB2F3 0xB2F4 0xB2F5 0xB2F6 0xB2F7 +0xB2F8 0xB2F9 0xB2FA 0xB2FB 0xB2FC 0xB2FD 0xB2FE 0xB2FF 0xB300 0xB301 0xB304 0xB307 0xB308 0xB310 0xB311 0xB312 +0xB313 0xB314 0xB315 0xB316 0xB319 0xB31C 0xB31D 0xB320 0xB324 0xB327 0xB32C 0xB32D 0xB32E 0xB32F 0xB330 0xB331 +0xB338 0xB33C 0xB348 0xB349 0xB34A 0xB34B 0xB34C 0xB34D 0xB34E 0xB354 0xB355 0xB356 0xB358 0xB359 0xB35B 0xB35C +0xB35E 0xB35F 0xB364 0xB365 0xB366 0xB367 0xB368 0xB369 0xB36A 0xB36B 0xB36D 0xB36E 0xB36F 0xB370 0xB371 0xB374 +0xB377 0xB378 0xB380 0xB381 0xB382 0xB383 0xB384 0xB385 0xB386 0xB38A 0xB38C 0xB38D 0xB38F 0xB390 0xB393 0xB394 +0xB398 0xB39C 0xB39D 0xB39E 0xB39F 0xB3A0 0xB3A1 0xB3A8 0xB3A9 0xB3AC 0xB3B0 0xB3B8 0xB3B9 0xB3BA 0xB3BB 0xB3BC +0xB3BD 0xB3C4 0xB3C5 0xB3C6 0xB3C7 0xB3C8 0xB3CB 0xB3CC 0xB3CE 0xB3CF 0xB3D0 0xB3D3 0xB3D4 0xB3D5 0xB3D6 0xB3D7 +0xB3D8 0xB3D9 0xB3DA 0xB3DB 0xB3DC 0xB3DD 0xB3DE 0xB3DF 0xB3E0 0xB3E1 0xB3E4 0xB3E8 0xB3F0 0xB3F1 0xB3F2 0xB3F3 +0xB3F4 0xB3F5 0xB3FC 0xB400 0xB403 0xB404 0xB40C 0xB40D 0xB40E 0xB40F 0xB410 0xB411 0xB418 0xB419 0xB41C 0xB41F +0xB420 0xB424 0xB428 0xB429 0xB42A 0xB42B 0xB42C 0xB42D 0xB434 0xB435 0xB438 0xB43B 0xB43C 0xB444 0xB445 0xB446 +0xB447 0xB448 0xB449 0xB44F 0xB450 0xB451 0xB452 0xB454 0xB457 0xB458 0xB459 0xB45A 0xB45B 0xB460 0xB461 0xB462 +0xB463 0xB464 0xB465 0xB46A 0xB46C 0xB46D 0xB470 0xB473 0xB474 0xB47C 0xB47D 0xB47E 0xB47F 0xB480 0xB481 0xB488 +0xB489 0xB48C 0xB48F 0xB490 0xB498 0xB499 0xB49A 0xB49B 0xB49C 0xB49D 0xB4A4 0xB4A5 0xB4A8 0xB4AB 0xB4AC 0xB4B4 +0xB4B5 0xB4B6 0xB4B7 0xB4B8 0xB4B9 0xB4C0 0xB4C1 0xB4C4 0xB4C8 0xB4D0 0xB4D1 0xB4D2 0xB4D3 0xB4D4 0xB4D5 0xB4DC +0xB4DD 0xB4DE 0xB4DF 0xB4E0 0xB4E3 0xB4E4 0xB4E5 0xB4E6 0xB4E7 0xB4E8 0xB4EC 0xB4ED 0xB4EE 0xB4EF 0xB4F0 0xB4F1 +0xB4F8 0xB4F9 0xB4FA 0xB4FC 0xB4FF 0xB500 0xB508 0xB509 0xB50A 0xB50B 0xB50C 0xB50D 0xB511 0xB514 0xB515 0xB516 +0xB518 0xB51B 0xB51C 0xB524 0xB525 0xB526 0xB527 0xB528 0xB529 0xB52A 0xB52B 0xB52D 0xB52E 0xB52F 0xB530 0xB531 +0xB532 0xB534 0xB537 0xB538 0xB539 0xB53A 0xB53B 0xB53F 0xB540 0xB541 0xB542 0xB543 0xB544 0xB545 0xB54B 0xB54C +0xB54D 0xB54E 0xB550 0xB553 0xB554 0xB55C 0xB55D 0xB55E 0xB55F 0xB560 0xB561 0xB567 0xB568 0xB569 0xB56C 0xB570 +0xB578 0xB579 0xB57A 0xB57B 0xB57C 0xB57D 0xB584 0xB585 0xB588 0xB594 0xB595 0xB596 0xB597 0xB598 0xB599 0xB5A0 +0xB5A1 0xB5A4 0xB5A7 0xB5A8 0xB5AA 0xB5AB 0xB5AF 0xB5B0 0xB5B1 0xB5B2 0xB5B3 0xB5B4 0xB5B5 0xB5BB 0xB5BC 0xB5BD +0xB5BE 0xB5C0 0xB5C3 0xB5C4 0xB5CC 0xB5CD 0xB5CE 0xB5CF 0xB5D0 0xB5D1 0xB5D8 0xB5D9 0xB5DC 0xB5DF 0xB5E8 0xB5E9 +0xB5EA 0xB5EB 0xB5EC 0xB5ED 0xB5F4 0xB5F5 0xB5F8 0xB604 0xB605 0xB606 0xB607 0xB608 0xB609 0xB610 0xB611 0xB612 +0xB614 0xB617 0xB618 0xB619 0xB61A 0xB61F 0xB620 0xB621 0xB622 0xB623 0xB624 0xB625 0xB62C 0xB62D 0xB630 0xB634 +0xB63C 0xB63D 0xB63E 0xB63F 0xB640 0xB641 0xB647 0xB648 0xB649 0xB64C 0xB64F 0xB650 0xB658 0xB659 0xB65A 0xB65B +0xB65C 0xB65D 0xB664 0xB665 0xB668 0xB66B 0xB66C 0xB674 0xB675 0xB676 0xB677 0xB678 0xB679 0xB680 0xB681 0xB690 +0xB691 0xB692 0xB693 0xB694 0xB695 0xB69C 0xB69D 0xB6A0 0xB6A3 0xB6A4 0xB6A6 0xB6A7 0xB6AB 0xB6AC 0xB6AD 0xB6AE +0xB6AF 0xB6B0 0xB6B1 0xB6B5 0xB6B8 0xB6BC 0xB6BF 0xB6C8 0xB6C9 0xB6CA 0xB6CB 0xB6CC 0xB6CD 0xB6D4 0xB6D8 0xB6DB +0xB6DC 0xB6E4 0xB6E5 0xB6E6 0xB6E7 0xB6E8 0xB6E9 0xB6F0 0xB6F4 0xB6F7 0xB6F8 0xB700 0xB701 0xB702 0xB703 0xB704 +0xB705 0xB70C 0xB70D 0xB710 0xB714 0xB71C 0xB71D 0xB71E 0xB71F 0xB720 0xB721 0xB728 0xB729 0xB72A 0xB72B 0xB72C +0xB72F 0xB730 0xB732 0xB733 0xB737 0xB738 0xB739 0xB73A 0xB73B 0xB73C 0xB73D 0xB73E 0xB743 0xB744 0xB745 0xB748 +0xB74C 0xB754 0xB755 0xB756 0xB757 0xB758 0xB759 0xB760 0xB761 0xB764 0xB767 0xB768 0xB770 0xB771 0xB772 0xB773 +0xB774 0xB775 0xB77B 0xB77C 0xB77D 0xB780 0xB783 0xB784 0xB788 0xB78C 0xB78D 0xB78E 0xB78F 0xB790 0xB791 0xB792 +0xB793 0xB794 0xB795 0xB796 0xB797 0xB798 0xB799 0xB79C 0xB79F 0xB7A0 0xB7A8 0xB7A9 0xB7AA 0xB7AB 0xB7AC 0xB7AD +0xB7B0 0xB7B1 0xB7B2 0xB7B4 0xB7B5 0xB7B8 0xB7BB 0xB7BC 0xB7C4 0xB7C5 0xB7C6 0xB7C7 0xB7C8 0xB7C9 0xB7D0 0xB7D4 +0xB7E0 0xB7E1 0xB7E2 0xB7E3 0xB7E4 0xB7E5 0xB7EC 0xB7ED 0xB7F0 0xB7F2 0xB7F3 0xB7F4 0xB7FC 0xB7FD 0xB7FE 0xB7FF +0xB800 0xB801 0xB802 0xB804 0xB806 0xB807 0xB808 0xB809 0xB80C 0xB80F 0xB810 0xB818 0xB819 0xB81A 0xB81B 0xB81C +0xB81D 0xB821 0xB822 0xB823 0xB824 0xB825 0xB828 0xB82B 0xB82C 0xB830 0xB834 0xB835 0xB836 0xB837 0xB838 0xB839 +0xB83C 0xB83E 0xB840 0xB841 0xB844 0xB847 0xB848 0xB850 0xB851 0xB852 0xB853 0xB854 0xB855 0xB85C 0xB85D 0xB860 +0xB863 0xB864 0xB868 0xB86B 0xB86C 0xB86D 0xB86E 0xB86F 0xB870 0xB871 0xB874 0xB876 0xB877 0xB878 0xB879 0xB87C +0xB880 0xB888 0xB889 0xB88A 0xB88B 0xB88C 0xB88D 0xB894 0xB895 0xB896 0xB897 0xB898 0xB89B 0xB89C 0xB8A4 0xB8A5 +0xB8A6 0xB8A7 0xB8A8 0xB8A9 0xB8B0 0xB8B1 0xB8B4 0xB8B5 0xB8B7 0xB8B8 0xB8C0 0xB8C1 0xB8C2 0xB8C3 0xB8C4 0xB8C5 +0xB8CC 0xB8CD 0xB8CE 0xB8CF 0xB8D0 0xB8D3 0xB8D4 0xB8DC 0xB8DD 0xB8DE 0xB8DF 0xB8E0 0xB8E1 0xB8E8 0xB8E9 0xB8EC +0xB8EF 0xB8F0 0xB8F3 0xB8F8 0xB8F9 0xB8FA 0xB8FB 0xB8FC 0xB8FD 0xB900 0xB902 0xB904 0xB905 0xB908 0xB90B 0xB90C +0xB914 0xB915 0xB916 0xB917 0xB918 0xB919 0xB920 0xB921 0xB924 0xB928 0xB930 0xB931 0xB932 0xB933 0xB934 0xB935 +0xB93C 0xB93D 0xB940 0xB943 0xB944 0xB94C 0xB94D 0xB94E 0xB94F 0xB950 0xB951 0xB958 0xB959 0xB95C 0xB95F 0xB960 +0xB968 0xB969 0xB96A 0xB96B 0xB96C 0xB96D 0xB974 0xB975 0xB978 0xB97B 0xB97C 0xB97D 0xB980 0xB984 0xB985 0xB986 +0xB987 0xB988 0xB989 0xB98A 0xB98B 0xB98D 0xB98E 0xB98F 0xB990 0xB991 0xB994 0xB998 0xB99E 0xB9A0 0xB9A1 0xB9A2 +0xB9A3 0xB9A4 0xB9A5 0xB9AC 0xB9AD 0xB9AE 0xB9AF 0xB9B0 0xB9B3 0xB9B4 0xB9BC 0xB9BD 0xB9BE 0xB9BF 0xB9C0 0xB9C1 +0xB9C2 0xB9C4 0xB9C6 0xB9C8 0xB9C9 0xB9CA 0xB9CB 0xB9CC 0xB9CD 0xB9CE 0xB9CF 0xB9D0 0xB9D1 0xB9D2 0xB9D4 0xB9D8 +0xB9D9 0xB9DA 0xB9DB 0xB9DC 0xB9DD 0xB9DE 0xB9DF 0xB9E0 0xB9E1 0xB9E2 0xB9E3 0xB9E4 0xB9E5 0xB9E6 0xB9E7 0xB9E8 +0xB9EB 0xB9EC 0xB9ED 0xB9F4 0xB9F5 0xB9F6 0xB9F7 0xB9F8 0xB9F9 0xB9FA 0xB9FB 0xB9FC 0xB9FD 0xB9FE 0xB9FF 0xBA00 +0xBA01 0xBA02 0xBA03 0xBA04 0xBA05 0xBA06 0xBA07 0xBA08 0xBA10 0xBA11 0xBA12 0xBA13 0xBA14 0xBA15 0xBA18 0xBA1C +0xBA1D 0xBA1E 0xBA1F 0xBA20 0xBA2C 0xBA2D 0xBA2E 0xBA2F 0xBA30 0xBA31 0xBA32 0xBA33 0xBA34 0xBA35 0xBA36 0xBA37 +0xBA38 0xBA39 0xBA3A 0xBA3B 0xBA3C 0xBA3D 0xBA3E 0xBA3F 0xBA40 0xBA41 0xBA42 0xBA43 0xBA44 0xBA45 0xBA46 0xBA47 +0xBA48 0xBA49 0xBA4A 0xBA4B 0xBA4C 0xBA4D 0xBA4E 0xBA4F 0xBA50 0xBA51 0xBA52 0xBA53 0xBA54 0xBA55 0xBA56 0xBA57 +0xBA58 0xBA59 0xBA5A 0xBA5B 0xBA5C 0xBA60 0xBA64 0xBA65 0xBA66 0xBA67 0xBA68 0xBA69 0xBA6A 0xBA6B 0xBA6C 0xBA6D +0xBA6E 0xBA6F 0xBA70 0xBA71 0xBA72 0xBA73 0xBA74 0xBA75 0xBA76 0xBA77 0xBA78 0xBA79 0xBA7A 0xBA7B 0xBA7C 0xBA7D +0xBA7E 0xBA7F 0xBA80 0xBA81 0xBA82 0xBA83 0xBA84 0xBA85 0xBA86 0xBA87 0xBA89 0xBA8C 0xBA8D 0xBA8E 0xBA8F 0xBA90 +0xBA93 0xBA94 0xBA9C 0xBA9D 0xBA9E 0xBA9F 0xBAA0 0xBAA1 0xBAA2 0xBAA3 0xBAA4 0xBAA5 0xBAA6 0xBAA7 0xBAA8 0xBAA9 +0xBAAA 0xBAAB 0xBAAC 0xBAAD 0xBAAE 0xBAAF 0xBAB0 0xBAB1 0xBAB2 0xBAB3 0xBAB4 0xBAB5 0xBAB6 0xBAB7 0xBAB8 0xBAB9 +0xBABA 0xBABB 0xBABC 0xBABD 0xBABF 0xBAC3 0xBAC4 0xBAC5 0xBAC6 0xBAC8 0xBACB 0xBACC 0xBAD4 0xBAD5 0xBAD6 0xBAD7 +0xBAD8 0xBAD9 0xBAE0 0xBAE4 0xBAE8 0xBAF0 0xBAF1 0xBAF2 0xBAF3 0xBAF4 0xBAF5 0xBAFC 0xBAFD 0xBAFE 0xBB00 0xBB03 +0xBB04 0xBB0C 0xBB0D 0xBB0E 0xBB0F 0xBB10 0xBB11 0xBB18 0xBB19 0xBB1C 0xBB1F 0xBB20 0xBB28 0xBB29 0xBB2A 0xBB2B +0xBB2C 0xBB2D 0xBB34 0xBB35 0xBB36 0xBB38 0xBB3A 0xBB3B 0xBB3C 0xBB3D 0xBB3E 0xBB40 0xBB44 0xBB45 0xBB46 0xBB47 +0xBB48 0xBB49 0xBB4B 0xBB4D 0xBB4F 0xBB50 0xBB51 0xBB54 0xBB57 0xBB58 0xBB60 0xBB61 0xBB62 0xBB63 0xBB64 0xBB65 +0xBB6C 0xBB6D 0xBB6E 0xBB70 0xBB74 0xBB7C 0xBB7D 0xBB7E 0xBB7F 0xBB80 0xBB81 0xBB88 0xBB89 0xBB8A 0xBB8C 0xBB90 +0xBB98 0xBB99 0xBB9A 0xBB9B 0xBB9C 0xBB9D 0xBBA4 0xBBA5 0xBBA6 0xBBA8 0xBBAB 0xBBAC 0xBBB4 0xBBB5 0xBBB6 0xBBB7 +0xBBB8 0xBBB9 0xBBC0 0xBBC1 0xBBC3 0xBBC4 0xBBC7 0xBBC8 0xBBC9 0xBBCA 0xBBCB 0xBBCC 0xBBCD 0xBBCE 0xBBCF 0xBBD0 +0xBBD1 0xBBD2 0xBBD3 0xBBD4 0xBBD5 0xBBD9 0xBBDC 0xBBDD 0xBBDE 0xBBE0 0xBBE4 0xBBEC 0xBBED 0xBBEE 0xBBEF 0xBBF0 +0xBBF1 0xBBF2 0xBBF8 0xBBF9 0xBBFC 0xBBFF 0xBC00 0xBC01 0xBC02 0xBC03 0xBC04 0xBC05 0xBC06 0xBC07 0xBC08 0xBC09 +0xBC0A 0xBC0B 0xBC0C 0xBC0D 0xBC0E 0xBC0F 0xBC10 0xBC11 0xBC14 0xBC15 0xBC16 0xBC17 0xBC18 0xBC1B 0xBC1C 0xBC1D +0xBC1E 0xBC1F 0xBC20 0xBC23 0xBC24 0xBC25 0xBC26 0xBC27 0xBC28 0xBC29 0xBC2B 0xBC2C 0xBC2D 0xBC2F 0xBC30 0xBC31 +0xBC32 0xBC33 0xBC34 0xBC35 0xBC36 0xBC37 0xBC38 0xBC39 0xBC3A 0xBC3B 0xBC3C 0xBC3D 0xBC3E 0xBC3F 0xBC40 0xBC41 +0xBC42 0xBC43 0xBC44 0xBC45 0xBC46 0xBC49 0xBC4C 0xBC4D 0xBC4E 0xBC50 0xBC54 0xBC5C 0xBC5D 0xBC5E 0xBC5F 0xBC60 +0xBC61 0xBC67 0xBC68 0xBC69 0xBC6A 0xBC6B 0xBC6C 0xBC6F 0xBC70 0xBC77 0xBC78 0xBC79 0xBC7A 0xBC7B 0xBC7C 0xBC7D +0xBC84 0xBC85 0xBC86 0xBC88 0xBC8B 0xBC8C 0xBC8D 0xBC8E 0xBC90 0xBC94 0xBC95 0xBC96 0xBC97 0xBC98 0xBC99 0xBC9A +0xBC9C 0xBC9D 0xBC9F 0xBCA0 0xBCA1 0xBCA2 0xBCA3 0xBCA4 0xBCA7 0xBCA8 0xBCB0 0xBCB1 0xBCB2 0xBCB3 0xBCB4 0xBCB5 +0xBCB8 0xBCB9 0xBCBC 0xBCBD 0xBCC0 0xBCC3 0xBCC4 0xBCC8 0xBCCC 0xBCCD 0xBCCE 0xBCCF 0xBCD0 0xBCD1 0xBCD2 0xBCD3 +0xBCD4 0xBCD5 0xBCD8 0xBCD9 0xBCDC 0xBCE0 0xBCE8 0xBCE9 0xBCEA 0xBCEB 0xBCEC 0xBCED 0xBCF4 0xBCF5 0xBCF6 0xBCF7 +0xBCF8 0xBCFB 0xBCFC 0xBCFD 0xBCFE 0xBCFF 0xBD04 0xBD05 0xBD06 0xBD07 0xBD08 0xBD09 0xBD0A 0xBD0B 0xBD0D 0xBD0F +0xBD10 0xBD11 0xBD14 0xBD17 0xBD18 0xBD20 0xBD21 0xBD22 0xBD23 0xBD24 0xBD25 0xBD2C 0xBD30 0xBD33 0xBD34 0xBD3C +0xBD3D 0xBD3E 0xBD3F 0xBD40 0xBD41 0xBD48 0xBD49 0xBD4A 0xBD4C 0xBD4F 0xBD50 0xBD58 0xBD59 0xBD5A 0xBD5B 0xBD5C +0xBD5D 0xBD64 0xBD65 0xBD68 0xBD6C 0xBD74 0xBD75 0xBD76 0xBD77 0xBD78 0xBD79 0xBD80 0xBD81 0xBD82 0xBD84 0xBD87 +0xBD88 0xBD89 0xBD8A 0xBD8B 0xBD8E 0xBD90 0xBD91 0xBD92 0xBD93 0xBD94 0xBD95 0xBD96 0xBD97 0xBD98 0xBD99 0xBD9A +0xBD9B 0xBD9C 0xBD9D 0xBDA0 0xBDA3 0xBDA4 0xBDAC 0xBDAD 0xBDAE 0xBDAF 0xBDB0 0xBDB1 0xBDB4 0xBDB8 0xBDB9 0xBDBC +0xBDBF 0xBDC0 0xBDC1 0xBDC8 0xBDC9 0xBDCA 0xBDCB 0xBDCC 0xBDCD 0xBDD4 0xBDD5 0xBDD8 0xBDDB 0xBDDC 0xBDE4 0xBDE5 +0xBDE6 0xBDE7 0xBDE8 0xBDE9 0xBDF0 0xBDF1 0xBDF2 0xBDF4 0xBDF7 0xBDF8 0xBE00 0xBE01 0xBE02 0xBE03 0xBE04 0xBE05 +0xBE0C 0xBE0D 0xBE10 0xBE13 0xBE14 0xBE15 0xBE17 0xBE18 0xBE1B 0xBE1C 0xBE1D 0xBE1E 0xBE1F 0xBE20 0xBE21 0xBE22 +0xBE23 0xBE25 0xBE27 0xBE28 0xBE29 0xBE2C 0xBE30 0xBE38 0xBE39 0xBE3A 0xBE3B 0xBE3C 0xBE3D 0xBE44 0xBE45 0xBE46 +0xBE47 0xBE48 0xBE49 0xBE4A 0xBE4B 0xBE4C 0xBE4E 0xBE54 0xBE55 0xBE56 0xBE57 0xBE58 0xBE59 0xBE5A 0xBE5B 0xBE5C +0xBE5D 0xBE5F 0xBE60 0xBE61 0xBE62 0xBE63 0xBE64 0xBE65 0xBE66 0xBE67 0xBE68 0xBE69 0xBE6A 0xBE70 0xBE71 0xBE72 +0xBE73 0xBE74 0xBE75 0xBE76 0xBE79 0xBE7B 0xBE7C 0xBE7D 0xBE7E 0xBE7F 0xBE80 0xBE83 0xBE84 0xBE8C 0xBE8D 0xBE8E +0xBE8F 0xBE90 0xBE91 0xBE92 0xBE93 0xBE94 0xBE95 0xBE96 0xBE98 0xBE99 0xBE9C 0xBEA8 0xBEA9 0xBEAA 0xBEAB 0xBEAC +0xBEAD 0xBEAE 0xBEB4 0xBEB5 0xBEB6 0xBEB7 0xBEB8 0xBEBB 0xBEBC 0xBEC4 0xBEC5 0xBEC6 0xBEC7 0xBEC8 0xBEC9 0xBECA +0xBECB 0xBECC 0xBECD 0xBECE 0xBED0 0xBED1 0xBED4 0xBED7 0xBED8 0xBED9 0xBEE0 0xBEE1 0xBEE2 0xBEE3 0xBEE4 0xBEE5 +0xBEE6 0xBEEC 0xBEED 0xBEEE 0xBEEF 0xBEF0 0xBEF3 0xBEF4 0xBEFC 0xBEFD 0xBEFE 0xBEFF 0xBF00 0xBF01 0xBF02 0xBF03 +0xBF04 0xBF05 0xBF06 0xBF08 0xBF09 0xBF0C 0xBF0F 0xBF10 0xBF18 0xBF19 0xBF1A 0xBF1B 0xBF1C 0xBF1D 0xBF1F 0xBF21 +0xBF24 0xBF25 0xBF26 0xBF27 0xBF28 0xBF2B 0xBF2C 0xBF34 0xBF35 0xBF36 0xBF37 0xBF38 0xBF39 0xBF3A 0xBF3B 0xBF3C +0xBF3D 0xBF3E 0xBF40 0xBF41 0xBF44 0xBF47 0xBF48 0xBF50 0xBF51 0xBF52 0xBF53 0xBF54 0xBF55 0xBF59 0xBF5B 0xBF5C +0xBF60 0xBF63 0xBF78 0xBF7F 0xBF94 0xBF98 0xBF9B 0xBFA4 0xBFA5 0xBFAC 0xBFB0 0xBFB1 0xBFB4 0xBFC0 0xBFC1 0xBFC2 +0xBFC3 0xBFC4 0xBFC5 0xBFCC 0xBFCD 0xBFD0 0xBFD3 0xBFD4 0xBFD5 0xBFDC 0xBFDD 0xBFDF 0xBFE1 0xBFE5 0xBFE8 0xBFEF +0xC004 0xC020 0xC021 0xC03C 0xC03D 0xC040 0xC043 0xC044 0xC051 0xC058 0xC059 0xC05C 0xC05F 0xC060 0xC068 0xC069 +0xC06A 0xC06B 0xC06C 0xC06D 0xC074 0xC090 0xC091 0xC094 0xC097 0xC098 0xC0A0 0xC0A1 0xC0A2 0xC0A3 0xC0A4 0xC0A5 +0xC0A6 0xC0A7 0xC0AB 0xC0AC 0xC0AD 0xC0AE 0xC0AF 0xC0B0 0xC0B1 0xC0B2 0xC0B3 0xC0B4 0xC0B5 0xC0B6 0xC0B7 0xC0B8 +0xC0B9 0xC0BA 0xC0BB 0xC0BC 0xC0BD 0xC0BE 0xC0BF 0xC0C0 0xC0C1 0xC0C2 0xC0C3 0xC0C4 0xC0C5 0xC0C6 0xC0C7 0xC0C8 +0xC0C9 0xC0CA 0xC0CB 0xC0CC 0xC0CF 0xC0D0 0xC0D2 0xC0D8 0xC0D9 0xC0DA 0xC0DB 0xC0DC 0xC0DD 0xC0E3 0xC0E4 0xC0E5 +0xC0E8 0xC0EB 0xC0EC 0xC0F4 0xC0F5 0xC0F6 0xC0F7 0xC0F8 0xC0F9 0xC0FB 0xC0FE 0xC0FF 0xC100 0xC101 0xC104 0xC108 +0xC10A 0xC110 0xC111 0xC112 0xC113 0xC114 0xC115 0xC11C 0xC11D 0xC11E 0xC11F 0xC120 0xC123 0xC124 0xC125 0xC126 +0xC127 0xC128 0xC12A 0xC12C 0xC12D 0xC12E 0xC12F 0xC130 0xC131 0xC134 0xC136 0xC138 0xC139 0xC13C 0xC13F 0xC140 +0xC148 0xC149 0xC14A 0xC14B 0xC14C 0xC14D 0xC14E 0xC151 0xC152 0xC154 0xC155 0xC156 0xC157 0xC158 0xC15B 0xC15C +0xC15F 0xC160 0xC164 0xC165 0xC166 0xC167 0xC168 0xC169 0xC170 0xC171 0xC173 0xC174 0xC178 0xC180 0xC181 0xC182 +0xC183 0xC184 0xC185 0xC18A 0xC18C 0xC18D 0xC18E 0xC18F 0xC190 0xC193 0xC194 0xC195 0xC196 0xC197 0xC198 0xC19C +0xC19D 0xC19E 0xC19F 0xC1A0 0xC1A1 0xC1A3 0xC1A5 0xC1A6 0xC1A8 0xC1A9 0xC1AC 0xC1B0 0xC1B8 0xC1B9 0xC1BA 0xC1BB +0xC1BC 0xC1BD 0xC1C4 0xC1C5 0xC1C8 0xC1CB 0xC1CC 0xC1D4 0xC1D5 0xC1D6 0xC1D7 0xC1D8 0xC1D9 0xC1E0 0xC1E1 0xC1E4 +0xC1E7 0xC1E8 0xC1F0 0xC1F1 0xC1F2 0xC1F3 0xC1F4 0xC1F5 0xC1FC 0xC1FD 0xC200 0xC203 0xC204 0xC20C 0xC20D 0xC20E +0xC20F 0xC210 0xC211 0xC216 0xC218 0xC219 0xC21C 0xC21F 0xC220 0xC221 0xC224 0xC227 0xC228 0xC229 0xC22A 0xC22B +0xC22C 0xC22D 0xC22E 0xC22F 0xC231 0xC232 0xC233 0xC234 0xC235 0xC238 0xC23B 0xC23C 0xC244 0xC245 0xC246 0xC247 +0xC248 0xC249 0xC250 0xC251 0xC254 0xC257 0xC258 0xC260 0xC261 0xC262 0xC263 0xC264 0xC265 0xC26C 0xC26D 0xC270 +0xC273 0xC274 0xC27C 0xC27D 0xC27E 0xC27F 0xC280 0xC281 0xC286 0xC288 0xC289 0xC28C 0xC28F 0xC290 0xC298 0xC299 +0xC29A 0xC29B 0xC29C 0xC29D 0xC2A4 0xC2A5 0xC2A8 0xC2AB 0xC2AC 0xC2AD 0xC2AE 0xC2AF 0xC2B0 0xC2B2 0xC2B3 0xC2B4 +0xC2B5 0xC2B6 0xC2B7 0xC2B8 0xC2B9 0xC2BA 0xC2BB 0xC2BC 0xC2BD 0xC2BE 0xC2BF 0xC2C0 0xC2C1 0xC2C4 0xC2C8 0xC2D0 +0xC2D1 0xC2D2 0xC2D3 0xC2D4 0xC2D5 0xC2DC 0xC2DD 0xC2DE 0xC2E0 0xC2E2 0xC2E3 0xC2E4 0xC2E5 0xC2E6 0xC2E8 0xC2EB +0xC2EC 0xC2ED 0xC2EE 0xC2EF 0xC2F0 0xC2F1 0xC2F3 0xC2F4 0xC2F6 0xC2F8 0xC2F9 0xC2FB 0xC2FC 0xC2FF 0xC300 0xC301 +0xC302 0xC308 0xC309 0xC30A 0xC30B 0xC30C 0xC30D 0xC30E 0xC311 0xC313 0xC314 0xC315 0xC316 0xC317 0xC318 0xC31B +0xC31C 0xC324 0xC325 0xC326 0xC327 0xC328 0xC329 0xC32A 0xC32B 0xC32C 0xC32D 0xC32E 0xC32F 0xC330 0xC331 0xC334 +0xC337 0xC338 0xC340 0xC341 0xC342 0xC343 0xC344 0xC345 0xC34C 0xC34D 0xC34E 0xC34F 0xC350 0xC353 0xC354 0xC35C +0xC35D 0xC35E 0xC35F 0xC360 0xC361 0xC362 0xC363 0xC364 0xC365 0xC366 0xC367 0xC368 0xC369 0xC36A 0xC36C 0xC36F +0xC370 0xC372 0xC378 0xC379 0xC37A 0xC37B 0xC37C 0xC37D 0xC382 0xC384 0xC385 0xC386 0xC387 0xC388 0xC38B 0xC38C +0xC394 0xC395 0xC396 0xC397 0xC398 0xC399 0xC39A 0xC39B 0xC39C 0xC39D 0xC39E 0xC39F 0xC3A0 0xC3A1 0xC3A4 0xC3A7 +0xC3A8 0xC3B0 0xC3B1 0xC3B2 0xC3B3 0xC3B4 0xC3B5 0xC3BC 0xC3BD 0xC3BE 0xC3BF 0xC3C0 0xC3C3 0xC3C4 0xC3CC 0xC3CD +0xC3CE 0xC3CF 0xC3D0 0xC3D1 0xC3D2 0xC3D3 0xC3D4 0xC3D5 0xC3D6 0xC3D7 0xC3D8 0xC3D9 0xC3DA 0xC3DC 0xC3DF 0xC3E0 +0xC3E2 0xC3E8 0xC3E9 0xC3EA 0xC3EB 0xC3EC 0xC3ED 0xC3F1 0xC3F4 0xC3F5 0xC3F8 0xC3FB 0xC3FC 0xC404 0xC405 0xC406 +0xC407 0xC408 0xC409 0xC40B 0xC410 0xC411 0xC414 0xC417 0xC418 0xC420 0xC421 0xC422 0xC423 0xC424 0xC425 0xC42C +0xC42D 0xC430 0xC433 0xC434 0xC43C 0xC43D 0xC43E 0xC43F 0xC440 0xC441 0xC448 0xC449 0xC44C 0xC44F 0xC450 0xC458 +0xC459 0xC45A 0xC45B 0xC45C 0xC45D 0xC464 0xC465 0xC468 0xC46B 0xC46C 0xC474 0xC475 0xC476 0xC477 0xC478 0xC479 +0xC47A 0xC47B 0xC47C 0xC47D 0xC47E 0xC47F 0xC480 0xC481 0xC484 0xC487 0xC488 0xC490 0xC491 0xC492 0xC493 0xC494 +0xC495 0xC49C 0xC49D 0xC4A0 0xC4A3 0xC4A4 0xC4AC 0xC4AD 0xC4AE 0xC4AF 0xC4B0 0xC4B1 0xC4B8 0xC4B9 0xC4BC 0xC4BF +0xC4C0 0xC4C8 0xC4C9 0xC4CA 0xC4CB 0xC4CC 0xC4CD 0xC4D3 0xC4D4 0xC4D5 0xC4D8 0xC4DB 0xC4DC 0xC4E4 0xC4E5 0xC4E6 +0xC4E7 0xC4E8 0xC4E9 0xC4F0 0xC4F1 0xC4F4 0xC4F7 0xC4F8 0xC4FA 0xC4FF 0xC500 0xC501 0xC502 0xC503 0xC504 0xC505 +0xC50C 0xC50D 0xC510 0xC514 0xC51C 0xC51D 0xC51E 0xC51F 0xC520 0xC521 0xC528 0xC529 0xC52B 0xC52C 0xC52F 0xC530 +0xC531 0xC538 0xC539 0xC53A 0xC53B 0xC53C 0xC53D 0xC53F 0xC540 0xC543 0xC544 0xC545 0xC546 0xC547 0xC548 0xC549 +0xC54A 0xC54B 0xC54C 0xC54D 0xC54E 0xC54F 0xC550 0xC551 0xC552 0xC553 0xC554 0xC555 0xC556 0xC557 0xC558 0xC559 +0xC55A 0xC55B 0xC55C 0xC55D 0xC55E 0xC55F 0xC560 0xC561 0xC562 0xC563 0xC564 0xC565 0xC566 0xC567 0xC568 0xC569 +0xC56A 0xC56B 0xC56C 0xC56D 0xC56E 0xC56F 0xC570 0xC571 0xC572 0xC573 0xC574 0xC575 0xC576 0xC577 0xC578 0xC579 +0xC57A 0xC57B 0xC57C 0xC57D 0xC57E 0xC57F 0xC580 0xC581 0xC582 0xC583 0xC584 0xC585 0xC586 0xC587 0xC588 0xC589 +0xC58A 0xC58B 0xC58C 0xC58D 0xC58E 0xC58F 0xC590 0xC591 0xC592 0xC593 0xC594 0xC595 0xC596 0xC597 0xC598 0xC599 +0xC59A 0xC59B 0xC59C 0xC59D 0xC59E 0xC59F 0xC5A0 0xC5A1 0xC5A2 0xC5A3 0xC5A4 0xC5A5 0xC5A6 0xC5A7 0xC5A8 0xC5A9 +0xC5AA 0xC5AB 0xC5AC 0xC5AD 0xC5AE 0xC5AF 0xC5B0 0xC5B1 0xC5B2 0xC5B3 0xC5B4 0xC5B5 0xC5B6 0xC5B7 0xC5B8 0xC5B9 +0xC5BA 0xC5BB 0xC5BC 0xC5BD 0xC5BE 0xC5BF 0xC5C0 0xC5C1 0xC5C2 0xC5C3 0xC5C4 0xC5C5 0xC5C6 0xC5C7 0xC5C8 0xC5C9 +0xC5CA 0xC5CB 0xC5CC 0xC5CD 0xC5CE 0xC5CF 0xC5D0 0xC5D1 0xC5D4 0xC5D7 0xC5D8 0xC5E0 0xC5E1 0xC5E2 0xC5E3 0xC5E4 +0xC5E5 0xC5E6 0xC5E7 0xC5E8 0xC5E9 0xC5EA 0xC5EB 0xC5EC 0xC5ED 0xC5EE 0xC5EF 0xC5F0 0xC5F1 0xC5F2 0xC5F3 0xC5F4 +0xC5F5 0xC5F6 0xC5F7 0xC5F8 0xC5F9 0xC5FA 0xC5FB 0xC5FC 0xC5FD 0xC5FE 0xC5FF 0xC600 0xC601 0xC602 0xC603 0xC604 +0xC605 0xC606 0xC607 0xC608 0xC609 0xC60C 0xC60F 0xC610 0xC618 0xC619 0xC61A 0xC61B 0xC61C 0xC61D 0xC620 0xC624 +0xC625 0xC626 0xC628 0xC629 0xC62A 0xC62B 0xC62C 0xC62D 0xC62E 0xC62F 0xC630 0xC631 0xC632 0xC633 0xC634 0xC635 +0xC636 0xC637 0xC638 0xC639 0xC63A 0xC63B 0xC63C 0xC63D 0xC63E 0xC63F 0xC640 0xC641 0xC644 0xC647 0xC648 0xC64E +0xC650 0xC651 0xC652 0xC653 0xC654 0xC655 0xC658 0xC659 0xC65C 0xC65D 0xC660 0xC661 0xC662 0xC663 0xC664 0xC66C +0xC66D 0xC66E 0xC66F 0xC670 0xC671 0xC678 0xC679 0xC67C 0xC67F 0xC680 0xC682 0xC688 0xC689 0xC68A 0xC68B 0xC68C +0xC68D 0xC692 0xC694 0xC695 0xC698 0xC699 0xC69A 0xC69B 0xC69C 0xC69D 0xC6A4 0xC6A5 0xC6A6 0xC6A7 0xC6A8 0xC6A9 +0xC6AC 0xC6B0 0xC6B1 0xC6B2 0xC6B3 0xC6B4 0xC6B5 0xC6B6 0xC6B7 0xC6B8 0xC6B9 0xC6BA 0xC6BB 0xC6BC 0xC6BE 0xC6BF +0xC6C0 0xC6C1 0xC6C2 0xC6C3 0xC6C4 0xC6C5 0xC6C6 0xC6C7 0xC6C8 0xC6C9 0xC6CA 0xC6CB 0xC6CC 0xC6CD 0xC6D0 0xC6D1 +0xC6D2 0xC6D3 0xC6D4 0xC6D8 0xC6DC 0xC6DD 0xC6DE 0xC6DF 0xC6E0 0xC6E1 0xC6E4 0xC6E5 0xC6E8 0xC6E9 0xC6EC 0xC6EF +0xC6F0 0xC6F8 0xC6F9 0xC6FA 0xC6FB 0xC6FC 0xC6FD 0xC701 0xC704 0xC705 0xC708 0xC70B 0xC70C 0xC70E 0xC713 0xC714 +0xC715 0xC716 0xC717 0xC718 0xC719 0xC71C 0xC71D 0xC720 0xC721 0xC724 0xC727 0xC728 0xC730 0xC731 0xC732 0xC733 +0xC734 0xC735 0xC736 0xC737 0xC738 0xC739 0xC73C 0xC73D 0xC73E 0xC73F 0xC740 0xC741 0xC742 0xC743 0xC744 0xC745 +0xC746 0xC747 0xC748 0xC749 0xC74A 0xC74B 0xC74C 0xC74D 0xC74E 0xC74F 0xC750 0xC751 0xC752 0xC753 0xC754 0xC755 +0xC756 0xC757 0xC758 0xC759 0xC75C 0xC75F 0xC760 0xC766 0xC768 0xC769 0xC76A 0xC76B 0xC76C 0xC76D 0xC774 0xC775 +0xC776 0xC777 0xC778 0xC779 0xC77A 0xC77B 0xC77C 0xC77D 0xC77E 0xC77F 0xC780 0xC781 0xC782 0xC783 0xC784 0xC785 +0xC786 0xC787 0xC788 0xC789 0xC78A 0xC78B 0xC78C 0xC78D 0xC78E 0xC78F 0xC790 0xC791 0xC793 0xC794 0xC796 0xC797 +0xC798 0xC799 0xC79A 0xC7A0 0xC7A1 0xC7A2 0xC7A3 0xC7A4 0xC7A5 0xC7A6 0xC7A7 0xC7A9 0xC7AA 0xC7AB 0xC7AC 0xC7AD +0xC7B0 0xC7B2 0xC7B3 0xC7B4 0xC7BC 0xC7BD 0xC7BE 0xC7BF 0xC7C0 0xC7C1 0xC7C2 0xC7C8 0xC7C9 0xC7CC 0xC7CE 0xC7CF +0xC7D0 0xC7D8 0xC7D9 0xC7DA 0xC7DB 0xC7DC 0xC7DD 0xC7E4 0xC7E5 0xC7E8 0xC7EB 0xC7EC 0xC7F4 0xC7F5 0xC7F6 0xC7F7 +0xC7F8 0xC7F9 0xC800 0xC801 0xC802 0xC804 0xC806 0xC807 0xC808 0xC809 0xC80A 0xC80B 0xC810 0xC811 0xC812 0xC813 +0xC814 0xC815 0xC816 0xC819 0xC81B 0xC81C 0xC81D 0xC820 0xC823 0xC824 0xC82C 0xC82D 0xC82E 0xC82F 0xC830 0xC831 +0xC832 0xC836 0xC838 0xC839 0xC83C 0xC83F 0xC840 0xC841 0xC842 0xC843 0xC847 0xC848 0xC849 0xC84A 0xC84B 0xC84C +0xC84D 0xC84E 0xC851 0xC853 0xC854 0xC855 0xC858 0xC85C 0xC864 0xC865 0xC866 0xC867 0xC868 0xC869 0xC870 0xC871 +0xC874 0xC877 0xC878 0xC87A 0xC880 0xC881 0xC882 0xC883 0xC884 0xC885 0xC886 0xC887 0xC88B 0xC88C 0xC88D 0xC890 +0xC892 0xC893 0xC894 0xC895 0xC896 0xC89C 0xC89D 0xC89E 0xC89F 0xC8A0 0xC8A1 0xC8A6 0xC8A8 0xC8A9 0xC8AC 0xC8AF +0xC8B0 0xC8B8 0xC8B9 0xC8BA 0xC8BB 0xC8BC 0xC8BD 0xC8C4 0xC8C5 0xC8C8 0xC8CB 0xC8CC 0xC8D4 0xC8D5 0xC8D6 0xC8D7 +0xC8D8 0xC8D9 0xC8E0 0xC8E1 0xC8E4 0xC8E7 0xC8E8 0xC8F0 0xC8F1 0xC8F2 0xC8F3 0xC8F4 0xC8F5 0xC8FB 0xC8FC 0xC8FD +0xC900 0xC903 0xC904 0xC905 0xC906 0xC908 0xC90C 0xC90D 0xC90E 0xC90F 0xC910 0xC911 0xC917 0xC918 0xC919 0xC91C +0xC91F 0xC920 0xC928 0xC929 0xC92A 0xC92B 0xC92C 0xC92D 0xC934 0xC935 0xC938 0xC93B 0xC93C 0xC944 0xC945 0xC946 +0xC947 0xC948 0xC949 0xC950 0xC951 0xC954 0xC957 0xC958 0xC960 0xC961 0xC962 0xC963 0xC964 0xC965 0xC96C 0xC96D +0xC970 0xC974 0xC97C 0xC97D 0xC97E 0xC97F 0xC980 0xC981 0xC988 0xC989 0xC98C 0xC98F 0xC990 0xC991 0xC992 0xC994 +0xC998 0xC999 0xC99A 0xC99B 0xC99C 0xC99D 0xC99E 0xC9A4 0xC9A5 0xC9A8 0xC9AC 0xC9B4 0xC9B5 0xC9B6 0xC9B7 0xC9B8 +0xC9B9 0xC9C0 0xC9C1 0xC9C4 0xC9C7 0xC9C8 0xC9CA 0xC9CF 0xC9D0 0xC9D1 0xC9D2 0xC9D3 0xC9D4 0xC9D5 0xC9D6 0xC9D7 +0xC9D8 0xC9D9 0xC9DA 0xC9DB 0xC9DC 0xC9DD 0xC9DE 0xC9E0 0xC9E2 0xC9E3 0xC9E4 0xC9E7 0xC9E8 0xC9EC 0xC9ED 0xC9EE +0xC9EF 0xC9F0 0xC9F1 0xC9F2 0xC9F7 0xC9F8 0xC9F9 0xC9FA 0xC9FB 0xC9FC 0xC9FF 0xCA00 0xCA08 0xCA09 0xCA0A 0xCA0B +0xCA0C 0xCA0D 0xCA0E 0xCA0F 0xCA10 0xCA11 0xCA12 0xCA13 0xCA14 0xCA15 0xCA18 0xCA1A 0xCA1C 0xCA24 0xCA25 0xCA26 +0xCA27 0xCA28 0xCA29 0xCA2D 0xCA30 0xCA31 0xCA32 0xCA33 0xCA34 0xCA37 0xCA38 0xCA40 0xCA41 0xCA42 0xCA43 0xCA44 +0xCA45 0xCA46 0xCA47 0xCA48 0xCA49 0xCA4A 0xCA4B 0xCA4C 0xCA4D 0xCA50 0xCA53 0xCA54 0xCA57 0xCA58 0xCA5B 0xCA5C +0xCA5D 0xCA5E 0xCA5F 0xCA60 0xCA61 0xCA67 0xCA68 0xCA69 0xCA6A 0xCA6B 0xCA6C 0xCA6F 0xCA70 0xCA78 0xCA79 0xCA7A +0xCA7B 0xCA7C 0xCA7D 0xCA7E 0xCA7F 0xCA80 0xCA81 0xCA82 0xCA83 0xCA84 0xCA85 0xCA88 0xCA8B 0xCA8C 0xCA94 0xCA95 +0xCA96 0xCA97 0xCA98 0xCA99 0xCAA0 0xCAA1 0xCAA2 0xCAA3 0xCAA4 0xCAA7 0xCAA8 0xCAB0 0xCAB1 0xCAB2 0xCAB3 0xCAB4 +0xCAB5 0xCAB6 0xCAB7 0xCAB8 0xCAB9 0xCABA 0xCABB 0xCABC 0xCABD 0xCABE 0xCAC0 0xCAC3 0xCAC4 0xCAC6 0xCACC 0xCACD +0xCACE 0xCACF 0xCAD0 0xCAD1 0xCAD2 0xCAD3 0xCAD7 0xCAD8 0xCAD9 0xCADC 0xCADF 0xCAE0 0xCAE8 0xCAE9 0xCAEA 0xCAEB +0xCAEC 0xCAED 0xCAF4 0xCAF5 0xCAF8 0xCAFB 0xCAFC 0xCB08 0xCB10 0xCB11 0xCB14 0xCB17 0xCB18 0xCB20 0xCB21 0xCB22 +0xCB23 0xCB24 0xCB25 0xCB26 0xCB27 0xCB28 0xCB29 0xCB2A 0xCB2B 0xCB2C 0xCB2D 0xCB30 0xCB32 0xCB34 0xCB3C 0xCB3D +0xCB3F 0xCB40 0xCB41 0xCB48 0xCB49 0xCB4A 0xCB4C 0xCB4F 0xCB50 0xCB52 0xCB58 0xCB59 0xCB5A 0xCB5B 0xCB5C 0xCB5D +0xCB64 0xCB65 0xCB68 0xCB6B 0xCB6C 0xCB74 0xCB75 0xCB77 0xCB78 0xCB79 0xCB80 0xCB81 0xCB84 0xCB87 0xCB88 0xCB90 +0xCB91 0xCB92 0xCB93 0xCB94 0xCB95 0xCB9C 0xCB9D 0xCBA0 0xCBA3 0xCBA4 0xCBAC 0xCBAD 0xCBAF 0xCBB1 0xCBB8 0xCBB9 +0xCBBC 0xCBC0 0xCBC8 0xCBC9 0xCBCA 0xCBCB 0xCBCC 0xCBCD 0xCBD4 0xCBD5 0xCBD8 0xCBDB 0xCBDC 0xCBE4 0xCBE5 0xCBE6 +0xCBE7 0xCBE8 0xCBE9 0xCBEA 0xCBF0 0xCBF1 0xCBF4 0xCBF8 0xCC00 0xCC01 0xCC02 0xCC03 0xCC04 0xCC05 0xCC06 0xCC0C +0xCC0D 0xCC10 0xCC13 0xCC14 0xCC1C 0xCC1D 0xCC1E 0xCC1F 0xCC20 0xCC21 0xCC22 0xCC26 0xCC27 0xCC28 0xCC29 0xCC2C +0xCC2E 0xCC2F 0xCC30 0xCC31 0xCC38 0xCC39 0xCC3A 0xCC3B 0xCC3C 0xCC3D 0xCC3E 0xCC3F 0xCC42 0xCC44 0xCC45 0xCC48 +0xCC4B 0xCC4C 0xCC54 0xCC55 0xCC56 0xCC57 0xCC58 0xCC59 0xCC5B 0xCC5E 0xCC60 0xCC61 0xCC64 0xCC66 0xCC68 0xCC70 +0xCC71 0xCC72 0xCC73 0xCC74 0xCC75 0xCC7A 0xCC7C 0xCC7D 0xCC91 0xCC98 0xCC99 0xCC9C 0xCC9F 0xCCA0 0xCCA7 0xCCA8 +0xCCA9 0xCCAA 0xCCAB 0xCCAC 0xCCAD 0xCCAE 0xCCB2 0xCCB4 0xCCB5 0xCCB8 0xCCBB 0xCCBC 0xCCC3 0xCCC4 0xCCC5 0xCCC6 +0xCCC7 0xCCC8 0xCCC9 0xCCCA 0xCCD0 0xCCD1 0xCCD4 0xCCD7 0xCCD8 0xCCE0 0xCCE1 0xCCE2 0xCCE3 0xCCE4 0xCCE5 0xCCEC +0xCCED 0xCCF0 0xCCF4 0xCCFC 0xCCFD 0xCCFE 0xCCFF 0xCD00 0xCD01 0xCD08 0xCD09 0xCD0C 0xCD0F 0xCD10 0xCD18 0xCD19 +0xCD1A 0xCD1B 0xCD1C 0xCD1D 0xCD23 0xCD24 0xCD25 0xCD28 0xCD2B 0xCD2C 0xCD34 0xCD35 0xCD36 0xCD37 0xCD38 0xCD39 +0xCD40 0xCD44 0xCD50 0xCD51 0xCD52 0xCD53 0xCD54 0xCD55 0xCD5C 0xCD5D 0xCD60 0xCD63 0xCD64 0xCD6C 0xCD6D 0xCD6E +0xCD6F 0xCD70 0xCD71 0xCD78 0xCD79 0xCD7C 0xCD80 0xCD88 0xCD89 0xCD8A 0xCD8B 0xCD8C 0xCD8D 0xCD94 0xCD95 0xCD98 +0xCD9B 0xCD9C 0xCDA4 0xCDA5 0xCDA6 0xCDA7 0xCDA8 0xCDA9 0xCDB0 0xCDB1 0xCDB4 0xCDB7 0xCDB8 0xCDC0 0xCDC1 0xCDC2 +0xCDC3 0xCDC4 0xCDC5 0xCDCC 0xCDCD 0xCDD0 0xCDD4 0xCDDC 0xCDDD 0xCDDE 0xCDDF 0xCDE0 0xCDE1 0xCDE8 0xCDE9 0xCDEC +0xCDEF 0xCDF0 0xCDF8 0xCDF9 0xCDFA 0xCDFB 0xCDFC 0xCDFD 0xCE04 0xCE05 0xCE08 0xCE0C 0xCE14 0xCE15 0xCE16 0xCE17 +0xCE18 0xCE19 0xCE20 0xCE21 0xCE24 0xCE27 0xCE28 0xCE29 0xCE2C 0xCE30 0xCE31 0xCE32 0xCE33 0xCE34 0xCE35 0xCE3C +0xCE3D 0xCE40 0xCE44 0xCE4C 0xCE4D 0xCE4E 0xCE4F 0xCE50 0xCE51 0xCE58 0xCE59 0xCE5C 0xCE5F 0xCE60 0xCE61 0xCE62 +0xCE68 0xCE69 0xCE6A 0xCE6B 0xCE6C 0xCE6D 0xCE6E 0xCE70 0xCE72 0xCE74 0xCE75 0xCE78 0xCE7B 0xCE7C 0xCE84 0xCE85 +0xCE86 0xCE87 0xCE88 0xCE89 0xCE8D 0xCE8E 0xCE90 0xCE91 0xCE94 0xCE97 0xCE98 0xCEA0 0xCEA1 0xCEA2 0xCEA3 0xCEA4 +0xCEA5 0xCEA8 0xCEA9 0xCEAA 0xCEAC 0xCEAD 0xCEB0 0xCEB4 0xCEBC 0xCEBD 0xCEBE 0xCEBF 0xCEC0 0xCEC1 0xCEC4 0xCEC8 +0xCEC9 0xCECC 0xCED8 0xCED9 0xCEDA 0xCEDB 0xCEDC 0xCEDD 0xCEE4 0xCEE5 0xCEE8 0xCEEB 0xCEEC 0xCEF4 0xCEF5 0xCEF6 +0xCEF7 0xCEF8 0xCEF9 0xCEFB 0xCEFD 0xCEFE 0xCF00 0xCF01 0xCF04 0xCF07 0xCF08 0xCF10 0xCF11 0xCF12 0xCF13 0xCF14 +0xCF15 0xCF18 0xCF19 0xCF1A 0xCF1C 0xCF1D 0xCF20 0xCF23 0xCF24 0xCF2C 0xCF2D 0xCF2E 0xCF2F 0xCF30 0xCF31 0xCF38 +0xCF39 0xCF3C 0xCF40 0xCF48 0xCF49 0xCF4A 0xCF4B 0xCF4C 0xCF4D 0xCF54 0xCF55 0xCF58 0xCF5B 0xCF5C 0xCF64 0xCF65 +0xCF66 0xCF67 0xCF68 0xCF69 0xCF6A 0xCF6E 0xCF70 0xCF71 0xCF74 0xCF78 0xCF80 0xCF81 0xCF82 0xCF83 0xCF84 0xCF85 +0xCF8C 0xCF8D 0xCF90 0xCF93 0xCF94 0xCF9C 0xCF9D 0xCF9E 0xCF9F 0xCFA0 0xCFA1 0xCFA8 0xCFA9 0xCFAC 0xCFB0 0xCFB8 +0xCFB9 0xCFBA 0xCFBB 0xCFBC 0xCFBD 0xCFC4 0xCFC5 0xCFC8 0xCFCC 0xCFD4 0xCFD5 0xCFD6 0xCFD7 0xCFD8 0xCFD9 0xCFE0 +0xCFE1 0xCFE4 0xCFE7 0xCFE8 0xCFF0 0xCFF1 0xCFF2 0xCFF3 0xCFF4 0xCFF5 0xCFFA 0xCFFC 0xCFFD 0xD000 0xD003 0xD004 +0xD00C 0xD00D 0xD00E 0xD00F 0xD010 0xD011 0xD018 0xD019 0xD01C 0xD020 0xD028 0xD029 0xD02A 0xD02B 0xD02C 0xD02D +0xD034 0xD035 0xD038 0xD03B 0xD03C 0xD044 0xD045 0xD046 0xD047 0xD048 0xD049 0xD050 0xD051 0xD054 0xD058 0xD060 +0xD061 0xD062 0xD063 0xD064 0xD065 0xD068 0xD06C 0xD06D 0xD070 0xD072 0xD074 0xD076 0xD07C 0xD07D 0xD07E 0xD07F +0xD080 0xD081 0xD084 0xD088 0xD089 0xD08C 0xD090 0xD098 0xD099 0xD09A 0xD09B 0xD09C 0xD09D 0xD0A4 0xD0A5 0xD0A8 +0xD0AB 0xD0AC 0xD0B4 0xD0B5 0xD0B6 0xD0B7 0xD0B8 0xD0B9 0xD0BE 0xD0C0 0xD0C1 0xD0C4 0xD0C7 0xD0C8 0xD0C9 0xD0CA +0xD0CF 0xD0D0 0xD0D1 0xD0D2 0xD0D3 0xD0D4 0xD0D5 0xD0DA 0xD0DC 0xD0DD 0xD0E0 0xD0E2 0xD0E3 0xD0E4 0xD0E5 0xD0EC +0xD0ED 0xD0EE 0xD0EF 0xD0F0 0xD0F1 0xD0F6 0xD0F8 0xD0F9 0xD0FC 0xD100 0xD108 0xD109 0xD10A 0xD10B 0xD10C 0xD10D +0xD114 0xD115 0xD118 0xD11A 0xD124 0xD125 0xD126 0xD127 0xD128 0xD129 0xD130 0xD131 0xD134 0xD137 0xD138 0xD139 +0xD13A 0xD13B 0xD140 0xD141 0xD142 0xD143 0xD144 0xD145 0xD14C 0xD14D 0xD150 0xD153 0xD154 0xD15C 0xD15D 0xD15E +0xD15F 0xD160 0xD161 0xD166 0xD168 0xD169 0xD16C 0xD16F 0xD170 0xD178 0xD179 0xD17A 0xD17B 0xD17C 0xD17D 0xD184 +0xD185 0xD188 0xD18C 0xD194 0xD195 0xD196 0xD197 0xD198 0xD199 0xD1A0 0xD1A1 0xD1A4 0xD1A7 0xD1A8 0xD1B0 0xD1B1 +0xD1B2 0xD1B3 0xD1B4 0xD1B5 0xD1B7 0xD1B8 0xD1B9 0xD1BA 0xD1BC 0xD1BD 0xD1C0 0xD1C4 0xD1CC 0xD1CD 0xD1CE 0xD1CF +0xD1D0 0xD1D1 0xD1D8 0xD1E8 0xD1E9 0xD1EA 0xD1EB 0xD1EC 0xD1ED 0xD1F4 0xD1F5 0xD1F8 0xD1FB 0xD1FC 0xD204 0xD205 +0xD206 0xD207 0xD208 0xD209 0xD210 0xD211 0xD214 0xD218 0xD220 0xD221 0xD222 0xD223 0xD224 0xD225 0xD22C 0xD22D +0xD230 0xD233 0xD234 0xD236 0xD23C 0xD23D 0xD23E 0xD23F 0xD240 0xD241 0xD248 0xD249 0xD24C 0xD24F 0xD250 0xD254 +0xD258 0xD259 0xD25A 0xD25B 0xD25C 0xD25D 0xD264 0xD265 0xD268 0xD26B 0xD26C 0xD274 0xD275 0xD276 0xD277 0xD278 +0xD279 0xD280 0xD281 0xD284 0xD287 0xD288 0xD290 0xD291 0xD292 0xD293 0xD294 0xD295 0xD29C 0xD29D 0xD2A0 0xD2A4 +0xD2AC 0xD2AD 0xD2AE 0xD2AF 0xD2B0 0xD2B1 0xD2B8 0xD2B9 0xD2BB 0xD2BC 0xD2BF 0xD2C0 0xD2C1 0xD2C2 0xD2C4 0xD2C8 +0xD2C9 0xD2CA 0xD2CB 0xD2CC 0xD2CD 0xD2D1 0xD2D4 0xD2D5 0xD2D8 0xD2DC 0xD2E0 0xD2E4 0xD2E5 0xD2E6 0xD2E7 0xD2E8 +0xD2E9 0xD2F0 0xD2F1 0xD2F4 0xD2F7 0xD2F8 0xD300 0xD301 0xD302 0xD303 0xD304 0xD305 0xD308 0xD30A 0xD30C 0xD30D +0xD30E 0xD310 0xD311 0xD313 0xD314 0xD316 0xD31C 0xD31D 0xD31E 0xD31F 0xD320 0xD321 0xD323 0xD324 0xD325 0xD326 +0xD328 0xD329 0xD32C 0xD32F 0xD330 0xD338 0xD339 0xD33A 0xD33B 0xD33C 0xD33D 0xD341 0xD344 0xD345 0xD348 0xD34C +0xD354 0xD355 0xD356 0xD357 0xD358 0xD359 0xD35D 0xD360 0xD361 0xD364 0xD370 0xD371 0xD372 0xD373 0xD374 0xD375 +0xD37C 0xD37D 0xD380 0xD383 0xD384 0xD38C 0xD38D 0xD38E 0xD38F 0xD390 0xD391 0xD395 0xD396 0xD398 0xD399 0xD39C +0xD39F 0xD3A0 0xD3A8 0xD3A9 0xD3AA 0xD3AB 0xD3AC 0xD3AD 0xD3B2 0xD3B4 0xD3B5 0xD3B8 0xD3B9 0xD3BB 0xD3BC 0xD3C4 +0xD3C5 0xD3C6 0xD3C7 0xD3C8 0xD3C9 0xD3D0 0xD3D1 0xD3D4 0xD3D7 0xD3D8 0xD3E0 0xD3E1 0xD3E2 0xD3E3 0xD3E4 0xD3E5 +0xD3EC 0xD3ED 0xD3EE 0xD3F0 0xD3F3 0xD3F4 0xD3FC 0xD3FD 0xD3FE 0xD3FF 0xD400 0xD401 0xD404 0xD405 0xD406 0xD408 +0xD409 0xD40C 0xD410 0xD418 0xD419 0xD41A 0xD41B 0xD41C 0xD41D 0xD424 0xD440 0xD441 0xD444 0xD448 0xD450 0xD451 +0xD452 0xD453 0xD454 0xD455 0xD45C 0xD45D 0xD460 0xD463 0xD464 0xD46C 0xD46D 0xD46E 0xD46F 0xD470 0xD471 0xD478 +0xD479 0xD47C 0xD47F 0xD480 0xD482 0xD488 0xD489 0xD48A 0xD48B 0xD48C 0xD48D 0xD494 0xD495 0xD498 0xD49B 0xD49C +0xD4A4 0xD4A5 0xD4A6 0xD4A7 0xD4A8 0xD4A9 0xD4B0 0xD4B1 0xD4B4 0xD4B8 0xD4C0 0xD4C1 0xD4C2 0xD4C3 0xD4C4 0xD4C5 +0xD4CC 0xD4CD 0xD4D0 0xD4D4 0xD4DC 0xD4DD 0xD4DE 0xD4DF 0xD4E0 0xD4E1 0xD4E8 0xD4E9 0xD4EC 0xD4EF 0xD4F0 0xD4F8 +0xD4F9 0xD4FA 0xD4FB 0xD4FC 0xD4FD 0xD504 0xD505 0xD508 0xD50B 0xD50C 0xD510 0xD514 0xD515 0xD516 0xD517 0xD518 +0xD519 0xD520 0xD521 0xD524 0xD528 0xD530 0xD531 0xD532 0xD533 0xD534 0xD535 0xD53C 0xD53D 0xD540 0xD543 0xD544 +0xD54C 0xD54D 0xD54E 0xD54F 0xD550 0xD551 0xD555 0xD556 0xD558 0xD559 0xD55C 0xD55F 0xD560 0xD561 0xD563 0xD564 +0xD565 0xD567 0xD568 0xD569 0xD56A 0xD56B 0xD56C 0xD56D 0xD56E 0xD570 0xD571 0xD572 0xD573 0xD574 0xD575 0xD578 +0xD57B 0xD57C 0xD584 0xD585 0xD586 0xD587 0xD588 0xD589 0xD58B 0xD58D 0xD58F 0xD590 0xD591 0xD594 0xD598 0xD5A0 +0xD5A1 0xD5A2 0xD5A3 0xD5A4 0xD5A5 0xD5AB 0xD5AC 0xD5AD 0xD5BC 0xD5BD 0xD5BE 0xD5BF 0xD5C0 0xD5C1 0xD5C8 0xD5C9 +0xD5CC 0xD5CF 0xD5D0 0xD5D1 0xD5D2 0xD5D5 0xD5D7 0xD5D8 0xD5D9 0xD5DA 0xD5DB 0xD5DC 0xD5DD 0xD5E0 0xD5E1 0xD5E2 +0xD5E3 0xD5E4 0xD5E5 0xD5E8 0xD5EB 0xD5EC 0xD5F4 0xD5F5 0xD5F6 0xD5F7 0xD5F8 0xD5F9 0xD5FE 0xD5FF 0xD600 0xD601 +0xD604 0xD607 0xD608 0xD610 0xD611 0xD612 0xD613 0xD614 0xD615 0xD61C 0xD61D 0xD620 0xD624 0xD62C 0xD62D 0xD62E +0xD62F 0xD630 0xD631 0xD638 0xD639 0xD63B 0xD63C 0xD63D 0xD63F 0xD640 0xD641 0xD644 0xD645 0xD647 0xD648 0xD649 +0xD64A 0xD64B 0xD64C 0xD64D 0xD651 0xD654 0xD655 0xD658 0xD65B 0xD65C 0xD660 0xD664 0xD665 0xD666 0xD667 0xD668 +0xD669 0xD670 0xD671 0xD674 0xD677 0xD678 0xD680 0xD681 0xD682 0xD683 0xD684 0xD685 0xD68C 0xD68D 0xD690 0xD693 +0xD694 0xD69C 0xD69D 0xD69E 0xD69F 0xD6A0 0xD6A1 0xD6A8 0xD6A9 0xD6AC 0xD6AF 0xD6B0 0xD6B8 0xD6B9 0xD6BA 0xD6BB +0xD6BC 0xD6BD 0xD6C4 0xD6C5 0xD6C8 0xD6CB 0xD6CC 0xD6CD 0xD6CE 0xD6D0 0xD6D1 0xD6D2 0xD6D3 0xD6D4 0xD6D5 0xD6D6 +0xD6D7 0xD6D8 0xD6D9 0xD6DC 0xD6DD 0xD6E0 0xD6E1 0xD6E4 0xD6E8 0xD6F0 0xD6F1 0xD6F2 0xD6F3 0xD6F4 0xD6F5 0xD6FC +0xD6FD 0xD700 0xD703 0xD704 0xD70C 0xD70D 0xD70E 0xD70F 0xD710 0xD711 0xD718 0xD719 0xD71C 0xD71F 0xD720 0xD728 +0xD729 0xD72A 0xD72B 0xD72C 0xD72D 0xD734 0xD735 0xD738 0xD73A 0xD73B 0xD73C 0xD743 0xD744 0xD745 0xD746 0xD747 +0xD748 0xD749 0xD74D 0xD750 0xD751 0xD752 0xD754 0xD755 0xD756 0xD757 0xD758 0xD759 0xD75D 0xD75F 0xD760 0xD761 +0xD762 0xD763 0xD764 0xD765 0xD768 0xD769 0xD76A 0xD76B 0xD76C 0xD76D 0xD770 0xD773 0xD774 0xD77C 0xD77D 0xD77E +0xD77F 0xD780 0xD781 0xD788 0xD789 0xD78A 0xD78B 0xD78C 0xD78D 0xD78E 0xD78F 0xD790 0xD797 0xD798 0xD799 0xD79A +0xD79B 0xD79C 0xD79D 0xD79E 0xD7A0 0xD7A1 0xD7A2 0xD7A3 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE007 +0xE008 0xE009 0xE00A 0xE00B 0xE00C 0xE00D 0xE020 0xE021 0xE022 0xE023 0xE030 0xE031 0xE032 0xE033 0xE040 0xE041 +0xE042 0xE043 0xE044 0xE045 0xE050 0xE051 0xE052 0xE053 0xE054 0xE055 0xE056 0xE057 0xE058 0xE059 0xE05A 0xE05B +0xE05C 0xE05D 0xE070 0xE071 0xE072 0xE073 0xE080 0xE081 0xE082 0xE083 0xE090 0xE091 0xE092 0xE093 0xE094 0xE095 +0xE09D 0xE0A0 0xE0A1 0xE0A2 0xE0A3 0xE0B0 0xE0B1 0xE0B2 0xE0B3 0xF000 0xF001 0xF007 0xF020 0xF021 0xF022 0xF023 +0xF024 0xF025 0xF026 0xF027 0xF028 0xF029 0xF02A 0xF030 0xF031 0xF032 0xF033 0xF034 0xF035 0xF036 0xF037 0xF038 +0xF039 0xF03A 0xF03B 0xF03C 0xF03D 0xF8FF 0xFE10 0xFE11 0xFE12 0xFE13 0xFE14 0xFE15 0xFE16 0xFE17 0xFE18 0xFE19 +0xFE30 0xFE31 0xFE33 0xFE34 0xFE35 0xFE36 0xFE37 0xFE38 0xFE39 0xFE3A 0xFE3B 0xFE3C 0xFE3D 0xFE3E 0xFE3F 0xFE40 +0xFE41 0xFE42 0xFE43 0xFE44 0xFE49 0xFE4A 0xFE4B 0xFE4C 0xFE4D 0xFE4E 0xFE4F 0xFE50 0xFE51 0xFE52 0xFE54 0xFE55 +0xFE56 0xFE57 0xFE59 0xFE5A 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0xFE5F 0xFE60 0xFE61 0xFE62 0xFE63 0xFE64 0xFE65 0xFE66 +0xFE68 0xFE69 0xFE6A 0xFE6B 0xFF01 0xFF02 0xFF03 0xFF04 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C +0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C +0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C +0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C +0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C +0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C +0xFF5D 0xFF5E 0xFF5F 0xFF60 0xFF61 0xFF62 0xFF63 0xFF64 0xFF65 0xFF66 0xFF67 0xFF68 0xFF69 0xFF6A 0xFF6B 0xFF6C +0xFF6D 0xFF6E 0xFF6F 0xFF70 0xFF71 0xFF72 0xFF73 0xFF74 0xFF75 0xFF76 0xFF77 0xFF78 0xFF79 0xFF7A 0xFF7B 0xFF7C +0xFF7D 0xFF7E 0xFF7F 0xFF80 0xFF81 0xFF82 0xFF83 0xFF84 0xFF85 0xFF86 0xFF87 0xFF88 0xFF89 0xFF8A 0xFF8B 0xFF8C +0xFF8D 0xFF8E 0xFF8F 0xFF90 0xFF91 0xFF92 0xFF93 0xFF94 0xFF95 0xFF96 0xFF97 0xFF98 0xFF99 0xFF9A 0xFF9B 0xFF9C +0xFF9D 0xFF9E 0xFF9F 0xFFE0 0xFFE1 0xFFE2 0xFFE3 0xFFE4 0xFFE5 0xFFE9 0xFFEB 0xFFFC 0xFFFD 0xFFFE diff --git a/resources/fonts/fusion/font_fusion_ko_8x8.frf b/resources/fonts/fusion/font_fusion_ko_8x8.frf new file mode 100644 index 000000000..f42fa3b15 Binary files /dev/null and b/resources/fonts/fusion/font_fusion_ko_8x8.frf differ diff --git a/resources/fonts/fusion/font_fusion_ko_8x8.pbm b/resources/fonts/fusion/font_fusion_ko_8x8.pbm new file mode 100644 index 000000000..870c735d3 Binary files /dev/null and b/resources/fonts/fusion/font_fusion_ko_8x8.pbm differ diff --git a/resources/fonts/fusion/font_fusion_ko_8x8.txt b/resources/fonts/fusion/font_fusion_ko_8x8.txt new file mode 100644 index 000000000..cd88777dd --- /dev/null +++ b/resources/fonts/fusion/font_fusion_ko_8x8.txt @@ -0,0 +1,1379 @@ +0x0020 0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F +0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F +0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F +0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F +0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F +0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E 0x00A1 +0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00AF 0x00B0 0x00B1 0x00B2 +0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00B8 0x00B9 0x00BA 0x00BB 0x00BC 0x00BD 0x00BE 0x00BF 0x00C0 0x00C1 0x00C2 +0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 +0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 +0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 +0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0100 0x0101 0x0102 +0x0103 0x0104 0x0105 0x0106 0x0107 0x0108 0x0109 0x010A 0x010B 0x010C 0x010D 0x010E 0x010F 0x0110 0x0111 0x0112 +0x0113 0x0114 0x0115 0x0116 0x0117 0x0118 0x0119 0x011A 0x011B 0x011C 0x011D 0x011E 0x011F 0x0120 0x0121 0x0122 +0x0123 0x0124 0x0125 0x0126 0x0127 0x0128 0x0129 0x012A 0x012B 0x012C 0x012D 0x012E 0x012F 0x0130 0x0131 0x0132 +0x0133 0x0134 0x0135 0x0136 0x0137 0x0138 0x0139 0x013A 0x013B 0x013C 0x013D 0x013E 0x013F 0x0140 0x0141 0x0142 +0x0143 0x0144 0x0145 0x0146 0x0147 0x0148 0x0149 0x014A 0x014B 0x014C 0x014D 0x014E 0x014F 0x0150 0x0151 0x0152 +0x0153 0x0154 0x0155 0x0156 0x0157 0x0158 0x0159 0x015A 0x015B 0x015C 0x015D 0x015E 0x015F 0x0160 0x0161 0x0162 +0x0163 0x0164 0x0165 0x0166 0x0167 0x0168 0x0169 0x016A 0x016B 0x016C 0x016D 0x016E 0x016F 0x0170 0x0171 0x0172 +0x0173 0x0174 0x0175 0x0176 0x0177 0x0178 0x0179 0x017A 0x017B 0x017C 0x017D 0x017E 0x017F 0x0192 0x0197 0x01A0 +0x01A1 0x01AC 0x01AF 0x01B0 0x01C0 0x01C1 0x01C2 0x01C3 0x01CD 0x01CE 0x01CF 0x01D0 0x01D1 0x01D2 0x01D3 0x01D4 +0x01D5 0x01D6 0x01D7 0x01D8 0x01D9 0x01DA 0x01DB 0x01DC 0x01DE 0x01DF 0x01E0 0x01E1 0x01E2 0x01E3 0x01E6 0x01E7 +0x01E8 0x01E9 0x01EA 0x01EB 0x01EC 0x01ED 0x01F0 0x01F4 0x01F5 0x01F8 0x01F9 0x01FA 0x01FB 0x01FC 0x01FD 0x01FE +0x01FF 0x0218 0x0219 0x021A 0x021B 0x021E 0x021F 0x0221 0x0226 0x0227 0x0228 0x0229 0x022A 0x022B 0x022C 0x022D +0x022E 0x022F 0x0230 0x0231 0x0232 0x0233 0x0235 0x0236 0x0237 0x0244 0x2010 0x2011 0x2012 0x2013 0x2014 0x2015 +0x2016 0x2017 0x2018 0x2019 0x201A 0x201C 0x201D 0x201E 0x2020 0x2021 0x2022 0x2023 0x2025 0x2026 0x2027 0x2030 +0x2031 0x2032 0x2033 0x2034 0x2035 0x2037 0x2038 0x2039 0x203A 0x203B 0x203C 0x203E 0x203F 0x2044 0x2103 0x2109 +0x2160 0x2161 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 0x216A 0x216B 0x2170 0x2171 0x2172 0x2173 +0x2174 0x2175 0x2176 0x2177 0x2178 0x2179 0x2181 0x2182 0x2190 0x2191 0x2192 0x2193 0x2194 0x2195 0x2196 0x2197 +0x2198 0x2199 0x219A 0x219B 0x21BA 0x21BB 0x21D0 0x21D1 0x21D2 0x21D3 0x21D4 0x21D5 0x21D6 0x21D7 0x21D8 0x21D9 +0x21DA 0x21DB 0x21E0 0x21E1 0x21E2 0x21E3 0x21E4 0x21E5 0x21E6 0x21E7 0x21E8 0x21E9 0x21EA 0x21EB 0x21EC 0x21ED +0x21EE 0x21EF 0x21F0 0x21F1 0x21F2 0x21F3 0x21FD 0x21FE 0x21FF 0x2200 0x2202 0x2203 0x2207 0x2208 0x220B 0x2211 +0x2212 0x221A 0x221D 0x221E 0x221F 0x2220 0x2225 0x2227 0x2228 0x2229 0x222A 0x222B 0x222C 0x222E 0x2234 0x2235 +0x223D 0x2252 0x2260 0x2261 0x2266 0x2267 0x226A 0x226B 0x2282 0x2283 0x2286 0x2287 0x22A5 0x22BF 0x2460 0x2461 +0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 0x246A 0x246B 0x246C 0x246D 0x246E 0x246F 0x2470 0x2471 +0x2472 0x2473 0x2500 0x2501 0x2502 0x2503 0x2504 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C 0x250D +0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C 0x251D +0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C 0x252D +0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C 0x253D +0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0x254C 0x254D +0x254E 0x254F 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D +0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x256D +0x256E 0x256F 0x2570 0x2571 0x2572 0x2573 0x2574 0x2575 0x2576 0x2577 0x2578 0x2579 0x257A 0x257B 0x257C 0x257D +0x257E 0x257F 0x2580 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 0x2589 0x258A 0x258B 0x258C 0x258D +0x258E 0x258F 0x2590 0x2591 0x2592 0x2593 0x2594 0x2595 0x2596 0x2597 0x2598 0x2599 0x259A 0x259B 0x259C 0x259D +0x259E 0x259F 0x25A0 0x25A1 0x25A2 0x25A3 0x25A4 0x25A5 0x25A6 0x25A7 0x25A8 0x25A9 0x25AA 0x25AB 0x25AC 0x25AD +0x25AE 0x25AF 0x25B0 0x25B1 0x25B2 0x25B3 0x25B4 0x25B5 0x25B6 0x25B7 0x25B8 0x25B9 0x25BA 0x25BB 0x25BC 0x25BD +0x25BE 0x25BF 0x25C0 0x25C1 0x25C2 0x25C3 0x25C4 0x25C5 0x25C6 0x25C7 0x25C8 0x25C9 0x25CA 0x25CB 0x25CC 0x25CD +0x25CE 0x25CF 0x25D0 0x25D1 0x25D2 0x25D3 0x25D4 0x25D5 0x25D6 0x25D7 0x25D8 0x25D9 0x25DA 0x25DB 0x25DC 0x25DD +0x25DE 0x25DF 0x25E0 0x25E1 0x25E2 0x25E3 0x25E4 0x25E5 0x25E6 0x25E7 0x25E8 0x25E9 0x25EA 0x25EB 0x25EC 0x25ED +0x25EE 0x25EF 0x25F0 0x25F1 0x25F2 0x25F3 0x25F4 0x25F5 0x25F6 0x25F7 0x25F8 0x25F9 0x25FA 0x25FB 0x25FC 0x25FD +0x25FE 0x25FF 0x2600 0x2602 0x2604 0x2605 0x2606 0x2609 0x260A 0x260B 0x260C 0x260D 0x260E 0x260F 0x2616 0x2617 +0x262D 0x262E 0x262F 0x2630 0x2631 0x2632 0x2633 0x2634 0x2635 0x2636 0x2637 0x2639 0x263A 0x263B 0x263C 0x263D +0x263E 0x2640 0x2641 0x2642 0x2660 0x2661 0x2662 0x2663 0x2664 0x2665 0x2666 0x2667 0x2668 0x2669 0x266A 0x266B +0x266C 0x266D 0x266E 0x266F 0x2680 0x2681 0x2682 0x2683 0x2684 0x2685 0x2686 0x2687 0x2688 0x2689 0x268A 0x268B +0x268C 0x268D 0x268E 0x268F 0x2694 0x2698 0x2699 0x26AA 0x26AB 0x26AC 0x26C9 0x26CA 0x26F6 0x2800 0x2801 0x2802 +0x2803 0x2804 0x2805 0x2806 0x2807 0x2808 0x2809 0x280A 0x280B 0x280C 0x280D 0x280E 0x280F 0x2810 0x2811 0x2812 +0x2813 0x2814 0x2815 0x2816 0x2817 0x2818 0x2819 0x281A 0x281B 0x281C 0x281D 0x281E 0x281F 0x2820 0x2821 0x2822 +0x2823 0x2824 0x2825 0x2826 0x2827 0x2828 0x2829 0x282A 0x282B 0x282C 0x282D 0x282E 0x282F 0x2830 0x2831 0x2832 +0x2833 0x2834 0x2835 0x2836 0x2837 0x2838 0x2839 0x283A 0x283B 0x283C 0x283D 0x283E 0x283F 0x2840 0x2841 0x2842 +0x2843 0x2844 0x2845 0x2846 0x2847 0x2848 0x2849 0x284A 0x284B 0x284C 0x284D 0x284E 0x284F 0x2850 0x2851 0x2852 +0x2853 0x2854 0x2855 0x2856 0x2857 0x2858 0x2859 0x285A 0x285B 0x285C 0x285D 0x285E 0x285F 0x2860 0x2861 0x2862 +0x2863 0x2864 0x2865 0x2866 0x2867 0x2868 0x2869 0x286A 0x286B 0x286C 0x286D 0x286E 0x286F 0x2870 0x2871 0x2872 +0x2873 0x2874 0x2875 0x2876 0x2877 0x2878 0x2879 0x287A 0x287B 0x287C 0x287D 0x287E 0x287F 0x2880 0x2881 0x2882 +0x2883 0x2884 0x2885 0x2886 0x2887 0x2888 0x2889 0x288A 0x288B 0x288C 0x288D 0x288E 0x288F 0x2890 0x2891 0x2892 +0x2893 0x2894 0x2895 0x2896 0x2897 0x2898 0x2899 0x289A 0x289B 0x289C 0x289D 0x289E 0x289F 0x28A0 0x28A1 0x28A2 +0x28A3 0x28A4 0x28A5 0x28A6 0x28A7 0x28A8 0x28A9 0x28AA 0x28AB 0x28AC 0x28AD 0x28AE 0x28AF 0x28B0 0x28B1 0x28B2 +0x28B3 0x28B4 0x28B5 0x28B6 0x28B7 0x28B8 0x28B9 0x28BA 0x28BB 0x28BC 0x28BD 0x28BE 0x28BF 0x28C0 0x28C1 0x28C2 +0x28C3 0x28C4 0x28C5 0x28C6 0x28C7 0x28C8 0x28C9 0x28CA 0x28CB 0x28CC 0x28CD 0x28CE 0x28CF 0x28D0 0x28D1 0x28D2 +0x28D3 0x28D4 0x28D5 0x28D6 0x28D7 0x28D8 0x28D9 0x28DA 0x28DB 0x28DC 0x28DD 0x28DE 0x28DF 0x28E0 0x28E1 0x28E2 +0x28E3 0x28E4 0x28E5 0x28E6 0x28E7 0x28E8 0x28E9 0x28EA 0x28EB 0x28EC 0x28ED 0x28EE 0x28EF 0x28F0 0x28F1 0x28F2 +0x28F3 0x28F4 0x28F5 0x28F6 0x28F7 0x28F8 0x28F9 0x28FA 0x28FB 0x28FC 0x28FD 0x28FE 0x28FF 0x3000 0x3001 0x3002 +0x3003 0x3004 0x3005 0x3006 0x3007 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0x3012 +0x3013 0x3014 0x3015 0x3016 0x3017 0x3018 0x3019 0x301A 0x301B 0x301C 0x301D 0x301E 0x301F 0x3020 0x3021 0x3022 +0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 0x3029 0x3036 0x3037 0x3038 0x3039 0x303A 0x303C 0x303E 0x303F 0x3041 +0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 +0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 +0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 +0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 +0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 +0x3092 0x3093 0x309B 0x309C 0x309D 0x309E 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA +0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA +0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA +0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA +0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA +0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x30FB 0x30FC 0x30FD 0x30FE +0x3105 0x3106 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 +0x3115 0x3116 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 +0x3125 0x3126 0x3127 0x3128 0x3129 0x312A 0x312B 0x312C 0x312D 0x312E 0x312F 0x3131 0x3132 0x3133 0x3134 0x3135 +0x3136 0x3137 0x3138 0x3139 0x313A 0x313B 0x313C 0x313D 0x313E 0x313F 0x3140 0x3141 0x3142 0x3143 0x3144 0x3145 +0x3146 0x3147 0x3148 0x3149 0x314A 0x314B 0x314C 0x314D 0x314E 0x314F 0x3150 0x3151 0x3152 0x3153 0x3154 0x3155 +0x3156 0x3157 0x3158 0x3159 0x315A 0x315B 0x315C 0x315D 0x315E 0x315F 0x3160 0x3161 0x3162 0x3163 0x3164 0x3220 +0x3221 0x3222 0x3223 0x3224 0x3225 0x3226 0x3227 0x3228 0x3229 0x3231 0x3232 0x3239 0x3268 0x3280 0x3281 0x3282 +0x3283 0x3284 0x3285 0x3286 0x3287 0x3288 0x3289 0x32A3 0x32A4 0x32A5 0x32A6 0x32A7 0x32A8 0x32FF 0x4E00 0x4E01 +0x4E02 0x4E03 0x4E04 0x4E05 0x4E06 0x4E07 0x4E08 0x4E09 0x4E0A 0x4E0B 0x4E0C 0x4E0D 0x4E0E 0x4E0F 0x4E10 0x4E11 +0x4E12 0x4E13 0x4E14 0x4E15 0x4E16 0x4E17 0x4E18 0x4E19 0x4E1A 0x4E1B 0x4E1C 0x4E1D 0x4E1E 0x4E1F 0x4E20 0x4E21 +0x4E22 0x4E23 0x4E24 0x4E25 0x4E26 0x4E27 0x4E28 0x4E29 0x4E2A 0x4E2B 0x4E2C 0x4E2D 0x4E2E 0x4E2F 0x4E30 0x4E31 +0x4E32 0x4E33 0x4E34 0x4E35 0x4E36 0x4E37 0x4E38 0x4E39 0x4E3A 0x4E3B 0x4E3C 0x4E3D 0x4E3E 0x4E3F 0x4E40 0x4E41 +0x4E42 0x4E43 0x4E44 0x4E45 0x4E46 0x4E47 0x4E48 0x4E49 0x4E4A 0x4E4B 0x4E4C 0x4E4D 0x4E4E 0x4E4F 0x4E50 0x4E51 +0x4E52 0x4E53 0x4E54 0x4E55 0x4E56 0x4E57 0x4E58 0x4E59 0x4E5A 0x4E5B 0x4E5C 0x4E5D 0x4E5E 0x4E5F 0x4E60 0x4E61 +0x4E62 0x4E63 0x4E64 0x4E65 0x4E66 0x4E67 0x4E68 0x4E69 0x4E6A 0x4E6B 0x4E6C 0x4E6D 0x4E6E 0x4E6F 0x4E70 0x4E71 +0x4E72 0x4E73 0x4E74 0x4E75 0x4E76 0x4E77 0x4E78 0x4E79 0x4E7A 0x4E7B 0x4E7C 0x4E7D 0x4E7E 0x4E7F 0x4E80 0x4E81 +0x4E82 0x4E83 0x4E84 0x4E85 0x4E86 0x4E87 0x4E88 0x4E89 0x4E8A 0x4E8B 0x4E8C 0x4E8D 0x4E8E 0x4E8F 0x4E90 0x4E91 +0x4E92 0x4E93 0x4E94 0x4E95 0x4E96 0x4E97 0x4E98 0x4E99 0x4E9A 0x4E9B 0x4E9C 0x4E9D 0x4E9E 0x4E9F 0x4EA0 0x4EA1 +0x4EA2 0x4EA3 0x4EA4 0x4EA5 0x4EA6 0x4EA7 0x4EA8 0x4EA9 0x4EAA 0x4EAB 0x4EAC 0x4EAD 0x4EAE 0x4EAF 0x4EB0 0x4EB1 +0x4EB2 0x4EB3 0x4EB4 0x4EB5 0x4EB6 0x4EB7 0x4EB8 0x4EB9 0x4EBA 0x4EBB 0x4EBC 0x4EBD 0x4EBE 0x4EBF 0x4EC0 0x4EC1 +0x4EC2 0x4EC3 0x4EC4 0x4EC5 0x4EC6 0x4EC7 0x4EC8 0x4EC9 0x4ECA 0x4ECB 0x4ECC 0x4ECD 0x4ECE 0x4ECF 0x4ED0 0x4ED1 +0x4ED2 0x4ED3 0x4ED4 0x4ED5 0x4ED6 0x4ED7 0x4ED8 0x4ED9 0x4EDA 0x4EDB 0x4EDC 0x4EDD 0x4EDE 0x4EDF 0x4EE0 0x4EE1 +0x4EE2 0x4EE3 0x4EE4 0x4EE5 0x4EE6 0x4EE7 0x4EE8 0x4EE9 0x4EEA 0x4EEB 0x4EEC 0x4EED 0x4EEE 0x4EEF 0x4EF0 0x4EF1 +0x4EF2 0x4EF3 0x4EF4 0x4EF5 0x4EF6 0x4EF7 0x4EF8 0x4EF9 0x4EFA 0x4EFB 0x4EFC 0x4EFD 0x4EFE 0x4EFF 0x4F00 0x4F01 +0x4F02 0x4F03 0x4F04 0x4F05 0x4F06 0x4F07 0x4F08 0x4F09 0x4F0A 0x4F0B 0x4F0C 0x4F0D 0x4F0E 0x4F0F 0x4F10 0x4F11 +0x4F12 0x4F13 0x4F14 0x4F15 0x4F16 0x4F17 0x4F18 0x4F19 0x4F1A 0x4F1B 0x4F1C 0x4F1D 0x4F1E 0x4F1F 0x4F20 0x4F21 +0x4F22 0x4F23 0x4F24 0x4F25 0x4F26 0x4F27 0x4F28 0x4F29 0x4F2A 0x4F2B 0x4F2C 0x4F2D 0x4F2E 0x4F2F 0x4F30 0x4F31 +0x4F32 0x4F33 0x4F34 0x4F35 0x4F36 0x4F37 0x4F38 0x4F39 0x4F3A 0x4F3B 0x4F3C 0x4F3D 0x4F3E 0x4F3F 0x4F40 0x4F41 +0x4F42 0x4F43 0x4F44 0x4F45 0x4F46 0x4F47 0x4F48 0x4F49 0x4F4A 0x4F4B 0x4F4C 0x4F4D 0x4F4E 0x4F4F 0x4F50 0x4F51 +0x4F52 0x4F53 0x4F54 0x4F55 0x4F56 0x4F57 0x4F58 0x4F59 0x4F5A 0x4F5B 0x4F5C 0x4F5D 0x4F5E 0x4F5F 0x4F60 0x4F61 +0x4F62 0x4F63 0x4F64 0x4F65 0x4F66 0x4F67 0x4F68 0x4F69 0x4F6A 0x4F6B 0x4F6C 0x4F6D 0x4F6E 0x4F6F 0x4F70 0x4F71 +0x4F72 0x4F73 0x4F74 0x4F75 0x4F76 0x4F77 0x4F78 0x4F79 0x4F7A 0x4F7B 0x4F7C 0x4F7D 0x4F7E 0x4F7F 0x4F80 0x4F81 +0x4F82 0x4F83 0x4F84 0x4F85 0x4F86 0x4F87 0x4F88 0x4F89 0x4F8A 0x4F8B 0x4F8C 0x4F8D 0x4F8E 0x4F8F 0x4F90 0x4F91 +0x4F92 0x4F93 0x4F94 0x4F95 0x4F96 0x4F97 0x4F98 0x4F99 0x4F9A 0x4F9B 0x4F9C 0x4F9D 0x4F9E 0x4F9F 0x4FA0 0x4FA1 +0x4FA2 0x4FA3 0x4FA4 0x4FA5 0x4FA6 0x4FA7 0x4FA8 0x4FA9 0x4FAA 0x4FAB 0x4FAC 0x4FAD 0x4FAE 0x4FAF 0x4FB0 0x4FB1 +0x4FB2 0x4FB3 0x4FB4 0x4FB5 0x4FB6 0x4FB7 0x4FB8 0x4FB9 0x4FBA 0x4FBB 0x4FBC 0x4FBD 0x4FBE 0x4FBF 0x4FC0 0x4FC1 +0x4FC2 0x4FC3 0x4FC4 0x4FC5 0x4FC6 0x4FC7 0x4FC8 0x4FC9 0x4FCA 0x4FCB 0x4FCC 0x4FCD 0x4FCE 0x4FCF 0x4FD0 0x4FD1 +0x4FD2 0x4FD3 0x4FD4 0x4FD5 0x4FD6 0x4FD7 0x4FD8 0x4FD9 0x4FDA 0x4FDB 0x4FDC 0x4FDD 0x4FDE 0x4FDF 0x4FE0 0x4FE1 +0x4FE2 0x4FE3 0x4FE4 0x4FE5 0x4FE6 0x4FE7 0x4FE8 0x4FE9 0x4FEA 0x4FEB 0x4FEC 0x4FED 0x4FEE 0x4FEF 0x4FF0 0x4FF1 +0x4FF2 0x4FF3 0x4FF4 0x4FF5 0x4FF6 0x4FF7 0x4FF8 0x4FF9 0x4FFA 0x4FFB 0x4FFC 0x4FFD 0x4FFE 0x4FFF 0x5000 0x5001 +0x5002 0x5003 0x5004 0x5005 0x5006 0x5007 0x5008 0x5009 0x500A 0x500B 0x500C 0x500D 0x500E 0x500F 0x5010 0x5011 +0x5012 0x5013 0x5014 0x5015 0x5016 0x5017 0x5018 0x5019 0x501A 0x501B 0x501C 0x501D 0x501E 0x501F 0x5020 0x5021 +0x5022 0x5023 0x5024 0x5025 0x5026 0x5027 0x5028 0x5029 0x502A 0x502B 0x502C 0x502D 0x502E 0x502F 0x5030 0x5031 +0x5033 0x5034 0x5035 0x5036 0x5037 0x5039 0x503A 0x503B 0x503C 0x503E 0x5040 0x5041 0x5043 0x5045 0x5046 0x5047 +0x5048 0x5049 0x504A 0x504B 0x504C 0x504D 0x504E 0x504F 0x5050 0x5051 0x5053 0x5055 0x5056 0x5057 0x505A 0x505B +0x505C 0x505D 0x505E 0x505F 0x5060 0x5061 0x5062 0x5063 0x5064 0x5065 0x5068 0x5069 0x506A 0x506B 0x506C 0x506D +0x506E 0x506F 0x5070 0x5072 0x5073 0x5074 0x5075 0x5076 0x5077 0x5078 0x507A 0x507B 0x507D 0x507E 0x507F 0x5080 +0x5082 0x5083 0x5085 0x5087 0x5088 0x5089 0x508B 0x508C 0x508D 0x508E 0x5091 0x5092 0x5094 0x5095 0x5096 0x5098 +0x5099 0x509A 0x509B 0x509C 0x509D 0x509E 0x50A2 0x50A3 0x50A4 0x50A5 0x50A7 0x50A8 0x50A9 0x50AC 0x50AD 0x50AE +0x50AF 0x50B0 0x50B1 0x50B2 0x50B3 0x50B4 0x50B5 0x50B6 0x50B7 0x50B8 0x50BA 0x50BB 0x50BD 0x50BE 0x50BF 0x50C1 +0x50C2 0x50C4 0x50C5 0x50C6 0x50C7 0x50C8 0x50C9 0x50CA 0x50CB 0x50CD 0x50CE 0x50CF 0x50D1 0x50D3 0x50D4 0x50D5 +0x50D6 0x50D7 0x50D9 0x50DA 0x50DB 0x50DC 0x50DD 0x50DE 0x50E0 0x50E3 0x50E4 0x50E5 0x50E6 0x50E7 0x50E8 0x50E9 +0x50EA 0x50EB 0x50EC 0x50ED 0x50EE 0x50EF 0x50F0 0x50F1 0x50F3 0x50F5 0x50F6 0x50F8 0x50F9 0x50FB 0x50FD 0x50FE +0x50FF 0x5100 0x5101 0x5102 0x5103 0x5104 0x5105 0x5106 0x5107 0x5108 0x5109 0x510A 0x510B 0x510C 0x510D 0x510E +0x5110 0x5111 0x5112 0x5113 0x5114 0x5115 0x5116 0x5117 0x5118 0x511A 0x511C 0x511F 0x5120 0x5121 0x5122 0x5124 +0x5125 0x5126 0x5129 0x512A 0x512D 0x512E 0x5130 0x5131 0x5132 0x5133 0x5134 0x5135 0x5137 0x5138 0x5139 0x513A +0x513B 0x513C 0x513D 0x513F 0x5140 0x5141 0x5142 0x5143 0x5144 0x5145 0x5146 0x5147 0x5148 0x5149 0x514A 0x514B +0x514C 0x514D 0x514E 0x514F 0x5150 0x5151 0x5152 0x5153 0x5154 0x5155 0x5156 0x5157 0x5159 0x515A 0x515B 0x515C +0x515D 0x515E 0x515F 0x5161 0x5162 0x5163 0x5165 0x5166 0x5167 0x5168 0x5169 0x516A 0x516B 0x516C 0x516D 0x516E +0x516F 0x5170 0x5171 0x5172 0x5173 0x5174 0x5175 0x5176 0x5177 0x5178 0x5179 0x517B 0x517C 0x517D 0x5180 0x5181 +0x5182 0x5183 0x5184 0x5185 0x5186 0x5187 0x5188 0x5189 0x518A 0x518B 0x518C 0x518D 0x518E 0x518F 0x5190 0x5191 +0x5192 0x5193 0x5194 0x5195 0x5196 0x5197 0x5198 0x5199 0x519A 0x519B 0x519C 0x519D 0x519E 0x51A0 0x51A2 0x51A4 +0x51A5 0x51A6 0x51A7 0x51A8 0x51A9 0x51AA 0x51AB 0x51AC 0x51AD 0x51AE 0x51AF 0x51B0 0x51B1 0x51B2 0x51B3 0x51B4 +0x51B5 0x51B6 0x51B7 0x51B9 0x51BB 0x51BC 0x51BD 0x51BE 0x51C0 0x51C3 0x51C4 0x51C5 0x51C6 0x51C7 0x51C8 0x51C9 +0x51CA 0x51CB 0x51CC 0x51CD 0x51CE 0x51CF 0x51D0 0x51D1 0x51D3 0x51D4 0x51D6 0x51D7 0x51D8 0x51D9 0x51DB 0x51DC +0x51DD 0x51DE 0x51E0 0x51E1 0x51E2 0x51E4 0x51E5 0x51E6 0x51E7 0x51E9 0x51EA 0x51EB 0x51ED 0x51EE 0x51EF 0x51F0 +0x51F1 0x51F3 0x51F4 0x51F5 0x51F6 0x51F7 0x51F8 0x51F9 0x51FA 0x51FB 0x51FC 0x51FD 0x51FE 0x51FF 0x5200 0x5201 +0x5202 0x5203 0x5204 0x5205 0x5206 0x5207 0x5208 0x5209 0x520A 0x520B 0x520C 0x520D 0x520E 0x5210 0x5211 0x5212 +0x5213 0x5214 0x5215 0x5216 0x5217 0x5218 0x5219 0x521A 0x521B 0x521C 0x521D 0x521E 0x5220 0x5221 0x5223 0x5224 +0x5225 0x5227 0x5228 0x5229 0x522A 0x522B 0x522C 0x522D 0x522E 0x5230 0x5231 0x5232 0x5233 0x5235 0x5236 0x5237 +0x5238 0x5239 0x523A 0x523B 0x523D 0x523F 0x5240 0x5241 0x5242 0x5243 0x5244 0x5245 0x5246 0x5247 0x5249 0x524A +0x524B 0x524C 0x524D 0x524E 0x524F 0x5250 0x5251 0x5252 0x5254 0x5255 0x5256 0x5257 0x525A 0x525B 0x525C 0x525D +0x525E 0x525F 0x5261 0x5262 0x5263 0x5264 0x5265 0x5267 0x5269 0x526A 0x526B 0x526C 0x526D 0x526E 0x526F 0x5270 +0x5271 0x5272 0x5273 0x5274 0x5275 0x5277 0x5278 0x527A 0x527B 0x527C 0x527D 0x527E 0x527F 0x5280 0x5281 0x5282 +0x5283 0x5284 0x5287 0x5288 0x5289 0x528A 0x528B 0x528C 0x528D 0x528F 0x5290 0x5291 0x5292 0x5293 0x5294 0x5296 +0x5297 0x5298 0x5299 0x529B 0x529C 0x529D 0x529E 0x529F 0x52A0 0x52A1 0x52A2 0x52A3 0x52A4 0x52A6 0x52A8 0x52A9 +0x52AA 0x52AB 0x52AC 0x52AD 0x52AE 0x52B1 0x52B2 0x52B3 0x52B4 0x52B5 0x52B9 0x52BB 0x52BC 0x52BE 0x52BF 0x52C0 +0x52C1 0x52C2 0x52C3 0x52C5 0x52C7 0x52C9 0x52CB 0x52CD 0x52D0 0x52D2 0x52D3 0x52D4 0x52D5 0x52D6 0x52D7 0x52D8 +0x52D9 0x52DA 0x52DB 0x52DD 0x52DE 0x52DF 0x52E0 0x52E2 0x52E3 0x52E4 0x52E5 0x52E6 0x52E7 0x52E9 0x52EB 0x52EF +0x52F0 0x52F1 0x52F2 0x52F3 0x52F4 0x52F5 0x52F7 0x52F8 0x52F9 0x52FA 0x52FB 0x52FC 0x52FD 0x52FE 0x52FF 0x5300 +0x5301 0x5302 0x5303 0x5304 0x5305 0x5306 0x5308 0x5309 0x530A 0x530B 0x530D 0x530E 0x530F 0x5310 0x5311 0x5312 +0x5315 0x5316 0x5317 0x5318 0x5319 0x531A 0x531B 0x531C 0x531D 0x531E 0x531F 0x5320 0x5321 0x5322 0x5323 0x5326 +0x5327 0x532A 0x532D 0x532E 0x532F 0x5330 0x5331 0x5333 0x5334 0x5337 0x5338 0x5339 0x533A 0x533B 0x533C 0x533D +0x533E 0x533F 0x5340 0x5341 0x5342 0x5343 0x5344 0x5345 0x5346 0x5347 0x5348 0x5349 0x534A 0x534B 0x534C 0x534D +0x534E 0x534F 0x5350 0x5351 0x5352 0x5353 0x5354 0x5355 0x5356 0x5357 0x5358 0x535A 0x535C 0x535D 0x535E 0x535F +0x5360 0x5361 0x5362 0x5363 0x5364 0x5365 0x5366 0x5367 0x5368 0x5369 0x536A 0x536B 0x536C 0x536D 0x536E 0x536F +0x5370 0x5371 0x5372 0x5373 0x5374 0x5375 0x5377 0x5378 0x5379 0x537A 0x537B 0x537C 0x537D 0x537F 0x5382 0x5383 +0x5384 0x5385 0x5386 0x5389 0x538A 0x538B 0x538C 0x538D 0x538E 0x538F 0x5390 0x5392 0x5393 0x5394 0x5395 0x5396 +0x5397 0x5398 0x5399 0x539A 0x539C 0x539D 0x539E 0x539F 0x53A0 0x53A2 0x53A3 0x53A4 0x53A5 0x53A6 0x53A7 0x53A8 +0x53A9 0x53AC 0x53AD 0x53AE 0x53B0 0x53B2 0x53B3 0x53B4 0x53B6 0x53B7 0x53B9 0x53BB 0x53BE 0x53BF 0x53C1 0x53C2 +0x53C3 0x53C4 0x53C6 0x53C7 0x53C8 0x53C9 0x53CA 0x53CB 0x53CC 0x53CD 0x53CE 0x53D1 0x53D2 0x53D4 0x53D5 0x53D6 +0x53D7 0x53D8 0x53D9 0x53DA 0x53DB 0x53DF 0x53E0 0x53E1 0x53E2 0x53E3 0x53E4 0x53E5 0x53E6 0x53E8 0x53E9 0x53EA +0x53EB 0x53EC 0x53ED 0x53EE 0x53EF 0x53F0 0x53F1 0x53F2 0x53F3 0x53F5 0x53F6 0x53F7 0x53F8 0x53F9 0x53FA 0x53FB +0x53FC 0x53FD 0x53FE 0x5401 0x5403 0x5404 0x5406 0x5407 0x5408 0x5409 0x540A 0x540B 0x540C 0x540D 0x540E 0x540F +0x5410 0x5411 0x5412 0x5413 0x5414 0x5415 0x5416 0x5417 0x5418 0x5419 0x541B 0x541C 0x541D 0x541E 0x541F 0x5420 +0x5421 0x5423 0x5424 0x5425 0x5426 0x5427 0x5428 0x5429 0x542A 0x542B 0x542C 0x542D 0x542E 0x542F 0x5430 0x5431 +0x5432 0x5433 0x5434 0x5435 0x5436 0x5437 0x5438 0x5439 0x543B 0x543C 0x543D 0x543E 0x543F 0x5440 0x5441 0x5442 +0x5443 0x5445 0x5446 0x5447 0x5448 0x5449 0x544A 0x544B 0x544E 0x544F 0x5450 0x5451 0x5452 0x5453 0x5454 0x5455 +0x5456 0x5457 0x5458 0x5459 0x545B 0x545C 0x545D 0x545F 0x5460 0x5461 0x5462 0x5463 0x5464 0x5465 0x5466 0x5467 +0x5468 0x546A 0x546B 0x546C 0x546F 0x5470 0x5471 0x5472 0x5473 0x5474 0x5475 0x5476 0x5477 0x5478 0x547A 0x547B +0x547C 0x547D 0x547E 0x547F 0x5480 0x5481 0x5482 0x5484 0x5486 0x5487 0x5488 0x5489 0x548B 0x548C 0x548D 0x548E +0x548F 0x5490 0x5491 0x5492 0x5493 0x5494 0x5495 0x5496 0x5497 0x5498 0x5499 0x549A 0x549B 0x549D 0x54A0 0x54A1 +0x54A2 0x54A3 0x54A4 0x54A5 0x54A6 0x54A7 0x54A8 0x54A9 0x54AA 0x54AB 0x54AC 0x54AD 0x54AE 0x54AF 0x54B0 0x54B1 +0x54B2 0x54B3 0x54B4 0x54B5 0x54B6 0x54B7 0x54B8 0x54B9 0x54BA 0x54BB 0x54BC 0x54BD 0x54BE 0x54BF 0x54C0 0x54C1 +0x54C2 0x54C3 0x54C4 0x54C5 0x54C6 0x54C7 0x54C8 0x54C9 0x54CA 0x54CB 0x54CC 0x54CD 0x54CE 0x54CF 0x54D0 0x54D1 +0x54D2 0x54D3 0x54D4 0x54D5 0x54D6 0x54D7 0x54D8 0x54D9 0x54DA 0x54DC 0x54DD 0x54DE 0x54DF 0x54E0 0x54E1 0x54E2 +0x54E4 0x54E5 0x54E6 0x54E7 0x54E8 0x54E9 0x54EA 0x54EB 0x54ED 0x54EE 0x54F1 0x54F2 0x54F3 0x54F7 0x54F8 0x54FA +0x54FB 0x54FC 0x54FD 0x54FF 0x5501 0x5503 0x5504 0x5505 0x5506 0x5507 0x5508 0x5509 0x550A 0x550B 0x550C 0x550E +0x550F 0x5510 0x5511 0x5512 0x5513 0x5514 0x5516 0x5517 0x551A 0x551B 0x551C 0x551D 0x551E 0x5520 0x5521 0x5522 +0x5523 0x5524 0x5525 0x5526 0x5527 0x552A 0x552C 0x552D 0x552E 0x552F 0x5530 0x5531 0x5532 0x5533 0x5534 0x5535 +0x5536 0x5537 0x5538 0x5539 0x553B 0x553C 0x553E 0x553F 0x5540 0x5541 0x5543 0x5544 0x5545 0x5546 0x5548 0x5549 +0x554A 0x554B 0x554C 0x554D 0x554E 0x554F 0x5550 0x5551 0x5552 0x5553 0x5555 0x5556 0x5557 0x5559 0x555B 0x555C +0x555D 0x555E 0x555F 0x5561 0x5562 0x5563 0x5564 0x5565 0x5566 0x5567 0x5569 0x556A 0x556B 0x556C 0x556D 0x556E +0x556F 0x5570 0x5571 0x5572 0x5574 0x5575 0x5576 0x5577 0x5578 0x5579 0x557B 0x557C 0x557D 0x557E 0x557F 0x5580 +0x5581 0x5582 0x5583 0x5584 0x5586 0x5587 0x5588 0x5589 0x558A 0x558B 0x558C 0x558D 0x558E 0x558F 0x5591 0x5592 +0x5593 0x5594 0x5595 0x5598 0x5599 0x559A 0x559C 0x559D 0x559E 0x559F 0x55A1 0x55A2 0x55A3 0x55A4 0x55A5 0x55A6 +0x55A7 0x55A8 0x55A9 0x55AA 0x55AB 0x55AC 0x55AD 0x55AE 0x55B0 0x55B1 0x55B2 0x55B3 0x55B5 0x55B6 0x55B7 0x55B9 +0x55BA 0x55BB 0x55BC 0x55BD 0x55BE 0x55BF 0x55C0 0x55C2 0x55C3 0x55C4 0x55C5 0x55C6 0x55C7 0x55C8 0x55C9 0x55CA +0x55CB 0x55CC 0x55CD 0x55CE 0x55CF 0x55D0 0x55D1 0x55D2 0x55D3 0x55D4 0x55D5 0x55D6 0x55D7 0x55D9 0x55DA 0x55DB +0x55DC 0x55DD 0x55DE 0x55DF 0x55E1 0x55E2 0x55E3 0x55E4 0x55E5 0x55E6 0x55E7 0x55E8 0x55E9 0x55EA 0x55EB 0x55EC +0x55EE 0x55EF 0x55F0 0x55F1 0x55F2 0x55F3 0x55F5 0x55F6 0x55F7 0x55F9 0x55FA 0x55FB 0x55FC 0x55FD 0x55FE 0x55FF +0x5600 0x5601 0x5602 0x5604 0x5605 0x5606 0x5608 0x5609 0x560C 0x560D 0x560E 0x560F 0x5610 0x5611 0x5612 0x5613 +0x5614 0x5615 0x5616 0x5617 0x5618 0x561A 0x561B 0x561C 0x561D 0x561E 0x561F 0x5621 0x5622 0x5623 0x5624 0x5625 +0x5627 0x5629 0x562A 0x562B 0x562C 0x562D 0x562E 0x562F 0x5630 0x5631 0x5632 0x5633 0x5634 0x5635 0x5636 0x5638 +0x5639 0x563A 0x563B 0x563D 0x563E 0x563F 0x5640 0x5641 0x5642 0x5643 0x5645 0x5646 0x5647 0x5648 0x5649 0x564A +0x564C 0x564D 0x564E 0x564F 0x5650 0x5652 0x5653 0x5654 0x5657 0x5658 0x5659 0x565A 0x565B 0x565C 0x565D 0x565E +0x5660 0x5662 0x5663 0x5664 0x5665 0x5666 0x5668 0x5669 0x566A 0x566B 0x566C 0x566D 0x566E 0x566F 0x5670 0x5671 +0x5672 0x5673 0x5674 0x5676 0x5677 0x5678 0x5679 0x567A 0x567B 0x567C 0x567E 0x567F 0x5680 0x5681 0x5682 0x5683 +0x5684 0x5685 0x5686 0x5687 0x5689 0x568A 0x568C 0x568D 0x568E 0x568F 0x5690 0x5692 0x5693 0x5694 0x5695 0x5697 +0x5698 0x5699 0x569A 0x569B 0x569C 0x569D 0x569F 0x56A0 0x56A1 0x56A2 0x56A3 0x56A4 0x56A5 0x56A6 0x56A7 0x56A8 +0x56AA 0x56AB 0x56AC 0x56AD 0x56AE 0x56AF 0x56B1 0x56B2 0x56B3 0x56B4 0x56B5 0x56B6 0x56B7 0x56B9 0x56BC 0x56BD +0x56BE 0x56BF 0x56C0 0x56C1 0x56C2 0x56C3 0x56C5 0x56C6 0x56C8 0x56C9 0x56CA 0x56CB 0x56CC 0x56CD 0x56CE 0x56D1 +0x56D2 0x56D3 0x56D4 0x56D6 0x56D7 0x56D8 0x56D9 0x56DA 0x56DB 0x56DC 0x56DD 0x56DE 0x56DF 0x56E0 0x56E1 0x56E2 +0x56E3 0x56E4 0x56E5 0x56E6 0x56E7 0x56E8 0x56E9 0x56EA 0x56EB 0x56EC 0x56ED 0x56EE 0x56EF 0x56F0 0x56F1 0x56F2 +0x56F3 0x56F4 0x56F5 0x56F6 0x56F7 0x56F8 0x56F9 0x56FA 0x56FB 0x56FC 0x56FD 0x56FE 0x56FF 0x5700 0x5701 0x5702 +0x5703 0x5704 0x5705 0x5706 0x5707 0x5708 0x5709 0x570A 0x570B 0x570C 0x570D 0x570E 0x570F 0x5710 0x5711 0x5712 +0x5713 0x5714 0x5715 0x5716 0x5717 0x5718 0x5719 0x571A 0x571B 0x571C 0x571D 0x571E 0x571F 0x5720 0x5721 0x5722 +0x5723 0x5724 0x5726 0x5727 0x5728 0x5729 0x572A 0x572B 0x572C 0x572D 0x572E 0x572F 0x5730 0x5732 0x5733 0x5734 +0x5737 0x5738 0x5739 0x573A 0x573B 0x573E 0x5740 0x5741 0x5742 0x5745 0x5747 0x5749 0x574A 0x574B 0x574C 0x574D +0x574E 0x574F 0x5750 0x5751 0x5752 0x5754 0x5757 0x575A 0x575B 0x575C 0x575D 0x575E 0x575F 0x5760 0x5761 0x5762 +0x5764 0x5765 0x5766 0x5768 0x5769 0x576A 0x576B 0x576C 0x576D 0x576E 0x576F 0x5770 0x5771 0x5772 0x5773 0x5774 +0x5775 0x5776 0x5777 0x577B 0x577C 0x577D 0x577F 0x5780 0x5782 0x5783 0x5784 0x5785 0x5786 0x5787 0x5788 0x5789 +0x578B 0x578C 0x578D 0x578E 0x578F 0x5792 0x5793 0x5794 0x5795 0x5797 0x5798 0x5799 0x579A 0x579B 0x579D 0x579E +0x579F 0x57A0 0x57A1 0x57A2 0x57A3 0x57A4 0x57A5 0x57A6 0x57A7 0x57A8 0x57A9 0x57AA 0x57AB 0x57AD 0x57AE 0x57AF +0x57B0 0x57B1 0x57B2 0x57B3 0x57B4 0x57B5 0x57B6 0x57B8 0x57B9 0x57BA 0x57BB 0x57BC 0x57BD 0x57BE 0x57BF 0x57C0 +0x57C1 0x57C2 0x57C3 0x57C6 0x57C7 0x57C8 0x57CB 0x57CC 0x57CE 0x57CF 0x57D0 0x57D2 0x57D3 0x57D4 0x57D5 0x57D6 +0x57D7 0x57D8 0x57D9 0x57DA 0x57DC 0x57DD 0x57DE 0x57DF 0x57E0 0x57E1 0x57E2 0x57E3 0x57E4 0x57E5 0x57E7 0x57E8 +0x57E9 0x57EA 0x57EB 0x57EC 0x57ED 0x57EE 0x57EF 0x57F0 0x57F1 0x57F2 0x57F3 0x57F4 0x57F5 0x57F6 0x57F7 0x57F8 +0x57F9 0x57FA 0x57FB 0x57FC 0x57FD 0x5800 0x5801 0x5802 0x5803 0x5804 0x5805 0x5806 0x5807 0x5808 0x5809 0x580A +0x580B 0x580C 0x580D 0x580E 0x5810 0x5811 0x5814 0x5815 0x5816 0x5817 0x5819 0x581B 0x581C 0x581D 0x581E 0x5820 +0x5821 0x5823 0x5824 0x5825 0x5827 0x5828 0x5829 0x582A 0x582C 0x582D 0x582E 0x582F 0x5830 0x5831 0x5832 0x5833 +0x5834 0x5835 0x5836 0x5837 0x5838 0x5839 0x583A 0x583B 0x583C 0x583D 0x583E 0x583F 0x5840 0x5841 0x5842 0x5843 +0x5844 0x5845 0x5846 0x5848 0x5849 0x584A 0x584B 0x584C 0x584D 0x584E 0x584F 0x5851 0x5852 0x5853 0x5854 0x5855 +0x5857 0x5858 0x5859 0x585A 0x585B 0x585D 0x585E 0x5861 0x5862 0x5863 0x5864 0x5865 0x5868 0x5869 0x586B 0x586C +0x586D 0x586E 0x586F 0x5870 0x5871 0x5872 0x5873 0x5874 0x5875 0x5876 0x5878 0x5879 0x587A 0x587B 0x587C 0x587D +0x587E 0x587F 0x5880 0x5881 0x5882 0x5883 0x5884 0x5885 0x5886 0x5887 0x5888 0x5889 0x588A 0x588B 0x588E 0x588F +0x5890 0x5891 0x5892 0x5893 0x5894 0x5895 0x5897 0x5898 0x5899 0x589A 0x589C 0x589D 0x589E 0x589F 0x58A0 0x58A1 +0x58A3 0x58A5 0x58A6 0x58A8 0x58A9 0x58AB 0x58AC 0x58AE 0x58AF 0x58B1 0x58B3 0x58B6 0x58B8 0x58B9 0x58BA 0x58BB +0x58BC 0x58BD 0x58BE 0x58BF 0x58C1 0x58C2 0x58C5 0x58C6 0x58C7 0x58C8 0x58C9 0x58CA 0x58CB 0x58CC 0x58CE 0x58CF +0x58D1 0x58D2 0x58D3 0x58D4 0x58D5 0x58D6 0x58D7 0x58D8 0x58D9 0x58DA 0x58DB 0x58DC 0x58DD 0x58DE 0x58DF 0x58E0 +0x58E2 0x58E3 0x58E4 0x58E5 0x58E7 0x58E8 0x58E9 0x58EA 0x58EB 0x58EC 0x58EE 0x58EF 0x58F0 0x58F1 0x58F2 0x58F3 +0x58F4 0x58F6 0x58F7 0x58F8 0x58F9 0x58FA 0x58FB 0x58FC 0x58FD 0x58FE 0x58FF 0x5902 0x5903 0x5904 0x5906 0x5907 +0x5909 0x590A 0x590B 0x590C 0x590D 0x590E 0x590F 0x5910 0x5912 0x5913 0x5914 0x5915 0x5916 0x5917 0x5918 0x5919 +0x591A 0x591B 0x591C 0x591F 0x5920 0x5922 0x5924 0x5925 0x5927 0x5928 0x5929 0x592A 0x592B 0x592C 0x592D 0x592E +0x592F 0x5930 0x5931 0x5932 0x5933 0x5934 0x5937 0x5938 0x5939 0x593A 0x593C 0x593D 0x593E 0x593F 0x5940 0x5941 +0x5942 0x5944 0x5945 0x5947 0x5948 0x5949 0x594A 0x594B 0x594C 0x594E 0x594F 0x5950 0x5951 0x5953 0x5954 0x5955 +0x5956 0x5957 0x5958 0x595A 0x595C 0x5960 0x5961 0x5962 0x5964 0x5965 0x5967 0x5968 0x5969 0x596A 0x596B 0x596C +0x596D 0x596E 0x5970 0x5971 0x5972 0x5973 0x5974 0x5976 0x5977 0x5978 0x5979 0x597B 0x597C 0x597D 0x597E 0x597F +0x5980 0x5981 0x5982 0x5983 0x5984 0x5985 0x5986 0x5987 0x5988 0x5989 0x598A 0x598D 0x598E 0x598F 0x5990 0x5992 +0x5993 0x5996 0x5997 0x5998 0x5999 0x599B 0x599D 0x599E 0x59A0 0x59A1 0x59A2 0x59A3 0x59A4 0x59A5 0x59A6 0x59A7 +0x59A8 0x59A9 0x59AA 0x59AB 0x59AC 0x59AD 0x59AE 0x59AF 0x59B1 0x59B2 0x59B3 0x59B4 0x59B5 0x59B6 0x59B8 0x59B9 +0x59BA 0x59BB 0x59BC 0x59BD 0x59BE 0x59C0 0x59C1 0x59C3 0x59C5 0x59C6 0x59C7 0x59C8 0x59C9 0x59CA 0x59CB 0x59CC +0x59CD 0x59CE 0x59CF 0x59D0 0x59D1 0x59D2 0x59D3 0x59D4 0x59D6 0x59D7 0x59D8 0x59D9 0x59DA 0x59DB 0x59DC 0x59DD +0x59DE 0x59E0 0x59E1 0x59E3 0x59E4 0x59E5 0x59E6 0x59E8 0x59E9 0x59EA 0x59EB 0x59EC 0x59ED 0x59EE 0x59F1 0x59F2 +0x59F3 0x59F4 0x59F5 0x59F6 0x59F7 0x59F8 0x59F9 0x59FA 0x59FB 0x59FC 0x59FD 0x59FE 0x59FF 0x5A00 0x5A01 0x5A03 +0x5A04 0x5A05 0x5A06 0x5A07 0x5A08 0x5A09 0x5A0A 0x5A0C 0x5A0D 0x5A0F 0x5A11 0x5A12 0x5A13 0x5A15 0x5A16 0x5A17 +0x5A18 0x5A19 0x5A1A 0x5A1B 0x5A1C 0x5A1E 0x5A1F 0x5A20 0x5A23 0x5A25 0x5A29 0x5A2B 0x5A2D 0x5A2E 0x5A2F 0x5A31 +0x5A32 0x5A33 0x5A34 0x5A35 0x5A36 0x5A37 0x5A38 0x5A39 0x5A3C 0x5A3E 0x5A3F 0x5A40 0x5A41 0x5A42 0x5A43 0x5A44 +0x5A46 0x5A47 0x5A48 0x5A49 0x5A4A 0x5A4B 0x5A4C 0x5A4D 0x5A50 0x5A51 0x5A52 0x5A53 0x5A55 0x5A56 0x5A57 0x5A58 +0x5A5A 0x5A5B 0x5A5C 0x5A5D 0x5A5E 0x5A5F 0x5A60 0x5A62 0x5A64 0x5A65 0x5A66 0x5A67 0x5A69 0x5A6A 0x5A6B 0x5A6C +0x5A6D 0x5A70 0x5A73 0x5A74 0x5A75 0x5A76 0x5A77 0x5A78 0x5A7A 0x5A7B 0x5A7C 0x5A7D 0x5A7F 0x5A82 0x5A83 0x5A84 +0x5A86 0x5A8A 0x5A8B 0x5A8C 0x5A8E 0x5A8F 0x5A90 0x5A92 0x5A93 0x5A94 0x5A95 0x5A96 0x5A97 0x5A9A 0x5A9B 0x5A9C +0x5A9D 0x5A9E 0x5A9F 0x5AA0 0x5AA2 0x5AA4 0x5AA5 0x5AA6 0x5AA7 0x5AA9 0x5AAA 0x5AAC 0x5AAD 0x5AAE 0x5AAF 0x5AB0 +0x5AB1 0x5AB2 0x5AB3 0x5AB4 0x5AB5 0x5AB6 0x5AB7 0x5AB8 0x5AB9 0x5ABA 0x5ABB 0x5ABC 0x5ABD 0x5ABE 0x5ABF 0x5AC0 +0x5AC1 0x5AC2 0x5AC4 0x5AC6 0x5AC7 0x5AC8 0x5AC9 0x5ACA 0x5ACB 0x5ACC 0x5ACD 0x5ACF 0x5AD0 0x5AD2 0x5AD4 0x5AD5 +0x5AD6 0x5AD7 0x5AD8 0x5AD9 0x5ADA 0x5ADB 0x5ADC 0x5ADD 0x5ADE 0x5ADF 0x5AE0 0x5AE1 0x5AE2 0x5AE3 0x5AE4 0x5AE5 +0x5AE6 0x5AE8 0x5AE9 0x5AEA 0x5AEB 0x5AEC 0x5AED 0x5AEE 0x5AF1 0x5AF2 0x5AF3 0x5AF4 0x5AF5 0x5AF6 0x5AF7 0x5AF8 +0x5AF9 0x5AFA 0x5AFB 0x5AFD 0x5AFF 0x5B00 0x5B01 0x5B02 0x5B03 0x5B05 0x5B07 0x5B08 0x5B09 0x5B0B 0x5B0C 0x5B0F +0x5B10 0x5B13 0x5B14 0x5B16 0x5B17 0x5B19 0x5B1A 0x5B1B 0x5B1D 0x5B1E 0x5B20 0x5B21 0x5B22 0x5B23 0x5B24 0x5B25 +0x5B26 0x5B27 0x5B28 0x5B2A 0x5B2C 0x5B2D 0x5B2E 0x5B2F 0x5B30 0x5B32 0x5B34 0x5B36 0x5B37 0x5B38 0x5B3C 0x5B3D +0x5B3E 0x5B3F 0x5B40 0x5B43 0x5B45 0x5B47 0x5B48 0x5B4B 0x5B4C 0x5B4D 0x5B4E 0x5B50 0x5B51 0x5B52 0x5B53 0x5B54 +0x5B55 0x5B56 0x5B57 0x5B58 0x5B59 0x5B5A 0x5B5B 0x5B5C 0x5B5D 0x5B5E 0x5B5F 0x5B62 0x5B63 0x5B64 0x5B65 0x5B66 +0x5B69 0x5B6A 0x5B6B 0x5B6C 0x5B6D 0x5B6E 0x5B70 0x5B71 0x5B72 0x5B73 0x5B75 0x5B77 0x5B78 0x5B7A 0x5B7B 0x5B7C +0x5B7D 0x5B7F 0x5B80 0x5B81 0x5B82 0x5B83 0x5B84 0x5B85 0x5B87 0x5B88 0x5B89 0x5B8B 0x5B8C 0x5B8D 0x5B8E 0x5B8F +0x5B90 0x5B92 0x5B93 0x5B95 0x5B96 0x5B97 0x5B98 0x5B99 0x5B9A 0x5B9B 0x5B9C 0x5B9D 0x5B9E 0x5B9F 0x5BA0 0x5BA1 +0x5BA2 0x5BA3 0x5BA4 0x5BA5 0x5BA6 0x5BA7 0x5BA8 0x5BAA 0x5BAB 0x5BAC 0x5BAD 0x5BAE 0x5BB0 0x5BB3 0x5BB4 0x5BB5 +0x5BB6 0x5BB8 0x5BB9 0x5BBD 0x5BBE 0x5BBF 0x5BC0 0x5BC1 0x5BC2 0x5BC3 0x5BC4 0x5BC5 0x5BC6 0x5BC7 0x5BC9 0x5BCA +0x5BCB 0x5BCC 0x5BCD 0x5BCE 0x5BD0 0x5BD1 0x5BD2 0x5BD3 0x5BD4 0x5BD6 0x5BD7 0x5BD8 0x5BD9 0x5BDB 0x5BDD 0x5BDE +0x5BDF 0x5BE0 0x5BE1 0x5BE2 0x5BE3 0x5BE4 0x5BE5 0x5BE6 0x5BE7 0x5BE8 0x5BE9 0x5BEA 0x5BEB 0x5BEC 0x5BEE 0x5BEF +0x5BF0 0x5BF1 0x5BF2 0x5BF3 0x5BF5 0x5BF6 0x5BF8 0x5BF9 0x5BFA 0x5BFB 0x5BFC 0x5BFE 0x5BFF 0x5C01 0x5C02 0x5C03 +0x5C04 0x5C05 0x5C06 0x5C07 0x5C08 0x5C09 0x5C0A 0x5C0B 0x5C0C 0x5C0D 0x5C0E 0x5C0F 0x5C10 0x5C11 0x5C12 0x5C13 +0x5C14 0x5C15 0x5C16 0x5C17 0x5C18 0x5C19 0x5C1A 0x5C1B 0x5C1C 0x5C1D 0x5C1F 0x5C20 0x5C22 0x5C23 0x5C24 0x5C25 +0x5C27 0x5C28 0x5C2A 0x5C2C 0x5C2D 0x5C30 0x5C31 0x5C33 0x5C34 0x5C35 0x5C36 0x5C37 0x5C38 0x5C39 0x5C3A 0x5C3B +0x5C3C 0x5C3D 0x5C3E 0x5C3F 0x5C40 0x5C41 0x5C42 0x5C43 0x5C44 0x5C45 0x5C46 0x5C47 0x5C48 0x5C49 0x5C4A 0x5C4B +0x5C4C 0x5C4D 0x5C4E 0x5C4F 0x5C50 0x5C51 0x5C53 0x5C54 0x5C55 0x5C56 0x5C58 0x5C59 0x5C5B 0x5C5C 0x5C5D 0x5C5E +0x5C60 0x5C61 0x5C62 0x5C63 0x5C64 0x5C65 0x5C66 0x5C67 0x5C68 0x5C69 0x5C6A 0x5C6C 0x5C6D 0x5C6E 0x5C6F 0x5C70 +0x5C71 0x5C72 0x5C73 0x5C74 0x5C75 0x5C76 0x5C79 0x5C7A 0x5C7B 0x5C7C 0x5C7E 0x5C7F 0x5C81 0x5C82 0x5C83 0x5C86 +0x5C88 0x5C89 0x5C8A 0x5C8B 0x5C8C 0x5C8D 0x5C8F 0x5C90 0x5C91 0x5C92 0x5C93 0x5C94 0x5C95 0x5C96 0x5C97 0x5C98 +0x5C99 0x5C9A 0x5C9B 0x5C9C 0x5C9D 0x5C9E 0x5C9F 0x5CA0 0x5CA1 0x5CA2 0x5CA3 0x5CA4 0x5CA5 0x5CA6 0x5CA7 0x5CA8 +0x5CA9 0x5CAA 0x5CAB 0x5CAC 0x5CAD 0x5CAE 0x5CAF 0x5CB0 0x5CB1 0x5CB3 0x5CB5 0x5CB6 0x5CB7 0x5CB8 0x5CBA 0x5CBB +0x5CBC 0x5CBD 0x5CBE 0x5CBF 0x5CC0 0x5CC1 0x5CC2 0x5CC3 0x5CC4 0x5CC5 0x5CC6 0x5CC7 0x5CC8 0x5CC9 0x5CCA 0x5CCB +0x5CCC 0x5CCE 0x5CCF 0x5CD0 0x5CD2 0x5CD3 0x5CD4 0x5CD6 0x5CD7 0x5CD8 0x5CD9 0x5CDA 0x5CDB 0x5CDE 0x5CDF 0x5CE0 +0x5CE1 0x5CE3 0x5CE4 0x5CE5 0x5CE6 0x5CE7 0x5CE8 0x5CE9 0x5CEA 0x5CEC 0x5CED 0x5CEE 0x5CEF 0x5CF0 0x5CF1 0x5CF4 +0x5CF6 0x5CF7 0x5CF8 0x5CF9 0x5CFA 0x5CFB 0x5CFD 0x5CFF 0x5D00 0x5D01 0x5D02 0x5D03 0x5D04 0x5D05 0x5D06 0x5D07 +0x5D0B 0x5D0C 0x5D0D 0x5D0E 0x5D0F 0x5D10 0x5D11 0x5D12 0x5D14 0x5D15 0x5D16 0x5D17 0x5D18 0x5D19 0x5D1A 0x5D1B +0x5D1D 0x5D1E 0x5D1F 0x5D20 0x5D21 0x5D22 0x5D23 0x5D24 0x5D25 0x5D26 0x5D27 0x5D28 0x5D29 0x5D2C 0x5D2D 0x5D2E +0x5D30 0x5D31 0x5D32 0x5D33 0x5D34 0x5D35 0x5D36 0x5D37 0x5D38 0x5D39 0x5D3A 0x5D3C 0x5D3D 0x5D3E 0x5D3F 0x5D40 +0x5D41 0x5D42 0x5D43 0x5D44 0x5D45 0x5D47 0x5D49 0x5D4A 0x5D4B 0x5D4C 0x5D4E 0x5D50 0x5D51 0x5D52 0x5D55 0x5D56 +0x5D58 0x5D59 0x5D5A 0x5D5B 0x5D5C 0x5D5D 0x5D5E 0x5D62 0x5D63 0x5D65 0x5D67 0x5D68 0x5D69 0x5D6B 0x5D6C 0x5D6F +0x5D71 0x5D72 0x5D73 0x5D74 0x5D76 0x5D77 0x5D79 0x5D7A 0x5D7C 0x5D7D 0x5D7E 0x5D7F 0x5D80 0x5D81 0x5D82 0x5D84 +0x5D85 0x5D86 0x5D87 0x5D88 0x5D89 0x5D8A 0x5D8B 0x5D8C 0x5D8D 0x5D90 0x5D92 0x5D93 0x5D94 0x5D95 0x5D97 0x5D99 +0x5D9A 0x5D9C 0x5D9D 0x5D9E 0x5D9F 0x5DA0 0x5DA1 0x5DA2 0x5DA6 0x5DA7 0x5DA8 0x5DA9 0x5DAA 0x5DAC 0x5DAD 0x5DAE +0x5DAF 0x5DB0 0x5DB1 0x5DB2 0x5DB4 0x5DB5 0x5DB7 0x5DB8 0x5DBA 0x5DBC 0x5DBD 0x5DC0 0x5DC2 0x5DC3 0x5DC5 0x5DC6 +0x5DC7 0x5DC9 0x5DCB 0x5DCC 0x5DCD 0x5DCF 0x5DD1 0x5DD2 0x5DD3 0x5DD4 0x5DD5 0x5DD6 0x5DD8 0x5DDB 0x5DDD 0x5DDE +0x5DDF 0x5DE0 0x5DE1 0x5DE2 0x5DE3 0x5DE4 0x5DE5 0x5DE6 0x5DE7 0x5DE8 0x5DE9 0x5DEA 0x5DEB 0x5DED 0x5DEE 0x5DEF +0x5DF0 0x5DF1 0x5DF2 0x5DF3 0x5DF4 0x5DF5 0x5DF7 0x5DF8 0x5DF9 0x5DFB 0x5DFD 0x5DFE 0x5DFF 0x5E00 0x5E01 0x5E02 +0x5E03 0x5E04 0x5E05 0x5E06 0x5E08 0x5E0A 0x5E0B 0x5E0C 0x5E0E 0x5E0F 0x5E10 0x5E11 0x5E14 0x5E15 0x5E16 0x5E17 +0x5E18 0x5E19 0x5E1A 0x5E1B 0x5E1C 0x5E1D 0x5E1F 0x5E20 0x5E21 0x5E22 0x5E23 0x5E24 0x5E25 0x5E26 0x5E27 0x5E28 +0x5E29 0x5E2B 0x5E2D 0x5E2E 0x5E2F 0x5E30 0x5E31 0x5E33 0x5E34 0x5E35 0x5E36 0x5E37 0x5E38 0x5E3B 0x5E3C 0x5E3D +0x5E3E 0x5E3F 0x5E40 0x5E41 0x5E42 0x5E43 0x5E44 0x5E45 0x5E47 0x5E48 0x5E4A 0x5E4B 0x5E4C 0x5E4D 0x5E4E 0x5E4F +0x5E53 0x5E54 0x5E55 0x5E56 0x5E57 0x5E58 0x5E59 0x5E5B 0x5E5C 0x5E5D 0x5E5E 0x5E5F 0x5E60 0x5E61 0x5E62 0x5E63 +0x5E64 0x5E66 0x5E67 0x5E68 0x5E69 0x5E6A 0x5E6B 0x5E6C 0x5E6D 0x5E6E 0x5E6F 0x5E70 0x5E72 0x5E73 0x5E74 0x5E75 +0x5E76 0x5E77 0x5E78 0x5E79 0x5E7A 0x5E7B 0x5E7C 0x5E7D 0x5E7E 0x5E7F 0x5E80 0x5E81 0x5E82 0x5E83 0x5E84 0x5E85 +0x5E86 0x5E87 0x5E88 0x5E89 0x5E8A 0x5E8B 0x5E8C 0x5E8D 0x5E8F 0x5E90 0x5E91 0x5E93 0x5E94 0x5E95 0x5E96 0x5E97 +0x5E99 0x5E9A 0x5E9B 0x5E9C 0x5E9D 0x5E9E 0x5E9F 0x5EA0 0x5EA2 0x5EA3 0x5EA4 0x5EA5 0x5EA6 0x5EA7 0x5EA8 0x5EAA +0x5EAB 0x5EAC 0x5EAD 0x5EAE 0x5EB0 0x5EB1 0x5EB2 0x5EB3 0x5EB4 0x5EB5 0x5EB6 0x5EB7 0x5EB8 0x5EB9 0x5EBC 0x5EBE +0x5EC1 0x5EC2 0x5EC3 0x5EC4 0x5EC5 0x5EC6 0x5EC7 0x5EC8 0x5EC9 0x5ECA 0x5ECB 0x5ECC 0x5ECD 0x5ECE 0x5ECF 0x5ED0 +0x5ED1 0x5ED2 0x5ED3 0x5ED4 0x5ED5 0x5ED6 0x5ED7 0x5ED8 0x5ED9 0x5EDA 0x5EDB 0x5EDC 0x5EDD 0x5EDE 0x5EDF 0x5EE0 +0x5EE1 0x5EE2 0x5EE3 0x5EE5 0x5EE6 0x5EE7 0x5EE8 0x5EE9 0x5EEA 0x5EEC 0x5EEE 0x5EEF 0x5EF0 0x5EF1 0x5EF2 0x5EF3 +0x5EF4 0x5EF6 0x5EF7 0x5EF8 0x5EFA 0x5EFB 0x5EFC 0x5EFE 0x5EFF 0x5F00 0x5F01 0x5F02 0x5F03 0x5F04 0x5F05 0x5F06 +0x5F07 0x5F08 0x5F09 0x5F0A 0x5F0B 0x5F0C 0x5F0D 0x5F0E 0x5F0F 0x5F10 0x5F11 0x5F12 0x5F13 0x5F14 0x5F15 0x5F16 +0x5F17 0x5F18 0x5F1A 0x5F1B 0x5F1C 0x5F1D 0x5F1F 0x5F20 0x5F22 0x5F23 0x5F24 0x5F25 0x5F26 0x5F27 0x5F28 0x5F29 +0x5F2A 0x5F2D 0x5F2E 0x5F2F 0x5F30 0x5F31 0x5F33 0x5F34 0x5F35 0x5F36 0x5F37 0x5F38 0x5F39 0x5F3A 0x5F3C 0x5F3E +0x5F40 0x5F41 0x5F43 0x5F44 0x5F45 0x5F46 0x5F48 0x5F49 0x5F4A 0x5F4B 0x5F4C 0x5F4E 0x5F4F 0x5F50 0x5F51 0x5F52 +0x5F53 0x5F54 0x5F55 0x5F56 0x5F57 0x5F58 0x5F59 0x5F5B 0x5F5C 0x5F5D 0x5F5E 0x5F5F 0x5F60 0x5F61 0x5F62 0x5F63 +0x5F64 0x5F65 0x5F66 0x5F67 0x5F68 0x5F69 0x5F6A 0x5F6B 0x5F6C 0x5F6D 0x5F6E 0x5F6F 0x5F70 0x5F71 0x5F72 0x5F73 +0x5F74 0x5F76 0x5F77 0x5F78 0x5F79 0x5F7B 0x5F7C 0x5F7D 0x5F7E 0x5F7F 0x5F80 0x5F81 0x5F82 0x5F83 0x5F84 0x5F85 +0x5F86 0x5F87 0x5F88 0x5F89 0x5F8A 0x5F8B 0x5F8C 0x5F90 0x5F91 0x5F92 0x5F93 0x5F95 0x5F96 0x5F97 0x5F98 0x5F99 +0x5F9B 0x5F9C 0x5F9E 0x5F9F 0x5FA0 0x5FA1 0x5FA5 0x5FA6 0x5FA7 0x5FA8 0x5FA9 0x5FAA 0x5FAB 0x5FAC 0x5FAD 0x5FAE +0x5FAF 0x5FB3 0x5FB4 0x5FB5 0x5FB7 0x5FB9 0x5FBC 0x5FBD 0x5FC3 0x5FC4 0x5FC5 0x5FC6 0x5FC9 0x5FCC 0x5FCD 0x5FCF +0x5FD0 0x5FD1 0x5FD2 0x5FD3 0x5FD6 0x5FD7 0x5FD8 0x5FD9 0x5FDC 0x5FDD 0x5FDE 0x5FDF 0x5FE0 0x5FE1 0x5FE3 0x5FE4 +0x5FE7 0x5FE8 0x5FEA 0x5FEB 0x5FED 0x5FEE 0x5FF0 0x5FF1 0x5FF3 0x5FF5 0x5FF8 0x5FFA 0x5FFB 0x5FFC 0x5FFD 0x5FFE +0x5FFF 0x6000 0x6001 0x6002 0x6003 0x6004 0x6005 0x6006 0x600A 0x600D 0x600E 0x600F 0x6010 0x6012 0x6014 0x6015 +0x6016 0x6017 0x6019 0x601B 0x601C 0x601D 0x6020 0x6021 0x6025 0x6026 0x6027 0x6028 0x6029 0x602A 0x602B 0x602F +0x6031 0x6033 0x6035 0x6039 0x603A 0x603B 0x603C 0x603F 0x6041 0x6042 0x6043 0x6046 0x6047 0x604A 0x604B 0x604D +0x604F 0x6050 0x6052 0x6053 0x6054 0x6055 0x6059 0x605A 0x605D 0x605F 0x6060 0x6062 0x6063 0x6064 0x6065 0x6067 +0x6068 0x6069 0x606A 0x606B 0x606C 0x606D 0x606F 0x6070 0x6073 0x6075 0x6076 0x6077 0x6078 0x6079 0x607A 0x607B +0x607C 0x607D 0x607F 0x6081 0x6083 0x6084 0x6085 0x6086 0x6088 0x6089 0x608B 0x608C 0x608D 0x6092 0x6094 0x6095 +0x6096 0x6097 0x609A 0x609B 0x609D 0x609E 0x609F 0x60A0 0x60A2 0x60A3 0x60A4 0x60A6 0x60A7 0x60A8 0x60A9 0x60AA +0x60AB 0x60AC 0x60AD 0x60AE 0x60AF 0x60B0 0x60B1 0x60B2 0x60B3 0x60B4 0x60B5 0x60B6 0x60B8 0x60BB 0x60BC 0x60BD +0x60BE 0x60C5 0x60C6 0x60C7 0x60CA 0x60CB 0x60CE 0x60D1 0x60D3 0x60D4 0x60D5 0x60D7 0x60D8 0x60D9 0x60DA 0x60DB +0x60DC 0x60DD 0x60DF 0x60E0 0x60E1 0x60E2 0x60E3 0x60E6 0x60E7 0x60E8 0x60E9 0x60EB 0x60EC 0x60ED 0x60EE 0x60EF +0x60F0 0x60F1 0x60F2 0x60F3 0x60F4 0x60F6 0x60F7 0x60F9 0x60FA 0x60FB 0x60FC 0x6100 0x6101 0x6103 0x6106 0x6108 +0x6109 0x610A 0x610D 0x610E 0x610F 0x6110 0x6112 0x6113 0x6114 0x6115 0x6116 0x611A 0x611B 0x611C 0x611F 0x6120 +0x6121 0x6123 0x6124 0x6126 0x6127 0x6128 0x612B 0x612C 0x612D 0x6130 0x6134 0x6137 0x613C 0x613D 0x613E 0x613F +0x6142 0x6144 0x6146 0x6147 0x6148 0x614A 0x614B 0x614C 0x614D 0x614E 0x6151 0x6153 0x6155 0x6158 0x6159 0x615A +0x615C 0x615D 0x615F 0x6160 0x6162 0x6163 0x6164 0x6165 0x6167 0x6168 0x616A 0x616B 0x616C 0x616D 0x616E 0x616F +0x6170 0x6171 0x6173 0x6174 0x6175 0x6176 0x6177 0x617C 0x617D 0x617E 0x6181 0x6182 0x6183 0x6187 0x618A 0x618B +0x618D 0x618E 0x618F 0x6190 0x6191 0x6192 0x6193 0x6194 0x6195 0x6196 0x6198 0x6199 0x619A 0x619D 0x61A4 0x61A7 +0x61A8 0x61A9 0x61AB 0x61AC 0x61AD 0x61AE 0x61AF 0x61B1 0x61B2 0x61B6 0x61B7 0x61B9 0x61BA 0x61BE 0x61C1 0x61C2 +0x61C3 0x61C6 0x61C7 0x61C8 0x61C9 0x61CA 0x61CB 0x61CC 0x61CD 0x61D0 0x61D1 0x61D2 0x61D4 0x61DE 0x61DF 0x61E3 +0x61E6 0x61E8 0x61F2 0x61F4 0x61F5 0x61F6 0x61F7 0x61F8 0x61FA 0x61FC 0x61FD 0x61FE 0x61FF 0x6200 0x6206 0x6207 +0x6208 0x6209 0x620A 0x620B 0x620C 0x620D 0x620E 0x620F 0x6210 0x6211 0x6212 0x6213 0x6214 0x6215 0x6216 0x6217 +0x6218 0x6219 0x621A 0x621B 0x621D 0x621E 0x621F 0x6221 0x6222 0x6223 0x6224 0x6225 0x6226 0x6227 0x6229 0x622A +0x622C 0x622D 0x622E 0x622F 0x6230 0x6231 0x6232 0x6233 0x6234 0x6236 0x6237 0x6238 0x623A 0x623B 0x623D 0x623E +0x623F 0x6240 0x6241 0x6242 0x6243 0x6245 0x6246 0x6247 0x6248 0x6249 0x624A 0x624B 0x624C 0x624D 0x624E 0x6250 +0x6251 0x6252 0x6253 0x6254 0x6255 0x6258 0x6259 0x625A 0x625B 0x625E 0x6260 0x6261 0x6263 0x6264 0x6265 0x6266 +0x6267 0x6268 0x6269 0x626A 0x626B 0x626C 0x626D 0x626E 0x626F 0x6270 0x6271 0x6273 0x6276 0x6279 0x627A 0x627C +0x627D 0x627E 0x627F 0x6280 0x6282 0x6283 0x6284 0x6286 0x6288 0x6289 0x628A 0x628C 0x628F 0x6291 0x6292 0x6293 +0x6294 0x6295 0x6296 0x6297 0x6298 0x629A 0x629B 0x629C 0x629E 0x629F 0x62A0 0x62A1 0x62A2 0x62A4 0x62A5 0x62A6 +0x62A8 0x62AB 0x62AC 0x62AE 0x62B1 0x62B5 0x62B6 0x62B9 0x62BA 0x62BB 0x62BC 0x62BD 0x62BF 0x62C2 0x62C3 0x62C4 +0x62C5 0x62C6 0x62C7 0x62C8 0x62C9 0x62CA 0x62CB 0x62CC 0x62CD 0x62CE 0x62CF 0x62D0 0x62D1 0x62D2 0x62D3 0x62D4 +0x62D6 0x62D7 0x62D8 0x62D9 0x62DA 0x62DB 0x62DC 0x62DD 0x62DF 0x62E0 0x62E1 0x62E2 0x62E3 0x62E4 0x62E5 0x62E6 +0x62E7 0x62E8 0x62E9 0x62EC 0x62ED 0x62EE 0x62EF 0x62F1 0x62F3 0x62F4 0x62F5 0x62F6 0x62F7 0x62FC 0x62FD 0x62FE +0x62FF 0x6301 0x6302 0x6307 0x6308 0x6309 0x630C 0x630E 0x6311 0x6313 0x6316 0x6319 0x631A 0x631B 0x631C 0x631D +0x631E 0x631F 0x6320 0x6321 0x6322 0x6323 0x6324 0x6325 0x6326 0x6327 0x6328 0x632A 0x632B 0x632F 0x6332 0x6335 +0x6339 0x633A 0x633B 0x633C 0x633D 0x633E 0x633F 0x6342 0x6343 0x6345 0x6346 0x6349 0x634B 0x634C 0x634D 0x634E +0x634F 0x6350 0x6355 0x6357 0x6358 0x635C 0x635E 0x635F 0x6361 0x6362 0x6363 0x6367 0x6368 0x6369 0x636B 0x636D +0x636E 0x636F 0x6371 0x6372 0x6376 0x6377 0x637A 0x637B 0x637D 0x637F 0x6380 0x6382 0x6383 0x6384 0x6387 0x6388 +0x6389 0x638A 0x638C 0x638E 0x638F 0x6390 0x6392 0x6396 0x6397 0x6398 0x6399 0x639B 0x639E 0x639F 0x63A0 0x63A1 +0x63A2 0x63A3 0x63A5 0x63A7 0x63A8 0x63A9 0x63AA 0x63AB 0x63AC 0x63AD 0x63AE 0x63AF 0x63B0 0x63B1 0x63B2 0x63B3 +0x63B4 0x63B5 0x63B7 0x63B8 0x63B9 0x63BA 0x63BB 0x63BC 0x63BE 0x63C0 0x63C3 0x63C4 0x63C5 0x63C6 0x63C8 0x63C9 +0x63CC 0x63CD 0x63CE 0x63CF 0x63D0 0x63D2 0x63D5 0x63D6 0x63DA 0x63DB 0x63DE 0x63E0 0x63E1 0x63E2 0x63E3 0x63E4 +0x63E6 0x63E9 0x63EA 0x63EC 0x63ED 0x63EE 0x63F2 0x63F3 0x63F4 0x63F6 0x63F7 0x63F8 0x63F9 0x63FA 0x63FB 0x63FC +0x63FD 0x63FE 0x63FF 0x6400 0x6401 0x6402 0x6405 0x6406 0x6407 0x640A 0x640B 0x640C 0x640D 0x640F 0x6410 0x6412 +0x6413 0x6414 0x6415 0x6416 0x6417 0x6419 0x641B 0x641C 0x641D 0x641E 0x6420 0x6421 0x6422 0x6423 0x6425 0x6426 +0x6427 0x6428 0x642A 0x642C 0x642D 0x6430 0x6432 0x6434 0x6435 0x6436 0x643A 0x643D 0x643E 0x643F 0x6440 0x6441 +0x6442 0x6443 0x6444 0x6445 0x6446 0x6447 0x6448 0x644A 0x644B 0x644E 0x644F 0x6451 0x6452 0x6454 0x6458 0x6459 +0x645B 0x645C 0x645E 0x645F 0x6460 0x6467 0x6469 0x646D 0x646F 0x6470 0x6471 0x6473 0x6474 0x6475 0x6476 0x6477 +0x6478 0x6479 0x647A 0x647B 0x647D 0x6482 0x6483 0x6484 0x6485 0x6487 0x6488 0x648D 0x648F 0x6490 0x6491 0x6492 +0x6493 0x6495 0x6496 0x6498 0x6499 0x649A 0x649D 0x649E 0x649F 0x64A2 0x64A3 0x64A4 0x64A5 0x64A9 0x64AB 0x64AC +0x64AD 0x64AE 0x64B0 0x64B2 0x64B3 0x64B4 0x64B5 0x64B7 0x64B8 0x64B9 0x64BA 0x64BB 0x64BC 0x64BE 0x64BF 0x64C0 +0x64C1 0x64C2 0x64C4 0x64C5 0x64C7 0x64CA 0x64CB 0x64CD 0x64CE 0x64D0 0x64D2 0x64D3 0x64D4 0x64D6 0x64D7 0x64D8 +0x64DA 0x64DD 0x64DE 0x64E0 0x64E1 0x64E2 0x64E3 0x64E4 0x64E5 0x64E6 0x64E7 0x64E9 0x64EC 0x64ED 0x64EF 0x64F0 +0x64F1 0x64F2 0x64F4 0x64F6 0x64F7 0x64F8 0x64FA 0x64FB 0x64FC 0x64FD 0x64FE 0x64FF 0x6500 0x6504 0x6505 0x6506 +0x6509 0x650F 0x6511 0x6512 0x6514 0x6516 0x6518 0x6519 0x651B 0x651C 0x651D 0x651E 0x6522 0x6523 0x6524 0x6525 +0x652A 0x652B 0x652C 0x652E 0x652F 0x6530 0x6534 0x6535 0x6536 0x6537 0x6538 0x6539 0x653A 0x653B 0x653D 0x653E +0x653F 0x6541 0x6543 0x6545 0x6548 0x6549 0x654C 0x654D 0x654E 0x654F 0x6551 0x6554 0x6555 0x6556 0x6557 0x6558 +0x6559 0x655B 0x655C 0x655D 0x655E 0x6560 0x6562 0x6563 0x6566 0x6569 0x656B 0x656C 0x656D 0x6570 0x6572 0x6574 +0x6575 0x6577 0x6578 0x6579 0x657E 0x6582 0x6583 0x6585 0x6586 0x6587 0x6588 0x6589 0x658B 0x658C 0x658E 0x658F +0x6590 0x6591 0x6593 0x6595 0x6597 0x6599 0x659B 0x659C 0x659D 0x659E 0x659F 0x65A0 0x65A1 0x65A2 0x65A4 0x65A5 +0x65A7 0x65A8 0x65A9 0x65AB 0x65AC 0x65AD 0x65AF 0x65B0 0x65B2 0x65B6 0x65B7 0x65B8 0x65B9 0x65BC 0x65BD 0x65C1 +0x65C2 0x65C3 0x65C4 0x65C5 0x65C6 0x65CB 0x65CC 0x65CE 0x65CF 0x65D0 0x65D2 0x65D6 0x65D7 0x65D9 0x65DB 0x65DE +0x65E0 0x65E1 0x65E2 0x65E3 0x65E5 0x65E6 0x65E7 0x65E8 0x65E9 0x65EC 0x65ED 0x65EE 0x65EF 0x65F0 0x65F1 0x65F2 +0x65F3 0x65F4 0x65F5 0x65F6 0x65F7 0x65F8 0x65FA 0x65FB 0x65FC 0x65FD 0x65FF 0x6600 0x6602 0x6603 0x6604 0x6605 +0x6606 0x6607 0x6608 0x6609 0x660A 0x660B 0x660C 0x660D 0x660E 0x660F 0x6610 0x6611 0x6612 0x6613 0x6614 0x6615 +0x6619 0x661A 0x661C 0x661D 0x661E 0x661F 0x6620 0x6621 0x6622 0x6623 0x6624 0x6625 0x6626 0x6627 0x6628 0x662A +0x662B 0x662D 0x662E 0x662F 0x6630 0x6631 0x6632 0x6633 0x6634 0x6635 0x6636 0x663A 0x663B 0x663C 0x663D 0x663E +0x663F 0x6641 0x6642 0x6643 0x6644 0x6645 0x6649 0x664A 0x664B 0x664C 0x664F 0x6650 0x6652 0x6653 0x6654 0x6655 +0x6656 0x6657 0x6659 0x665A 0x665B 0x665D 0x665E 0x665F 0x6661 0x6662 0x6664 0x6665 0x6666 0x6667 0x6668 0x6669 +0x666A 0x666B 0x666C 0x666E 0x666F 0x6670 0x6671 0x6673 0x6674 0x6676 0x6677 0x6678 0x6679 0x667A 0x667B 0x667E +0x6681 0x6682 0x6683 0x6684 0x6685 0x6687 0x6688 0x6689 0x668B 0x668C 0x668D 0x668E 0x6690 0x6691 0x6692 0x6695 +0x6696 0x6697 0x6698 0x669D 0x66A0 0x66A2 0x66A3 0x66A6 0x66A7 0x66A8 0x66AA 0x66AB 0x66AE 0x66B1 0x66B2 0x66B3 +0x66B4 0x66B5 0x66B6 0x66B8 0x66B9 0x66BB 0x66BC 0x66BE 0x66BF 0x66C1 0x66C4 0x66C6 0x66C7 0x66C8 0x66C9 0x66CC +0x66D6 0x66D9 0x66DA 0x66DB 0x66DC 0x66DD 0x66E0 0x66E3 0x66E6 0x66E8 0x66E9 0x66EC 0x66EF 0x66F0 0x66F1 0x66F2 +0x66F3 0x66F4 0x66F5 0x66F7 0x66F8 0x66F9 0x66FA 0x66FC 0x66FD 0x66FE 0x66FF 0x6700 0x6701 0x6703 0x6706 0x6708 +0x6709 0x670A 0x670B 0x670D 0x670F 0x6710 0x6711 0x6712 0x6713 0x6714 0x6715 0x6716 0x6717 0x6718 0x671B 0x671D +0x671E 0x671F 0x6723 0x6725 0x6726 0x6727 0x6728 0x6729 0x672A 0x672B 0x672C 0x672D 0x672E 0x672F 0x6730 0x6731 +0x6732 0x6733 0x6734 0x6735 0x6736 0x6737 0x6738 0x673A 0x673D 0x673F 0x6740 0x6741 0x6742 0x6743 0x6744 0x6745 +0x6746 0x6748 0x6749 0x674B 0x674C 0x674E 0x674F 0x6750 0x6751 0x6753 0x6755 0x6756 0x6757 0x6759 0x675C 0x675E +0x675F 0x6760 0x6761 0x6762 0x6763 0x6764 0x6765 0x6767 0x6768 0x6769 0x676A 0x676D 0x676E 0x676F 0x6770 0x6771 +0x6772 0x6773 0x6774 0x6775 0x6777 0x677A 0x677B 0x677C 0x677E 0x677F 0x6781 0x6784 0x6785 0x6787 0x6789 0x678B +0x678C 0x678D 0x678F 0x6790 0x6791 0x6792 0x6793 0x6795 0x6797 0x6798 0x6799 0x679A 0x679C 0x679D 0x679E 0x679F +0x67A0 0x67A1 0x67A2 0x67A3 0x67A5 0x67A6 0x67A7 0x67A8 0x67A9 0x67AA 0x67AB 0x67AD 0x67AF 0x67B0 0x67B1 0x67B2 +0x67B3 0x67B4 0x67B5 0x67B6 0x67B7 0x67B8 0x67B9 0x67BE 0x67C1 0x67C3 0x67C4 0x67C6 0x67C8 0x67CA 0x67CE 0x67CF +0x67D0 0x67D1 0x67D2 0x67D3 0x67D4 0x67D6 0x67D8 0x67D9 0x67DA 0x67DC 0x67DD 0x67DE 0x67E0 0x67E2 0x67E4 0x67E5 +0x67E7 0x67E9 0x67EC 0x67EE 0x67EF 0x67F0 0x67F1 0x67F3 0x67F4 0x67F5 0x67F6 0x67F7 0x67FA 0x67FB 0x67FD 0x67FE +0x67FF 0x6800 0x6802 0x6803 0x6804 0x6805 0x6807 0x6808 0x6809 0x680A 0x680B 0x680C 0x680E 0x680F 0x6810 0x6811 +0x6812 0x6813 0x6814 0x6816 0x6817 0x6818 0x681D 0x681E 0x681F 0x6821 0x6822 0x6829 0x682A 0x682B 0x682F 0x6832 +0x6833 0x6834 0x6837 0x6838 0x6839 0x683B 0x683C 0x683D 0x683E 0x683F 0x6840 0x6841 0x6842 0x6843 0x6844 0x6845 +0x6846 0x6848 0x6849 0x684A 0x684B 0x684C 0x684D 0x684E 0x6850 0x6851 0x6853 0x6854 0x6855 0x6859 0x685C 0x685D +0x685F 0x6860 0x6861 0x6862 0x6863 0x6864 0x6865 0x6866 0x6867 0x6868 0x6869 0x686A 0x686B 0x686C 0x686D 0x686F +0x6872 0x6874 0x6876 0x6877 0x6879 0x687E 0x687F 0x6881 0x6882 0x6883 0x6885 0x6886 0x6887 0x688C 0x688D 0x688F +0x6890 0x6893 0x6894 0x6897 0x6898 0x689B 0x689C 0x689D 0x689F 0x68A0 0x68A1 0x68A2 0x68A3 0x68A6 0x68A7 0x68A8 +0x68AD 0x68AF 0x68B0 0x68B1 0x68B2 0x68B3 0x68B4 0x68B5 0x68B6 0x68B9 0x68BA 0x68BC 0x68BD 0x68BE 0x68BF 0x68C0 +0x68C1 0x68C2 0x68C4 0x68C5 0x68C6 0x68C9 0x68CA 0x68CB 0x68CD 0x68D0 0x68D1 0x68D2 0x68D3 0x68D4 0x68D5 0x68D6 +0x68D7 0x68D8 0x68DA 0x68DF 0x68E0 0x68E1 0x68E3 0x68E4 0x68E7 0x68E8 0x68EA 0x68EB 0x68EC 0x68EE 0x68EF 0x68F0 +0x68F1 0x68F2 0x68F5 0x68F6 0x68F8 0x68F9 0x68FA 0x68FB 0x68FC 0x68FD 0x6900 0x6901 0x6904 0x6905 0x6906 0x6907 +0x6908 0x690B 0x690C 0x690D 0x690E 0x690F 0x6910 0x6911 0x6912 0x6913 0x6919 0x691A 0x691B 0x691C 0x691D 0x691F +0x6920 0x6921 0x6922 0x6923 0x6924 0x6925 0x6926 0x6927 0x6928 0x692A 0x692B 0x692D 0x6930 0x6934 0x6935 0x6936 +0x6938 0x6939 0x693D 0x693F 0x6940 0x6942 0x694A 0x6952 0x6953 0x6954 0x6955 0x6957 0x6959 0x695A 0x695B 0x695C +0x695D 0x695E 0x695F 0x6960 0x6961 0x6962 0x6963 0x6966 0x6968 0x6969 0x696A 0x696B 0x696C 0x696D 0x696E 0x696F +0x6971 0x6973 0x6974 0x6975 0x6977 0x6978 0x6979 0x697C 0x697D 0x697E 0x6980 0x6981 0x6982 0x6983 0x6984 0x6985 +0x6986 0x6987 0x6988 0x6989 0x698A 0x698D 0x698E 0x6991 0x6994 0x6995 0x6996 0x6998 0x699B 0x699C 0x69A0 0x69A3 +0x69A5 0x69A6 0x69A7 0x69A8 0x69AA 0x69AB 0x69AD 0x69AE 0x69B0 0x69B1 0x69B2 0x69B4 0x69B7 0x69BB 0x69BC 0x69BE +0x69BF 0x69C1 0x69C3 0x69C5 0x69C7 0x69CA 0x69CB 0x69CC 0x69CD 0x69CE 0x69CF 0x69D0 0x69D1 0x69D3 0x69D4 0x69D8 +0x69D9 0x69DA 0x69DB 0x69DC 0x69DD 0x69DE 0x69DF 0x69E0 0x69E4 0x69E5 0x69E7 0x69E8 0x69EA 0x69EB 0x69ED 0x69F1 +0x69F2 0x69F3 0x69F9 0x69FA 0x69FB 0x69FC 0x69FD 0x69FE 0x69FF 0x6A01 0x6A02 0x6A05 0x6A0A 0x6A0B 0x6A0C 0x6A11 +0x6A12 0x6A13 0x6A14 0x6A17 0x6A18 0x6A19 0x6A1B 0x6A1E 0x6A1F 0x6A21 0x6A22 0x6A23 0x6A28 0x6A29 0x6A2A 0x6A2B +0x6A2E 0x6A2F 0x6A31 0x6A33 0x6A35 0x6A36 0x6A38 0x6A39 0x6A3A 0x6A3D 0x6A3E 0x6A3F 0x6A44 0x6A47 0x6A48 0x6A4B +0x6A50 0x6A51 0x6A52 0x6A53 0x6A58 0x6A59 0x6A5A 0x6A5B 0x6A5E 0x6A5F 0x6A61 0x6A62 0x6A65 0x6A66 0x6A6B 0x6A71 +0x6A72 0x6A74 0x6A78 0x6A79 0x6A7C 0x6A7D 0x6A7E 0x6A7F 0x6A80 0x6A81 0x6A84 0x6A87 0x6A89 0x6A8D 0x6A8E 0x6A90 +0x6A91 0x6A94 0x6A96 0x6A97 0x6A9C 0x6A9E 0x6A9F 0x6AA0 0x6AA2 0x6AA3 0x6AA8 0x6AA9 0x6AAA 0x6AAB 0x6AAC 0x6AAE +0x6AAF 0x6AB3 0x6AB4 0x6AB5 0x6AB8 0x6ABB 0x6AC1 0x6AC2 0x6AC3 0x6AC6 0x6AC8 0x6ACD 0x6AD1 0x6AD3 0x6ADA 0x6ADB +0x6ADD 0x6ADE 0x6ADF 0x6AE5 0x6AE7 0x6AE8 0x6AEA 0x6AEB 0x6AEC 0x6AF1 0x6AF3 0x6AF6 0x6AF8 0x6AFA 0x6AFB 0x6AFC +0x6B02 0x6B04 0x6B05 0x6B09 0x6B0A 0x6B0C 0x6B0F 0x6B10 0x6B12 0x6B13 0x6B16 0x6B17 0x6B1D 0x6B1E 0x6B1F 0x6B20 +0x6B21 0x6B22 0x6B23 0x6B24 0x6B27 0x6B2C 0x6B32 0x6B37 0x6B38 0x6B39 0x6B3A 0x6B3B 0x6B3D 0x6B3E 0x6B3F 0x6B43 +0x6B45 0x6B46 0x6B47 0x6B49 0x6B4C 0x6B4E 0x6B50 0x6B53 0x6B54 0x6B58 0x6B59 0x6B5B 0x6B5C 0x6B5F 0x6B61 0x6B62 +0x6B63 0x6B64 0x6B65 0x6B66 0x6B67 0x6B69 0x6B6A 0x6B6C 0x6B6F 0x6B72 0x6B73 0x6B74 0x6B77 0x6B78 0x6B79 0x6B7A +0x6B7B 0x6B7C 0x6B7F 0x6B80 0x6B81 0x6B82 0x6B83 0x6B84 0x6B86 0x6B87 0x6B89 0x6B8A 0x6B8B 0x6B8D 0x6B92 0x6B93 +0x6B95 0x6B96 0x6B98 0x6B9A 0x6B9B 0x6B9E 0x6BA1 0x6BA2 0x6BA3 0x6BA4 0x6BAA 0x6BAB 0x6BAD 0x6BAE 0x6BAF 0x6BB1 +0x6BB2 0x6BB3 0x6BB4 0x6BB5 0x6BB7 0x6BBA 0x6BBB 0x6BBC 0x6BBD 0x6BBF 0x6BC0 0x6BC1 0x6BC2 0x6BC5 0x6BC6 0x6BCB +0x6BCC 0x6BCD 0x6BCE 0x6BCF 0x6BD0 0x6BD1 0x6BD2 0x6BD3 0x6BD4 0x6BD5 0x6BD6 0x6BD7 0x6BD8 0x6BD9 0x6BDA 0x6BDB +0x6BDF 0x6BE1 0x6BEA 0x6BEB 0x6BEC 0x6BEF 0x6BF3 0x6BF4 0x6BF5 0x6BF7 0x6BF9 0x6BFD 0x6BFF 0x6C02 0x6C05 0x6C06 +0x6C07 0x6C08 0x6C09 0x6C0A 0x6C0C 0x6C0D 0x6C0F 0x6C10 0x6C11 0x6C13 0x6C14 0x6C15 0x6C16 0x6C17 0x6C18 0x6C19 +0x6C1A 0x6C1B 0x6C1C 0x6C1D 0x6C1E 0x6C1F 0x6C20 0x6C21 0x6C22 0x6C23 0x6C24 0x6C25 0x6C26 0x6C27 0x6C28 0x6C29 +0x6C2A 0x6C2B 0x6C2C 0x6C2D 0x6C2E 0x6C2F 0x6C30 0x6C31 0x6C32 0x6C33 0x6C34 0x6C35 0x6C36 0x6C37 0x6C38 0x6C39 +0x6C3A 0x6C3B 0x6C3C 0x6C3D 0x6C3E 0x6C3F 0x6C40 0x6C41 0x6C42 0x6C43 0x6C46 0x6C47 0x6C48 0x6C49 0x6C4A 0x6C4B +0x6C4D 0x6C4E 0x6C4F 0x6C50 0x6C54 0x6C55 0x6C57 0x6C59 0x6C5A 0x6C5B 0x6C5C 0x6C5D 0x6C5E 0x6C5F 0x6C60 0x6C61 +0x6C62 0x6C64 0x6C67 0x6C68 0x6C69 0x6C6A 0x6C6B 0x6C6D 0x6C70 0x6C72 0x6C73 0x6C74 0x6C76 0x6C78 0x6C79 0x6C7A +0x6C7D 0x6C7E 0x6C81 0x6C82 0x6C83 0x6C84 0x6C85 0x6C86 0x6C87 0x6C88 0x6C89 0x6C8C 0x6C8D 0x6C8F 0x6C90 0x6C92 +0x6C93 0x6C94 0x6C95 0x6C96 0x6C98 0x6C99 0x6C9A 0x6C9B 0x6C9C 0x6C9F 0x6CA1 0x6CA2 0x6CA3 0x6CA4 0x6CA5 0x6CA6 +0x6CA7 0x6CA8 0x6CA9 0x6CAA 0x6CAB 0x6CAC 0x6CAD 0x6CAE 0x6CB1 0x6CB2 0x6CB3 0x6CB5 0x6CB8 0x6CB9 0x6CBA 0x6CBB +0x6CBC 0x6CBD 0x6CBE 0x6CBF 0x6CC1 0x6CC2 0x6CC3 0x6CC4 0x6CC5 0x6CC6 0x6CC7 0x6CC9 0x6CCA 0x6CCC 0x6CD0 0x6CD3 +0x6CD4 0x6CD5 0x6CD6 0x6CD7 0x6CD9 0x6CDA 0x6CDB 0x6CDC 0x6CDD 0x6CDE 0x6CE0 0x6CE1 0x6CE2 0x6CE3 0x6CE5 0x6CE8 +0x6CEA 0x6CEB 0x6CEE 0x6CEF 0x6CF0 0x6CF1 0x6CF3 0x6CF5 0x6CF6 0x6CF7 0x6CF8 0x6CFA 0x6CFB 0x6CFC 0x6CFD 0x6CFE +0x6D01 0x6D04 0x6D05 0x6D07 0x6D08 0x6D0B 0x6D0C 0x6D0D 0x6D0E 0x6D10 0x6D11 0x6D12 0x6D13 0x6D16 0x6D17 0x6D18 +0x6D19 0x6D1A 0x6D1B 0x6D1E 0x6D1F 0x6D22 0x6D23 0x6D25 0x6D27 0x6D28 0x6D29 0x6D2A 0x6D2B 0x6D2D 0x6D2E 0x6D31 +0x6D32 0x6D33 0x6D34 0x6D35 0x6D36 0x6D38 0x6D39 0x6D3A 0x6D3B 0x6D3C 0x6D3D 0x6D3E 0x6D3F 0x6D41 0x6D43 0x6D44 +0x6D45 0x6D46 0x6D47 0x6D48 0x6D49 0x6D4A 0x6D4B 0x6D4D 0x6D4E 0x6D4F 0x6D50 0x6D51 0x6D52 0x6D53 0x6D54 0x6D55 +0x6D59 0x6D5A 0x6D5B 0x6D5C 0x6D5E 0x6D5F 0x6D60 0x6D61 0x6D63 0x6D64 0x6D65 0x6D66 0x6D69 0x6D6A 0x6D6C 0x6D6D +0x6D6E 0x6D6F 0x6D70 0x6D72 0x6D74 0x6D77 0x6D78 0x6D79 0x6D7B 0x6D7C 0x6D7F 0x6D82 0x6D84 0x6D85 0x6D87 0x6D88 +0x6D89 0x6D8A 0x6D8C 0x6D8D 0x6D8E 0x6D8F 0x6D90 0x6D91 0x6D93 0x6D94 0x6D95 0x6D97 0x6D98 0x6D99 0x6D9A 0x6D9B +0x6D9C 0x6D9D 0x6D9E 0x6D9F 0x6DA0 0x6DA1 0x6DA2 0x6DA3 0x6DA4 0x6DA6 0x6DA7 0x6DA8 0x6DA9 0x6DAA 0x6DAB 0x6DAD +0x6DAE 0x6DAF 0x6DB2 0x6DB4 0x6DB5 0x6DB7 0x6DB8 0x6DBC 0x6DBF 0x6DC0 0x6DC3 0x6DC4 0x6DC5 0x6DC6 0x6DC7 0x6DCB +0x6DCC 0x6DCD 0x6DCF 0x6DD1 0x6DD2 0x6DD5 0x6DD6 0x6DD8 0x6DD9 0x6DDA 0x6DDC 0x6DDD 0x6DDE 0x6DDF 0x6DE0 0x6DE1 +0x6DE4 0x6DE5 0x6DE6 0x6DE8 0x6DE9 0x6DEA 0x6DEB 0x6DEC 0x6DEE 0x6DEF 0x6DF1 0x6DF3 0x6DF4 0x6DF5 0x6DF6 0x6DF7 +0x6DF8 0x6DF9 0x6DFA 0x6DFB 0x6DFC 0x6DFD 0x6E05 0x6E07 0x6E08 0x6E09 0x6E0A 0x6E0B 0x6E0C 0x6E0D 0x6E0E 0x6E10 +0x6E11 0x6E13 0x6E14 0x6E15 0x6E16 0x6E17 0x6E19 0x6E1A 0x6E1B 0x6E1D 0x6E1F 0x6E20 0x6E21 0x6E22 0x6E23 0x6E24 +0x6E25 0x6E26 0x6E29 0x6E2B 0x6E2C 0x6E2D 0x6E2E 0x6E2F 0x6E30 0x6E32 0x6E34 0x6E36 0x6E38 0x6E3A 0x6E3C 0x6E3D +0x6E3E 0x6E43 0x6E44 0x6E49 0x6E4A 0x6E4B 0x6E4D 0x6E4E 0x6E51 0x6E53 0x6E54 0x6E56 0x6E58 0x6E5B 0x6E5C 0x6E5D +0x6E5E 0x6E5F 0x6E61 0x6E62 0x6E63 0x6E66 0x6E67 0x6E68 0x6E69 0x6E6A 0x6E6B 0x6E6E 0x6E6F 0x6E72 0x6E73 0x6E74 +0x6E76 0x6E7A 0x6E7B 0x6E7E 0x6E7F 0x6E80 0x6E81 0x6E82 0x6E83 0x6E85 0x6E86 0x6E87 0x6E88 0x6E89 0x6E8C 0x6E8D +0x6E8E 0x6E8F 0x6E90 0x6E96 0x6E98 0x6E9A 0x6E9C 0x6E9D 0x6E9E 0x6E9F 0x6EA0 0x6EA2 0x6EA5 0x6EA6 0x6EA7 0x6EAA +0x6EAB 0x6EAE 0x6EAF 0x6EB1 0x6EB2 0x6EB3 0x6EB4 0x6EB5 0x6EB6 0x6EB7 0x6EB9 0x6EBA 0x6EBB 0x6EBC 0x6EBD 0x6EC1 +0x6EC2 0x6EC3 0x6EC4 0x6EC5 0x6EC6 0x6EC7 0x6EC8 0x6EC9 0x6ECB 0x6ECC 0x6ECD 0x6ECE 0x6ECF 0x6ED1 0x6ED3 0x6ED4 +0x6ED5 0x6ED7 0x6ED8 0x6ED9 0x6EDA 0x6EDD 0x6EDE 0x6EDF 0x6EE0 0x6EE1 0x6EE2 0x6EE4 0x6EE5 0x6EE6 0x6EE7 0x6EE8 +0x6EE9 0x6EEA 0x6EEB 0x6EEC 0x6EEE 0x6EEF 0x6EF2 0x6EF4 0x6EF7 0x6EF8 0x6EF9 0x6EFB 0x6EFE 0x6EFF 0x6F01 0x6F02 +0x6F06 0x6F08 0x6F09 0x6F0A 0x6F0B 0x6F0C 0x6F0D 0x6F0F 0x6F11 0x6F13 0x6F14 0x6F15 0x6F16 0x6F1A 0x6F20 0x6F22 +0x6F23 0x6F24 0x6F25 0x6F26 0x6F27 0x6F29 0x6F2A 0x6F2B 0x6F2C 0x6F2D 0x6F2F 0x6F30 0x6F31 0x6F32 0x6F33 0x6F34 +0x6F35 0x6F36 0x6F37 0x6F38 0x6F39 0x6F3B 0x6F3C 0x6F3E 0x6F3F 0x6F41 0x6F45 0x6F46 0x6F47 0x6F4A 0x6F4B 0x6F4D +0x6F4F 0x6F51 0x6F54 0x6F55 0x6F56 0x6F57 0x6F58 0x6F59 0x6F5A 0x6F5B 0x6F5C 0x6F5E 0x6F5F 0x6F60 0x6F62 0x6F63 +0x6F64 0x6F66 0x6F69 0x6F6D 0x6F6E 0x6F6F 0x6F70 0x6F72 0x6F74 0x6F75 0x6F76 0x6F77 0x6F78 0x6F7A 0x6F7C 0x6F7D +0x6F7E 0x6F7F 0x6F80 0x6F81 0x6F82 0x6F84 0x6F86 0x6F87 0x6F88 0x6F89 0x6F8C 0x6F8D 0x6F8E 0x6F90 0x6F91 0x6F92 +0x6F94 0x6F97 0x6F9B 0x6F9C 0x6FA0 0x6FA1 0x6FA3 0x6FA4 0x6FA5 0x6FA6 0x6FA7 0x6FA8 0x6FA9 0x6FAA 0x6FAB 0x6FAD +0x6FAE 0x6FAF 0x6FB1 0x6FB3 0x6FB4 0x6FB6 0x6FB9 0x6FBC 0x6FBD 0x6FBE 0x6FC0 0x6FC1 0x6FC2 0x6FC3 0x6FC6 0x6FC7 +0x6FC9 0x6FCA 0x6FCB 0x6FD1 0x6FD2 0x6FD4 0x6FD5 0x6FD8 0x6FDA 0x6FDB 0x6FDC 0x6FDE 0x6FDF 0x6FE0 0x6FE1 0x6FE4 +0x6FE8 0x6FE9 0x6FEB 0x6FEC 0x6FEE 0x6FEF 0x6FF0 0x6FF1 0x6FF3 0x6FF6 0x6FFA 0x6FFC 0x6FFE 0x7001 0x7002 0x7005 +0x7006 0x7009 0x700B 0x700C 0x700D 0x700F 0x7011 0x7014 0x7015 0x7018 0x701A 0x701B 0x701C 0x701D 0x701E 0x701F +0x7020 0x7021 0x7023 0x7026 0x7027 0x7028 0x702C 0x702F 0x7030 0x7031 0x7032 0x7035 0x7037 0x7039 0x703C 0x703E +0x7043 0x7044 0x7048 0x704C 0x704F 0x7050 0x7051 0x7054 0x7055 0x7058 0x705D 0x705E 0x7060 0x7063 0x7064 0x7065 +0x7067 0x7069 0x706B 0x706C 0x706D 0x706F 0x7070 0x7074 0x7075 0x7076 0x7078 0x707A 0x707C 0x707D 0x707E 0x707F +0x7080 0x7081 0x7085 0x7086 0x7089 0x708A 0x708C 0x708E 0x7092 0x7094 0x7095 0x7096 0x7098 0x7099 0x709A 0x709C +0x709D 0x709E 0x709F 0x70A1 0x70A3 0x70A4 0x70A9 0x70AB 0x70AC 0x70AD 0x70AE 0x70AF 0x70B0 0x70B1 0x70B3 0x70B5 +0x70B7 0x70B8 0x70B9 0x70BA 0x70BB 0x70BC 0x70BD 0x70C0 0x70C1 0x70C2 0x70C3 0x70C7 0x70C8 0x70CA 0x70CB 0x70CE +0x70CF 0x70D3 0x70D4 0x70D8 0x70D9 0x70DA 0x70DB 0x70DC 0x70DD 0x70DF 0x70E0 0x70E4 0x70E6 0x70E7 0x70E8 0x70E9 +0x70EB 0x70EC 0x70ED 0x70EF 0x70F1 0x70F4 0x70F6 0x70F7 0x70F9 0x70FA 0x70FB 0x70FD 0x7104 0x7106 0x7109 0x710A +0x710C 0x7110 0x7113 0x7114 0x7115 0x7116 0x7117 0x7118 0x7119 0x711A 0x711C 0x711E 0x7120 0x7121 0x7122 0x7126 +0x712E 0x712F 0x7130 0x7131 0x7136 0x713A 0x713C 0x713F 0x7140 0x7141 0x7143 0x7145 0x7146 0x7147 0x7149 0x714A +0x714B 0x714C 0x714E 0x714F 0x7150 0x7151 0x7152 0x7153 0x7155 0x7156 0x7159 0x715A 0x715C 0x715E 0x715F 0x7162 +0x7163 0x7164 0x7165 0x7166 0x7167 0x7168 0x7169 0x716C 0x716E 0x7172 0x7173 0x7174 0x7178 0x717A 0x717D 0x717F +0x7180 0x7184 0x7185 0x7187 0x7188 0x7189 0x718A 0x718F 0x7190 0x7192 0x7194 0x7195 0x7197 0x7198 0x7199 0x719B +0x719C 0x719F 0x71A0 0x71A2 0x71A5 0x71A8 0x71AC 0x71AF 0x71B0 0x71B1 0x71B2 0x71B3 0x71B5 0x71B9 0x71BA 0x71BB +0x71BE 0x71C0 0x71C1 0x71C3 0x71C4 0x71C8 0x71C9 0x71CA 0x71CB 0x71CE 0x71CF 0x71D0 0x71D2 0x71D4 0x71D5 0x71D6 +0x71D7 0x71D9 0x71DA 0x71DC 0x71DF 0x71E0 0x71E1 0x71E5 0x71E6 0x71E7 0x71EC 0x71ED 0x71EE 0x71F4 0x71F5 0x71F6 +0x71F8 0x71F9 0x71FB 0x71FC 0x71FE 0x71FF 0x7200 0x7201 0x7206 0x7207 0x720C 0x720D 0x7210 0x7213 0x7214 0x7215 +0x721A 0x721B 0x721D 0x721F 0x7228 0x722A 0x722B 0x722C 0x722D 0x7230 0x7231 0x7232 0x7235 0x7236 0x7237 0x7238 +0x7239 0x723A 0x723B 0x723C 0x723D 0x723E 0x723F 0x7240 0x7241 0x7242 0x7246 0x7247 0x7248 0x724B 0x724C 0x724D +0x7252 0x7256 0x7258 0x7259 0x725A 0x725B 0x725D 0x725E 0x725F 0x7260 0x7261 0x7262 0x7263 0x7264 0x7265 0x7266 +0x7267 0x7269 0x726E 0x726F 0x7272 0x7274 0x7275 0x7277 0x7278 0x7279 0x727A 0x727B 0x727D 0x727E 0x727F 0x7280 +0x7281 0x7282 0x7284 0x7287 0x728A 0x728B 0x728D 0x728F 0x7292 0x7296 0x7297 0x729B 0x729F 0x72A0 0x72A1 0x72A2 +0x72A7 0x72A8 0x72AC 0x72AD 0x72AE 0x72AF 0x72B0 0x72B2 0x72B4 0x72B6 0x72B7 0x72B8 0x72B9 0x72BC 0x72C0 0x72C1 +0x72C2 0x72C3 0x72C4 0x72C6 0x72C8 0x72C9 0x72CD 0x72CE 0x72D0 0x72D2 0x72D3 0x72D7 0x72D9 0x72DB 0x72DD 0x72DE +0x72DF 0x72E0 0x72E1 0x72E2 0x72E8 0x72E9 0x72EC 0x72ED 0x72EE 0x72EF 0x72F0 0x72F1 0x72F2 0x72F3 0x72F4 0x72F7 +0x72F8 0x72F9 0x72FA 0x72FB 0x72FC 0x72FD 0x7301 0x7303 0x7304 0x7306 0x7307 0x730A 0x730B 0x730E 0x7313 0x7314 +0x7315 0x7316 0x7317 0x7319 0x731B 0x731C 0x731D 0x731E 0x731F 0x7321 0x7322 0x7325 0x7329 0x732A 0x732B 0x732C +0x732E 0x732F 0x7330 0x7331 0x7334 0x7336 0x7337 0x7338 0x7339 0x733A 0x733B 0x733E 0x733F 0x7341 0x7343 0x7344 +0x7345 0x7347 0x734D 0x734E 0x734F 0x7350 0x7352 0x7355 0x7357 0x735A 0x735B 0x7360 0x7362 0x7363 0x7364 0x7368 +0x736A 0x736B 0x736C 0x736D 0x736E 0x736F 0x7370 0x7372 0x7374 0x7375 0x7377 0x7378 0x737A 0x737B 0x737C 0x737E +0x7380 0x7381 0x7383 0x7384 0x7386 0x7387 0x7389 0x738A 0x738B 0x738E 0x738F 0x7391 0x7392 0x7393 0x7394 0x7395 +0x7396 0x7397 0x7398 0x7399 0x739A 0x739B 0x739E 0x739F 0x73A0 0x73A1 0x73A2 0x73A4 0x73A5 0x73A6 0x73A7 0x73A8 +0x73A9 0x73AB 0x73AD 0x73AE 0x73AF 0x73B0 0x73B1 0x73B2 0x73B3 0x73B5 0x73B6 0x73B7 0x73B9 0x73BA 0x73BB 0x73BC +0x73BD 0x73BF 0x73C0 0x73C2 0x73C3 0x73C4 0x73C5 0x73C7 0x73C8 0x73C9 0x73CA 0x73CB 0x73CC 0x73CD 0x73CE 0x73CF +0x73D0 0x73D1 0x73D2 0x73D5 0x73D6 0x73D7 0x73D9 0x73DB 0x73DD 0x73DE 0x73E0 0x73E1 0x73E2 0x73E3 0x73E4 0x73E5 +0x73E6 0x73E7 0x73E8 0x73E9 0x73EA 0x73EB 0x73ED 0x73EE 0x73F0 0x73F1 0x73F2 0x73F5 0x73F6 0x73F7 0x73F8 0x73F9 +0x73FA 0x73FD 0x73FE 0x7400 0x7401 0x7402 0x7403 0x7404 0x7405 0x7406 0x7407 0x7408 0x7409 0x740A 0x740D 0x740E +0x740F 0x7410 0x7413 0x7414 0x7415 0x741A 0x741B 0x741E 0x741F 0x7420 0x7421 0x7422 0x7424 0x7425 0x7426 0x7428 +0x742A 0x742B 0x742C 0x742D 0x742E 0x742F 0x7430 0x7431 0x7432 0x7433 0x7434 0x7435 0x7436 0x7437 0x7438 0x743A +0x743C 0x743F 0x7440 0x7441 0x7442 0x7443 0x7444 0x7445 0x7446 0x744A 0x744B 0x744C 0x7451 0x7452 0x7453 0x7454 +0x7455 0x7456 0x7457 0x7459 0x745A 0x745B 0x745C 0x745D 0x745E 0x745F 0x7460 0x7462 0x7463 0x7464 0x7465 0x7467 +0x7468 0x7469 0x746A 0x746C 0x746D 0x746F 0x7470 0x7471 0x7472 0x7473 0x7476 0x7477 0x7478 0x747D 0x747E 0x7480 +0x7481 0x7482 0x7483 0x7486 0x7487 0x7488 0x7489 0x748A 0x748B 0x748E 0x748F 0x7490 0x7492 0x7495 0x7497 0x7498 +0x749C 0x749E 0x749F 0x74A0 0x74A1 0x74A2 0x74A3 0x74A4 0x74A5 0x74A6 0x74A7 0x74A8 0x74A9 0x74AA 0x74AB 0x74AC +0x74AE 0x74B0 0x74B1 0x74B2 0x74B5 0x74B8 0x74B9 0x74BA 0x74BD 0x74BF 0x74C0 0x74C5 0x74C6 0x74C8 0x74CA 0x74CC +0x74CF 0x74D2 0x74D3 0x74D4 0x74D6 0x74D8 0x74DA 0x74DB 0x74DC 0x74DE 0x74E0 0x74E2 0x74E3 0x74E4 0x74E6 0x74E7 +0x74E9 0x74EE 0x74EF 0x74F0 0x74F1 0x74F2 0x74F4 0x74F6 0x74F7 0x74F8 0x74FB 0x74FF 0x7501 0x7503 0x7504 0x7505 +0x7507 0x750C 0x750D 0x750E 0x750F 0x7511 0x7513 0x7515 0x7516 0x7517 0x7518 0x7519 0x751A 0x751B 0x751C 0x751D +0x751E 0x751F 0x7521 0x7522 0x7523 0x7525 0x7526 0x7528 0x7529 0x752A 0x752B 0x752C 0x752D 0x752E 0x752F 0x7530 +0x7531 0x7532 0x7533 0x7534 0x7535 0x7537 0x7538 0x7539 0x753A 0x753B 0x753C 0x753D 0x753E 0x753F 0x7540 0x7544 +0x7545 0x7546 0x7547 0x7548 0x7549 0x754A 0x754B 0x754C 0x754D 0x754E 0x754F 0x7551 0x7553 0x7554 0x7556 0x7559 +0x755A 0x755B 0x755C 0x755D 0x755F 0x7560 0x7562 0x7563 0x7564 0x7565 0x7566 0x7567 0x7569 0x756A 0x756B 0x756C +0x756D 0x756F 0x7570 0x7572 0x7573 0x7574 0x7575 0x7576 0x7577 0x7578 0x7579 0x757A 0x757D 0x757E 0x757F 0x7580 +0x7581 0x7582 0x7583 0x7584 0x7586 0x7587 0x7589 0x758A 0x758B 0x758C 0x758D 0x758E 0x758F 0x7590 0x7591 0x7592 +0x7594 0x7595 0x7596 0x7597 0x7598 0x7599 0x759A 0x759D 0x759F 0x75A0 0x75A1 0x75A2 0x75A3 0x75A4 0x75A5 0x75A7 +0x75AA 0x75AB 0x75AC 0x75AD 0x75AE 0x75AF 0x75B0 0x75B1 0x75B2 0x75B3 0x75B4 0x75B5 0x75B6 0x75B8 0x75B9 0x75BA +0x75BB 0x75BC 0x75BD 0x75BE 0x75BF 0x75C0 0x75C1 0x75C2 0x75C3 0x75C4 0x75C5 0x75C7 0x75C8 0x75C9 0x75CA 0x75CB +0x75CC 0x75CD 0x75CE 0x75CF 0x75D0 0x75D1 0x75D2 0x75D3 0x75D4 0x75D5 0x75D6 0x75D7 0x75D8 0x75D9 0x75DA 0x75DB +0x75DD 0x75DE 0x75DF 0x75E0 0x75E1 0x75E2 0x75E3 0x75E4 0x75E6 0x75E7 0x75E8 0x75E9 0x75EA 0x75EB 0x75ED 0x75EF +0x75F0 0x75F1 0x75F2 0x75F3 0x75F4 0x75F5 0x75F6 0x75F7 0x75F8 0x75F9 0x75FA 0x75FB 0x75FC 0x75FD 0x75FE 0x75FF +0x7600 0x7601 0x7602 0x7603 0x7604 0x7605 0x7606 0x7608 0x7609 0x760A 0x760B 0x760C 0x760D 0x760F 0x7610 0x7611 +0x7613 0x7614 0x7615 0x7616 0x7617 0x7618 0x7619 0x761A 0x761B 0x761C 0x761D 0x761E 0x761F 0x7620 0x7621 0x7622 +0x7623 0x7624 0x7625 0x7626 0x7627 0x7628 0x7629 0x762A 0x762B 0x762D 0x762E 0x762F 0x7630 0x7631 0x7632 0x7633 +0x7634 0x7635 0x7638 0x763A 0x763B 0x763C 0x763D 0x763E 0x763F 0x7640 0x7642 0x7643 0x7646 0x7647 0x7648 0x7649 +0x764C 0x764D 0x764E 0x7650 0x7652 0x7653 0x7654 0x7656 0x7657 0x7658 0x7659 0x765A 0x765C 0x765E 0x765F 0x7660 +0x7661 0x7662 0x7663 0x7664 0x7665 0x7666 0x7667 0x7668 0x7669 0x766A 0x766B 0x766C 0x766D 0x766E 0x766F 0x7670 +0x7671 0x7672 0x7675 0x7676 0x7678 0x7679 0x767A 0x767B 0x767C 0x767D 0x767E 0x767F 0x7680 0x7681 0x7682 0x7683 +0x7684 0x7686 0x7687 0x7688 0x7689 0x768A 0x768B 0x768E 0x768F 0x7690 0x7691 0x7692 0x7693 0x7695 0x7696 0x7699 +0x769A 0x769B 0x769C 0x769D 0x769E 0x76A4 0x76A6 0x76AA 0x76AB 0x76AD 0x76AE 0x76AF 0x76B0 0x76B1 0x76B2 0x76B4 +0x76B5 0x76B6 0x76B7 0x76B8 0x76B9 0x76BA 0x76BB 0x76BD 0x76BE 0x76BF 0x76C2 0x76C3 0x76C4 0x76C5 0x76C6 0x76C8 +0x76C9 0x76CA 0x76CC 0x76CD 0x76CE 0x76CF 0x76D0 0x76D1 0x76D2 0x76D3 0x76D4 0x76D6 0x76D7 0x76D8 0x76DA 0x76DB +0x76DC 0x76DD 0x76DE 0x76DF 0x76E1 0x76E3 0x76E4 0x76E5 0x76E6 0x76E7 0x76E8 0x76E9 0x76EA 0x76EC 0x76ED 0x76EE +0x76EF 0x76F0 0x76F1 0x76F2 0x76F3 0x76F4 0x76F5 0x76F7 0x76F8 0x76F9 0x76FA 0x76FB 0x76FC 0x76FE 0x7701 0x7704 +0x7707 0x7708 0x7709 0x770A 0x770B 0x770C 0x770D 0x7712 0x7715 0x7719 0x771A 0x771B 0x771C 0x771E 0x771F 0x7720 +0x7722 0x7724 0x7725 0x7726 0x7728 0x7729 0x772C 0x772D 0x772F 0x7735 0x7736 0x7737 0x7738 0x773A 0x773C 0x773D +0x773E 0x7740 0x7741 0x7743 0x7744 0x7746 0x7747 0x774D 0x774E 0x774F 0x7750 0x7751 0x7752 0x775A 0x775B 0x775C +0x775E 0x7761 0x7762 0x7763 0x7765 0x7766 0x7768 0x7769 0x776A 0x776B 0x776C 0x7779 0x777A 0x777D 0x777E 0x777F +0x7780 0x7784 0x7785 0x7786 0x7787 0x778B 0x778C 0x778D 0x778E 0x778F 0x7791 0x7792 0x7793 0x7798 0x779A 0x779C +0x779E 0x779F 0x77A0 0x77A2 0x77A4 0x77A5 0x77A7 0x77A9 0x77AA 0x77AB 0x77AC 0x77AD 0x77B0 0x77B3 0x77B5 0x77B6 +0x77B7 0x77B9 0x77BB 0x77BC 0x77BD 0x77BF 0x77C7 0x77CB 0x77CD 0x77CE 0x77D3 0x77D7 0x77DA 0x77DB 0x77DC 0x77DE +0x77E2 0x77E3 0x77E5 0x77E7 0x77E9 0x77EB 0x77EC 0x77ED 0x77EE 0x77EF 0x77F0 0x77F3 0x77F4 0x77F6 0x77F7 0x77F8 +0x77F9 0x77FA 0x77FB 0x77FC 0x77FD 0x77FE 0x77FF 0x7800 0x7801 0x7802 0x7803 0x7804 0x7805 0x7806 0x7807 0x7808 +0x7809 0x780C 0x780D 0x780E 0x780F 0x7810 0x7811 0x7812 0x7813 0x7814 0x7815 0x7816 0x7817 0x7818 0x781A 0x781C +0x781D 0x781F 0x7820 0x7821 0x7822 0x7823 0x7825 0x7826 0x7827 0x7828 0x7829 0x782A 0x782B 0x782C 0x782D 0x782E +0x782F 0x7830 0x7831 0x7832 0x7833 0x7834 0x7835 0x7837 0x7838 0x7839 0x783A 0x783B 0x783C 0x783E 0x783F 0x7840 +0x7841 0x7843 0x7845 0x7847 0x7848 0x7849 0x784A 0x784B 0x784C 0x784D 0x784E 0x784F 0x7850 0x7852 0x7853 0x7854 +0x7855 0x7856 0x7857 0x7859 0x785A 0x785C 0x785D 0x785E 0x7860 0x7862 0x7864 0x7865 0x7866 0x7868 0x7869 0x786A +0x786B 0x786C 0x786D 0x786E 0x786F 0x7870 0x7871 0x7872 0x7874 0x7875 0x7877 0x7879 0x787B 0x787C 0x787E 0x787F +0x7880 0x7881 0x7883 0x7884 0x7885 0x7886 0x7887 0x7888 0x7889 0x788C 0x788D 0x788E 0x788F 0x7891 0x7893 0x7894 +0x7895 0x7896 0x7897 0x7898 0x789A 0x789B 0x789C 0x789F 0x78A1 0x78A3 0x78A5 0x78A7 0x78A8 0x78A9 0x78AA 0x78AD +0x78AF 0x78B0 0x78B1 0x78B2 0x78B3 0x78B4 0x78B5 0x78B6 0x78B8 0x78B9 0x78BA 0x78BB 0x78BC 0x78BE 0x78C1 0x78C5 +0x78C6 0x78C8 0x78C9 0x78CA 0x78CB 0x78CE 0x78CF 0x78D0 0x78D1 0x78D4 0x78D5 0x78D8 0x78D9 0x78DA 0x78DC 0x78E0 +0x78E1 0x78E2 0x78E3 0x78E7 0x78E8 0x78EC 0x78EF 0x78F2 0x78F4 0x78F5 0x78F7 0x78F9 0x78FA 0x78FB 0x78FD 0x78FE +0x7901 0x7903 0x7904 0x7905 0x7906 0x7907 0x790C 0x790E 0x7910 0x7911 0x7912 0x7913 0x7916 0x7919 0x791E 0x7921 +0x7924 0x7926 0x792A 0x792B 0x792C 0x7931 0x7933 0x7934 0x7935 0x793A 0x793B 0x793C 0x793D 0x793E 0x7940 0x7941 +0x7942 0x7943 0x7945 0x7946 0x7947 0x7948 0x7949 0x794A 0x794B 0x794E 0x794F 0x7950 0x7953 0x7955 0x7956 0x7957 +0x795A 0x795B 0x795C 0x795D 0x795E 0x795F 0x7960 0x7962 0x7965 0x7967 0x7968 0x7969 0x796B 0x796D 0x796F 0x7972 +0x7977 0x7978 0x797A 0x797C 0x797E 0x797F 0x7980 0x7981 0x7984 0x7985 0x798A 0x798B 0x798D 0x798E 0x798F 0x7991 +0x7992 0x7994 0x7995 0x7998 0x799A 0x799B 0x799D 0x799F 0x79A0 0x79A1 0x79A4 0x79A5 0x79A6 0x79A7 0x79A9 0x79AA +0x79AE 0x79B0 0x79B1 0x79B3 0x79B8 0x79B9 0x79BA 0x79BB 0x79BD 0x79BE 0x79BF 0x79C0 0x79C1 0x79C2 0x79C3 0x79C6 +0x79C8 0x79C9 0x79CA 0x79CB 0x79CD 0x79CF 0x79D1 0x79D2 0x79D5 0x79D8 0x79DD 0x79DE 0x79DF 0x79E1 0x79E3 0x79E4 +0x79E6 0x79E7 0x79E9 0x79EB 0x79EC 0x79ED 0x79EF 0x79F0 0x79F8 0x79FB 0x79FD 0x79FE 0x7A00 0x7A02 0x7A03 0x7A04 +0x7A05 0x7A06 0x7A08 0x7A09 0x7A0B 0x7A0C 0x7A0D 0x7A0E 0x7A11 0x7A14 0x7A16 0x7A17 0x7A18 0x7A19 0x7A1A 0x7A1C +0x7A1E 0x7A1F 0x7A20 0x7A23 0x7A26 0x7A2E 0x7A31 0x7A32 0x7A33 0x7A36 0x7A37 0x7A39 0x7A3B 0x7A3C 0x7A3D 0x7A3E +0x7A3F 0x7A40 0x7A42 0x7A43 0x7A44 0x7A46 0x7A47 0x7A49 0x7A4B 0x7A4C 0x7A4D 0x7A4E 0x7A4F 0x7A50 0x7A51 0x7A57 +0x7A59 0x7A5C 0x7A5E 0x7A5F 0x7A60 0x7A61 0x7A62 0x7A63 0x7A66 0x7A68 0x7A69 0x7A6B 0x7A6D 0x7A70 0x7A74 0x7A75 +0x7A76 0x7A77 0x7A78 0x7A79 0x7A7A 0x7A7D 0x7A7F 0x7A80 0x7A81 0x7A83 0x7A84 0x7A85 0x7A86 0x7A88 0x7A8A 0x7A8D +0x7A8E 0x7A91 0x7A92 0x7A93 0x7A95 0x7A96 0x7A97 0x7A98 0x7A9C 0x7A9D 0x7A9F 0x7AA0 0x7AA3 0x7AA5 0x7AA6 0x7AA8 +0x7AA9 0x7AAA 0x7AAC 0x7AAD 0x7AAE 0x7AAF 0x7AB0 0x7AB3 0x7AB5 0x7AB6 0x7AB8 0x7ABA 0x7ABE 0x7ABF 0x7AC3 0x7AC4 +0x7AC5 0x7AC7 0x7AC8 0x7ACA 0x7ACB 0x7ACD 0x7ACF 0x7AD1 0x7AD2 0x7AD3 0x7AD5 0x7AD6 0x7AD7 0x7AD8 0x7AD9 0x7ADA +0x7ADC 0x7ADD 0x7ADE 0x7ADF 0x7AE0 0x7AE1 0x7AE2 0x7AE3 0x7AE5 0x7AE6 0x7AEA 0x7AEB 0x7AED 0x7AEF 0x7AF0 0x7AF6 +0x7AF7 0x7AF8 0x7AF9 0x7AFA 0x7AFD 0x7AFF 0x7B02 0x7B03 0x7B04 0x7B06 0x7B08 0x7B0A 0x7B0B 0x7B0F 0x7B11 0x7B14 +0x7B15 0x7B18 0x7B19 0x7B1B 0x7B1E 0x7B20 0x7B24 0x7B25 0x7B26 0x7B28 0x7B2A 0x7B2B 0x7B2C 0x7B2D 0x7B2E 0x7B2F +0x7B31 0x7B33 0x7B35 0x7B36 0x7B38 0x7B39 0x7B3A 0x7B3C 0x7B3E 0x7B40 0x7B45 0x7B46 0x7B47 0x7B48 0x7B49 0x7B4A +0x7B4B 0x7B4C 0x7B4D 0x7B4E 0x7B4F 0x7B50 0x7B51 0x7B52 0x7B54 0x7B56 0x7B58 0x7B5A 0x7B5B 0x7B5C 0x7B5D 0x7B60 +0x7B62 0x7B64 0x7B65 0x7B66 0x7B67 0x7B69 0x7B6C 0x7B6E 0x7B6F 0x7B70 0x7B71 0x7B72 0x7B74 0x7B75 0x7B76 0x7B77 +0x7B79 0x7B7A 0x7B7B 0x7B7C 0x7B7D 0x7B7E 0x7B7F 0x7B80 0x7B84 0x7B85 0x7B86 0x7B87 0x7B8B 0x7B8D 0x7B8E 0x7B8F +0x7B90 0x7B92 0x7B93 0x7B94 0x7B95 0x7B96 0x7B97 0x7B98 0x7B99 0x7B9A 0x7B9C 0x7B9D 0x7B9F 0x7BA0 0x7BA1 0x7BA2 +0x7BA3 0x7BA6 0x7BA7 0x7BA8 0x7BA9 0x7BAA 0x7BAB 0x7BAC 0x7BAD 0x7BB1 0x7BB4 0x7BB8 0x7BC0 0x7BC1 0x7BC4 0x7BC6 +0x7BC7 0x7BC9 0x7BCB 0x7BCC 0x7BCF 0x7BD1 0x7BD2 0x7BD3 0x7BD4 0x7BD9 0x7BDA 0x7BDB 0x7BDD 0x7BE0 0x7BE1 0x7BE2 +0x7BE4 0x7BE5 0x7BE6 0x7BE9 0x7BEA 0x7BED 0x7BEE 0x7BEF 0x7BF0 0x7BF1 0x7BF2 0x7BF3 0x7BF6 0x7BF7 0x7BFC 0x7BFE +0x7C00 0x7C03 0x7C07 0x7C09 0x7C0B 0x7C0C 0x7C0D 0x7C0F 0x7C11 0x7C12 0x7C13 0x7C14 0x7C15 0x7C16 0x7C17 0x7C1D +0x7C1E 0x7C1F 0x7C20 0x7C21 0x7C23 0x7C26 0x7C27 0x7C29 0x7C2A 0x7C2B 0x7C30 0x7C37 0x7C38 0x7C39 0x7C3D 0x7C3E +0x7C3F 0x7C40 0x7C41 0x7C43 0x7C4C 0x7C4D 0x7C4F 0x7C50 0x7C53 0x7C54 0x7C56 0x7C57 0x7C58 0x7C59 0x7C5B 0x7C5C +0x7C5D 0x7C5F 0x7C60 0x7C63 0x7C64 0x7C65 0x7C69 0x7C6A 0x7C6C 0x7C6E 0x7C72 0x7C73 0x7C74 0x7C75 0x7C78 0x7C79 +0x7C7B 0x7C7C 0x7C7D 0x7C7E 0x7C81 0x7C82 0x7C83 0x7C84 0x7C89 0x7C8B 0x7C8D 0x7C90 0x7C91 0x7C92 0x7C95 0x7C97 +0x7C98 0x7C9B 0x7C9C 0x7C9D 0x7C9E 0x7C9F 0x7CA1 0x7CA2 0x7CA4 0x7CA5 0x7CA6 0x7CA7 0x7CA8 0x7CAA 0x7CAB 0x7CAC +0x7CAD 0x7CAE 0x7CB1 0x7CB2 0x7CB3 0x7CB5 0x7CB9 0x7CBA 0x7CBC 0x7CBD 0x7CBE 0x7CBF 0x7CC0 0x7CC1 0x7CC2 0x7CC4 +0x7CC5 0x7CC7 0x7CC8 0x7CC9 0x7CCA 0x7CCC 0x7CCD 0x7CCE 0x7CD2 0x7CD5 0x7CD6 0x7CD7 0x7CD8 0x7CD9 0x7CDC 0x7CDD +0x7CDE 0x7CDF 0x7CE0 0x7CE2 0x7CE7 0x7CE8 0x7CEC 0x7CED 0x7CEF 0x7CF0 0x7CF2 0x7CF4 0x7CF5 0x7CF6 0x7CF8 0x7CF9 +0x7CFA 0x7CFB 0x7CFE 0x7D00 0x7D02 0x7D03 0x7D04 0x7D05 0x7D06 0x7D07 0x7D08 0x7D09 0x7D0A 0x7D0B 0x7D0D 0x7D10 +0x7D11 0x7D13 0x7D14 0x7D15 0x7D16 0x7D17 0x7D18 0x7D19 0x7D1A 0x7D1B 0x7D1C 0x7D1D 0x7D1E 0x7D20 0x7D21 0x7D22 +0x7D27 0x7D2B 0x7D2C 0x7D2E 0x7D2F 0x7D30 0x7D31 0x7D32 0x7D33 0x7D35 0x7D39 0x7D3A 0x7D3C 0x7D3F 0x7D40 0x7D42 +0x7D43 0x7D44 0x7D45 0x7D46 0x7D4B 0x7D4C 0x7D4E 0x7D4F 0x7D50 0x7D53 0x7D55 0x7D56 0x7D5A 0x7D5B 0x7D5C 0x7D5D +0x7D5E 0x7D61 0x7D62 0x7D63 0x7D66 0x7D68 0x7D6A 0x7D6E 0x7D70 0x7D71 0x7D72 0x7D73 0x7D75 0x7D76 0x7D77 0x7D79 +0x7D7A 0x7D7D 0x7D7F 0x7D81 0x7D83 0x7D84 0x7D86 0x7D88 0x7D89 0x7D8C 0x7D8E 0x7D8F 0x7D91 0x7D93 0x7D96 0x7D99 +0x7D9A 0x7D9B 0x7D9C 0x7D9D 0x7D9E 0x7D9F 0x7DA0 0x7DA1 0x7DA2 0x7DA3 0x7DA6 0x7DA7 0x7DAA 0x7DAB 0x7DAC 0x7DAD +0x7DAE 0x7DAF 0x7DB0 0x7DB1 0x7DB2 0x7DB3 0x7DB4 0x7DB5 0x7DB7 0x7DB8 0x7DB9 0x7DBA 0x7DBB 0x7DBD 0x7DBE 0x7DBF +0x7DC1 0x7DC4 0x7DC7 0x7DC8 0x7DCA 0x7DCB 0x7DCC 0x7DCF 0x7DD1 0x7DD2 0x7DD3 0x7DD4 0x7DD5 0x7DD6 0x7DD7 0x7DD8 +0x7DD9 0x7DDA 0x7DDC 0x7DDD 0x7DDE 0x7DE0 0x7DE1 0x7DE3 0x7DE4 0x7DE6 0x7DE8 0x7DE9 0x7DEA 0x7DEC 0x7DEF 0x7DF1 +0x7DF2 0x7DF4 0x7DF6 0x7DF9 0x7DFB 0x7DFC 0x7E01 0x7E04 0x7E05 0x7E08 0x7E09 0x7E0A 0x7E0B 0x7E10 0x7E11 0x7E12 +0x7E15 0x7E17 0x7E1B 0x7E1D 0x7E1E 0x7E1F 0x7E20 0x7E21 0x7E22 0x7E23 0x7E26 0x7E27 0x7E29 0x7E2B 0x7E2D 0x7E2E +0x7E2F 0x7E31 0x7E32 0x7E33 0x7E34 0x7E35 0x7E36 0x7E37 0x7E39 0x7E3A 0x7E3B 0x7E3D 0x7E3E 0x7E3F 0x7E41 0x7E43 +0x7E44 0x7E45 0x7E46 0x7E47 0x7E48 0x7E4A 0x7E4B 0x7E4D 0x7E4E 0x7E51 0x7E52 0x7E54 0x7E55 0x7E56 0x7E59 0x7E5A +0x7E5D 0x7E5E 0x7E61 0x7E62 0x7E66 0x7E67 0x7E69 0x7E6A 0x7E6B 0x7E6D 0x7E6E 0x7E6F 0x7E70 0x7E73 0x7E76 0x7E79 +0x7E7B 0x7E7C 0x7E7D 0x7E7E 0x7E7F 0x7E81 0x7E82 0x7E83 0x7E86 0x7E87 0x7E88 0x7E89 0x7E8A 0x7E8C 0x7E8D 0x7E8E +0x7E8F 0x7E90 0x7E92 0x7E93 0x7E94 0x7E95 0x7E96 0x7E98 0x7E9A 0x7E9B 0x7E9C 0x7E9F 0x7EA0 0x7EA1 0x7EA2 0x7EA3 +0x7EA4 0x7EA5 0x7EA6 0x7EA7 0x7EA8 0x7EA9 0x7EAA 0x7EAB 0x7EAC 0x7EAD 0x7EAE 0x7EAF 0x7EB0 0x7EB1 0x7EB2 0x7EB3 +0x7EB4 0x7EB5 0x7EB6 0x7EB7 0x7EB8 0x7EB9 0x7EBA 0x7EBB 0x7EBC 0x7EBD 0x7EBE 0x7EBF 0x7EC0 0x7EC1 0x7EC2 0x7EC3 +0x7EC4 0x7EC5 0x7EC6 0x7EC7 0x7EC8 0x7EC9 0x7ECA 0x7ECB 0x7ECC 0x7ECD 0x7ECE 0x7ECF 0x7ED0 0x7ED1 0x7ED2 0x7ED3 +0x7ED4 0x7ED5 0x7ED6 0x7ED7 0x7ED8 0x7ED9 0x7EDA 0x7EDB 0x7EDC 0x7EDD 0x7EDE 0x7EDF 0x7EE0 0x7EE1 0x7EE2 0x7EE3 +0x7EE4 0x7EE5 0x7EE6 0x7EE7 0x7EE8 0x7EE9 0x7EEA 0x7EEB 0x7EEC 0x7EED 0x7EEE 0x7EEF 0x7EF0 0x7EF1 0x7EF2 0x7EF3 +0x7EF4 0x7EF5 0x7EF6 0x7EF7 0x7EF8 0x7EF9 0x7EFA 0x7EFB 0x7EFC 0x7EFD 0x7EFE 0x7EFF 0x7F00 0x7F01 0x7F02 0x7F03 +0x7F04 0x7F05 0x7F06 0x7F07 0x7F08 0x7F09 0x7F0A 0x7F0B 0x7F0C 0x7F0D 0x7F0E 0x7F0F 0x7F10 0x7F11 0x7F12 0x7F13 +0x7F14 0x7F15 0x7F16 0x7F17 0x7F18 0x7F19 0x7F1A 0x7F1B 0x7F1C 0x7F1D 0x7F1E 0x7F1F 0x7F20 0x7F21 0x7F22 0x7F23 +0x7F24 0x7F25 0x7F26 0x7F27 0x7F28 0x7F29 0x7F2A 0x7F2B 0x7F2C 0x7F2D 0x7F2E 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 +0x7F34 0x7F35 0x7F36 0x7F38 0x7F39 0x7F3A 0x7F3D 0x7F42 0x7F43 0x7F44 0x7F45 0x7F48 0x7F49 0x7F4C 0x7F4D 0x7F4E +0x7F4F 0x7F50 0x7F51 0x7F52 0x7F53 0x7F54 0x7F55 0x7F57 0x7F58 0x7F5A 0x7F5B 0x7F5C 0x7F5D 0x7F5E 0x7F5F 0x7F60 +0x7F61 0x7F62 0x7F63 0x7F65 0x7F66 0x7F67 0x7F68 0x7F69 0x7F6A 0x7F6B 0x7F6C 0x7F6D 0x7F6E 0x7F70 0x7F71 0x7F72 +0x7F73 0x7F74 0x7F75 0x7F76 0x7F77 0x7F78 0x7F79 0x7F7D 0x7F7E 0x7F81 0x7F82 0x7F83 0x7F85 0x7F86 0x7F87 0x7F88 +0x7F8A 0x7F8B 0x7F8C 0x7F8E 0x7F91 0x7F93 0x7F94 0x7F95 0x7F96 0x7F97 0x7F9A 0x7F9D 0x7F9E 0x7F9F 0x7FA1 0x7FA3 +0x7FA4 0x7FA5 0x7FA7 0x7FA8 0x7FA9 0x7FAE 0x7FAF 0x7FB0 0x7FB1 0x7FB2 0x7FB4 0x7FB6 0x7FB8 0x7FB9 0x7FBC 0x7FBD +0x7FBF 0x7FC0 0x7FC1 0x7FC2 0x7FC3 0x7FC5 0x7FC6 0x7FC8 0x7FCA 0x7FCB 0x7FCC 0x7FCE 0x7FD2 0x7FD4 0x7FD5 0x7FD8 +0x7FD9 0x7FDA 0x7FDB 0x7FDF 0x7FE0 0x7FE1 0x7FE5 0x7FE6 0x7FE7 0x7FE9 0x7FEB 0x7FEC 0x7FEE 0x7FEF 0x7FF0 0x7FF1 +0x7FF3 0x7FF7 0x7FF9 0x7FFA 0x7FFB 0x7FFC 0x7FFD 0x7FFE 0x8000 0x8001 0x8002 0x8003 0x8004 0x8005 0x8006 0x8007 +0x8008 0x8009 0x800B 0x800C 0x800D 0x800E 0x800F 0x8010 0x8011 0x8012 0x8014 0x8015 0x8016 0x8017 0x8018 0x8019 +0x801C 0x8020 0x8021 0x8022 0x8024 0x8025 0x8026 0x8027 0x8028 0x8029 0x802A 0x802C 0x802D 0x802E 0x8030 0x8031 +0x8032 0x8033 0x8035 0x8036 0x8037 0x8038 0x803B 0x803D 0x803F 0x8042 0x8043 0x8046 0x804A 0x804B 0x804C 0x804D +0x804F 0x8050 0x8051 0x8052 0x8054 0x8056 0x8058 0x805A 0x805E 0x805F 0x8061 0x8062 0x8064 0x8068 0x8069 0x806A +0x806F 0x8070 0x8071 0x8072 0x8073 0x8074 0x8075 0x8076 0x8077 0x8079 0x807D 0x807E 0x807F 0x8080 0x8083 0x8084 +0x8085 0x8086 0x8087 0x8089 0x808B 0x808C 0x808F 0x8090 0x8093 0x8096 0x8098 0x8099 0x809A 0x809B 0x809C 0x809D +0x809F 0x80A0 0x80A1 0x80A2 0x80A4 0x80A5 0x80A9 0x80AA 0x80AB 0x80AC 0x80AD 0x80AE 0x80AF 0x80B1 0x80B2 0x80B4 +0x80B7 0x80B8 0x80BA 0x80BC 0x80BD 0x80BE 0x80BF 0x80C0 0x80C1 0x80C2 0x80C3 0x80C4 0x80C6 0x80C8 0x80CC 0x80CD +0x80CE 0x80D4 0x80D6 0x80D7 0x80D9 0x80DA 0x80DB 0x80DC 0x80DD 0x80DE 0x80E0 0x80E1 0x80E3 0x80E4 0x80E5 0x80E7 +0x80E8 0x80E9 0x80EA 0x80EB 0x80EC 0x80ED 0x80EF 0x80F0 0x80F1 0x80F2 0x80F3 0x80F4 0x80F6 0x80F8 0x80FA 0x80FC +0x80FD 0x80FE 0x80FF 0x8102 0x8105 0x8106 0x8107 0x8108 0x8109 0x810A 0x810D 0x810E 0x810F 0x8110 0x8111 0x8112 +0x8113 0x8114 0x8116 0x8117 0x8118 0x811A 0x811B 0x811D 0x811E 0x811F 0x8122 0x8123 0x8124 0x8126 0x8127 0x8129 +0x812B 0x812C 0x812F 0x8130 0x8131 0x8132 0x8133 0x8136 0x8137 0x8138 0x8139 0x813E 0x813F 0x8146 0x8148 0x814A +0x814B 0x814C 0x814E 0x8150 0x8151 0x8152 0x8153 0x8154 0x8155 0x8156 0x8158 0x8159 0x815A 0x815F 0x8160 0x8161 +0x8165 0x8166 0x8167 0x8168 0x8169 0x816B 0x816D 0x816E 0x816F 0x8170 0x8171 0x8173 0x8174 0x8178 0x8179 0x817A +0x817B 0x817C 0x817D 0x817E 0x817F 0x8180 0x8182 0x8183 0x8188 0x818A 0x818D 0x818E 0x818F 0x8191 0x8193 0x8195 +0x8196 0x8198 0x8199 0x819A 0x819B 0x819C 0x819D 0x819E 0x81A0 0x81A2 0x81A3 0x81A4 0x81A5 0x81A6 0x81A8 0x81A9 +0x81AA 0x81B0 0x81B3 0x81B5 0x81B6 0x81B8 0x81BA 0x81BB 0x81BD 0x81BE 0x81BF 0x81C0 0x81C1 0x81C2 0x81C3 0x81C6 +0x81C8 0x81C9 0x81CA 0x81CC 0x81CD 0x81CF 0x81D1 0x81D3 0x81D8 0x81D9 0x81DA 0x81DC 0x81DF 0x81E0 0x81E2 0x81E3 +0x81E5 0x81E7 0x81E8 0x81EA 0x81EC 0x81ED 0x81F3 0x81F4 0x81FA 0x81FB 0x81FC 0x81FE 0x81FF 0x8200 0x8201 0x8202 +0x8204 0x8205 0x8206 0x8207 0x8208 0x8209 0x820A 0x820B 0x820C 0x820D 0x820E 0x8210 0x8212 0x8214 0x8216 0x8217 +0x8218 0x821B 0x821C 0x821E 0x821F 0x8220 0x8221 0x8222 0x8223 0x8225 0x8226 0x8228 0x8229 0x822A 0x822B 0x822C +0x822D 0x822E 0x822F 0x8230 0x8231 0x8232 0x8233 0x8234 0x8235 0x8236 0x8237 0x8238 0x8239 0x823A 0x823B 0x823E +0x8240 0x8244 0x8245 0x8247 0x8249 0x824B 0x824E 0x824F 0x8258 0x8259 0x825A 0x825D 0x825F 0x8262 0x8264 0x8266 +0x8268 0x826A 0x826B 0x826E 0x826F 0x8270 0x8271 0x8272 0x8273 0x8274 0x8276 0x8277 0x8278 0x8279 0x827A 0x827D +0x827E 0x827F 0x8280 0x8282 0x8283 0x8284 0x8288 0x828A 0x828B 0x828D 0x828E 0x828F 0x8291 0x8292 0x8297 0x8298 +0x8299 0x829A 0x829C 0x829D 0x829F 0x82A0 0x82A1 0x82A3 0x82A4 0x82A5 0x82A6 0x82A7 0x82A8 0x82A9 0x82AA 0x82AB +0x82AC 0x82AD 0x82AE 0x82AF 0x82B0 0x82B1 0x82B3 0x82B4 0x82B5 0x82B6 0x82B7 0x82B8 0x82B9 0x82BB 0x82BC 0x82BD +0x82BE 0x82BF 0x82C1 0x82C4 0x82C5 0x82C7 0x82C8 0x82C9 0x82CA 0x82CB 0x82CC 0x82CD 0x82CE 0x82CF 0x82D1 0x82D2 +0x82D3 0x82D4 0x82D5 0x82D6 0x82D7 0x82D8 0x82D9 0x82DB 0x82DC 0x82DD 0x82DE 0x82DF 0x82E0 0x82E1 0x82E3 0x82E4 +0x82E5 0x82E6 0x82E7 0x82E8 0x82EB 0x82EF 0x82F1 0x82F3 0x82F4 0x82F6 0x82F7 0x82F9 0x82FA 0x82FB 0x82FD 0x82FE +0x8300 0x8301 0x8302 0x8303 0x8304 0x8305 0x8306 0x8307 0x8308 0x8309 0x830B 0x830C 0x830D 0x830E 0x830F 0x8311 +0x8313 0x8314 0x8315 0x8316 0x8317 0x8318 0x831A 0x831B 0x831C 0x831D 0x8322 0x8323 0x8327 0x8328 0x8329 0x832B +0x832C 0x832D 0x832F 0x8331 0x8332 0x8333 0x8334 0x8335 0x8336 0x8338 0x8339 0x833A 0x833C 0x833D 0x8340 0x8341 +0x8343 0x8344 0x8345 0x8346 0x8347 0x8349 0x834A 0x834E 0x834F 0x8350 0x8351 0x8352 0x8353 0x8354 0x8356 0x8358 +0x8359 0x835A 0x835B 0x835C 0x835D 0x835E 0x835F 0x8360 0x8361 0x8363 0x8364 0x8365 0x8366 0x8367 0x8368 0x8369 +0x836A 0x836B 0x836C 0x836D 0x836E 0x836F 0x8373 0x8375 0x8377 0x8378 0x837A 0x837B 0x837C 0x837D 0x8380 0x8382 +0x8385 0x8386 0x8387 0x8389 0x838A 0x838E 0x8392 0x8393 0x8395 0x8396 0x8398 0x8399 0x839A 0x839B 0x839C 0x839D +0x839E 0x839F 0x83A0 0x83A2 0x83A3 0x83A6 0x83A7 0x83A8 0x83A9 0x83AA 0x83AB 0x83AF 0x83B0 0x83B1 0x83B2 0x83B3 +0x83B4 0x83B5 0x83B6 0x83B7 0x83B8 0x83B9 0x83BA 0x83BC 0x83BD 0x83BF 0x83C0 0x83C1 0x83C2 0x83C5 0x83C7 0x83C8 +0x83C9 0x83CA 0x83CC 0x83CD 0x83CE 0x83CF 0x83D1 0x83D3 0x83D4 0x83D6 0x83D8 0x83DC 0x83DD 0x83DF 0x83E0 0x83E1 +0x83E5 0x83E9 0x83EA 0x83EB 0x83EF 0x83F0 0x83F1 0x83F2 0x83F4 0x83F5 0x83F7 0x83F8 0x83F9 0x83FB 0x83FC 0x83FD +0x83FE 0x83FF 0x8401 0x8403 0x8404 0x8406 0x8407 0x840A 0x840B 0x840C 0x840D 0x840E 0x840F 0x8411 0x8413 0x8418 +0x841A 0x841C 0x841D 0x8420 0x8422 0x8423 0x8424 0x8425 0x8426 0x8427 0x8428 0x8429 0x842A 0x842C 0x8431 0x8433 +0x8434 0x8435 0x8438 0x8439 0x843C 0x843D 0x8446 0x8447 0x8449 0x844E 0x8451 0x8452 0x8453 0x8456 0x8457 0x8459 +0x845A 0x845B 0x845C 0x8460 0x8461 0x8462 0x8463 0x8464 0x8466 0x8469 0x846B 0x846C 0x846D 0x846E 0x846F 0x8470 +0x8471 0x8473 0x8474 0x8475 0x8476 0x8477 0x8478 0x8479 0x847A 0x8482 0x8484 0x8487 0x8488 0x8489 0x848B 0x848C +0x848D 0x848E 0x8490 0x8493 0x8494 0x8497 0x8499 0x849C 0x849D 0x849E 0x849F 0x84A1 0x84A8 0x84AD 0x84AF 0x84B1 +0x84B2 0x84B4 0x84B8 0x84B9 0x84BA 0x84BB 0x84BC 0x84BD 0x84BE 0x84BF 0x84C0 0x84C1 0x84C2 0x84C4 0x84C6 0x84C7 +0x84C9 0x84CA 0x84CB 0x84CD 0x84CF 0x84D0 0x84D1 0x84D3 0x84D6 0x84D9 0x84DA 0x84DD 0x84DF 0x84E0 0x84E2 0x84E3 +0x84E5 0x84E6 0x84EA 0x84EC 0x84EE 0x84EF 0x84F0 0x84F3 0x84F4 0x84F7 0x84FC 0x84FD 0x84FF 0x8500 0x8503 0x8504 +0x8506 0x8508 0x850A 0x850C 0x8511 0x8513 0x8514 0x8515 0x8517 0x8518 0x851A 0x851E 0x851F 0x8521 0x8523 0x8525 +0x8526 0x852B 0x852C 0x852D 0x852F 0x8534 0x8535 0x8537 0x8538 0x8539 0x853A 0x853B 0x853C 0x853D 0x853F 0x8540 +0x8541 0x8543 0x8546 0x8548 0x8549 0x854A 0x854B 0x854E 0x8552 0x8553 0x8555 0x8556 0x8557 0x8558 0x8559 0x855A +0x855E 0x8562 0x8563 0x8564 0x8565 0x8568 0x8569 0x856A 0x856D 0x8570 0x8572 0x8574 0x8577 0x8579 0x857A 0x857B +0x857E 0x8580 0x8581 0x8584 0x8585 0x8586 0x8587 0x8588 0x858A 0x858C 0x858F 0x8590 0x8591 0x8594 0x8597 0x8598 +0x8599 0x859B 0x859C 0x859F 0x85A0 0x85A2 0x85A4 0x85A6 0x85A8 0x85A9 0x85AA 0x85AB 0x85AC 0x85AE 0x85AF 0x85B0 +0x85B3 0x85B4 0x85B6 0x85B7 0x85B8 0x85B9 0x85BA 0x85BE 0x85BF 0x85C1 0x85C2 0x85C9 0x85CD 0x85CE 0x85CF 0x85D0 +0x85D3 0x85D5 0x85DC 0x85DD 0x85DF 0x85E0 0x85E4 0x85E5 0x85E6 0x85E8 0x85E9 0x85EA 0x85ED 0x85F4 0x85F6 0x85F7 +0x85F9 0x85FA 0x85FB 0x85FE 0x85FF 0x8600 0x8602 0x8604 0x8605 0x8606 0x8607 0x860A 0x860B 0x8611 0x8613 0x8616 +0x8617 0x8618 0x861A 0x861E 0x8621 0x8622 0x8626 0x8627 0x8629 0x862D 0x862F 0x8630 0x8635 0x8638 0x863A 0x863C +0x863F 0x8649 0x864D 0x864E 0x864F 0x8650 0x8651 0x8652 0x8653 0x8654 0x8655 0x8656 0x8659 0x865A 0x865B 0x865C +0x865E 0x865F 0x8661 0x8662 0x8663 0x8664 0x8667 0x866B 0x866C 0x866D 0x866E 0x866F 0x8670 0x8671 0x8673 0x8674 +0x8677 0x8678 0x8679 0x867A 0x867B 0x867C 0x867D 0x867E 0x867F 0x8680 0x8681 0x8682 0x8683 0x8684 0x8685 0x8686 +0x8687 0x868A 0x868B 0x868C 0x868D 0x868E 0x8690 0x8691 0x8693 0x8694 0x8695 0x8696 0x8697 0x8698 0x8699 0x869A +0x869C 0x869D 0x869E 0x86A1 0x86A2 0x86A3 0x86A4 0x86A5 0x86A7 0x86A8 0x86A9 0x86AA 0x86AB 0x86AC 0x86AF 0x86B0 +0x86B1 0x86B2 0x86B3 0x86B4 0x86B5 0x86B6 0x86B7 0x86B8 0x86B9 0x86BA 0x86C0 0x86C1 0x86C2 0x86C3 0x86C4 0x86C5 +0x86C6 0x86C7 0x86C8 0x86C9 0x86CA 0x86CB 0x86CD 0x86CE 0x86CF 0x86D0 0x86D1 0x86D4 0x86D8 0x86D9 0x86DB 0x86DE +0x86DF 0x86E4 0x86E9 0x86EC 0x86ED 0x86EE 0x86EF 0x86F0 0x86F1 0x86F2 0x86F3 0x86F4 0x86F8 0x86F9 0x86FA 0x86FB +0x86FE 0x8700 0x8702 0x8703 0x8705 0x8706 0x8707 0x8708 0x8709 0x870A 0x870D 0x870E 0x8710 0x8711 0x8712 0x8713 +0x8715 0x8717 0x8718 0x871A 0x871C 0x871E 0x8721 0x8722 0x8723 0x8725 0x8729 0x872E 0x8730 0x8731 0x8734 0x8737 +0x873B 0x873D 0x873E 0x873F 0x8740 0x8742 0x8744 0x8747 0x8748 0x8749 0x874B 0x874C 0x874E 0x8753 0x8755 0x8757 +0x8758 0x8759 0x875C 0x875F 0x8760 0x8763 0x8764 0x8765 0x8766 0x8768 0x876A 0x876E 0x8770 0x8772 0x8774 0x8776 +0x8778 0x877B 0x877C 0x877D 0x877E 0x877F 0x8780 0x8782 0x8783 0x8784 0x8785 0x8786 0x8788 0x878B 0x878D 0x8793 +0x8797 0x879E 0x879F 0x87A0 0x87A2 0x87A3 0x87A8 0x87AB 0x87AC 0x87AD 0x87AE 0x87AF 0x87B1 0x87B3 0x87B5 0x87BA +0x87BB 0x87BD 0x87BF 0x87C0 0x87C4 0x87C6 0x87C7 0x87C8 0x87CA 0x87CB 0x87CE 0x87CF 0x87D0 0x87D1 0x87D2 0x87D3 +0x87DB 0x87E0 0x87E2 0x87E3 0x87E5 0x87E7 0x87EA 0x87EB 0x87EC 0x87EE 0x87EF 0x87F2 0x87F3 0x87F6 0x87F7 0x87F9 +0x87FB 0x87FE 0x87FF 0x8801 0x8803 0x8804 0x8805 0x8806 0x880A 0x880B 0x880D 0x880E 0x880F 0x8810 0x8811 0x8813 +0x8814 0x8815 0x8816 0x881B 0x881F 0x8821 0x8822 0x8823 0x8827 0x8828 0x882D 0x8831 0x8832 0x8835 0x8836 0x8839 +0x883B 0x883C 0x8840 0x8842 0x8843 0x8844 0x8845 0x8846 0x884A 0x884C 0x884D 0x884E 0x8852 0x8853 0x8854 0x8855 +0x8856 0x8857 0x8859 0x885A 0x885B 0x885D 0x885E 0x8860 0x8861 0x8862 0x8863 0x8864 0x8865 0x8868 0x8869 0x886B +0x886C 0x886E 0x8870 0x8872 0x8875 0x8877 0x8879 0x887D 0x887E 0x887F 0x8881 0x8882 0x8884 0x8885 0x8886 0x8888 +0x888B 0x888D 0x8892 0x8893 0x8896 0x8897 0x8899 0x889C 0x889E 0x88A2 0x88A4 0x88AA 0x88AB 0x88AD 0x88AE 0x88AF +0x88B0 0x88B1 0x88B4 0x88B5 0x88B7 0x88BA 0x88BC 0x88BF 0x88C0 0x88C1 0x88C2 0x88C3 0x88C4 0x88C5 0x88C6 0x88C7 +0x88C8 0x88C9 0x88CA 0x88CB 0x88CE 0x88CF 0x88D1 0x88D2 0x88D4 0x88D5 0x88D8 0x88D9 0x88DB 0x88DC 0x88DD 0x88DF +0x88E1 0x88E2 0x88E3 0x88E4 0x88E5 0x88E8 0x88EC 0x88EF 0x88F0 0x88F1 0x88F2 0x88F3 0x88F4 0x88F5 0x88F8 0x88F9 +0x88FB 0x88FC 0x88FD 0x88FE 0x8902 0x8904 0x8907 0x890A 0x890C 0x890E 0x8910 0x8912 0x8913 0x8914 0x8915 0x8918 +0x8919 0x891A 0x891B 0x891D 0x891E 0x891F 0x8921 0x8925 0x8926 0x892A 0x892B 0x892F 0x8930 0x8932 0x8933 0x8934 +0x8935 0x8936 0x8938 0x893B 0x893D 0x8940 0x8941 0x8943 0x8944 0x8947 0x8948 0x894C 0x894D 0x894F 0x8955 0x8956 +0x895A 0x895C 0x895D 0x895E 0x895F 0x8960 0x8964 0x8966 0x896A 0x896B 0x896C 0x896D 0x896F 0x8972 0x8974 0x8976 +0x8977 0x897B 0x897E 0x897F 0x8980 0x8981 0x8983 0x8985 0x8986 0x8987 0x8988 0x898A 0x898B 0x898E 0x898F 0x8993 +0x8996 0x8997 0x8998 0x8999 0x899A 0x899C 0x89A1 0x89A4 0x89A5 0x89A6 0x89A7 0x89A9 0x89AA 0x89AC 0x89AF 0x89B2 +0x89B3 0x89B7 0x89BA 0x89BC 0x89BD 0x89BF 0x89C0 0x89C1 0x89C2 0x89C3 0x89C4 0x89C5 0x89C6 0x89C7 0x89C8 0x89C9 +0x89CA 0x89CB 0x89CC 0x89CD 0x89CE 0x89CF 0x89D0 0x89D1 0x89D2 0x89D4 0x89D6 0x89DA 0x89DC 0x89DD 0x89DE 0x89DF +0x89E3 0x89E5 0x89E6 0x89E7 0x89EB 0x89ED 0x89EF 0x89F1 0x89F3 0x89F4 0x89F6 0x89F8 0x89FC 0x89FF 0x8A00 0x8A01 +0x8A02 0x8A03 0x8A04 0x8A07 0x8A08 0x8A0A 0x8A0C 0x8A0E 0x8A0F 0x8A10 0x8A11 0x8A12 0x8A13 0x8A15 0x8A16 0x8A17 +0x8A18 0x8A1A 0x8A1B 0x8A1D 0x8A1F 0x8A22 0x8A23 0x8A25 0x8A29 0x8A2A 0x8A2B 0x8A2D 0x8A31 0x8A33 0x8A34 0x8A36 +0x8A38 0x8A3A 0x8A3B 0x8A3C 0x8A3E 0x8A40 0x8A41 0x8A46 0x8A48 0x8A4E 0x8A50 0x8A51 0x8A52 0x8A54 0x8A55 0x8A56 +0x8A57 0x8A58 0x8A5B 0x8A5D 0x8A5E 0x8A5F 0x8A60 0x8A61 0x8A62 0x8A63 0x8A66 0x8A68 0x8A69 0x8A6A 0x8A6B 0x8A6C +0x8A6D 0x8A6E 0x8A70 0x8A71 0x8A72 0x8A73 0x8A75 0x8A77 0x8A79 0x8A7A 0x8A7B 0x8A7C 0x8A7F 0x8A81 0x8A82 0x8A84 +0x8A85 0x8A86 0x8A87 0x8A89 0x8A8A 0x8A8C 0x8A8D 0x8A91 0x8A92 0x8A93 0x8A95 0x8A98 0x8A9A 0x8A9E 0x8AA0 0x8AA1 +0x8AA3 0x8AA4 0x8AA5 0x8AA6 0x8AA7 0x8AA8 0x8AA9 0x8AAA 0x8AAC 0x8AAD 0x8AB0 0x8AB2 0x8AB6 0x8AB9 0x8ABC 0x8ABE +0x8ABF 0x8AC2 0x8AC4 0x8AC7 0x8AC9 0x8ACB 0x8ACC 0x8ACD 0x8ACF 0x8AD1 0x8AD2 0x8AD3 0x8AD4 0x8AD6 0x8AD7 0x8ADA +0x8ADB 0x8ADC 0x8ADD 0x8ADE 0x8ADF 0x8AE0 0x8AE1 0x8AE2 0x8AE4 0x8AE6 0x8AE7 0x8AEA 0x8AEB 0x8AED 0x8AEE 0x8AF1 +0x8AF2 0x8AF3 0x8AF4 0x8AF6 0x8AF7 0x8AF8 0x8AFA 0x8AFC 0x8AFE 0x8AFF 0x8B00 0x8B01 0x8B02 0x8B04 0x8B05 0x8B07 +0x8B0A 0x8B0B 0x8B0C 0x8B0E 0x8B0F 0x8B10 0x8B14 0x8B16 0x8B17 0x8B19 0x8B1A 0x8B1B 0x8B1D 0x8B1E 0x8B20 0x8B21 +0x8B22 0x8B26 0x8B28 0x8B2B 0x8B2C 0x8B2D 0x8B2E 0x8B33 0x8B37 0x8B39 0x8B3E 0x8B41 0x8B46 0x8B49 0x8B4A 0x8B4C +0x8B4E 0x8B4F 0x8B53 0x8B56 0x8B58 0x8B59 0x8B5A 0x8B5B 0x8B5C 0x8B5E 0x8B5F 0x8B60 0x8B63 0x8B66 0x8B69 0x8B6A +0x8B6B 0x8B6C 0x8B6D 0x8B6F 0x8B70 0x8B71 0x8B72 0x8B74 0x8B77 0x8B78 0x8B7D 0x8B7F 0x8B80 0x8B83 0x8B85 0x8B86 +0x8B8A 0x8B8B 0x8B8C 0x8B8E 0x8B90 0x8B92 0x8B93 0x8B94 0x8B95 0x8B96 0x8B99 0x8B9A 0x8B9C 0x8B9E 0x8B9F 0x8BA0 +0x8BA1 0x8BA2 0x8BA3 0x8BA4 0x8BA5 0x8BA6 0x8BA7 0x8BA8 0x8BA9 0x8BAA 0x8BAB 0x8BAC 0x8BAD 0x8BAE 0x8BAF 0x8BB0 +0x8BB1 0x8BB2 0x8BB3 0x8BB4 0x8BB5 0x8BB6 0x8BB7 0x8BB8 0x8BB9 0x8BBA 0x8BBB 0x8BBC 0x8BBD 0x8BBE 0x8BBF 0x8BC0 +0x8BC1 0x8BC2 0x8BC3 0x8BC4 0x8BC5 0x8BC6 0x8BC7 0x8BC8 0x8BC9 0x8BCA 0x8BCB 0x8BCC 0x8BCD 0x8BCE 0x8BCF 0x8BD0 +0x8BD1 0x8BD2 0x8BD3 0x8BD4 0x8BD5 0x8BD6 0x8BD7 0x8BD8 0x8BD9 0x8BDA 0x8BDB 0x8BDC 0x8BDD 0x8BDE 0x8BDF 0x8BE0 +0x8BE1 0x8BE2 0x8BE3 0x8BE4 0x8BE5 0x8BE6 0x8BE7 0x8BE8 0x8BE9 0x8BEA 0x8BEB 0x8BEC 0x8BED 0x8BEE 0x8BEF 0x8BF0 +0x8BF1 0x8BF2 0x8BF3 0x8BF4 0x8BF5 0x8BF6 0x8BF7 0x8BF8 0x8BF9 0x8BFA 0x8BFB 0x8BFC 0x8BFD 0x8BFE 0x8BFF 0x8C00 +0x8C01 0x8C02 0x8C03 0x8C04 0x8C05 0x8C06 0x8C07 0x8C08 0x8C09 0x8C0A 0x8C0B 0x8C0C 0x8C0D 0x8C0E 0x8C0F 0x8C10 +0x8C11 0x8C12 0x8C13 0x8C14 0x8C15 0x8C16 0x8C17 0x8C18 0x8C19 0x8C1A 0x8C1B 0x8C1C 0x8C1D 0x8C1E 0x8C1F 0x8C20 +0x8C21 0x8C22 0x8C23 0x8C24 0x8C25 0x8C26 0x8C27 0x8C28 0x8C29 0x8C2A 0x8C2B 0x8C2C 0x8C2D 0x8C2E 0x8C2F 0x8C30 +0x8C31 0x8C32 0x8C33 0x8C34 0x8C35 0x8C36 0x8C37 0x8C3A 0x8C3C 0x8C3F 0x8C41 0x8C46 0x8C47 0x8C48 0x8C49 0x8C4A +0x8C4C 0x8C4E 0x8C50 0x8C54 0x8C55 0x8C57 0x8C5A 0x8C61 0x8C62 0x8C68 0x8C6A 0x8C6B 0x8C6C 0x8C6D 0x8C6E 0x8C73 +0x8C76 0x8C78 0x8C79 0x8C7A 0x8C7C 0x8C82 0x8C85 0x8C86 0x8C89 0x8C8A 0x8C8C 0x8C8D 0x8C8E 0x8C90 0x8C92 0x8C93 +0x8C94 0x8C98 0x8C99 0x8C9D 0x8C9E 0x8C9F 0x8CA0 0x8CA1 0x8CA2 0x8CA7 0x8CA8 0x8CA9 0x8CAA 0x8CAB 0x8CAC 0x8CAD +0x8CAE 0x8CAF 0x8CB0 0x8CB2 0x8CB3 0x8CB4 0x8CB6 0x8CB7 0x8CB8 0x8CBA 0x8CBB 0x8CBC 0x8CBD 0x8CBF 0x8CC0 0x8CC1 +0x8CC2 0x8CC3 0x8CC4 0x8CC5 0x8CC7 0x8CC8 0x8CCA 0x8CCD 0x8CCE 0x8CCF 0x8CD1 0x8CD2 0x8CD3 0x8CD5 0x8CD9 0x8CDA +0x8CDB 0x8CDC 0x8CDE 0x8CE0 0x8CE1 0x8CE2 0x8CE3 0x8CE4 0x8CE6 0x8CE7 0x8CE8 0x8CEA 0x8CEB 0x8CEC 0x8CED 0x8CF0 +0x8CF1 0x8CF4 0x8CF5 0x8CF8 0x8CFA 0x8CFB 0x8CFC 0x8CFD 0x8CFE 0x8D04 0x8D05 0x8D07 0x8D08 0x8D0A 0x8D0B 0x8D0D +0x8D0F 0x8D10 0x8D13 0x8D14 0x8D16 0x8D17 0x8D1B 0x8D1C 0x8D1D 0x8D1E 0x8D1F 0x8D20 0x8D21 0x8D22 0x8D23 0x8D24 +0x8D25 0x8D26 0x8D27 0x8D28 0x8D29 0x8D2A 0x8D2B 0x8D2C 0x8D2D 0x8D2E 0x8D2F 0x8D30 0x8D31 0x8D32 0x8D33 0x8D34 +0x8D35 0x8D36 0x8D37 0x8D38 0x8D39 0x8D3A 0x8D3B 0x8D3C 0x8D3D 0x8D3E 0x8D3F 0x8D40 0x8D41 0x8D42 0x8D43 0x8D44 +0x8D45 0x8D46 0x8D47 0x8D48 0x8D49 0x8D4A 0x8D4B 0x8D4C 0x8D4D 0x8D4E 0x8D4F 0x8D50 0x8D51 0x8D52 0x8D53 0x8D54 +0x8D55 0x8D56 0x8D57 0x8D58 0x8D59 0x8D5A 0x8D5B 0x8D5C 0x8D5D 0x8D5E 0x8D5F 0x8D60 0x8D61 0x8D62 0x8D63 0x8D64 +0x8D66 0x8D67 0x8D69 0x8D6A 0x8D6B 0x8D6C 0x8D6D 0x8D70 0x8D71 0x8D73 0x8D74 0x8D75 0x8D76 0x8D77 0x8D81 0x8D84 +0x8D85 0x8D8A 0x8D8B 0x8D91 0x8D94 0x8D95 0x8D96 0x8D99 0x8D9F 0x8DA3 0x8DA8 0x8DAF 0x8DB1 0x8DB2 0x8DB3 0x8DB4 +0x8DB5 0x8DB8 0x8DBA 0x8DBC 0x8DBE 0x8DBF 0x8DC2 0x8DC3 0x8DC4 0x8DC5 0x8DC6 0x8DCB 0x8DCC 0x8DCE 0x8DCF 0x8DD0 +0x8DD1 0x8DD6 0x8DD7 0x8DDA 0x8DDB 0x8DDD 0x8DDE 0x8DDF 0x8DE1 0x8DE3 0x8DE4 0x8DE6 0x8DE8 0x8DE9 0x8DEA 0x8DEB +0x8DEC 0x8DEF 0x8DF0 0x8DF1 0x8DF3 0x8DF5 0x8DF6 0x8DF7 0x8DF8 0x8DF9 0x8DFA 0x8DFB 0x8DFC 0x8DFD 0x8DFF 0x8E04 +0x8E05 0x8E08 0x8E09 0x8E0A 0x8E0C 0x8E0E 0x8E0F 0x8E10 0x8E12 0x8E14 0x8E16 0x8E1C 0x8E1D 0x8E1E 0x8E1F 0x8E21 +0x8E22 0x8E23 0x8E26 0x8E27 0x8E29 0x8E2A 0x8E2B 0x8E2C 0x8E2D 0x8E2E 0x8E2F 0x8E30 0x8E31 0x8E34 0x8E35 0x8E36 +0x8E39 0x8E3A 0x8E3C 0x8E3D 0x8E40 0x8E41 0x8E42 0x8E44 0x8E45 0x8E47 0x8E48 0x8E49 0x8E4A 0x8E4B 0x8E4C 0x8E4D +0x8E4F 0x8E50 0x8E51 0x8E52 0x8E53 0x8E54 0x8E55 0x8E59 0x8E5A 0x8E5C 0x8E5F 0x8E60 0x8E61 0x8E62 0x8E63 0x8E64 +0x8E66 0x8E67 0x8E69 0x8E6C 0x8E6D 0x8E6F 0x8E70 0x8E72 0x8E74 0x8E76 0x8E7A 0x8E7B 0x8E7C 0x8E7D 0x8E7E 0x8E7F +0x8E80 0x8E81 0x8E82 0x8E84 0x8E85 0x8E87 0x8E89 0x8E8A 0x8E8B 0x8E8D 0x8E8F 0x8E90 0x8E91 0x8E92 0x8E93 0x8E94 +0x8E95 0x8E99 0x8E9A 0x8E9C 0x8E9D 0x8E9E 0x8EA1 0x8EA5 0x8EA6 0x8EAA 0x8EAB 0x8EAC 0x8EAD 0x8EAF 0x8EB0 0x8EB1 +0x8EB2 0x8EBA 0x8EBC 0x8EBE 0x8EC0 0x8EC1 0x8EC5 0x8EC6 0x8EC8 0x8ECA 0x8ECB 0x8ECC 0x8ECD 0x8ECE 0x8ECF 0x8ED1 +0x8ED2 0x8ED4 0x8EDA 0x8EDB 0x8EDD 0x8EDF 0x8EE2 0x8EE3 0x8EE4 0x8EE8 0x8EEB 0x8EF1 0x8EF2 0x8EF8 0x8EF9 0x8EFA +0x8EFB 0x8EFC 0x8EFD 0x8EFE 0x8EFF 0x8F00 0x8F03 0x8F04 0x8F05 0x8F07 0x8F08 0x8F09 0x8F0A 0x8F0B 0x8F0C 0x8F12 +0x8F13 0x8F14 0x8F15 0x8F17 0x8F19 0x8F1B 0x8F1C 0x8F1D 0x8F1E 0x8F1F 0x8F25 0x8F26 0x8F27 0x8F29 0x8F2A 0x8F2C +0x8F2D 0x8F2E 0x8F2F 0x8F33 0x8F36 0x8F38 0x8F39 0x8F3B 0x8F3C 0x8F3E 0x8F3F 0x8F40 0x8F42 0x8F44 0x8F45 0x8F46 +0x8F49 0x8F4C 0x8F4D 0x8F4E 0x8F54 0x8F57 0x8F58 0x8F5C 0x8F5D 0x8F5F 0x8F61 0x8F62 0x8F63 0x8F64 0x8F66 0x8F67 +0x8F68 0x8F69 0x8F6A 0x8F6B 0x8F6C 0x8F6D 0x8F6E 0x8F6F 0x8F70 0x8F71 0x8F72 0x8F73 0x8F74 0x8F75 0x8F76 0x8F77 +0x8F78 0x8F79 0x8F7A 0x8F7B 0x8F7C 0x8F7D 0x8F7E 0x8F7F 0x8F80 0x8F81 0x8F82 0x8F83 0x8F84 0x8F85 0x8F86 0x8F87 +0x8F88 0x8F89 0x8F8A 0x8F8B 0x8F8C 0x8F8D 0x8F8E 0x8F8F 0x8F90 0x8F91 0x8F92 0x8F93 0x8F94 0x8F95 0x8F96 0x8F97 +0x8F98 0x8F99 0x8F9A 0x8F9B 0x8F9C 0x8F9E 0x8F9F 0x8FA3 0x8FA6 0x8FA7 0x8FA8 0x8FA9 0x8FAB 0x8FAD 0x8FAE 0x8FAF +0x8FB0 0x8FB1 0x8FB2 0x8FB4 0x8FB5 0x8FB6 0x8FB7 0x8FB9 0x8FBA 0x8FBB 0x8FBC 0x8FBD 0x8FBE 0x8FBF 0x8FC0 0x8FC1 +0x8FC2 0x8FC4 0x8FC5 0x8FC6 0x8FC7 0x8FC8 0x8FC9 0x8FCB 0x8FCC 0x8FCD 0x8FCE 0x8FD0 0x8FD1 0x8FD2 0x8FD3 0x8FD4 +0x8FD5 0x8FD6 0x8FD7 0x8FD8 0x8FD9 0x8FDA 0x8FDB 0x8FDC 0x8FDD 0x8FDE 0x8FDF 0x8FE0 0x8FE1 0x8FE2 0x8FE3 0x8FE4 +0x8FE5 0x8FE6 0x8FE8 0x8FE9 0x8FEA 0x8FEB 0x8FED 0x8FEE 0x8FEF 0x8FF0 0x8FF2 0x8FF3 0x8FF4 0x8FF5 0x8FF6 0x8FF7 +0x8FF8 0x8FF9 0x8FFA 0x8FFB 0x8FFC 0x8FFD 0x8FFE 0x8FFF 0x9000 0x9001 0x9002 0x9003 0x9004 0x9005 0x9006 0x9008 +0x9009 0x900A 0x900B 0x900C 0x900D 0x900E 0x900F 0x9010 0x9011 0x9012 0x9013 0x9014 0x9015 0x9016 0x9017 0x9019 +0x901A 0x901B 0x901C 0x901D 0x901E 0x901F 0x9020 0x9021 0x9022 0x9023 0x9024 0x9026 0x9027 0x902D 0x902E 0x902F +0x9031 0x9032 0x9034 0x9035 0x9036 0x9038 0x9039 0x903B 0x903C 0x903D 0x903E 0x903F 0x9041 0x9042 0x9044 0x9045 +0x9046 0x9047 0x9049 0x904A 0x904B 0x904D 0x904E 0x904F 0x9050 0x9051 0x9052 0x9053 0x9054 0x9055 0x9056 0x9057 +0x9058 0x9059 0x905B 0x905C 0x905D 0x905E 0x9060 0x9061 0x9062 0x9063 0x9065 0x9067 0x9068 0x9069 0x906B 0x906D +0x906E 0x906F 0x9070 0x9072 0x9073 0x9074 0x9075 0x9076 0x9077 0x9078 0x9079 0x907A 0x907B 0x907C 0x907D 0x907E +0x907F 0x9080 0x9081 0x9082 0x9083 0x9084 0x9085 0x9086 0x9087 0x9088 0x9089 0x908A 0x908B 0x908D 0x908F 0x9090 +0x9091 0x9093 0x9094 0x9095 0x9097 0x9098 0x9099 0x909B 0x909D 0x909E 0x909F 0x90A0 0x90A1 0x90A2 0x90A3 0x90A5 +0x90A6 0x90A7 0x90A8 0x90AA 0x90AC 0x90AE 0x90AF 0x90B0 0x90B1 0x90B2 0x90B3 0x90B4 0x90B5 0x90B6 0x90B8 0x90B9 +0x90BA 0x90BB 0x90BD 0x90BE 0x90BF 0x90C1 0x90C3 0x90C4 0x90C5 0x90C7 0x90C8 0x90CA 0x90CE 0x90CF 0x90D0 0x90D1 +0x90D3 0x90D7 0x90DA 0x90DB 0x90DC 0x90DD 0x90DE 0x90DF 0x90E1 0x90E2 0x90E4 0x90E6 0x90E7 0x90E8 0x90EA 0x90EB +0x90EC 0x90ED 0x90EF 0x90F4 0x90F5 0x90F7 0x90F8 0x90FD 0x90FE 0x90FF 0x9100 0x9102 0x9103 0x9104 0x9105 0x9106 +0x9109 0x910C 0x9111 0x9112 0x9114 0x9115 0x9116 0x9117 0x9118 0x9119 0x911A 0x911C 0x911E 0x9120 0x9122 0x9123 +0x9127 0x9129 0x912B 0x912D 0x912E 0x912F 0x9130 0x9131 0x9132 0x9133 0x9134 0x9136 0x9139 0x913A 0x9142 0x9143 +0x9145 0x9146 0x9147 0x9148 0x9149 0x914A 0x914B 0x914C 0x914D 0x914E 0x914F 0x9150 0x9152 0x9154 0x9155 0x9156 +0x9157 0x9158 0x915A 0x915C 0x915D 0x915E 0x9161 0x9162 0x9163 0x9164 0x9165 0x9166 0x9169 0x916A 0x916C 0x916E +0x916F 0x9170 0x9171 0x9172 0x9173 0x9174 0x9175 0x9176 0x9177 0x9178 0x9179 0x917A 0x917D 0x917E 0x917F 0x9181 +0x9182 0x9183 0x9184 0x9185 0x9187 0x9189 0x918B 0x918C 0x918D 0x9190 0x9191 0x9192 0x9196 0x9197 0x919A 0x919B +0x919C 0x919E 0x91A1 0x91A2 0x91A3 0x91A4 0x91A8 0x91AA 0x91AB 0x91AC 0x91AD 0x91AE 0x91AF 0x91B1 0x91B2 0x91B4 +0x91B5 0x91B8 0x91BA 0x91BE 0x91C0 0x91C1 0x91C3 0x91C5 0x91C6 0x91C7 0x91C8 0x91C9 0x91CA 0x91CB 0x91CC 0x91CD +0x91CE 0x91CF 0x91D0 0x91D1 0x91D2 0x91D3 0x91D4 0x91D5 0x91D6 0x91D7 0x91D8 0x91D9 0x91DA 0x91DB 0x91DC 0x91DD +0x91DF 0x91E1 0x91E2 0x91E3 0x91E4 0x91E6 0x91E7 0x91E8 0x91E9 0x91EA 0x91EB 0x91EC 0x91ED 0x91EE 0x91F1 0x91F3 +0x91F4 0x91F5 0x91F6 0x91F7 0x91F8 0x91F9 0x91FA 0x91FC 0x91FD 0x91FE 0x91FF 0x9200 0x9201 0x9202 0x9203 0x9204 +0x9205 0x9206 0x9207 0x9208 0x9209 0x920A 0x920C 0x920D 0x920E 0x920F 0x9210 0x9211 0x9212 0x9214 0x9215 0x9216 +0x9217 0x9219 0x921A 0x921C 0x921E 0x9223 0x9224 0x9225 0x9226 0x9227 0x9229 0x922A 0x922C 0x922D 0x922E 0x9230 +0x9231 0x9232 0x9233 0x9234 0x9236 0x9237 0x9238 0x9239 0x923A 0x923D 0x923E 0x923F 0x9240 0x9244 0x9245 0x9246 +0x9248 0x9249 0x924A 0x924B 0x924C 0x924D 0x924E 0x924F 0x9250 0x9251 0x9252 0x9253 0x9254 0x9255 0x9256 0x9257 +0x925A 0x925B 0x925D 0x925E 0x9260 0x9261 0x9262 0x9263 0x9264 0x9265 0x9266 0x9267 0x9268 0x926C 0x926D 0x926E +0x926F 0x9270 0x9271 0x9272 0x9273 0x9274 0x9276 0x9277 0x9278 0x9279 0x927A 0x927B 0x927C 0x927D 0x927E 0x927F +0x9280 0x9282 0x9283 0x9285 0x9286 0x9287 0x9288 0x928A 0x928B 0x928C 0x928D 0x928E 0x9291 0x9293 0x9294 0x9295 +0x9296 0x9297 0x9298 0x9299 0x929A 0x929B 0x929C 0x929D 0x92A0 0x92A1 0x92A2 0x92A3 0x92A4 0x92A5 0x92A6 0x92A7 +0x92A8 0x92A9 0x92AA 0x92AB 0x92AC 0x92AD 0x92AE 0x92B1 0x92B2 0x92B3 0x92B6 0x92B7 0x92B9 0x92BB 0x92BC 0x92C1 +0x92C2 0x92C3 0x92C5 0x92C6 0x92C7 0x92C8 0x92C9 0x92CC 0x92CF 0x92D0 0x92D2 0x92D5 0x92D7 0x92D9 0x92DD 0x92DF +0x92E3 0x92E4 0x92E5 0x92E6 0x92E7 0x92E8 0x92E9 0x92EA 0x92EC 0x92ED 0x92EE 0x92EF 0x92F0 0x92F1 0x92F2 0x92F3 +0x92F6 0x92F8 0x92F9 0x92FA 0x92FC 0x9300 0x9301 0x9302 0x9304 0x9306 0x9307 0x9308 0x930F 0x9310 0x9312 0x9315 +0x9318 0x9319 0x931A 0x931B 0x931E 0x931F 0x9320 0x9321 0x9322 0x9323 0x9324 0x9326 0x9327 0x9328 0x9329 0x932A +0x932B 0x932C 0x932E 0x932F 0x9332 0x9333 0x9335 0x9336 0x9338 0x933A 0x933B 0x933C 0x933E 0x9340 0x9341 0x9343 +0x9344 0x9345 0x9346 0x9347 0x9348 0x9349 0x934A 0x934B 0x934D 0x9351 0x9352 0x9354 0x9355 0x9356 0x9358 0x9359 +0x935A 0x935B 0x935C 0x935E 0x9360 0x9364 0x9365 0x9369 0x936A 0x936C 0x936D 0x936E 0x9370 0x9375 0x9376 0x937A +0x937C 0x937E 0x9382 0x9384 0x9385 0x9387 0x938A 0x938C 0x938F 0x9393 0x9394 0x9396 0x9397 0x9398 0x939A 0x939B +0x939D 0x93A1 0x93A2 0x93A3 0x93A4 0x93A6 0x93A7 0x93A9 0x93AA 0x93AC 0x93AD 0x93AE 0x93AF 0x93B0 0x93B2 0x93B3 +0x93B5 0x93B6 0x93B7 0x93B8 0x93B9 0x93BF 0x93C2 0x93C3 0x93C4 0x93C7 0x93C8 0x93CA 0x93CB 0x93CC 0x93CD 0x93CF +0x93D0 0x93D1 0x93D6 0x93D7 0x93D8 0x93DC 0x93DD 0x93DE 0x93DF 0x93E1 0x93E2 0x93E4 0x93E5 0x93E6 0x93E8 0x93F0 +0x93F1 0x93F5 0x93F6 0x93F7 0x93F9 0x93FA 0x93FB 0x93FD 0x9403 0x9404 0x9407 0x940B 0x940D 0x940E 0x940F 0x9410 +0x9412 0x9413 0x9414 0x9418 0x9419 0x941A 0x941D 0x9420 0x9421 0x9424 0x9425 0x9426 0x9427 0x9428 0x9429 0x942B +0x942E 0x942F 0x9431 0x9432 0x9433 0x9435 0x9436 0x9438 0x943A 0x943D 0x943E 0x943F 0x9440 0x9441 0x9442 0x9444 +0x944A 0x944C 0x9451 0x9452 0x9453 0x9454 0x9455 0x945A 0x945B 0x945E 0x9460 0x9462 0x9463 0x9464 0x9465 0x946A +0x946B 0x946D 0x9470 0x9471 0x9472 0x9473 0x9474 0x9475 0x9476 0x9477 0x9478 0x9479 0x947C 0x947D 0x947E 0x947F +0x9480 0x9481 0x9482 0x9483 0x9485 0x9486 0x9487 0x9488 0x9489 0x948A 0x948B 0x948C 0x948D 0x948E 0x948F 0x9490 +0x9491 0x9492 0x9493 0x9494 0x9495 0x9496 0x9497 0x9498 0x9499 0x949A 0x949B 0x949C 0x949D 0x949E 0x949F 0x94A0 +0x94A1 0x94A2 0x94A3 0x94A4 0x94A5 0x94A6 0x94A7 0x94A8 0x94A9 0x94AA 0x94AB 0x94AC 0x94AD 0x94AE 0x94AF 0x94B0 +0x94B1 0x94B2 0x94B3 0x94B4 0x94B5 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BB 0x94BC 0x94BD 0x94BE 0x94BF 0x94C0 +0x94C1 0x94C2 0x94C3 0x94C4 0x94C5 0x94C6 0x94C7 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC 0x94CD 0x94CE 0x94CF 0x94D0 +0x94D1 0x94D2 0x94D3 0x94D4 0x94D5 0x94D6 0x94D7 0x94D8 0x94D9 0x94DA 0x94DB 0x94DC 0x94DD 0x94DE 0x94DF 0x94E0 +0x94E1 0x94E2 0x94E3 0x94E4 0x94E5 0x94E6 0x94E7 0x94E8 0x94E9 0x94EA 0x94EB 0x94EC 0x94ED 0x94EE 0x94EF 0x94F0 +0x94F1 0x94F2 0x94F3 0x94F4 0x94F5 0x94F6 0x94F7 0x94F8 0x94F9 0x94FA 0x94FB 0x94FC 0x94FD 0x94FE 0x94FF 0x9500 +0x9501 0x9502 0x9503 0x9504 0x9505 0x9506 0x9507 0x9508 0x9509 0x950A 0x950B 0x950C 0x950D 0x950E 0x950F 0x9510 +0x9511 0x9512 0x9513 0x9514 0x9515 0x9516 0x9517 0x9518 0x9519 0x951A 0x951B 0x951C 0x951D 0x951E 0x951F 0x9520 +0x9521 0x9522 0x9523 0x9524 0x9525 0x9526 0x9527 0x9528 0x9529 0x952A 0x952B 0x952C 0x952D 0x952E 0x952F 0x9530 +0x9531 0x9532 0x9533 0x9534 0x9535 0x9536 0x9537 0x9538 0x9539 0x953A 0x953B 0x953C 0x953D 0x953E 0x953F 0x9540 +0x9541 0x9542 0x9543 0x9544 0x9545 0x9546 0x9547 0x9548 0x9549 0x954A 0x954B 0x954C 0x954D 0x954E 0x954F 0x9550 +0x9551 0x9552 0x9553 0x9554 0x9555 0x9556 0x9557 0x9558 0x9559 0x955A 0x955B 0x955C 0x955D 0x955E 0x955F 0x9560 +0x9561 0x9562 0x9563 0x9564 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C 0x956D 0x956E 0x956F 0x9570 +0x9571 0x9572 0x9573 0x9574 0x9575 0x9576 0x9577 0x9578 0x957A 0x957B 0x957C 0x957D 0x957F 0x9580 0x9581 0x9582 +0x9583 0x9586 0x9587 0x9588 0x9589 0x958A 0x958B 0x958C 0x958D 0x958E 0x958F 0x9590 0x9591 0x9592 0x9593 0x9594 +0x9596 0x9598 0x9599 0x959B 0x959C 0x959E 0x959F 0x95A0 0x95A1 0x95A2 0x95A3 0x95A4 0x95A5 0x95A7 0x95A8 0x95A9 +0x95AA 0x95AB 0x95AC 0x95AD 0x95AE 0x95B0 0x95B1 0x95B2 0x95B5 0x95B6 0x95B7 0x95B9 0x95BA 0x95BB 0x95BC 0x95BD +0x95BE 0x95BF 0x95C0 0x95C3 0x95C5 0x95C6 0x95C7 0x95C8 0x95C9 0x95CA 0x95CB 0x95CC 0x95CD 0x95D0 0x95D1 0x95D2 +0x95D3 0x95D4 0x95D5 0x95D6 0x95D8 0x95DA 0x95DB 0x95DC 0x95DE 0x95DF 0x95E0 0x95E1 0x95E2 0x95E3 0x95E4 0x95E5 +0x95E8 0x95E9 0x95EA 0x95EB 0x95EC 0x95ED 0x95EE 0x95EF 0x95F0 0x95F1 0x95F2 0x95F3 0x95F4 0x95F5 0x95F6 0x95F7 +0x95F8 0x95F9 0x95FA 0x95FB 0x95FC 0x95FD 0x95FE 0x95FF 0x9600 0x9601 0x9602 0x9603 0x9604 0x9605 0x9606 0x9607 +0x9608 0x9609 0x960A 0x960B 0x960C 0x960D 0x960E 0x960F 0x9610 0x9611 0x9612 0x9613 0x9614 0x9615 0x9616 0x9617 +0x9618 0x9619 0x961A 0x961B 0x961C 0x961D 0x961E 0x961F 0x9620 0x9621 0x9622 0x9623 0x9624 0x9627 0x9628 0x962A +0x962C 0x962D 0x962E 0x962F 0x9630 0x9631 0x9632 0x9633 0x9634 0x9635 0x9636 0x9639 0x963A 0x963B 0x963C 0x963D +0x963F 0x9640 0x9641 0x9642 0x9644 0x9645 0x9646 0x9647 0x9648 0x9649 0x964B 0x964C 0x964D 0x964E 0x964F 0x9650 +0x9651 0x9654 0x9655 0x9658 0x965B 0x965C 0x965D 0x965E 0x965F 0x9661 0x9662 0x9663 0x9664 0x9665 0x9666 0x9667 +0x9668 0x9669 0x966A 0x966C 0x9670 0x9672 0x9673 0x9674 0x9675 0x9676 0x9677 0x9678 0x967A 0x967D 0x9683 0x9684 +0x9685 0x9686 0x9688 0x9689 0x968A 0x968B 0x968D 0x968E 0x968F 0x9690 0x9691 0x9694 0x9695 0x9697 0x9698 0x9699 +0x969B 0x969C 0x96A0 0x96A3 0x96A4 0x96A7 0x96A8 0x96A9 0x96AA 0x96AE 0x96B0 0x96B1 0x96B2 0x96B3 0x96B4 0x96B6 +0x96B7 0x96B8 0x96B9 0x96BA 0x96BB 0x96BC 0x96BD 0x96BE 0x96C0 0x96C1 0x96C3 0x96C4 0x96C5 0x96C6 0x96C7 0x96C9 +0x96CA 0x96CB 0x96CC 0x96CD 0x96CE 0x96CF 0x96D1 0x96D2 0x96D4 0x96D5 0x96D6 0x96D8 0x96D9 0x96DB 0x96DC 0x96DE +0x96E0 0x96E2 0x96E3 0x96E8 0x96E9 0x96EA 0x96EB 0x96EF 0x96F0 0x96F1 0x96F2 0x96F3 0x96F6 0x96F7 0x96F9 0x96FB +0x96FE 0x9700 0x9701 0x9702 0x9704 0x9705 0x9706 0x9707 0x9708 0x9709 0x970A 0x970D 0x970E 0x970F 0x9711 0x9713 +0x9716 0x9719 0x971C 0x971E 0x9721 0x9722 0x9724 0x9726 0x9727 0x9728 0x972A 0x972D 0x9730 0x9732 0x9738 0x9739 +0x973D 0x973E 0x9742 0x9744 0x9746 0x9748 0x9749 0x974D 0x974F 0x9751 0x9752 0x9753 0x9754 0x9756 0x9758 0x9759 +0x975A 0x975B 0x975C 0x975D 0x975E 0x9760 0x9761 0x9762 0x9764 0x9765 0x9766 0x9767 0x9768 0x9769 0x976A 0x976B +0x976C 0x976D 0x976E 0x9770 0x9771 0x9772 0x9773 0x9774 0x9776 0x9777 0x9778 0x9779 0x977A 0x977B 0x977C 0x977D +0x977F 0x9780 0x9781 0x9784 0x9785 0x9786 0x978B 0x978C 0x978D 0x978E 0x978F 0x9790 0x9791 0x9792 0x9794 0x9798 +0x979C 0x97A0 0x97A1 0x97A3 0x97A6 0x97A7 0x97A8 0x97AB 0x97AC 0x97AD 0x97AE 0x97AF 0x97B2 0x97B3 0x97B4 0x97BD +0x97BE 0x97BF 0x97C1 0x97C2 0x97C3 0x97C6 0x97C8 0x97C9 0x97CB 0x97CC 0x97CD 0x97D3 0x97D9 0x97DB 0x97DC 0x97DE +0x97E1 0x97E6 0x97E7 0x97E8 0x97E9 0x97EA 0x97EB 0x97EC 0x97ED 0x97EE 0x97F1 0x97F2 0x97F3 0x97F5 0x97F6 0x97F9 +0x97FB 0x97FE 0x97FF 0x9800 0x9801 0x9802 0x9803 0x9804 0x9805 0x9806 0x9807 0x9808 0x980A 0x980C 0x980D 0x980E +0x980F 0x9810 0x9811 0x9812 0x9813 0x9814 0x9816 0x9817 0x9818 0x981A 0x981C 0x9820 0x9821 0x9824 0x9826 0x982B +0x982C 0x982D 0x982E 0x9830 0x9832 0x9834 0x9835 0x9837 0x9838 0x9839 0x983B 0x983C 0x983D 0x9846 0x984B 0x984C +0x984D 0x984E 0x984F 0x9851 0x9852 0x9853 0x9854 0x9855 0x9857 0x9858 0x9859 0x985A 0x985B 0x985E 0x9862 0x9863 +0x9865 0x9867 0x9869 0x986B 0x986C 0x986F 0x9870 0x9871 0x9872 0x9873 0x9874 0x9875 0x9876 0x9877 0x9878 0x9879 +0x987A 0x987B 0x987C 0x987D 0x987E 0x987F 0x9880 0x9881 0x9882 0x9883 0x9884 0x9885 0x9886 0x9887 0x9888 0x9889 +0x988A 0x988B 0x988C 0x988D 0x988E 0x988F 0x9890 0x9891 0x9892 0x9893 0x9894 0x9895 0x9896 0x9897 0x9898 0x9899 +0x989A 0x989B 0x989C 0x989D 0x989E 0x989F 0x98A0 0x98A1 0x98A2 0x98A3 0x98A4 0x98A5 0x98A6 0x98A7 0x98A8 0x98A9 +0x98AA 0x98AC 0x98AD 0x98AE 0x98AF 0x98B1 0x98B2 0x98B3 0x98B6 0x98B8 0x98BA 0x98BB 0x98BC 0x98BD 0x98BE 0x98BF +0x98C0 0x98C1 0x98C2 0x98C3 0x98C4 0x98C6 0x98C7 0x98C8 0x98C9 0x98CB 0x98CC 0x98CE 0x98CF 0x98D0 0x98D1 0x98D2 +0x98D3 0x98D4 0x98D5 0x98D6 0x98D7 0x98D8 0x98D9 0x98DA 0x98DB 0x98DC 0x98DE 0x98DF 0x98E0 0x98E1 0x98E2 0x98E3 +0x98E5 0x98E7 0x98E8 0x98E9 0x98EA 0x98EB 0x98ED 0x98EE 0x98EF 0x98F2 0x98F4 0x98F6 0x98F9 0x98FA 0x98FC 0x98FD +0x98FE 0x98FF 0x9900 0x9902 0x9903 0x9904 0x9905 0x9907 0x9908 0x9909 0x990A 0x990C 0x990D 0x990E 0x990F 0x9910 +0x9911 0x9912 0x9913 0x9914 0x9915 0x9916 0x9917 0x9918 0x991A 0x991B 0x991C 0x991D 0x991E 0x991F 0x9920 0x9921 +0x9924 0x9928 0x992C 0x992E 0x9931 0x9932 0x9933 0x9935 0x9936 0x9937 0x9938 0x993A 0x993C 0x993D 0x993E 0x993F +0x9941 0x9942 0x9943 0x9945 0x9948 0x9949 0x994A 0x994B 0x994C 0x994D 0x9950 0x9951 0x9952 0x9954 0x9955 0x9957 +0x9958 0x995C 0x995E 0x9962 0x9963 0x9964 0x9965 0x9966 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x996D 0x996E +0x996F 0x9970 0x9971 0x9972 0x9973 0x9974 0x9975 0x9976 0x9977 0x9978 0x9979 0x997A 0x997B 0x997C 0x997D 0x997E +0x997F 0x9980 0x9981 0x9982 0x9983 0x9984 0x9985 0x9986 0x9987 0x9988 0x9989 0x998A 0x998B 0x998C 0x998D 0x998E +0x998F 0x9990 0x9991 0x9992 0x9993 0x9994 0x9995 0x9996 0x9997 0x9998 0x9999 0x999D 0x999E 0x99A5 0x99A7 0x99A8 +0x99AC 0x99AD 0x99AE 0x99AF 0x99B0 0x99B1 0x99B2 0x99B3 0x99B4 0x99B5 0x99B9 0x99BA 0x99BB 0x99BC 0x99BD 0x99C1 +0x99C2 0x99C3 0x99C4 0x99C5 0x99C6 0x99C7 0x99C8 0x99C9 0x99CB 0x99CC 0x99CD 0x99CE 0x99CF 0x99D0 0x99D1 0x99D2 +0x99D3 0x99D4 0x99D5 0x99D6 0x99D7 0x99D8 0x99D9 0x99DB 0x99DC 0x99DD 0x99DF 0x99E1 0x99E2 0x99E3 0x99E4 0x99E5 +0x99E7 0x99E9 0x99EA 0x99EC 0x99ED 0x99EE 0x99F0 0x99F1 0x99F2 0x99F8 0x99FB 0x99FC 0x99FF 0x9A01 0x9A02 0x9A03 +0x9A04 0x9A05 0x9A06 0x9A08 0x9A0A 0x9A0C 0x9A0D 0x9A0E 0x9A0F 0x9A11 0x9A12 0x9A13 0x9A16 0x9A19 0x9A1E 0x9A20 +0x9A24 0x9A27 0x9A28 0x9A2B 0x9A2D 0x9A2E 0x9A2F 0x9A30 0x9A31 0x9A35 0x9A36 0x9A37 0x9A38 0x9A3E 0x9A40 0x9A41 +0x9A42 0x9A43 0x9A44 0x9A45 0x9A4A 0x9A4C 0x9A4D 0x9A4E 0x9A4F 0x9A50 0x9A52 0x9A55 0x9A57 0x9A5A 0x9A5B 0x9A5F +0x9A62 0x9A63 0x9A64 0x9A65 0x9A66 0x9A69 0x9A6A 0x9A6B 0x9A6C 0x9A6D 0x9A6E 0x9A6F 0x9A70 0x9A71 0x9A72 0x9A73 +0x9A74 0x9A75 0x9A76 0x9A77 0x9A78 0x9A79 0x9A7A 0x9A7B 0x9A7C 0x9A7D 0x9A7E 0x9A7F 0x9A80 0x9A81 0x9A82 0x9A83 +0x9A84 0x9A85 0x9A86 0x9A87 0x9A88 0x9A89 0x9A8A 0x9A8B 0x9A8C 0x9A8D 0x9A8E 0x9A8F 0x9A90 0x9A91 0x9A92 0x9A93 +0x9A94 0x9A95 0x9A96 0x9A97 0x9A98 0x9A99 0x9A9A 0x9A9B 0x9A9C 0x9A9D 0x9A9E 0x9A9F 0x9AA0 0x9AA1 0x9AA2 0x9AA3 +0x9AA4 0x9AA5 0x9AA6 0x9AA7 0x9AA8 0x9AAB 0x9AAD 0x9AAF 0x9AB0 0x9AB1 0x9AB3 0x9AB4 0x9AB6 0x9AB7 0x9AB8 0x9AB9 +0x9ABA 0x9ABB 0x9ABC 0x9ABE 0x9ABF 0x9AC0 0x9AC1 0x9AC2 0x9AC3 0x9AC4 0x9AC5 0x9AC6 0x9AC7 0x9AC8 0x9ACA 0x9ACB +0x9ACC 0x9ACD 0x9ACE 0x9ACF 0x9AD0 0x9AD1 0x9AD2 0x9AD3 0x9AD4 0x9AD5 0x9AD6 0x9AD8 0x9AD9 0x9ADC 0x9ADD 0x9ADE +0x9ADF 0x9AE1 0x9AE2 0x9AE3 0x9AE5 0x9AE6 0x9AE7 0x9AEA 0x9AEB 0x9AEC 0x9AED 0x9AEE 0x9AEF 0x9AF1 0x9AF2 0x9AF3 +0x9AF4 0x9AF6 0x9AF7 0x9AF9 0x9AFA 0x9AFB 0x9AFC 0x9AFD 0x9AFE 0x9B01 0x9B03 0x9B04 0x9B05 0x9B06 0x9B08 0x9B0A +0x9B0B 0x9B0C 0x9B0D 0x9B0E 0x9B0F 0x9B10 0x9B11 0x9B12 0x9B13 0x9B15 0x9B16 0x9B17 0x9B18 0x9B19 0x9B1A 0x9B1E +0x9B1F 0x9B20 0x9B22 0x9B23 0x9B24 0x9B25 0x9B27 0x9B28 0x9B29 0x9B2A 0x9B2B 0x9B2E 0x9B2F 0x9B31 0x9B32 0x9B33 +0x9B35 0x9B36 0x9B37 0x9B39 0x9B3A 0x9B3B 0x9B3C 0x9B3E 0x9B3F 0x9B41 0x9B42 0x9B43 0x9B44 0x9B45 0x9B46 0x9B47 +0x9B48 0x9B49 0x9B4A 0x9B4B 0x9B4C 0x9B4D 0x9B4E 0x9B4F 0x9B51 0x9B52 0x9B54 0x9B55 0x9B56 0x9B58 0x9B59 0x9B5A +0x9B5B 0x9B5C 0x9B5F 0x9B60 0x9B61 0x9B62 0x9B64 0x9B66 0x9B67 0x9B68 0x9B69 0x9B6C 0x9B6F 0x9B70 0x9B71 0x9B74 +0x9B75 0x9B76 0x9B77 0x9B7A 0x9B7B 0x9B7C 0x9B7D 0x9B7E 0x9B80 0x9B81 0x9B82 0x9B83 0x9B84 0x9B85 0x9B86 0x9B87 +0x9B88 0x9B8A 0x9B8B 0x9B8D 0x9B8E 0x9B90 0x9B91 0x9B92 0x9B93 0x9B95 0x9B96 0x9B97 0x9B9A 0x9B9B 0x9B9C 0x9B9D +0x9B9E 0x9B9F 0x9BA0 0x9BA1 0x9BA2 0x9BA3 0x9BA4 0x9BA5 0x9BA6 0x9BA8 0x9BAA 0x9BAB 0x9BAD 0x9BAE 0x9BAF 0x9BB0 +0x9BB3 0x9BB4 0x9BB5 0x9BB6 0x9BB8 0x9BB9 0x9BBA 0x9BBD 0x9BBF 0x9BC0 0x9BC1 0x9BC3 0x9BC4 0x9BC6 0x9BC7 0x9BC8 +0x9BC9 0x9BCA 0x9BCF 0x9BD1 0x9BD2 0x9BD3 0x9BD4 0x9BD5 0x9BD6 0x9BD7 0x9BD9 0x9BDA 0x9BDB 0x9BDC 0x9BDD 0x9BDE +0x9BE0 0x9BE1 0x9BE2 0x9BE3 0x9BE4 0x9BE5 0x9BE6 0x9BE7 0x9BE8 0x9BEA 0x9BEB 0x9BEC 0x9BED 0x9BF0 0x9BF1 0x9BF2 +0x9BF4 0x9BF5 0x9BF6 0x9BF7 0x9BF8 0x9BFB 0x9BFD 0x9BFF 0x9C01 0x9C02 0x9C03 0x9C04 0x9C05 0x9C06 0x9C07 0x9C08 +0x9C09 0x9C0A 0x9C0B 0x9C0C 0x9C0D 0x9C0E 0x9C0F 0x9C10 0x9C12 0x9C13 0x9C14 0x9C15 0x9C17 0x9C1B 0x9C1C 0x9C1D +0x9C1F 0x9C20 0x9C21 0x9C23 0x9C24 0x9C25 0x9C27 0x9C28 0x9C29 0x9C2D 0x9C2E 0x9C2F 0x9C30 0x9C31 0x9C32 0x9C33 +0x9C35 0x9C36 0x9C37 0x9C39 0x9C3A 0x9C3B 0x9C3C 0x9C3E 0x9C40 0x9C42 0x9C45 0x9C46 0x9C47 0x9C48 0x9C49 0x9C4A +0x9C4B 0x9C4D 0x9C52 0x9C54 0x9C56 0x9C57 0x9C58 0x9C59 0x9C5A 0x9C5D 0x9C5F 0x9C60 0x9C63 0x9C64 0x9C65 0x9C66 +0x9C67 0x9C68 0x9C6D 0x9C6E 0x9C6F 0x9C72 0x9C74 0x9C75 0x9C76 0x9C77 0x9C78 0x9C7A 0x9C7C 0x9C7D 0x9C7E 0x9C7F +0x9C80 0x9C81 0x9C82 0x9C83 0x9C84 0x9C85 0x9C86 0x9C87 0x9C88 0x9C89 0x9C8A 0x9C8B 0x9C8C 0x9C8D 0x9C8E 0x9C8F +0x9C90 0x9C91 0x9C92 0x9C93 0x9C94 0x9C95 0x9C96 0x9C97 0x9C98 0x9C99 0x9C9A 0x9C9B 0x9C9C 0x9C9D 0x9C9E 0x9C9F +0x9CA0 0x9CA1 0x9CA2 0x9CA3 0x9CA4 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAA 0x9CAB 0x9CAC 0x9CAD 0x9CAE 0x9CAF +0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 0x9CB6 0x9CB7 0x9CB8 0x9CB9 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CBE 0x9CBF +0x9CC0 0x9CC1 0x9CC2 0x9CC3 0x9CC4 0x9CC5 0x9CC6 0x9CC7 0x9CC8 0x9CC9 0x9CCA 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF +0x9CD0 0x9CD1 0x9CD2 0x9CD3 0x9CD4 0x9CD5 0x9CD6 0x9CD7 0x9CD8 0x9CD9 0x9CDA 0x9CDB 0x9CDC 0x9CDD 0x9CDE 0x9CDF +0x9CE0 0x9CE1 0x9CE2 0x9CE3 0x9CE4 0x9CE5 0x9CE6 0x9CE7 0x9CE9 0x9CEA 0x9CEB 0x9CEC 0x9CED 0x9CF0 0x9CF1 0x9CF2 +0x9CF3 0x9CF4 0x9CF5 0x9CF6 0x9CF7 0x9CF9 0x9CFA 0x9CFB 0x9CFC 0x9CFD 0x9CFE 0x9CFF 0x9D00 0x9D02 0x9D03 0x9D04 +0x9D05 0x9D06 0x9D07 0x9D08 0x9D09 0x9D0E 0x9D10 0x9D12 0x9D14 0x9D15 0x9D1B 0x9D1C 0x9D1D 0x9D1E 0x9D1F 0x9D23 +0x9D26 0x9D28 0x9D2A 0x9D2B 0x9D2C 0x9D2F 0x9D30 0x9D33 0x9D34 0x9D37 0x9D3B 0x9D3D 0x9D3E 0x9D3F 0x9D41 0x9D42 +0x9D43 0x9D44 0x9D46 0x9D48 0x9D4F 0x9D50 0x9D51 0x9D52 0x9D53 0x9D59 0x9D5C 0x9D5D 0x9D5E 0x9D5F 0x9D60 0x9D61 +0x9D64 0x9D6A 0x9D6B 0x9D6C 0x9D6E 0x9D6F 0x9D70 0x9D72 0x9D77 0x9D7A 0x9D7E 0x9D84 0x9D86 0x9D87 0x9D89 0x9D8A +0x9D8F 0x9D92 0x9D93 0x9D96 0x9D98 0x9D9A 0x9DA0 0x9DA1 0x9DA4 0x9DA5 0x9DA9 0x9DAA 0x9DAB 0x9DAC 0x9DAF 0x9DB1 +0x9DB2 0x9DB4 0x9DB5 0x9DB8 0x9DB9 0x9DBA 0x9DBB 0x9DBC 0x9DBF 0x9DC0 0x9DC1 0x9DC2 0x9DC3 0x9DC4 0x9DC6 0x9DC8 +0x9DC9 0x9DCA 0x9DCF 0x9DD3 0x9DD6 0x9DD7 0x9DD9 0x9DDA 0x9DDF 0x9DE5 0x9DE6 0x9DEB 0x9DED 0x9DEF 0x9DF2 0x9DF3 +0x9DF4 0x9DF8 0x9DF9 0x9DFA 0x9DFD 0x9DFF 0x9E02 0x9E07 0x9E0A 0x9E0C 0x9E0F 0x9E11 0x9E15 0x9E18 0x9E19 0x9E1A +0x9E1B 0x9E1D 0x9E1E 0x9E1F 0x9E20 0x9E21 0x9E22 0x9E23 0x9E24 0x9E25 0x9E26 0x9E27 0x9E28 0x9E29 0x9E2A 0x9E2B +0x9E2C 0x9E2D 0x9E2E 0x9E2F 0x9E30 0x9E31 0x9E32 0x9E33 0x9E34 0x9E35 0x9E36 0x9E37 0x9E38 0x9E39 0x9E3A 0x9E3B +0x9E3C 0x9E3D 0x9E3E 0x9E3F 0x9E40 0x9E41 0x9E42 0x9E43 0x9E44 0x9E45 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4A 0x9E4B +0x9E4C 0x9E4D 0x9E4E 0x9E4F 0x9E50 0x9E51 0x9E52 0x9E53 0x9E54 0x9E55 0x9E56 0x9E57 0x9E58 0x9E59 0x9E5A 0x9E5B +0x9E5C 0x9E5D 0x9E5E 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E63 0x9E64 0x9E65 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B +0x9E6C 0x9E6D 0x9E6E 0x9E6F 0x9E70 0x9E71 0x9E72 0x9E73 0x9E74 0x9E75 0x9E78 0x9E79 0x9E7A 0x9E7C 0x9E7D 0x9E7E +0x9E7F 0x9E80 0x9E81 0x9E82 0x9E83 0x9E86 0x9E87 0x9E88 0x9E89 0x9E8A 0x9E8B 0x9E8C 0x9E8D 0x9E8E 0x9E90 0x9E91 +0x9E92 0x9E93 0x9E94 0x9E95 0x9E96 0x9E97 0x9E99 0x9E9A 0x9E9B 0x9E9C 0x9E9D 0x9E9F 0x9EA0 0x9EA1 0x9EA4 0x9EA5 +0x9EA6 0x9EA7 0x9EA8 0x9EA9 0x9EAA 0x9EAB 0x9EAC 0x9EAD 0x9EAE 0x9EAF 0x9EB0 0x9EB1 0x9EB2 0x9EB3 0x9EB4 0x9EB5 +0x9EB6 0x9EB7 0x9EB8 0x9EB9 0x9EBA 0x9EBB 0x9EBC 0x9EBD 0x9EBE 0x9EBF 0x9EC0 0x9EC1 0x9EC2 0x9EC3 0x9EC4 0x9EC5 +0x9EC6 0x9EC7 0x9EC8 0x9EC9 0x9ECA 0x9ECB 0x9ECC 0x9ECD 0x9ECE 0x9ECF 0x9ED0 0x9ED1 0x9ED2 0x9ED3 0x9ED4 0x9ED5 +0x9ED6 0x9ED7 0x9ED8 0x9ED9 0x9EDA 0x9EDB 0x9EDC 0x9EDD 0x9EDE 0x9EDF 0x9EE0 0x9EE1 0x9EE2 0x9EE3 0x9EE4 0x9EE5 +0x9EE6 0x9EE7 0x9EE8 0x9EE9 0x9EEA 0x9EEB 0x9EEC 0x9EED 0x9EEE 0x9EEF 0x9EF0 0x9EF1 0x9EF2 0x9EF3 0x9EF4 0x9EF5 +0x9EF6 0x9EF7 0x9EF8 0x9EF9 0x9EFA 0x9EFB 0x9EFC 0x9EFD 0x9EFE 0x9EFF 0x9F00 0x9F01 0x9F02 0x9F03 0x9F04 0x9F05 +0x9F06 0x9F07 0x9F08 0x9F09 0x9F0A 0x9F0B 0x9F0C 0x9F0D 0x9F0E 0x9F0F 0x9F10 0x9F11 0x9F12 0x9F13 0x9F14 0x9F15 +0x9F16 0x9F17 0x9F18 0x9F19 0x9F1A 0x9F1B 0x9F1C 0x9F1D 0x9F1E 0x9F1F 0x9F20 0x9F21 0x9F22 0x9F23 0x9F24 0x9F25 +0x9F26 0x9F27 0x9F28 0x9F29 0x9F2A 0x9F2B 0x9F2C 0x9F2D 0x9F2E 0x9F2F 0x9F30 0x9F31 0x9F32 0x9F33 0x9F34 0x9F35 +0x9F36 0x9F37 0x9F38 0x9F39 0x9F3A 0x9F3B 0x9F3C 0x9F3D 0x9F3E 0x9F3F 0x9F40 0x9F41 0x9F42 0x9F43 0x9F44 0x9F45 +0x9F46 0x9F47 0x9F48 0x9F49 0x9F4A 0x9F4B 0x9F4C 0x9F4D 0x9F4E 0x9F4F 0x9F50 0x9F51 0x9F52 0x9F53 0x9F54 0x9F55 +0x9F56 0x9F57 0x9F58 0x9F59 0x9F5A 0x9F5B 0x9F5C 0x9F5D 0x9F5E 0x9F5F 0x9F60 0x9F61 0x9F62 0x9F63 0x9F64 0x9F65 +0x9F66 0x9F67 0x9F68 0x9F69 0x9F6A 0x9F6B 0x9F6C 0x9F6D 0x9F6E 0x9F6F 0x9F70 0x9F71 0x9F72 0x9F73 0x9F74 0x9F75 +0x9F76 0x9F77 0x9F78 0x9F79 0x9F7A 0x9F7B 0x9F7C 0x9F7D 0x9F7E 0x9F7F 0x9F80 0x9F81 0x9F82 0x9F83 0x9F84 0x9F85 +0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A 0x9F8B 0x9F8C 0x9F8D 0x9F8E 0x9F8F 0x9F90 0x9F91 0x9F92 0x9F93 0x9F94 0x9F95 +0x9F96 0x9F97 0x9F98 0x9F99 0x9F9A 0x9F9B 0x9F9C 0x9F9D 0x9F9E 0x9F9F 0x9FA0 0x9FA1 0x9FA2 0x9FA3 0x9FA4 0x9FA5 +0x9FB0 0x9FB1 0x9FBF 0x9FCD 0x9FCE 0x9FCF 0x9FD4 0x9FEB 0x9FEC 0x9FED 0x9FFD 0xAC00 0xAC01 0xAC02 0xAC03 0xAC04 +0xAC05 0xAC06 0xAC07 0xAC08 0xAC09 0xAC0A 0xAC0B 0xAC0C 0xAC0D 0xAC0E 0xAC0F 0xAC10 0xAC11 0xAC12 0xAC13 0xAC14 +0xAC15 0xAC16 0xAC17 0xAC18 0xAC19 0xAC1A 0xAC1B 0xAC1C 0xAC1D 0xAC1E 0xAC1F 0xAC20 0xAC21 0xAC22 0xAC23 0xAC24 +0xAC25 0xAC26 0xAC27 0xAC28 0xAC29 0xAC2A 0xAC2B 0xAC2C 0xAC2D 0xAC2E 0xAC2F 0xAC30 0xAC31 0xAC32 0xAC33 0xAC34 +0xAC35 0xAC36 0xAC37 0xAC38 0xAC39 0xAC3A 0xAC3B 0xAC3C 0xAC3D 0xAC3E 0xAC3F 0xAC40 0xAC41 0xAC42 0xAC43 0xAC44 +0xAC45 0xAC46 0xAC47 0xAC48 0xAC49 0xAC4A 0xAC4B 0xAC4C 0xAC4D 0xAC4E 0xAC4F 0xAC50 0xAC51 0xAC52 0xAC53 0xAC54 +0xAC55 0xAC56 0xAC57 0xAC58 0xAC59 0xAC5A 0xAC5B 0xAC5C 0xAC5D 0xAC5E 0xAC5F 0xAC60 0xAC61 0xAC62 0xAC63 0xAC64 +0xAC65 0xAC66 0xAC67 0xAC68 0xAC69 0xAC6A 0xAC6B 0xAC6C 0xAC6D 0xAC6E 0xAC6F 0xAC70 0xAC71 0xAC72 0xAC73 0xAC74 +0xAC75 0xAC76 0xAC77 0xAC78 0xAC79 0xAC7A 0xAC7B 0xAC7C 0xAC7D 0xAC7E 0xAC7F 0xAC80 0xAC81 0xAC82 0xAC83 0xAC84 +0xAC85 0xAC86 0xAC87 0xAC88 0xAC89 0xAC8A 0xAC8B 0xAC8C 0xAC8D 0xAC8E 0xAC8F 0xAC90 0xAC91 0xAC92 0xAC93 0xAC94 +0xAC95 0xAC96 0xAC97 0xAC98 0xAC99 0xAC9A 0xAC9B 0xAC9C 0xAC9D 0xAC9E 0xAC9F 0xACA0 0xACA1 0xACA2 0xACA3 0xACA4 +0xACA5 0xACA6 0xACA7 0xACA8 0xACA9 0xACAA 0xACAB 0xACAC 0xACAD 0xACAE 0xACAF 0xACB0 0xACB1 0xACB2 0xACB3 0xACB4 +0xACB5 0xACB6 0xACB7 0xACB8 0xACB9 0xACBA 0xACBB 0xACBC 0xACBD 0xACBE 0xACBF 0xACC0 0xACC1 0xACC2 0xACC3 0xACC4 +0xACC5 0xACC6 0xACC7 0xACC8 0xACC9 0xACCA 0xACCB 0xACCC 0xACCD 0xACCE 0xACCF 0xACD0 0xACD1 0xACD2 0xACD3 0xACD4 +0xACD5 0xACD6 0xACD7 0xACD8 0xACD9 0xACDA 0xACDB 0xACDC 0xACDD 0xACDE 0xACDF 0xACE0 0xACE1 0xACE2 0xACE3 0xACE4 +0xACE7 0xACE8 0xACE9 0xACEA 0xACEB 0xACEC 0xACEE 0xACEF 0xACF0 0xACF1 0xACF2 0xACF3 0xACF4 0xACF5 0xACF6 0xACF7 +0xACF9 0xACFA 0xACFB 0xACFC 0xACFD 0xAD00 0xAD03 0xAD04 0xAD06 0xAD0C 0xAD0D 0xAD0E 0xAD0F 0xAD10 0xAD11 0xAD12 +0xAD18 0xAD19 0xAD1C 0xAD1F 0xAD20 0xAD22 0xAD28 0xAD29 0xAD2A 0xAD2B 0xAD2C 0xAD2D 0xAD34 0xAD35 0xAD38 0xAD3B +0xAD3C 0xAD3E 0xAD44 0xAD45 0xAD46 0xAD47 0xAD48 0xAD49 0xAD50 0xAD51 0xAD54 0xAD57 0xAD58 0xAD60 0xAD61 0xAD62 +0xAD63 0xAD64 0xAD65 0xAD6C 0xAD6D 0xAD70 0xAD73 0xAD74 0xAD75 0xAD76 0xAD78 0xAD7B 0xAD7C 0xAD7D 0xAD7E 0xAD7F +0xAD80 0xAD81 0xAD82 0xAD83 0xAD86 0xAD88 0xAD89 0xAD8C 0xAD8F 0xAD90 0xAD98 0xAD99 0xAD9A 0xAD9B 0xAD9C 0xAD9D +0xADA4 0xADA5 0xADA8 0xADAB 0xADAC 0xADB4 0xADB5 0xADB6 0xADB7 0xADB8 0xADB9 0xADC0 0xADC1 0xADC4 0xADC7 0xADC8 +0xADCA 0xADD0 0xADD1 0xADD2 0xADD3 0xADD4 0xADD5 0xADDC 0xADDD 0xADE0 0xADE4 0xADE8 0xADEC 0xADED 0xADEE 0xADEF +0xADF0 0xADF1 0xADF8 0xADF9 0xADFA 0xADFB 0xADFC 0xADFD 0xADFE 0xADFF 0xAE00 0xAE01 0xAE02 0xAE03 0xAE04 0xAE05 +0xAE06 0xAE07 0xAE08 0xAE09 0xAE0A 0xAE0B 0xAE0C 0xAE0D 0xAE0E 0xAE0F 0xAE11 0xAE12 0xAE13 0xAE14 0xAE15 0xAE18 +0xAE1C 0xAE20 0xAE24 0xAE25 0xAE26 0xAE27 0xAE28 0xAE29 0xAE30 0xAE31 0xAE32 0xAE33 0xAE34 0xAE35 0xAE36 0xAE37 +0xAE38 0xAE39 0xAE3A 0xAE3B 0xAE3C 0xAE3D 0xAE3E 0xAE3F 0xAE40 0xAE41 0xAE42 0xAE43 0xAE44 0xAE45 0xAE46 0xAE47 +0xAE48 0xAE49 0xAE4A 0xAE4B 0xAE4C 0xAE4D 0xAE4E 0xAE50 0xAE53 0xAE54 0xAE56 0xAE5C 0xAE5D 0xAE5E 0xAE5F 0xAE60 +0xAE61 0xAE62 0xAE63 0xAE65 0xAE68 0xAE69 0xAE6A 0xAE6C 0xAE6F 0xAE70 0xAE73 0xAE76 0xAE78 0xAE79 0xAE7A 0xAE7B +0xAE7C 0xAE7D 0xAE81 0xAE84 0xAE85 0xAE86 0xAE88 0xAE8B 0xAE8C 0xAE8D 0xAE94 0xAE95 0xAE96 0xAE97 0xAE98 0xAE99 +0xAEA0 0xAEA1 0xAEA4 0xAEB0 0xAEB1 0xAEB2 0xAEB3 0xAEB4 0xAEB5 0xAEBC 0xAEBD 0xAEBE 0xAEC0 0xAEC2 0xAEC3 0xAEC4 +0xAECC 0xAECD 0xAECE 0xAECF 0xAED0 0xAED1 0xAED2 0xAED3 0xAED5 0xAED8 0xAED9 0xAEDA 0xAEDC 0xAEDF 0xAEE0 0xAEE8 +0xAEE9 0xAEEA 0xAEEB 0xAEEC 0xAEED 0xAEF1 0xAEF4 0xAEF5 0xAEF8 0xAEFB 0xAEFC 0xAF04 0xAF05 0xAF06 0xAF07 0xAF08 +0xAF09 0xAF0D 0xAF10 0xAF11 0xAF17 0xAF20 0xAF21 0xAF22 0xAF23 0xAF24 0xAF25 0xAF2C 0xAF2D 0xAF30 0xAF31 0xAF32 +0xAF33 0xAF34 0xAF36 0xAF38 0xAF3B 0xAF3C 0xAF3D 0xAF3E 0xAF3F 0xAF40 0xAF41 0xAF42 0xAF43 0xAF45 0xAF47 0xAF48 +0xAF49 0xAF4C 0xAF4F 0xAF50 0xAF58 0xAF59 0xAF5A 0xAF5B 0xAF5C 0xAF5D 0xAF64 0xAF65 0xAF68 0xAF6B 0xAF6C 0xAF74 +0xAF75 0xAF76 0xAF77 0xAF78 0xAF79 0xAF80 0xAF81 0xAF84 0xAF87 0xAF88 0xAF90 0xAF91 0xAF92 0xAF93 0xAF94 0xAF95 +0xAF9C 0xAF9D 0xAFA0 0xAFA3 0xAFA4 0xAFAC 0xAFAD 0xAFAE 0xAFAF 0xAFB0 0xAFB1 0xAFB2 0xAFB8 0xAFB9 0xAFBC 0xAFBF +0xAFC0 0xAFC1 0xAFC7 0xAFC8 0xAFC9 0xAFCA 0xAFCB 0xAFCC 0xAFCD 0xAFCE 0xAFCF 0xAFD4 0xAFD5 0xAFD8 0xAFDB 0xAFDC +0xAFE4 0xAFE5 0xAFE6 0xAFE7 0xAFE8 0xAFE9 0xAFF0 0xAFF1 0xAFF4 0xAFF7 0xAFF8 0xB000 0xB001 0xB002 0xB003 0xB004 +0xB005 0xB00C 0xB00D 0xB010 0xB013 0xB014 0xB01C 0xB01D 0xB01E 0xB01F 0xB020 0xB021 0xB028 0xB029 0xB02C 0xB030 +0xB038 0xB039 0xB03A 0xB03B 0xB03C 0xB03D 0xB044 0xB045 0xB048 0xB04A 0xB04B 0xB04C 0xB04D 0xB04E 0xB053 0xB054 +0xB055 0xB056 0xB057 0xB058 0xB059 0xB05A 0xB05B 0xB05D 0xB05F 0xB060 0xB061 0xB064 0xB067 0xB068 0xB06B 0xB070 +0xB071 0xB072 0xB073 0xB074 0xB075 0xB07C 0xB07D 0xB080 0xB083 0xB084 0xB08B 0xB08C 0xB08D 0xB08E 0xB08F 0xB090 +0xB091 0xB095 0xB098 0xB099 0xB09A 0xB09B 0xB09C 0xB09F 0xB0A0 0xB0A1 0xB0A2 0xB0A4 0xB0A8 0xB0A9 0xB0AA 0xB0AB +0xB0AC 0xB0AD 0xB0AE 0xB0AF 0xB0B0 0xB0B1 0xB0B2 0xB0B3 0xB0B4 0xB0B5 0xB0B8 0xB0BB 0xB0BC 0xB0C4 0xB0C5 0xB0C6 +0xB0C7 0xB0C8 0xB0C9 0xB0CE 0xB0D0 0xB0D1 0xB0D4 0xB0D7 0xB0D8 0xB0E0 0xB0E1 0xB0E2 0xB0E3 0xB0E4 0xB0E5 0xB0E6 +0xB0E7 0xB0E9 0xB0EC 0xB0ED 0xB0F0 0xB0FC 0xB0FD 0xB0FE 0xB0FF 0xB100 0xB101 0xB108 0xB109 0xB10A 0xB10B 0xB10C +0xB10F 0xB110 0xB111 0xB112 0xB113 0xB117 0xB118 0xB119 0xB11A 0xB11B 0xB11C 0xB11D 0xB11E 0xB11F 0xB120 0xB121 +0xB122 0xB123 0xB124 0xB125 0xB128 0xB12B 0xB12C 0xB134 0xB135 0xB136 0xB137 0xB138 0xB139 0xB13C 0xB13D 0xB13E +0xB13F 0xB140 0xB141 0xB143 0xB144 0xB147 0xB148 0xB14B 0xB150 0xB151 0xB152 0xB153 0xB154 0xB155 0xB156 0xB157 +0xB158 0xB159 0xB15A 0xB15B 0xB15C 0xB15D 0xB160 0xB163 0xB164 0xB16C 0xB16D 0xB16E 0xB16F 0xB170 0xB171 0xB178 +0xB179 0xB17A 0xB17B 0xB17C 0xB17E 0xB17F 0xB180 0xB181 0xB182 0xB188 0xB189 0xB18A 0xB18B 0xB18C 0xB18D 0xB18E +0xB18F 0xB190 0xB191 0xB192 0xB193 0xB194 0xB195 0xB198 0xB19B 0xB19C 0xB1A4 0xB1A5 0xB1A6 0xB1A7 0xB1A8 0xB1A9 +0xB1B0 0xB1B4 0xB1B8 0xB1C0 0xB1C1 0xB1C2 0xB1C3 0xB1C4 0xB1C5 0xB1CC 0xB1CD 0xB1D0 0xB1D3 0xB1D4 0xB1DC 0xB1DD +0xB1DE 0xB1DF 0xB1E0 0xB1E1 0xB1E6 0xB1E8 0xB1E9 0xB1EC 0xB1EF 0xB1F0 0xB1F8 0xB1F9 0xB1FA 0xB1FB 0xB1FC 0xB1FD +0xB204 0xB205 0xB208 0xB20B 0xB20C 0xB20D 0xB210 0xB213 0xB214 0xB215 0xB216 0xB217 0xB218 0xB219 0xB21B 0xB21D +0xB21E 0xB220 0xB221 0xB224 0xB227 0xB228 0xB230 0xB231 0xB232 0xB233 0xB234 0xB235 0xB23C 0xB23D 0xB240 0xB243 +0xB244 0xB24C 0xB24D 0xB24E 0xB24F 0xB250 0xB251 0xB258 0xB259 0xB25C 0xB25F 0xB260 0xB268 0xB269 0xB26A 0xB26B +0xB26C 0xB26D 0xB26F 0xB274 0xB275 0xB278 0xB27B 0xB27C 0xB284 0xB285 0xB286 0xB287 0xB288 0xB289 0xB28A 0xB28B +0xB290 0xB291 0xB294 0xB297 0xB298 0xB299 0xB29A 0xB29C 0xB2A0 0xB2A1 0xB2A2 0xB2A3 0xB2A4 0xB2A5 0xB2A6 0xB2A7 +0xB2AA 0xB2AB 0xB2AC 0xB2AD 0xB2B0 0xB2B3 0xB2B4 0xB2BC 0xB2BD 0xB2BE 0xB2BF 0xB2C0 0xB2C1 0xB2C8 0xB2C9 0xB2CC +0xB2CF 0xB2D0 0xB2D1 0xB2D2 0xB2D3 0xB2D4 0xB2D8 0xB2D9 0xB2DA 0xB2DB 0xB2DC 0xB2DD 0xB2DE 0xB2E0 0xB2E2 0xB2E3 +0xB2E4 0xB2E5 0xB2E6 0xB2E8 0xB2EB 0xB2EC 0xB2ED 0xB2EE 0xB2EF 0xB2F0 0xB2F2 0xB2F3 0xB2F4 0xB2F5 0xB2F6 0xB2F7 +0xB2F8 0xB2F9 0xB2FA 0xB2FB 0xB2FC 0xB2FD 0xB2FE 0xB2FF 0xB300 0xB301 0xB304 0xB307 0xB308 0xB310 0xB311 0xB312 +0xB313 0xB314 0xB315 0xB316 0xB319 0xB31C 0xB31D 0xB320 0xB324 0xB327 0xB32C 0xB32D 0xB32E 0xB32F 0xB330 0xB331 +0xB338 0xB33C 0xB348 0xB349 0xB34A 0xB34B 0xB34C 0xB34D 0xB34E 0xB354 0xB355 0xB356 0xB358 0xB359 0xB35B 0xB35C +0xB35E 0xB35F 0xB364 0xB365 0xB366 0xB367 0xB368 0xB369 0xB36A 0xB36B 0xB36D 0xB36E 0xB36F 0xB370 0xB371 0xB374 +0xB377 0xB378 0xB380 0xB381 0xB382 0xB383 0xB384 0xB385 0xB386 0xB38A 0xB38C 0xB38D 0xB38F 0xB390 0xB393 0xB394 +0xB398 0xB39C 0xB39D 0xB39E 0xB39F 0xB3A0 0xB3A1 0xB3A8 0xB3A9 0xB3AC 0xB3B0 0xB3B8 0xB3B9 0xB3BA 0xB3BB 0xB3BC +0xB3BD 0xB3C4 0xB3C5 0xB3C6 0xB3C7 0xB3C8 0xB3CB 0xB3CC 0xB3CE 0xB3CF 0xB3D0 0xB3D3 0xB3D4 0xB3D5 0xB3D6 0xB3D7 +0xB3D8 0xB3D9 0xB3DA 0xB3DB 0xB3DC 0xB3DD 0xB3DE 0xB3DF 0xB3E0 0xB3E1 0xB3E4 0xB3E8 0xB3F0 0xB3F1 0xB3F2 0xB3F3 +0xB3F4 0xB3F5 0xB3FC 0xB400 0xB403 0xB404 0xB40C 0xB40D 0xB40E 0xB40F 0xB410 0xB411 0xB418 0xB419 0xB41C 0xB41F +0xB420 0xB424 0xB428 0xB429 0xB42A 0xB42B 0xB42C 0xB42D 0xB434 0xB435 0xB438 0xB43B 0xB43C 0xB444 0xB445 0xB446 +0xB447 0xB448 0xB449 0xB44F 0xB450 0xB451 0xB452 0xB454 0xB457 0xB458 0xB459 0xB45A 0xB45B 0xB460 0xB461 0xB462 +0xB463 0xB464 0xB465 0xB46A 0xB46C 0xB46D 0xB470 0xB473 0xB474 0xB47C 0xB47D 0xB47E 0xB47F 0xB480 0xB481 0xB488 +0xB489 0xB48C 0xB48F 0xB490 0xB498 0xB499 0xB49A 0xB49B 0xB49C 0xB49D 0xB4A4 0xB4A5 0xB4A8 0xB4AB 0xB4AC 0xB4B4 +0xB4B5 0xB4B6 0xB4B7 0xB4B8 0xB4B9 0xB4C0 0xB4C1 0xB4C4 0xB4C8 0xB4D0 0xB4D1 0xB4D2 0xB4D3 0xB4D4 0xB4D5 0xB4DC +0xB4DD 0xB4DE 0xB4DF 0xB4E0 0xB4E3 0xB4E4 0xB4E5 0xB4E6 0xB4E7 0xB4E8 0xB4EC 0xB4ED 0xB4EE 0xB4EF 0xB4F0 0xB4F1 +0xB4F8 0xB4F9 0xB4FA 0xB4FC 0xB4FF 0xB500 0xB508 0xB509 0xB50A 0xB50B 0xB50C 0xB50D 0xB511 0xB514 0xB515 0xB516 +0xB518 0xB51B 0xB51C 0xB524 0xB525 0xB526 0xB527 0xB528 0xB529 0xB52A 0xB52B 0xB52D 0xB52E 0xB52F 0xB530 0xB531 +0xB532 0xB534 0xB537 0xB538 0xB539 0xB53A 0xB53B 0xB53F 0xB540 0xB541 0xB542 0xB543 0xB544 0xB545 0xB54B 0xB54C +0xB54D 0xB54E 0xB550 0xB553 0xB554 0xB55C 0xB55D 0xB55E 0xB55F 0xB560 0xB561 0xB567 0xB568 0xB569 0xB56C 0xB570 +0xB578 0xB579 0xB57A 0xB57B 0xB57C 0xB57D 0xB584 0xB585 0xB588 0xB594 0xB595 0xB596 0xB597 0xB598 0xB599 0xB5A0 +0xB5A1 0xB5A4 0xB5A7 0xB5A8 0xB5AA 0xB5AB 0xB5AF 0xB5B0 0xB5B1 0xB5B2 0xB5B3 0xB5B4 0xB5B5 0xB5BB 0xB5BC 0xB5BD +0xB5BE 0xB5C0 0xB5C3 0xB5C4 0xB5CC 0xB5CD 0xB5CE 0xB5CF 0xB5D0 0xB5D1 0xB5D8 0xB5D9 0xB5DC 0xB5DF 0xB5E8 0xB5E9 +0xB5EA 0xB5EB 0xB5EC 0xB5ED 0xB5F4 0xB5F5 0xB5F8 0xB604 0xB605 0xB606 0xB607 0xB608 0xB609 0xB610 0xB611 0xB612 +0xB614 0xB617 0xB618 0xB619 0xB61A 0xB61F 0xB620 0xB621 0xB622 0xB623 0xB624 0xB625 0xB62C 0xB62D 0xB630 0xB634 +0xB63C 0xB63D 0xB63E 0xB63F 0xB640 0xB641 0xB647 0xB648 0xB649 0xB64C 0xB64F 0xB650 0xB658 0xB659 0xB65A 0xB65B +0xB65C 0xB65D 0xB664 0xB665 0xB668 0xB66B 0xB66C 0xB674 0xB675 0xB676 0xB677 0xB678 0xB679 0xB680 0xB681 0xB690 +0xB691 0xB692 0xB693 0xB694 0xB695 0xB69C 0xB69D 0xB6A0 0xB6A3 0xB6A4 0xB6A6 0xB6A7 0xB6AB 0xB6AC 0xB6AD 0xB6AE +0xB6AF 0xB6B0 0xB6B1 0xB6B5 0xB6B8 0xB6BC 0xB6BF 0xB6C8 0xB6C9 0xB6CA 0xB6CB 0xB6CC 0xB6CD 0xB6D4 0xB6D8 0xB6DB +0xB6DC 0xB6E4 0xB6E5 0xB6E6 0xB6E7 0xB6E8 0xB6E9 0xB6F0 0xB6F4 0xB6F7 0xB6F8 0xB700 0xB701 0xB702 0xB703 0xB704 +0xB705 0xB70C 0xB70D 0xB710 0xB714 0xB71C 0xB71D 0xB71E 0xB71F 0xB720 0xB721 0xB728 0xB729 0xB72A 0xB72B 0xB72C +0xB72F 0xB730 0xB732 0xB733 0xB737 0xB738 0xB739 0xB73A 0xB73B 0xB73C 0xB73D 0xB73E 0xB743 0xB744 0xB745 0xB748 +0xB74C 0xB754 0xB755 0xB756 0xB757 0xB758 0xB759 0xB760 0xB761 0xB764 0xB767 0xB768 0xB770 0xB771 0xB772 0xB773 +0xB774 0xB775 0xB77B 0xB77C 0xB77D 0xB780 0xB783 0xB784 0xB788 0xB78C 0xB78D 0xB78E 0xB78F 0xB790 0xB791 0xB792 +0xB793 0xB794 0xB795 0xB796 0xB797 0xB798 0xB799 0xB79C 0xB79F 0xB7A0 0xB7A8 0xB7A9 0xB7AA 0xB7AB 0xB7AC 0xB7AD +0xB7B0 0xB7B1 0xB7B2 0xB7B4 0xB7B5 0xB7B8 0xB7BB 0xB7BC 0xB7C4 0xB7C5 0xB7C6 0xB7C7 0xB7C8 0xB7C9 0xB7D0 0xB7D4 +0xB7E0 0xB7E1 0xB7E2 0xB7E3 0xB7E4 0xB7E5 0xB7EC 0xB7ED 0xB7F0 0xB7F2 0xB7F3 0xB7F4 0xB7FC 0xB7FD 0xB7FE 0xB7FF +0xB800 0xB801 0xB802 0xB804 0xB806 0xB807 0xB808 0xB809 0xB80C 0xB80F 0xB810 0xB818 0xB819 0xB81A 0xB81B 0xB81C +0xB81D 0xB821 0xB822 0xB823 0xB824 0xB825 0xB828 0xB82B 0xB82C 0xB830 0xB834 0xB835 0xB836 0xB837 0xB838 0xB839 +0xB83C 0xB83E 0xB840 0xB841 0xB844 0xB847 0xB848 0xB850 0xB851 0xB852 0xB853 0xB854 0xB855 0xB85C 0xB85D 0xB860 +0xB863 0xB864 0xB868 0xB86B 0xB86C 0xB86D 0xB86E 0xB86F 0xB870 0xB871 0xB874 0xB876 0xB877 0xB878 0xB879 0xB87C +0xB880 0xB888 0xB889 0xB88A 0xB88B 0xB88C 0xB88D 0xB894 0xB895 0xB896 0xB897 0xB898 0xB89B 0xB89C 0xB8A4 0xB8A5 +0xB8A6 0xB8A7 0xB8A8 0xB8A9 0xB8B0 0xB8B1 0xB8B4 0xB8B5 0xB8B7 0xB8B8 0xB8C0 0xB8C1 0xB8C2 0xB8C3 0xB8C4 0xB8C5 +0xB8CC 0xB8CD 0xB8CE 0xB8CF 0xB8D0 0xB8D3 0xB8D4 0xB8DC 0xB8DD 0xB8DE 0xB8DF 0xB8E0 0xB8E1 0xB8E8 0xB8E9 0xB8EC +0xB8EF 0xB8F0 0xB8F3 0xB8F8 0xB8F9 0xB8FA 0xB8FB 0xB8FC 0xB8FD 0xB900 0xB902 0xB904 0xB905 0xB908 0xB90B 0xB90C +0xB914 0xB915 0xB916 0xB917 0xB918 0xB919 0xB920 0xB921 0xB924 0xB928 0xB930 0xB931 0xB932 0xB933 0xB934 0xB935 +0xB93C 0xB93D 0xB940 0xB943 0xB944 0xB94C 0xB94D 0xB94E 0xB94F 0xB950 0xB951 0xB958 0xB959 0xB95C 0xB95F 0xB960 +0xB968 0xB969 0xB96A 0xB96B 0xB96C 0xB96D 0xB974 0xB975 0xB978 0xB97B 0xB97C 0xB97D 0xB980 0xB984 0xB985 0xB986 +0xB987 0xB988 0xB989 0xB98A 0xB98B 0xB98D 0xB98E 0xB98F 0xB990 0xB991 0xB994 0xB998 0xB99E 0xB9A0 0xB9A1 0xB9A2 +0xB9A3 0xB9A4 0xB9A5 0xB9AC 0xB9AD 0xB9AE 0xB9AF 0xB9B0 0xB9B3 0xB9B4 0xB9BC 0xB9BD 0xB9BE 0xB9BF 0xB9C0 0xB9C1 +0xB9C2 0xB9C4 0xB9C6 0xB9C8 0xB9C9 0xB9CA 0xB9CB 0xB9CC 0xB9CD 0xB9CE 0xB9CF 0xB9D0 0xB9D1 0xB9D2 0xB9D4 0xB9D8 +0xB9D9 0xB9DA 0xB9DB 0xB9DC 0xB9DD 0xB9DE 0xB9DF 0xB9E0 0xB9E1 0xB9E2 0xB9E3 0xB9E4 0xB9E5 0xB9E6 0xB9E7 0xB9E8 +0xB9EB 0xB9EC 0xB9ED 0xB9F4 0xB9F5 0xB9F6 0xB9F7 0xB9F8 0xB9F9 0xB9FA 0xB9FB 0xB9FC 0xB9FD 0xB9FE 0xB9FF 0xBA00 +0xBA01 0xBA02 0xBA03 0xBA04 0xBA05 0xBA06 0xBA07 0xBA08 0xBA10 0xBA11 0xBA12 0xBA13 0xBA14 0xBA15 0xBA18 0xBA1C +0xBA1D 0xBA1E 0xBA1F 0xBA20 0xBA2C 0xBA2D 0xBA2E 0xBA2F 0xBA30 0xBA31 0xBA32 0xBA33 0xBA34 0xBA35 0xBA36 0xBA37 +0xBA38 0xBA39 0xBA3A 0xBA3B 0xBA3C 0xBA3D 0xBA3E 0xBA3F 0xBA40 0xBA41 0xBA42 0xBA43 0xBA44 0xBA45 0xBA46 0xBA47 +0xBA48 0xBA49 0xBA4A 0xBA4B 0xBA4C 0xBA4D 0xBA4E 0xBA4F 0xBA50 0xBA51 0xBA52 0xBA53 0xBA54 0xBA55 0xBA56 0xBA57 +0xBA58 0xBA59 0xBA5A 0xBA5B 0xBA5C 0xBA60 0xBA64 0xBA65 0xBA66 0xBA67 0xBA68 0xBA69 0xBA6A 0xBA6B 0xBA6C 0xBA6D +0xBA6E 0xBA6F 0xBA70 0xBA71 0xBA72 0xBA73 0xBA74 0xBA75 0xBA76 0xBA77 0xBA78 0xBA79 0xBA7A 0xBA7B 0xBA7C 0xBA7D +0xBA7E 0xBA7F 0xBA80 0xBA81 0xBA82 0xBA83 0xBA84 0xBA85 0xBA86 0xBA87 0xBA89 0xBA8C 0xBA8D 0xBA8E 0xBA8F 0xBA90 +0xBA93 0xBA94 0xBA9C 0xBA9D 0xBA9E 0xBA9F 0xBAA0 0xBAA1 0xBAA2 0xBAA3 0xBAA4 0xBAA5 0xBAA6 0xBAA7 0xBAA8 0xBAA9 +0xBAAA 0xBAAB 0xBAAC 0xBAAD 0xBAAE 0xBAAF 0xBAB0 0xBAB1 0xBAB2 0xBAB3 0xBAB4 0xBAB5 0xBAB6 0xBAB7 0xBAB8 0xBAB9 +0xBABA 0xBABB 0xBABC 0xBABD 0xBABF 0xBAC3 0xBAC4 0xBAC5 0xBAC6 0xBAC8 0xBACB 0xBACC 0xBAD4 0xBAD5 0xBAD6 0xBAD7 +0xBAD8 0xBAD9 0xBAE0 0xBAE4 0xBAE8 0xBAF0 0xBAF1 0xBAF2 0xBAF3 0xBAF4 0xBAF5 0xBAFC 0xBAFD 0xBAFE 0xBB00 0xBB03 +0xBB04 0xBB0C 0xBB0D 0xBB0E 0xBB0F 0xBB10 0xBB11 0xBB18 0xBB19 0xBB1C 0xBB1F 0xBB20 0xBB28 0xBB29 0xBB2A 0xBB2B +0xBB2C 0xBB2D 0xBB34 0xBB35 0xBB36 0xBB38 0xBB3A 0xBB3B 0xBB3C 0xBB3D 0xBB3E 0xBB40 0xBB44 0xBB45 0xBB46 0xBB47 +0xBB48 0xBB49 0xBB4B 0xBB4D 0xBB4F 0xBB50 0xBB51 0xBB54 0xBB57 0xBB58 0xBB60 0xBB61 0xBB62 0xBB63 0xBB64 0xBB65 +0xBB6C 0xBB6D 0xBB6E 0xBB70 0xBB74 0xBB7C 0xBB7D 0xBB7E 0xBB7F 0xBB80 0xBB81 0xBB88 0xBB89 0xBB8A 0xBB8C 0xBB90 +0xBB98 0xBB99 0xBB9A 0xBB9B 0xBB9C 0xBB9D 0xBBA4 0xBBA5 0xBBA6 0xBBA8 0xBBAB 0xBBAC 0xBBB4 0xBBB5 0xBBB6 0xBBB7 +0xBBB8 0xBBB9 0xBBC0 0xBBC1 0xBBC3 0xBBC4 0xBBC7 0xBBC8 0xBBC9 0xBBCA 0xBBCB 0xBBCC 0xBBCD 0xBBCE 0xBBCF 0xBBD0 +0xBBD1 0xBBD2 0xBBD3 0xBBD4 0xBBD5 0xBBD9 0xBBDC 0xBBDD 0xBBDE 0xBBE0 0xBBE4 0xBBEC 0xBBED 0xBBEE 0xBBEF 0xBBF0 +0xBBF1 0xBBF2 0xBBF8 0xBBF9 0xBBFC 0xBBFF 0xBC00 0xBC01 0xBC02 0xBC03 0xBC04 0xBC05 0xBC06 0xBC07 0xBC08 0xBC09 +0xBC0A 0xBC0B 0xBC0C 0xBC0D 0xBC0E 0xBC0F 0xBC10 0xBC11 0xBC14 0xBC15 0xBC16 0xBC17 0xBC18 0xBC1B 0xBC1C 0xBC1D +0xBC1E 0xBC1F 0xBC20 0xBC23 0xBC24 0xBC25 0xBC26 0xBC27 0xBC28 0xBC29 0xBC2B 0xBC2C 0xBC2D 0xBC2F 0xBC30 0xBC31 +0xBC32 0xBC33 0xBC34 0xBC35 0xBC36 0xBC37 0xBC38 0xBC39 0xBC3A 0xBC3B 0xBC3C 0xBC3D 0xBC3E 0xBC3F 0xBC40 0xBC41 +0xBC42 0xBC43 0xBC44 0xBC45 0xBC46 0xBC49 0xBC4C 0xBC4D 0xBC4E 0xBC50 0xBC54 0xBC5C 0xBC5D 0xBC5E 0xBC5F 0xBC60 +0xBC61 0xBC67 0xBC68 0xBC69 0xBC6A 0xBC6B 0xBC6C 0xBC6F 0xBC70 0xBC77 0xBC78 0xBC79 0xBC7A 0xBC7B 0xBC7C 0xBC7D +0xBC84 0xBC85 0xBC86 0xBC88 0xBC8B 0xBC8C 0xBC8D 0xBC8E 0xBC90 0xBC94 0xBC95 0xBC96 0xBC97 0xBC98 0xBC99 0xBC9A +0xBC9C 0xBC9D 0xBC9F 0xBCA0 0xBCA1 0xBCA2 0xBCA3 0xBCA4 0xBCA7 0xBCA8 0xBCB0 0xBCB1 0xBCB2 0xBCB3 0xBCB4 0xBCB5 +0xBCB8 0xBCB9 0xBCBC 0xBCBD 0xBCC0 0xBCC3 0xBCC4 0xBCC8 0xBCCC 0xBCCD 0xBCCE 0xBCCF 0xBCD0 0xBCD1 0xBCD2 0xBCD3 +0xBCD4 0xBCD5 0xBCD8 0xBCD9 0xBCDC 0xBCE0 0xBCE8 0xBCE9 0xBCEA 0xBCEB 0xBCEC 0xBCED 0xBCF4 0xBCF5 0xBCF6 0xBCF7 +0xBCF8 0xBCFB 0xBCFC 0xBCFD 0xBCFE 0xBCFF 0xBD04 0xBD05 0xBD06 0xBD07 0xBD08 0xBD09 0xBD0A 0xBD0B 0xBD0D 0xBD0F +0xBD10 0xBD11 0xBD14 0xBD17 0xBD18 0xBD20 0xBD21 0xBD22 0xBD23 0xBD24 0xBD25 0xBD2C 0xBD30 0xBD33 0xBD34 0xBD3C +0xBD3D 0xBD3E 0xBD3F 0xBD40 0xBD41 0xBD48 0xBD49 0xBD4A 0xBD4C 0xBD4F 0xBD50 0xBD58 0xBD59 0xBD5A 0xBD5B 0xBD5C +0xBD5D 0xBD64 0xBD65 0xBD68 0xBD6C 0xBD74 0xBD75 0xBD76 0xBD77 0xBD78 0xBD79 0xBD80 0xBD81 0xBD82 0xBD84 0xBD87 +0xBD88 0xBD89 0xBD8A 0xBD8B 0xBD8E 0xBD90 0xBD91 0xBD92 0xBD93 0xBD94 0xBD95 0xBD96 0xBD97 0xBD98 0xBD99 0xBD9A +0xBD9B 0xBD9C 0xBD9D 0xBDA0 0xBDA3 0xBDA4 0xBDAC 0xBDAD 0xBDAE 0xBDAF 0xBDB0 0xBDB1 0xBDB4 0xBDB8 0xBDB9 0xBDBC +0xBDBF 0xBDC0 0xBDC1 0xBDC8 0xBDC9 0xBDCA 0xBDCB 0xBDCC 0xBDCD 0xBDD4 0xBDD5 0xBDD8 0xBDDB 0xBDDC 0xBDE4 0xBDE5 +0xBDE6 0xBDE7 0xBDE8 0xBDE9 0xBDF0 0xBDF1 0xBDF2 0xBDF4 0xBDF7 0xBDF8 0xBE00 0xBE01 0xBE02 0xBE03 0xBE04 0xBE05 +0xBE0C 0xBE0D 0xBE10 0xBE13 0xBE14 0xBE15 0xBE17 0xBE18 0xBE1B 0xBE1C 0xBE1D 0xBE1E 0xBE1F 0xBE20 0xBE21 0xBE22 +0xBE23 0xBE25 0xBE27 0xBE28 0xBE29 0xBE2C 0xBE30 0xBE38 0xBE39 0xBE3A 0xBE3B 0xBE3C 0xBE3D 0xBE44 0xBE45 0xBE46 +0xBE47 0xBE48 0xBE49 0xBE4A 0xBE4B 0xBE4C 0xBE4E 0xBE54 0xBE55 0xBE56 0xBE57 0xBE58 0xBE59 0xBE5A 0xBE5B 0xBE5C +0xBE5D 0xBE5F 0xBE60 0xBE61 0xBE62 0xBE63 0xBE64 0xBE65 0xBE66 0xBE67 0xBE68 0xBE69 0xBE6A 0xBE70 0xBE71 0xBE72 +0xBE73 0xBE74 0xBE75 0xBE76 0xBE79 0xBE7B 0xBE7C 0xBE7D 0xBE7E 0xBE7F 0xBE80 0xBE83 0xBE84 0xBE8C 0xBE8D 0xBE8E +0xBE8F 0xBE90 0xBE91 0xBE92 0xBE93 0xBE94 0xBE95 0xBE96 0xBE98 0xBE99 0xBE9C 0xBEA8 0xBEA9 0xBEAA 0xBEAB 0xBEAC +0xBEAD 0xBEAE 0xBEB4 0xBEB5 0xBEB6 0xBEB7 0xBEB8 0xBEBB 0xBEBC 0xBEC4 0xBEC5 0xBEC6 0xBEC7 0xBEC8 0xBEC9 0xBECA +0xBECB 0xBECC 0xBECD 0xBECE 0xBED0 0xBED1 0xBED4 0xBED7 0xBED8 0xBED9 0xBEE0 0xBEE1 0xBEE2 0xBEE3 0xBEE4 0xBEE5 +0xBEE6 0xBEEC 0xBEED 0xBEEE 0xBEEF 0xBEF0 0xBEF3 0xBEF4 0xBEFC 0xBEFD 0xBEFE 0xBEFF 0xBF00 0xBF01 0xBF02 0xBF03 +0xBF04 0xBF05 0xBF06 0xBF08 0xBF09 0xBF0C 0xBF0F 0xBF10 0xBF18 0xBF19 0xBF1A 0xBF1B 0xBF1C 0xBF1D 0xBF1F 0xBF21 +0xBF24 0xBF25 0xBF26 0xBF27 0xBF28 0xBF2B 0xBF2C 0xBF34 0xBF35 0xBF36 0xBF37 0xBF38 0xBF39 0xBF3A 0xBF3B 0xBF3C +0xBF3D 0xBF3E 0xBF40 0xBF41 0xBF44 0xBF47 0xBF48 0xBF50 0xBF51 0xBF52 0xBF53 0xBF54 0xBF55 0xBF59 0xBF5B 0xBF5C +0xBF60 0xBF63 0xBF78 0xBF7F 0xBF94 0xBF98 0xBF9B 0xBFA4 0xBFA5 0xBFAC 0xBFB0 0xBFB1 0xBFB4 0xBFC0 0xBFC1 0xBFC2 +0xBFC3 0xBFC4 0xBFC5 0xBFCC 0xBFCD 0xBFD0 0xBFD3 0xBFD4 0xBFD5 0xBFDC 0xBFDD 0xBFDF 0xBFE1 0xBFE5 0xBFE8 0xBFEF +0xC004 0xC020 0xC021 0xC03C 0xC03D 0xC040 0xC043 0xC044 0xC051 0xC058 0xC059 0xC05C 0xC05F 0xC060 0xC068 0xC069 +0xC06A 0xC06B 0xC06C 0xC06D 0xC074 0xC090 0xC091 0xC094 0xC097 0xC098 0xC0A0 0xC0A1 0xC0A2 0xC0A3 0xC0A4 0xC0A5 +0xC0A6 0xC0A7 0xC0AB 0xC0AC 0xC0AD 0xC0AE 0xC0AF 0xC0B0 0xC0B1 0xC0B2 0xC0B3 0xC0B4 0xC0B5 0xC0B6 0xC0B7 0xC0B8 +0xC0B9 0xC0BA 0xC0BB 0xC0BC 0xC0BD 0xC0BE 0xC0BF 0xC0C0 0xC0C1 0xC0C2 0xC0C3 0xC0C4 0xC0C5 0xC0C6 0xC0C7 0xC0C8 +0xC0C9 0xC0CA 0xC0CB 0xC0CC 0xC0CF 0xC0D0 0xC0D2 0xC0D8 0xC0D9 0xC0DA 0xC0DB 0xC0DC 0xC0DD 0xC0E3 0xC0E4 0xC0E5 +0xC0E8 0xC0EB 0xC0EC 0xC0F4 0xC0F5 0xC0F6 0xC0F7 0xC0F8 0xC0F9 0xC0FB 0xC0FE 0xC0FF 0xC100 0xC101 0xC104 0xC108 +0xC10A 0xC110 0xC111 0xC112 0xC113 0xC114 0xC115 0xC11C 0xC11D 0xC11E 0xC11F 0xC120 0xC123 0xC124 0xC125 0xC126 +0xC127 0xC128 0xC12A 0xC12C 0xC12D 0xC12E 0xC12F 0xC130 0xC131 0xC134 0xC136 0xC138 0xC139 0xC13C 0xC13F 0xC140 +0xC148 0xC149 0xC14A 0xC14B 0xC14C 0xC14D 0xC14E 0xC151 0xC152 0xC154 0xC155 0xC156 0xC157 0xC158 0xC15B 0xC15C +0xC15F 0xC160 0xC164 0xC165 0xC166 0xC167 0xC168 0xC169 0xC170 0xC171 0xC173 0xC174 0xC178 0xC180 0xC181 0xC182 +0xC183 0xC184 0xC185 0xC18A 0xC18C 0xC18D 0xC18E 0xC18F 0xC190 0xC193 0xC194 0xC195 0xC196 0xC197 0xC198 0xC19C +0xC19D 0xC19E 0xC19F 0xC1A0 0xC1A1 0xC1A3 0xC1A5 0xC1A6 0xC1A8 0xC1A9 0xC1AC 0xC1B0 0xC1B8 0xC1B9 0xC1BA 0xC1BB +0xC1BC 0xC1BD 0xC1C4 0xC1C5 0xC1C8 0xC1CB 0xC1CC 0xC1D4 0xC1D5 0xC1D6 0xC1D7 0xC1D8 0xC1D9 0xC1E0 0xC1E1 0xC1E4 +0xC1E7 0xC1E8 0xC1F0 0xC1F1 0xC1F2 0xC1F3 0xC1F4 0xC1F5 0xC1FC 0xC1FD 0xC200 0xC203 0xC204 0xC20C 0xC20D 0xC20E +0xC20F 0xC210 0xC211 0xC216 0xC218 0xC219 0xC21C 0xC21F 0xC220 0xC221 0xC224 0xC227 0xC228 0xC229 0xC22A 0xC22B +0xC22C 0xC22D 0xC22E 0xC22F 0xC231 0xC232 0xC233 0xC234 0xC235 0xC238 0xC23B 0xC23C 0xC244 0xC245 0xC246 0xC247 +0xC248 0xC249 0xC250 0xC251 0xC254 0xC257 0xC258 0xC260 0xC261 0xC262 0xC263 0xC264 0xC265 0xC26C 0xC26D 0xC270 +0xC273 0xC274 0xC27C 0xC27D 0xC27E 0xC27F 0xC280 0xC281 0xC286 0xC288 0xC289 0xC28C 0xC28F 0xC290 0xC298 0xC299 +0xC29A 0xC29B 0xC29C 0xC29D 0xC2A4 0xC2A5 0xC2A8 0xC2AB 0xC2AC 0xC2AD 0xC2AE 0xC2AF 0xC2B0 0xC2B2 0xC2B3 0xC2B4 +0xC2B5 0xC2B6 0xC2B7 0xC2B8 0xC2B9 0xC2BA 0xC2BB 0xC2BC 0xC2BD 0xC2BE 0xC2BF 0xC2C0 0xC2C1 0xC2C4 0xC2C8 0xC2D0 +0xC2D1 0xC2D2 0xC2D3 0xC2D4 0xC2D5 0xC2DC 0xC2DD 0xC2DE 0xC2E0 0xC2E2 0xC2E3 0xC2E4 0xC2E5 0xC2E6 0xC2E8 0xC2EB +0xC2EC 0xC2ED 0xC2EE 0xC2EF 0xC2F0 0xC2F1 0xC2F3 0xC2F4 0xC2F6 0xC2F8 0xC2F9 0xC2FB 0xC2FC 0xC2FF 0xC300 0xC301 +0xC302 0xC308 0xC309 0xC30A 0xC30B 0xC30C 0xC30D 0xC30E 0xC311 0xC313 0xC314 0xC315 0xC316 0xC317 0xC318 0xC31B +0xC31C 0xC324 0xC325 0xC326 0xC327 0xC328 0xC329 0xC32A 0xC32B 0xC32C 0xC32D 0xC32E 0xC32F 0xC330 0xC331 0xC334 +0xC337 0xC338 0xC340 0xC341 0xC342 0xC343 0xC344 0xC345 0xC34C 0xC34D 0xC34E 0xC34F 0xC350 0xC353 0xC354 0xC35C +0xC35D 0xC35E 0xC35F 0xC360 0xC361 0xC362 0xC363 0xC364 0xC365 0xC366 0xC367 0xC368 0xC369 0xC36A 0xC36C 0xC36F +0xC370 0xC372 0xC378 0xC379 0xC37A 0xC37B 0xC37C 0xC37D 0xC382 0xC384 0xC385 0xC386 0xC387 0xC388 0xC38B 0xC38C +0xC394 0xC395 0xC396 0xC397 0xC398 0xC399 0xC39A 0xC39B 0xC39C 0xC39D 0xC39E 0xC39F 0xC3A0 0xC3A1 0xC3A4 0xC3A7 +0xC3A8 0xC3B0 0xC3B1 0xC3B2 0xC3B3 0xC3B4 0xC3B5 0xC3BC 0xC3BD 0xC3BE 0xC3BF 0xC3C0 0xC3C3 0xC3C4 0xC3CC 0xC3CD +0xC3CE 0xC3CF 0xC3D0 0xC3D1 0xC3D2 0xC3D3 0xC3D4 0xC3D5 0xC3D6 0xC3D7 0xC3D8 0xC3D9 0xC3DA 0xC3DC 0xC3DF 0xC3E0 +0xC3E2 0xC3E8 0xC3E9 0xC3EA 0xC3EB 0xC3EC 0xC3ED 0xC3F1 0xC3F4 0xC3F5 0xC3F8 0xC3FB 0xC3FC 0xC404 0xC405 0xC406 +0xC407 0xC408 0xC409 0xC40B 0xC410 0xC411 0xC414 0xC417 0xC418 0xC420 0xC421 0xC422 0xC423 0xC424 0xC425 0xC42C +0xC42D 0xC430 0xC433 0xC434 0xC43C 0xC43D 0xC43E 0xC43F 0xC440 0xC441 0xC448 0xC449 0xC44C 0xC44F 0xC450 0xC458 +0xC459 0xC45A 0xC45B 0xC45C 0xC45D 0xC464 0xC465 0xC468 0xC46B 0xC46C 0xC474 0xC475 0xC476 0xC477 0xC478 0xC479 +0xC47A 0xC47B 0xC47C 0xC47D 0xC47E 0xC47F 0xC480 0xC481 0xC484 0xC487 0xC488 0xC490 0xC491 0xC492 0xC493 0xC494 +0xC495 0xC49C 0xC49D 0xC4A0 0xC4A3 0xC4A4 0xC4AC 0xC4AD 0xC4AE 0xC4AF 0xC4B0 0xC4B1 0xC4B8 0xC4B9 0xC4BC 0xC4BF +0xC4C0 0xC4C8 0xC4C9 0xC4CA 0xC4CB 0xC4CC 0xC4CD 0xC4D3 0xC4D4 0xC4D5 0xC4D8 0xC4DB 0xC4DC 0xC4E4 0xC4E5 0xC4E6 +0xC4E7 0xC4E8 0xC4E9 0xC4F0 0xC4F1 0xC4F4 0xC4F7 0xC4F8 0xC4FA 0xC4FF 0xC500 0xC501 0xC502 0xC503 0xC504 0xC505 +0xC50C 0xC50D 0xC510 0xC514 0xC51C 0xC51D 0xC51E 0xC51F 0xC520 0xC521 0xC528 0xC529 0xC52B 0xC52C 0xC52F 0xC530 +0xC531 0xC538 0xC539 0xC53A 0xC53B 0xC53C 0xC53D 0xC53F 0xC540 0xC543 0xC544 0xC545 0xC546 0xC547 0xC548 0xC549 +0xC54A 0xC54B 0xC54C 0xC54D 0xC54E 0xC54F 0xC550 0xC551 0xC552 0xC553 0xC554 0xC555 0xC556 0xC557 0xC558 0xC559 +0xC55A 0xC55B 0xC55C 0xC55D 0xC55E 0xC55F 0xC560 0xC561 0xC562 0xC563 0xC564 0xC565 0xC566 0xC567 0xC568 0xC569 +0xC56A 0xC56B 0xC56C 0xC56D 0xC56E 0xC56F 0xC570 0xC571 0xC572 0xC573 0xC574 0xC575 0xC576 0xC577 0xC578 0xC579 +0xC57A 0xC57B 0xC57C 0xC57D 0xC57E 0xC57F 0xC580 0xC581 0xC582 0xC583 0xC584 0xC585 0xC586 0xC587 0xC588 0xC589 +0xC58A 0xC58B 0xC58C 0xC58D 0xC58E 0xC58F 0xC590 0xC591 0xC592 0xC593 0xC594 0xC595 0xC596 0xC597 0xC598 0xC599 +0xC59A 0xC59B 0xC59C 0xC59D 0xC59E 0xC59F 0xC5A0 0xC5A1 0xC5A2 0xC5A3 0xC5A4 0xC5A5 0xC5A6 0xC5A7 0xC5A8 0xC5A9 +0xC5AA 0xC5AB 0xC5AC 0xC5AD 0xC5AE 0xC5AF 0xC5B0 0xC5B1 0xC5B2 0xC5B3 0xC5B4 0xC5B5 0xC5B6 0xC5B7 0xC5B8 0xC5B9 +0xC5BA 0xC5BB 0xC5BC 0xC5BD 0xC5BE 0xC5BF 0xC5C0 0xC5C1 0xC5C2 0xC5C3 0xC5C4 0xC5C5 0xC5C6 0xC5C7 0xC5C8 0xC5C9 +0xC5CA 0xC5CB 0xC5CC 0xC5CD 0xC5CE 0xC5CF 0xC5D0 0xC5D1 0xC5D4 0xC5D7 0xC5D8 0xC5E0 0xC5E1 0xC5E2 0xC5E3 0xC5E4 +0xC5E5 0xC5E6 0xC5E7 0xC5E8 0xC5E9 0xC5EA 0xC5EB 0xC5EC 0xC5ED 0xC5EE 0xC5EF 0xC5F0 0xC5F1 0xC5F2 0xC5F3 0xC5F4 +0xC5F5 0xC5F6 0xC5F7 0xC5F8 0xC5F9 0xC5FA 0xC5FB 0xC5FC 0xC5FD 0xC5FE 0xC5FF 0xC600 0xC601 0xC602 0xC603 0xC604 +0xC605 0xC606 0xC607 0xC608 0xC609 0xC60C 0xC60F 0xC610 0xC618 0xC619 0xC61A 0xC61B 0xC61C 0xC61D 0xC620 0xC624 +0xC625 0xC626 0xC628 0xC629 0xC62A 0xC62B 0xC62C 0xC62D 0xC62E 0xC62F 0xC630 0xC631 0xC632 0xC633 0xC634 0xC635 +0xC636 0xC637 0xC638 0xC639 0xC63A 0xC63B 0xC63C 0xC63D 0xC63E 0xC63F 0xC640 0xC641 0xC644 0xC647 0xC648 0xC64E +0xC650 0xC651 0xC652 0xC653 0xC654 0xC655 0xC658 0xC659 0xC65C 0xC65D 0xC660 0xC661 0xC662 0xC663 0xC664 0xC66C +0xC66D 0xC66E 0xC66F 0xC670 0xC671 0xC678 0xC679 0xC67C 0xC67F 0xC680 0xC682 0xC688 0xC689 0xC68A 0xC68B 0xC68C +0xC68D 0xC692 0xC694 0xC695 0xC698 0xC699 0xC69A 0xC69B 0xC69C 0xC69D 0xC6A4 0xC6A5 0xC6A6 0xC6A7 0xC6A8 0xC6A9 +0xC6AC 0xC6B0 0xC6B1 0xC6B2 0xC6B3 0xC6B4 0xC6B5 0xC6B6 0xC6B7 0xC6B8 0xC6B9 0xC6BA 0xC6BB 0xC6BC 0xC6BE 0xC6BF +0xC6C0 0xC6C1 0xC6C2 0xC6C3 0xC6C4 0xC6C5 0xC6C6 0xC6C7 0xC6C8 0xC6C9 0xC6CA 0xC6CB 0xC6CC 0xC6CD 0xC6D0 0xC6D1 +0xC6D2 0xC6D3 0xC6D4 0xC6D8 0xC6DC 0xC6DD 0xC6DE 0xC6DF 0xC6E0 0xC6E1 0xC6E4 0xC6E5 0xC6E8 0xC6E9 0xC6EC 0xC6EF +0xC6F0 0xC6F8 0xC6F9 0xC6FA 0xC6FB 0xC6FC 0xC6FD 0xC701 0xC704 0xC705 0xC708 0xC70B 0xC70C 0xC70E 0xC713 0xC714 +0xC715 0xC716 0xC717 0xC718 0xC719 0xC71C 0xC71D 0xC720 0xC721 0xC724 0xC727 0xC728 0xC730 0xC731 0xC732 0xC733 +0xC734 0xC735 0xC736 0xC737 0xC738 0xC739 0xC73C 0xC73D 0xC73E 0xC73F 0xC740 0xC741 0xC742 0xC743 0xC744 0xC745 +0xC746 0xC747 0xC748 0xC749 0xC74A 0xC74B 0xC74C 0xC74D 0xC74E 0xC74F 0xC750 0xC751 0xC752 0xC753 0xC754 0xC755 +0xC756 0xC757 0xC758 0xC759 0xC75C 0xC75F 0xC760 0xC766 0xC768 0xC769 0xC76A 0xC76B 0xC76C 0xC76D 0xC774 0xC775 +0xC776 0xC777 0xC778 0xC779 0xC77A 0xC77B 0xC77C 0xC77D 0xC77E 0xC77F 0xC780 0xC781 0xC782 0xC783 0xC784 0xC785 +0xC786 0xC787 0xC788 0xC789 0xC78A 0xC78B 0xC78C 0xC78D 0xC78E 0xC78F 0xC790 0xC791 0xC793 0xC794 0xC796 0xC797 +0xC798 0xC799 0xC79A 0xC7A0 0xC7A1 0xC7A2 0xC7A3 0xC7A4 0xC7A5 0xC7A6 0xC7A7 0xC7A9 0xC7AA 0xC7AB 0xC7AC 0xC7AD +0xC7B0 0xC7B2 0xC7B3 0xC7B4 0xC7BC 0xC7BD 0xC7BE 0xC7BF 0xC7C0 0xC7C1 0xC7C2 0xC7C8 0xC7C9 0xC7CC 0xC7CE 0xC7CF +0xC7D0 0xC7D8 0xC7D9 0xC7DA 0xC7DB 0xC7DC 0xC7DD 0xC7E4 0xC7E5 0xC7E8 0xC7EB 0xC7EC 0xC7F4 0xC7F5 0xC7F6 0xC7F7 +0xC7F8 0xC7F9 0xC800 0xC801 0xC802 0xC804 0xC806 0xC807 0xC808 0xC809 0xC80A 0xC80B 0xC810 0xC811 0xC812 0xC813 +0xC814 0xC815 0xC816 0xC819 0xC81B 0xC81C 0xC81D 0xC820 0xC823 0xC824 0xC82C 0xC82D 0xC82E 0xC82F 0xC830 0xC831 +0xC832 0xC836 0xC838 0xC839 0xC83C 0xC83F 0xC840 0xC841 0xC842 0xC843 0xC847 0xC848 0xC849 0xC84A 0xC84B 0xC84C +0xC84D 0xC84E 0xC851 0xC853 0xC854 0xC855 0xC858 0xC85C 0xC864 0xC865 0xC866 0xC867 0xC868 0xC869 0xC870 0xC871 +0xC874 0xC877 0xC878 0xC87A 0xC880 0xC881 0xC882 0xC883 0xC884 0xC885 0xC886 0xC887 0xC88B 0xC88C 0xC88D 0xC890 +0xC892 0xC893 0xC894 0xC895 0xC896 0xC89C 0xC89D 0xC89E 0xC89F 0xC8A0 0xC8A1 0xC8A6 0xC8A8 0xC8A9 0xC8AC 0xC8AF +0xC8B0 0xC8B8 0xC8B9 0xC8BA 0xC8BB 0xC8BC 0xC8BD 0xC8C4 0xC8C5 0xC8C8 0xC8CB 0xC8CC 0xC8D4 0xC8D5 0xC8D6 0xC8D7 +0xC8D8 0xC8D9 0xC8E0 0xC8E1 0xC8E4 0xC8E7 0xC8E8 0xC8F0 0xC8F1 0xC8F2 0xC8F3 0xC8F4 0xC8F5 0xC8FB 0xC8FC 0xC8FD +0xC900 0xC903 0xC904 0xC905 0xC906 0xC908 0xC90C 0xC90D 0xC90E 0xC90F 0xC910 0xC911 0xC917 0xC918 0xC919 0xC91C +0xC91F 0xC920 0xC928 0xC929 0xC92A 0xC92B 0xC92C 0xC92D 0xC934 0xC935 0xC938 0xC93B 0xC93C 0xC944 0xC945 0xC946 +0xC947 0xC948 0xC949 0xC950 0xC951 0xC954 0xC957 0xC958 0xC960 0xC961 0xC962 0xC963 0xC964 0xC965 0xC96C 0xC96D +0xC970 0xC974 0xC97C 0xC97D 0xC97E 0xC97F 0xC980 0xC981 0xC988 0xC989 0xC98C 0xC98F 0xC990 0xC991 0xC992 0xC994 +0xC998 0xC999 0xC99A 0xC99B 0xC99C 0xC99D 0xC99E 0xC9A4 0xC9A5 0xC9A8 0xC9AC 0xC9B4 0xC9B5 0xC9B6 0xC9B7 0xC9B8 +0xC9B9 0xC9C0 0xC9C1 0xC9C4 0xC9C7 0xC9C8 0xC9CA 0xC9CF 0xC9D0 0xC9D1 0xC9D2 0xC9D3 0xC9D4 0xC9D5 0xC9D6 0xC9D7 +0xC9D8 0xC9D9 0xC9DA 0xC9DB 0xC9DC 0xC9DD 0xC9DE 0xC9E0 0xC9E2 0xC9E3 0xC9E4 0xC9E7 0xC9E8 0xC9EC 0xC9ED 0xC9EE +0xC9EF 0xC9F0 0xC9F1 0xC9F2 0xC9F7 0xC9F8 0xC9F9 0xC9FA 0xC9FB 0xC9FC 0xC9FF 0xCA00 0xCA08 0xCA09 0xCA0A 0xCA0B +0xCA0C 0xCA0D 0xCA0E 0xCA0F 0xCA10 0xCA11 0xCA12 0xCA13 0xCA14 0xCA15 0xCA18 0xCA1A 0xCA1C 0xCA24 0xCA25 0xCA26 +0xCA27 0xCA28 0xCA29 0xCA2D 0xCA30 0xCA31 0xCA32 0xCA33 0xCA34 0xCA37 0xCA38 0xCA40 0xCA41 0xCA42 0xCA43 0xCA44 +0xCA45 0xCA46 0xCA47 0xCA48 0xCA49 0xCA4A 0xCA4B 0xCA4C 0xCA4D 0xCA50 0xCA53 0xCA54 0xCA57 0xCA58 0xCA5B 0xCA5C +0xCA5D 0xCA5E 0xCA5F 0xCA60 0xCA61 0xCA67 0xCA68 0xCA69 0xCA6A 0xCA6B 0xCA6C 0xCA6F 0xCA70 0xCA78 0xCA79 0xCA7A +0xCA7B 0xCA7C 0xCA7D 0xCA7E 0xCA7F 0xCA80 0xCA81 0xCA82 0xCA83 0xCA84 0xCA85 0xCA88 0xCA8B 0xCA8C 0xCA94 0xCA95 +0xCA96 0xCA97 0xCA98 0xCA99 0xCAA0 0xCAA1 0xCAA2 0xCAA3 0xCAA4 0xCAA7 0xCAA8 0xCAB0 0xCAB1 0xCAB2 0xCAB3 0xCAB4 +0xCAB5 0xCAB6 0xCAB7 0xCAB8 0xCAB9 0xCABA 0xCABB 0xCABC 0xCABD 0xCABE 0xCAC0 0xCAC3 0xCAC4 0xCAC6 0xCACC 0xCACD +0xCACE 0xCACF 0xCAD0 0xCAD1 0xCAD2 0xCAD3 0xCAD7 0xCAD8 0xCAD9 0xCADC 0xCADF 0xCAE0 0xCAE8 0xCAE9 0xCAEA 0xCAEB +0xCAEC 0xCAED 0xCAF4 0xCAF5 0xCAF8 0xCAFB 0xCAFC 0xCB08 0xCB10 0xCB11 0xCB14 0xCB17 0xCB18 0xCB20 0xCB21 0xCB22 +0xCB23 0xCB24 0xCB25 0xCB26 0xCB27 0xCB28 0xCB29 0xCB2A 0xCB2B 0xCB2C 0xCB2D 0xCB30 0xCB32 0xCB34 0xCB3C 0xCB3D +0xCB3F 0xCB40 0xCB41 0xCB48 0xCB49 0xCB4A 0xCB4C 0xCB4F 0xCB50 0xCB52 0xCB58 0xCB59 0xCB5A 0xCB5B 0xCB5C 0xCB5D +0xCB64 0xCB65 0xCB68 0xCB6B 0xCB6C 0xCB74 0xCB75 0xCB77 0xCB78 0xCB79 0xCB80 0xCB81 0xCB84 0xCB87 0xCB88 0xCB90 +0xCB91 0xCB92 0xCB93 0xCB94 0xCB95 0xCB9C 0xCB9D 0xCBA0 0xCBA3 0xCBA4 0xCBAC 0xCBAD 0xCBAF 0xCBB1 0xCBB8 0xCBB9 +0xCBBC 0xCBC0 0xCBC8 0xCBC9 0xCBCA 0xCBCB 0xCBCC 0xCBCD 0xCBD4 0xCBD5 0xCBD8 0xCBDB 0xCBDC 0xCBE4 0xCBE5 0xCBE6 +0xCBE7 0xCBE8 0xCBE9 0xCBEA 0xCBF0 0xCBF1 0xCBF4 0xCBF8 0xCC00 0xCC01 0xCC02 0xCC03 0xCC04 0xCC05 0xCC06 0xCC0C +0xCC0D 0xCC10 0xCC13 0xCC14 0xCC1C 0xCC1D 0xCC1E 0xCC1F 0xCC20 0xCC21 0xCC22 0xCC26 0xCC27 0xCC28 0xCC29 0xCC2C +0xCC2E 0xCC2F 0xCC30 0xCC31 0xCC38 0xCC39 0xCC3A 0xCC3B 0xCC3C 0xCC3D 0xCC3E 0xCC3F 0xCC42 0xCC44 0xCC45 0xCC48 +0xCC4B 0xCC4C 0xCC54 0xCC55 0xCC56 0xCC57 0xCC58 0xCC59 0xCC5B 0xCC5E 0xCC60 0xCC61 0xCC64 0xCC66 0xCC68 0xCC70 +0xCC71 0xCC72 0xCC73 0xCC74 0xCC75 0xCC7A 0xCC7C 0xCC7D 0xCC91 0xCC98 0xCC99 0xCC9C 0xCC9F 0xCCA0 0xCCA7 0xCCA8 +0xCCA9 0xCCAA 0xCCAB 0xCCAC 0xCCAD 0xCCAE 0xCCB2 0xCCB4 0xCCB5 0xCCB8 0xCCBB 0xCCBC 0xCCC3 0xCCC4 0xCCC5 0xCCC6 +0xCCC7 0xCCC8 0xCCC9 0xCCCA 0xCCD0 0xCCD1 0xCCD4 0xCCD7 0xCCD8 0xCCE0 0xCCE1 0xCCE2 0xCCE3 0xCCE4 0xCCE5 0xCCEC +0xCCED 0xCCF0 0xCCF4 0xCCFC 0xCCFD 0xCCFE 0xCCFF 0xCD00 0xCD01 0xCD08 0xCD09 0xCD0C 0xCD0F 0xCD10 0xCD18 0xCD19 +0xCD1A 0xCD1B 0xCD1C 0xCD1D 0xCD23 0xCD24 0xCD25 0xCD28 0xCD2B 0xCD2C 0xCD34 0xCD35 0xCD36 0xCD37 0xCD38 0xCD39 +0xCD40 0xCD44 0xCD50 0xCD51 0xCD52 0xCD53 0xCD54 0xCD55 0xCD5C 0xCD5D 0xCD60 0xCD63 0xCD64 0xCD6C 0xCD6D 0xCD6E +0xCD6F 0xCD70 0xCD71 0xCD78 0xCD79 0xCD7C 0xCD80 0xCD88 0xCD89 0xCD8A 0xCD8B 0xCD8C 0xCD8D 0xCD94 0xCD95 0xCD98 +0xCD9B 0xCD9C 0xCDA4 0xCDA5 0xCDA6 0xCDA7 0xCDA8 0xCDA9 0xCDB0 0xCDB1 0xCDB4 0xCDB7 0xCDB8 0xCDC0 0xCDC1 0xCDC2 +0xCDC3 0xCDC4 0xCDC5 0xCDCC 0xCDCD 0xCDD0 0xCDD4 0xCDDC 0xCDDD 0xCDDE 0xCDDF 0xCDE0 0xCDE1 0xCDE8 0xCDE9 0xCDEC +0xCDEF 0xCDF0 0xCDF8 0xCDF9 0xCDFA 0xCDFB 0xCDFC 0xCDFD 0xCE04 0xCE05 0xCE08 0xCE0C 0xCE14 0xCE15 0xCE16 0xCE17 +0xCE18 0xCE19 0xCE20 0xCE21 0xCE24 0xCE27 0xCE28 0xCE29 0xCE2C 0xCE30 0xCE31 0xCE32 0xCE33 0xCE34 0xCE35 0xCE3C +0xCE3D 0xCE40 0xCE44 0xCE4C 0xCE4D 0xCE4E 0xCE4F 0xCE50 0xCE51 0xCE58 0xCE59 0xCE5C 0xCE5F 0xCE60 0xCE61 0xCE62 +0xCE68 0xCE69 0xCE6A 0xCE6B 0xCE6C 0xCE6D 0xCE6E 0xCE70 0xCE72 0xCE74 0xCE75 0xCE78 0xCE7B 0xCE7C 0xCE84 0xCE85 +0xCE86 0xCE87 0xCE88 0xCE89 0xCE8D 0xCE8E 0xCE90 0xCE91 0xCE94 0xCE97 0xCE98 0xCEA0 0xCEA1 0xCEA2 0xCEA3 0xCEA4 +0xCEA5 0xCEA8 0xCEA9 0xCEAA 0xCEAC 0xCEAD 0xCEB0 0xCEB4 0xCEBC 0xCEBD 0xCEBE 0xCEBF 0xCEC0 0xCEC1 0xCEC4 0xCEC8 +0xCEC9 0xCECC 0xCED8 0xCED9 0xCEDA 0xCEDB 0xCEDC 0xCEDD 0xCEE4 0xCEE5 0xCEE8 0xCEEB 0xCEEC 0xCEF4 0xCEF5 0xCEF6 +0xCEF7 0xCEF8 0xCEF9 0xCEFB 0xCEFD 0xCEFE 0xCF00 0xCF01 0xCF04 0xCF07 0xCF08 0xCF10 0xCF11 0xCF12 0xCF13 0xCF14 +0xCF15 0xCF18 0xCF19 0xCF1A 0xCF1C 0xCF1D 0xCF20 0xCF23 0xCF24 0xCF2C 0xCF2D 0xCF2E 0xCF2F 0xCF30 0xCF31 0xCF38 +0xCF39 0xCF3C 0xCF40 0xCF48 0xCF49 0xCF4A 0xCF4B 0xCF4C 0xCF4D 0xCF54 0xCF55 0xCF58 0xCF5B 0xCF5C 0xCF64 0xCF65 +0xCF66 0xCF67 0xCF68 0xCF69 0xCF6A 0xCF6E 0xCF70 0xCF71 0xCF74 0xCF78 0xCF80 0xCF81 0xCF82 0xCF83 0xCF84 0xCF85 +0xCF8C 0xCF8D 0xCF90 0xCF93 0xCF94 0xCF9C 0xCF9D 0xCF9E 0xCF9F 0xCFA0 0xCFA1 0xCFA8 0xCFA9 0xCFAC 0xCFB0 0xCFB8 +0xCFB9 0xCFBA 0xCFBB 0xCFBC 0xCFBD 0xCFC4 0xCFC5 0xCFC8 0xCFCC 0xCFD4 0xCFD5 0xCFD6 0xCFD7 0xCFD8 0xCFD9 0xCFE0 +0xCFE1 0xCFE4 0xCFE7 0xCFE8 0xCFF0 0xCFF1 0xCFF2 0xCFF3 0xCFF4 0xCFF5 0xCFFA 0xCFFC 0xCFFD 0xD000 0xD003 0xD004 +0xD00C 0xD00D 0xD00E 0xD00F 0xD010 0xD011 0xD018 0xD019 0xD01C 0xD020 0xD028 0xD029 0xD02A 0xD02B 0xD02C 0xD02D +0xD034 0xD035 0xD038 0xD03B 0xD03C 0xD044 0xD045 0xD046 0xD047 0xD048 0xD049 0xD050 0xD051 0xD054 0xD058 0xD060 +0xD061 0xD062 0xD063 0xD064 0xD065 0xD068 0xD06C 0xD06D 0xD070 0xD072 0xD074 0xD076 0xD07C 0xD07D 0xD07E 0xD07F +0xD080 0xD081 0xD084 0xD088 0xD089 0xD08C 0xD090 0xD098 0xD099 0xD09A 0xD09B 0xD09C 0xD09D 0xD0A4 0xD0A5 0xD0A8 +0xD0AB 0xD0AC 0xD0B4 0xD0B5 0xD0B6 0xD0B7 0xD0B8 0xD0B9 0xD0BE 0xD0C0 0xD0C1 0xD0C4 0xD0C7 0xD0C8 0xD0C9 0xD0CA +0xD0CF 0xD0D0 0xD0D1 0xD0D2 0xD0D3 0xD0D4 0xD0D5 0xD0DA 0xD0DC 0xD0DD 0xD0E0 0xD0E2 0xD0E3 0xD0E4 0xD0E5 0xD0EC +0xD0ED 0xD0EE 0xD0EF 0xD0F0 0xD0F1 0xD0F6 0xD0F8 0xD0F9 0xD0FC 0xD100 0xD108 0xD109 0xD10A 0xD10B 0xD10C 0xD10D +0xD114 0xD115 0xD118 0xD11A 0xD124 0xD125 0xD126 0xD127 0xD128 0xD129 0xD130 0xD131 0xD134 0xD137 0xD138 0xD139 +0xD13A 0xD13B 0xD140 0xD141 0xD142 0xD143 0xD144 0xD145 0xD14C 0xD14D 0xD150 0xD153 0xD154 0xD15C 0xD15D 0xD15E +0xD15F 0xD160 0xD161 0xD166 0xD168 0xD169 0xD16C 0xD16F 0xD170 0xD178 0xD179 0xD17A 0xD17B 0xD17C 0xD17D 0xD184 +0xD185 0xD188 0xD18C 0xD194 0xD195 0xD196 0xD197 0xD198 0xD199 0xD1A0 0xD1A1 0xD1A4 0xD1A7 0xD1A8 0xD1B0 0xD1B1 +0xD1B2 0xD1B3 0xD1B4 0xD1B5 0xD1B7 0xD1B8 0xD1B9 0xD1BA 0xD1BC 0xD1BD 0xD1C0 0xD1C4 0xD1CC 0xD1CD 0xD1CE 0xD1CF +0xD1D0 0xD1D1 0xD1D8 0xD1E8 0xD1E9 0xD1EA 0xD1EB 0xD1EC 0xD1ED 0xD1F4 0xD1F5 0xD1F8 0xD1FB 0xD1FC 0xD204 0xD205 +0xD206 0xD207 0xD208 0xD209 0xD210 0xD211 0xD214 0xD218 0xD220 0xD221 0xD222 0xD223 0xD224 0xD225 0xD22C 0xD22D +0xD230 0xD233 0xD234 0xD236 0xD23C 0xD23D 0xD23E 0xD23F 0xD240 0xD241 0xD248 0xD249 0xD24C 0xD24F 0xD250 0xD254 +0xD258 0xD259 0xD25A 0xD25B 0xD25C 0xD25D 0xD264 0xD265 0xD268 0xD26B 0xD26C 0xD274 0xD275 0xD276 0xD277 0xD278 +0xD279 0xD280 0xD281 0xD284 0xD287 0xD288 0xD290 0xD291 0xD292 0xD293 0xD294 0xD295 0xD29C 0xD29D 0xD2A0 0xD2A4 +0xD2AC 0xD2AD 0xD2AE 0xD2AF 0xD2B0 0xD2B1 0xD2B8 0xD2B9 0xD2BB 0xD2BC 0xD2BF 0xD2C0 0xD2C1 0xD2C2 0xD2C4 0xD2C8 +0xD2C9 0xD2CA 0xD2CB 0xD2CC 0xD2CD 0xD2D1 0xD2D4 0xD2D5 0xD2D8 0xD2DC 0xD2E0 0xD2E4 0xD2E5 0xD2E6 0xD2E7 0xD2E8 +0xD2E9 0xD2F0 0xD2F1 0xD2F4 0xD2F7 0xD2F8 0xD300 0xD301 0xD302 0xD303 0xD304 0xD305 0xD308 0xD30A 0xD30C 0xD30D +0xD30E 0xD310 0xD311 0xD313 0xD314 0xD316 0xD31C 0xD31D 0xD31E 0xD31F 0xD320 0xD321 0xD323 0xD324 0xD325 0xD326 +0xD328 0xD329 0xD32C 0xD32F 0xD330 0xD338 0xD339 0xD33A 0xD33B 0xD33C 0xD33D 0xD341 0xD344 0xD345 0xD348 0xD34C +0xD354 0xD355 0xD356 0xD357 0xD358 0xD359 0xD35D 0xD360 0xD361 0xD364 0xD370 0xD371 0xD372 0xD373 0xD374 0xD375 +0xD37C 0xD37D 0xD380 0xD383 0xD384 0xD38C 0xD38D 0xD38E 0xD38F 0xD390 0xD391 0xD395 0xD396 0xD398 0xD399 0xD39C +0xD39F 0xD3A0 0xD3A8 0xD3A9 0xD3AA 0xD3AB 0xD3AC 0xD3AD 0xD3B2 0xD3B4 0xD3B5 0xD3B8 0xD3B9 0xD3BB 0xD3BC 0xD3C4 +0xD3C5 0xD3C6 0xD3C7 0xD3C8 0xD3C9 0xD3D0 0xD3D1 0xD3D4 0xD3D7 0xD3D8 0xD3E0 0xD3E1 0xD3E2 0xD3E3 0xD3E4 0xD3E5 +0xD3EC 0xD3ED 0xD3EE 0xD3F0 0xD3F3 0xD3F4 0xD3FC 0xD3FD 0xD3FE 0xD3FF 0xD400 0xD401 0xD404 0xD405 0xD406 0xD408 +0xD409 0xD40C 0xD410 0xD418 0xD419 0xD41A 0xD41B 0xD41C 0xD41D 0xD424 0xD440 0xD441 0xD444 0xD448 0xD450 0xD451 +0xD452 0xD453 0xD454 0xD455 0xD45C 0xD45D 0xD460 0xD463 0xD464 0xD46C 0xD46D 0xD46E 0xD46F 0xD470 0xD471 0xD478 +0xD479 0xD47C 0xD47F 0xD480 0xD482 0xD488 0xD489 0xD48A 0xD48B 0xD48C 0xD48D 0xD494 0xD495 0xD498 0xD49B 0xD49C +0xD4A4 0xD4A5 0xD4A6 0xD4A7 0xD4A8 0xD4A9 0xD4B0 0xD4B1 0xD4B4 0xD4B8 0xD4C0 0xD4C1 0xD4C2 0xD4C3 0xD4C4 0xD4C5 +0xD4CC 0xD4CD 0xD4D0 0xD4D4 0xD4DC 0xD4DD 0xD4DE 0xD4DF 0xD4E0 0xD4E1 0xD4E8 0xD4E9 0xD4EC 0xD4EF 0xD4F0 0xD4F8 +0xD4F9 0xD4FA 0xD4FB 0xD4FC 0xD4FD 0xD504 0xD505 0xD508 0xD50B 0xD50C 0xD510 0xD514 0xD515 0xD516 0xD517 0xD518 +0xD519 0xD520 0xD521 0xD524 0xD528 0xD530 0xD531 0xD532 0xD533 0xD534 0xD535 0xD53C 0xD53D 0xD540 0xD543 0xD544 +0xD54C 0xD54D 0xD54E 0xD54F 0xD550 0xD551 0xD555 0xD556 0xD558 0xD559 0xD55C 0xD55F 0xD560 0xD561 0xD563 0xD564 +0xD565 0xD567 0xD568 0xD569 0xD56A 0xD56B 0xD56C 0xD56D 0xD56E 0xD570 0xD571 0xD572 0xD573 0xD574 0xD575 0xD578 +0xD57B 0xD57C 0xD584 0xD585 0xD586 0xD587 0xD588 0xD589 0xD58B 0xD58D 0xD58F 0xD590 0xD591 0xD594 0xD598 0xD5A0 +0xD5A1 0xD5A2 0xD5A3 0xD5A4 0xD5A5 0xD5AB 0xD5AC 0xD5AD 0xD5BC 0xD5BD 0xD5BE 0xD5BF 0xD5C0 0xD5C1 0xD5C8 0xD5C9 +0xD5CC 0xD5CF 0xD5D0 0xD5D1 0xD5D2 0xD5D5 0xD5D7 0xD5D8 0xD5D9 0xD5DA 0xD5DB 0xD5DC 0xD5DD 0xD5E0 0xD5E1 0xD5E2 +0xD5E3 0xD5E4 0xD5E5 0xD5E8 0xD5EB 0xD5EC 0xD5F4 0xD5F5 0xD5F6 0xD5F7 0xD5F8 0xD5F9 0xD5FE 0xD5FF 0xD600 0xD601 +0xD604 0xD607 0xD608 0xD610 0xD611 0xD612 0xD613 0xD614 0xD615 0xD61C 0xD61D 0xD620 0xD624 0xD62C 0xD62D 0xD62E +0xD62F 0xD630 0xD631 0xD638 0xD639 0xD63B 0xD63C 0xD63D 0xD63F 0xD640 0xD641 0xD644 0xD645 0xD647 0xD648 0xD649 +0xD64A 0xD64B 0xD64C 0xD64D 0xD651 0xD654 0xD655 0xD658 0xD65B 0xD65C 0xD660 0xD664 0xD665 0xD666 0xD667 0xD668 +0xD669 0xD670 0xD671 0xD674 0xD677 0xD678 0xD680 0xD681 0xD682 0xD683 0xD684 0xD685 0xD68C 0xD68D 0xD690 0xD693 +0xD694 0xD69C 0xD69D 0xD69E 0xD69F 0xD6A0 0xD6A1 0xD6A8 0xD6A9 0xD6AC 0xD6AF 0xD6B0 0xD6B8 0xD6B9 0xD6BA 0xD6BB +0xD6BC 0xD6BD 0xD6C4 0xD6C5 0xD6C8 0xD6CB 0xD6CC 0xD6CD 0xD6CE 0xD6D0 0xD6D1 0xD6D2 0xD6D3 0xD6D4 0xD6D5 0xD6D6 +0xD6D7 0xD6D8 0xD6D9 0xD6DC 0xD6DD 0xD6E0 0xD6E1 0xD6E4 0xD6E8 0xD6F0 0xD6F1 0xD6F2 0xD6F3 0xD6F4 0xD6F5 0xD6FC +0xD6FD 0xD700 0xD703 0xD704 0xD70C 0xD70D 0xD70E 0xD70F 0xD710 0xD711 0xD718 0xD719 0xD71C 0xD71F 0xD720 0xD728 +0xD729 0xD72A 0xD72B 0xD72C 0xD72D 0xD734 0xD735 0xD738 0xD73A 0xD73B 0xD73C 0xD743 0xD744 0xD745 0xD746 0xD747 +0xD748 0xD749 0xD74D 0xD750 0xD751 0xD752 0xD754 0xD755 0xD756 0xD757 0xD758 0xD759 0xD75D 0xD75F 0xD760 0xD761 +0xD762 0xD763 0xD764 0xD765 0xD768 0xD769 0xD76A 0xD76B 0xD76C 0xD76D 0xD770 0xD773 0xD774 0xD77C 0xD77D 0xD77E +0xD77F 0xD780 0xD781 0xD788 0xD789 0xD78A 0xD78B 0xD78C 0xD78D 0xD78E 0xD78F 0xD790 0xD797 0xD798 0xD799 0xD79A +0xD79B 0xD79C 0xD79D 0xD79E 0xD7A0 0xD7A1 0xD7A2 0xD7A3 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE007 +0xE008 0xE009 0xE00A 0xE00B 0xE00C 0xE00D 0xE020 0xE021 0xE022 0xE023 0xE030 0xE031 0xE032 0xE033 0xE040 0xE041 +0xE042 0xE043 0xE044 0xE045 0xE050 0xE051 0xE052 0xE053 0xE054 0xE055 0xE056 0xE057 0xE058 0xE059 0xE05A 0xE05B +0xE05C 0xE05D 0xE070 0xE071 0xE072 0xE073 0xE080 0xE081 0xE082 0xE083 0xE090 0xE091 0xE092 0xE093 0xE094 0xE095 +0xE09D 0xE0A0 0xE0A1 0xE0A2 0xE0A3 0xE0B0 0xE0B1 0xE0B2 0xE0B3 0xF000 0xF001 0xF007 0xF020 0xF021 0xF022 0xF023 +0xF024 0xF025 0xF026 0xF027 0xF028 0xF029 0xF02A 0xF030 0xF031 0xF032 0xF033 0xF034 0xF035 0xF036 0xF037 0xF038 +0xF039 0xF03A 0xF03B 0xF03C 0xF03D 0xF8FF 0xFE10 0xFE11 0xFE12 0xFE13 0xFE14 0xFE15 0xFE16 0xFE17 0xFE18 0xFE19 +0xFE30 0xFE31 0xFE33 0xFE34 0xFE35 0xFE36 0xFE37 0xFE38 0xFE39 0xFE3A 0xFE3B 0xFE3C 0xFE3D 0xFE3E 0xFE3F 0xFE40 +0xFE41 0xFE42 0xFE43 0xFE44 0xFE49 0xFE4A 0xFE4B 0xFE4C 0xFE4D 0xFE4E 0xFE4F 0xFE50 0xFE51 0xFE52 0xFE54 0xFE55 +0xFE56 0xFE57 0xFE59 0xFE5A 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0xFE5F 0xFE60 0xFE61 0xFE62 0xFE63 0xFE64 0xFE65 0xFE66 +0xFE68 0xFE69 0xFE6A 0xFE6B 0xFF01 0xFF02 0xFF03 0xFF04 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C +0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C +0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C +0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C +0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C +0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C +0xFF5D 0xFF5E 0xFF5F 0xFF60 0xFF61 0xFF62 0xFF63 0xFF64 0xFF65 0xFF66 0xFF67 0xFF68 0xFF69 0xFF6A 0xFF6B 0xFF6C +0xFF6D 0xFF6E 0xFF6F 0xFF70 0xFF71 0xFF72 0xFF73 0xFF74 0xFF75 0xFF76 0xFF77 0xFF78 0xFF79 0xFF7A 0xFF7B 0xFF7C +0xFF7D 0xFF7E 0xFF7F 0xFF80 0xFF81 0xFF82 0xFF83 0xFF84 0xFF85 0xFF86 0xFF87 0xFF88 0xFF89 0xFF8A 0xFF8B 0xFF8C +0xFF8D 0xFF8E 0xFF8F 0xFF90 0xFF91 0xFF92 0xFF93 0xFF94 0xFF95 0xFF96 0xFF97 0xFF98 0xFF99 0xFF9A 0xFF9B 0xFF9C +0xFF9D 0xFF9E 0xFF9F 0xFFE0 0xFFE1 0xFFE2 0xFFE3 0xFFE4 0xFFE5 0xFFE9 0xFFEB 0xFFFC 0xFFFD 0xFFFE diff --git a/resources/gm9/languages/ja.frf b/resources/gm9/languages/ja.frf new file mode 100644 index 000000000..295357d6c Binary files /dev/null and b/resources/gm9/languages/ja.frf differ diff --git a/resources/gm9/languages/ry.frf b/resources/gm9/languages/ry.frf new file mode 100644 index 000000000..295357d6c Binary files /dev/null and b/resources/gm9/languages/ry.frf differ diff --git a/resources/gm9/languages/zh-CN.frf b/resources/gm9/languages/zh-CN.frf new file mode 100644 index 000000000..16e0c2fe2 Binary files /dev/null and b/resources/gm9/languages/zh-CN.frf differ diff --git a/resources/gm9/languages/zh-TW.frf b/resources/gm9/languages/zh-TW.frf new file mode 100644 index 000000000..d3ed541a8 Binary files /dev/null and b/resources/gm9/languages/zh-TW.frf differ diff --git a/resources/gm9/scripts/GM9Megascript.gm9 b/resources/gm9/scripts/GM9Megascript.gm9 index 9ac263330..6ac145956 100644 --- a/resources/gm9/scripts/GM9Megascript.gm9 +++ b/resources/gm9/scripts/GM9Megascript.gm9 @@ -409,100 +409,6 @@ else end goto Hax_Options_Install_Boot9Strap -###################Hax Uninstall################## - -@Hax_Options_Un-install_Hax -set PREVIEW_MODE "GODMODE9 ALL-IN-ONE MEGASCRIPT\nby annson24\n \nHax Options\n>Hax Un-install" - -if not ask "!!WARNING!!\nThis will completely remove CFW and\nrevert your system to stock.\n \nProceed anyway?" - goto MainMenu_Hax_Options -end - -if not chk -u $[HAX] "ntrboot" - if not ask "!!WARNING!!\nntrboot not detected!\nYou should at least have ntrboot or a hardmod\nwith you before proceeding in case of brick.\n \nProceed anyway?" - goto MainMenu_Restore_Options - end -end - -if chk -u $[ONTYPE] "N3DS" - goto Unhax_Old -end - -if not sha S:/sector0x96.bin 82F2730D2C2DA3F30165F987FDCCAC5CBAB24B4E5F65C981CD7BE6F438E6D9D3 - if not find 0:/boot9strap/secret_sector.bin SECRET - if not find $[GM9IN]/boot9strap/secret_sector.bin SECRET - echo "Sector 0x96 is not genuine.\nYou must have the secret_sector.bin file in the\nboot9strap folder first then try again.\n \nAborting." - goto Hax_Options_Install_Boot9Strap - end - end - - if not allow -a S: - echo "Permissions denied. Aborting." - goto MainMenu_Hax_Options - end - - cp -n -w S:/sector0x96.bin $[SECRET].bak - cp -n -w $[SECRET] S:/sector0x96.bin -end - -if not find 1:/title/00040138/20000002/content/????????.app NATIVE_NCCH - echo "NATIVE_FIRM not found.\nIs this a N3DS?" - goto MainMenu_Hax_Options -end - -imgmount $[NATIVE_NCCH] -verify G:/exefs/.firm -set NATIVE_FIRM $[GM9OUT]/NATIVE_FIRM.firm -cp -w G:/exefs/.firm $[NATIVE_FIRM] -imgumount - -if allow -a S: - allow -a 1: - rm -o -s 1:/boot.firm - rm -o -s 1:/rw/luma - cp -n $[NATIVE_FIRM] S:/firm0.bin - cp -n $[NATIVE_FIRM] S:/firm1.bin - shaget S:/nand.bin@57FFE00:200 PRE_STAGE2_HASH - if not sha S:/nand.bin@B800000:200 $[PRE_STAGE2_HASH] - fget S:/nand.bin@57FFE00:1 PRE_STAGE2 - fill S:/nand.bin@B7FFE00:89C00 $[PRE_STAGE2] - end - echo "CFW uninstalled successfully" -else - echo "Permissions denied. Aborting." -end -goto MainMenu_Hax_Options - -@Unhax_Old - -if not find 1:/title/00040138/00000002/content/????????.app NATIVE_NCCH - echo "NATIVE_FIRM not found.\nIs this an O3DS?" - goto MainMenu_Hax_Options -end - -imgmount $[NATIVE_NCCH] -verify G:/exefs/.firm -set NATIVE_FIRM $[GM9OUT]/NATIVE_FIRM.firm -cp -w G:/exefs/.firm $[NATIVE_FIRM] -imgumount - -if allow -a S: - allow -a 1: - rm -o -s 1:/boot.firm - rm -o -s 1:/rw/luma - cp -n $[NATIVE_FIRM] S:/firm0.bin - cp -n $[NATIVE_FIRM] S:/firm1.bin - shaget S:/nand.bin@57FFE00:200 PRE_STAGE2_HASH - if not sha S:/nand.bin@B800000:200 $[PRE_STAGE2_HASH] - fget S:/nand.bin@57FFE00:1 PRE_STAGE2 - fill S:/nand.bin@B7FFE00:89C00 $[PRE_STAGE2] - end - echo "CFW uninstalled successfully" -else - echo "Permissions denied. Aborting." -end -goto MainMenu_Hax_Options - ################FBI to H&S Options################ @MainMenu_FBI_to_H&S_Options diff --git a/resources/languages/de.json b/resources/languages/de.json new file mode 100644 index 000000000..ec5d756f4 --- /dev/null +++ b/resources/languages/de.json @@ -0,0 +1,816 @@ +{ + "GM9_LANGUAGE": "Deutsch", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX.%3$02lX.%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM zu groß, kann nicht booten", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nWarnung: Boote keine FIRMs\naus nicht vertrauenswürdigen\nQuellen.\n\nFIRM booten?", + "NOT_BOOTABLE_FIRM": "Nicht ein bootfähiger FIRM.", + "FIRM_ENCRYPTED": "FIRM ist verschlüsselt.\n\nVor dem Booten entschlüsseln?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Erstelle eine Kopie unter %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Versuche trotzdem zu booten", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Warnung: Versuche, von einem nicht unterstütztem\nOrt zu booten.", + "ROOT": "[stammverzeichnis]", + "LOADING": "LADEN...", + "PANE_N": "FENSTER #%lu", + "CURRENT": "AKTUELL", + "DIR": "(ordner)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Spiel Virtuell)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtuell)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtuell)", + "IMAGE_FAT": "(Abbild FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtuell)", + "MEMORY_VIRTUAL": "(Speicher Virtuell)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtuell)", + "VRAM_VIRTUAL": "(VRAM Virtuell)", + "SEARCH": "(Suche)", + "TITLEMANAGER_VIRTUAL": "(TitelVerwalter Virtuell)", + "LAB_SDCARD": "SD-KARTE", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "SPIELABBILD", + "LAB_AESKEYDB_IMAGE": "AESKEYDB ABBILD", + "LAB_BDRI_IMAGE": "BRDI ABBILD", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF ABBILD", + "LAB_MEMORY_VIRTUAL": "SPEICHER VIRTUELL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUELL", + "LAB_TITLE_MANAGER": "TITEL VERWALTER", + "LAB_LAST_SEARCH": "LETZTE SUCHE", + "LAB_FAT_IMAGE": "FAT ABBILD", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[ZWISCHENABLAGE]", + "PLUS_N_MORE": "+ %lu weitere", + "MARK_DELETE_COPY": "L - MARKIERE Dateien (benutze mit ↑↓→←)\nX - LÖSCHE / [+R] UMBENENNE Datei(en)\nY - KOPIERE Dateien / [+R] ERSTELLE Einträge\n", + "MARK_DELETE_PASTE": "L - MARKIERE Dataien (benutze mit ↑↓→←)\nX - LÖSCHE / [+R] UMBENENNE Datei(en)\nY - Dateien Einfügen / [+R] ERSTELLE Einträge\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Schreibrechte erneut sperren\n", + "UNMOUNT_IMAGE": "R+X - Abbild aushängen\n", + "UNMOUNT_SD": "R+B - SD-Karte aushängen\n", + "REMOUNT_SD": "R+B - SD-Karte wieder einhängen\n", + "DIRECTORY_OPTIONS": "R+A - Verzeichnisoptionen\n", + "DRIVE_OPTIONS": "R+A - Laufwerkoptionen\n", + "MAKE_SCREENSHOT": "R+L - Screenshot erstellen\n", + "PREV_NEXT_PANE": "R+←→ - Zum vorherigen/nächsten Fenster wechseln\n", + "CLEAR_CLIPBOARD": "SELECT - Zwischenablage leeren\n", + "RESTORE_CLIPBOARD": "SELECT - Zwischenablage wiederherstellen\n", + "REBOOT_POWEROFF_HOME": "START - Neustarten / [+R] Ausschalten\nHOME Knopf für HOME-Menü", + "NO_EMUNAND": "Kein EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND-Größe (min)", + "GW_EMUNAND_SIZE_FULL": "GW-EmuNAND-Größe (voll)", + "MULTINAND_SIZE_2X": "MultiNAND-Größe (2x)", + "MULTINAND_SIZE_3X": "MultiNAND-Größe (3x)", + "MULTINAND_SIZE_4X": "MultiNAND-Größe (4x)", + "USER_INPUT": "Nutzereingabe...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB-Cluster", + "32KB_CLUSTERS": "32KB-Cluster", + "64KB_CLUSTERS": "64KB-Cluster", + "SD_NOT_DETECTED": "Fehler: SD-Karte nicht erkannt.", + "FORMAT_SD_CHOOSE_EMUNAND": "SD-Karte formatieren (%lluMB)?\nEmuNAND-Größe auswählen:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "Die Größe der SD-Karte ist %lluMB.\nEmuNAND-Größe (MB) unten eingeben:", + "FORMAT_SD_CHOOSE_CLUSTER": "SD-Karte (%lluMB) formatieren?\nCluster-Größe auswählen:", + "FORMAT_SD_ENTER_LABEL": "SD-Karte (%lluMB) formatieren?\nBeschriftung eingeben:", + "FORMAT_SD_FAILED": "SD-Formatierung: fehlgeschlagen!", + "REDNAND_TYPE": "RedNAND-Typ", + "REDNAND_TYPE_MULTI": "RedNAND-Typ (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND-Typ (einzel)", + "GW_EMUNAND_TYPE": "GW EmuNAND-Typ", + "DONT_SET_UP": "Nicht einrichten", + "CHOOSE_EMUNAND_TYPE": "Einzurichtenden EmuNAND-Typ auswählen:", + "CLONE_SYSNAND_TO_REDNAND": "SysNAND zu RedNAND klonen?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Klonen von SysNAND zu EmuNAND: fehlgeschlagen!", + "PRESS_A_TO_CONTINUE": "Drücke um fortzufahren", + "HEXEDITOR_CONTROLS": "Hexeditor-Tastenbelegung:\n↑↓→←(+R) - Scrollen\nR+Y - Ansicht wechseln\nX - Suche / gehe zu...\nA - Veränderungsmodus betreten\nA+↑↓→← - Wert verändern\nB - Beenden\n", + "NOT_FOUND": "Nicht gefunden!", + "GO_TO_OFFSET": "Gehe zu Versatz", + "SEARCH_FOR_STRING": "Nach Text suchen", + "SEARCH_FOR_DATA": "Nach Daten suchen", + "CURRENT_OFFSET_SELECT_ACTION": "Aktueller Versatz: %08lX\nAktion auswählen:", + "CURRENT_OFFSET_ENTER_NEW": "Aktueller Versatz: %08lX\nNeuen Versatz unten eingeben.", + "ENTER_SEARCH_REPEAT_SEARCH": "Gebe den Suchbegriff ein.\n(R+X um die Suche zu wiederholen)", + "MADE_EDITS_SAVE_CHANGES": "Sie haben Änderungen an %lu Stelle(n) vorgenommen.\nÄnderungen in die Datei schreiben?", + "FAILED_WRITING_TO_FILE": "Schreiben in die Datei fehlgeschlagen!", + "CALCULATING_SHA_FAILED": "Berechnung von SHA-%s: fehlgeschlagen!", + "SHA_VERIFICATION_PASSED": "\nSHA-Verifizierung: erfolgreich!", + "SHA_VERIFICATION_FAILED": "\nSHA-Verifizierung fehlgeschlagen", + "IDENTICAL_WITH_PREVIOUS": "\nIdentisch mit der vorherigen Datei:\n", + "WRITE_SHA_FILE": "\nSHA-Datei erstellen?", + "WRITE_SHA1_FILE": "\n.SHA1-Datei erstellen?", + "CALCULATING_CMAC_FAILED": "Berechnung von CMAC: fehlgeschlagen!", + "CMAC_VERIFICATION_PASSED": "CMAC-Verifizierung: erfolgreich!", + "CMAC_VERIFICATION_FAILED": "CMAC-Verifizierung: fehlgeschlagen!", + "FIX_CMAC_IN_FILE": "\nCMAC in Datei reparieren?", + "FIXING_CMAC_FAILED": "Reparieren von CMAC: fehlgeschlagen!", + "COPY_ALL_SELECTED_ITEMS": "Alle %lu ausgewählten Elemente kopieren?", + "FAILED_COPYING_ITEM": "Kopieren vom Element fehlgeschlagen", + "ITEMS_COPIED_TO_OUT": "%lu Elemente nach %s kopiert", + "PATH_COPIED_TO_OUT": "%s\nKopiert nach %s", + "CART_INIT_FAILED": "Karteninitialisierung fehlgeschlagen!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Karte: %s\nErkannte Größe: %s\n \nGebe Dumpgröße unten ein.", + "NDS_CART_DECRYPT_SECURE_AREA": "Karte: %s\nNDS-Karte erkannt\nSecure-Area entschlüsseln?", + "FAILED_DUMPING_CART": "%s\nDumpen der Karte fehlgeschlagen", + "PATH_DUMPED_TO_OUT": "%s\nUnter %s gedumpt", + "CREATED": "erstellt", + "MODIFIED": "geändert", + "ANALYZING_DRIVE": "Untersuche Laufwerk, bitte warten...", + "ANALYZING_DIR": "Untersuche Verzeichnis, bitte warten...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu Dateien & %lu Unterverzeichnisse\n%s Gesamtgröße\n \nFreier Speicherplatz: %s\nBelegter Speicherplatz: %s\nGesamter Speicherplatz: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu Dateien & %lu Unterverzeichnisse\n%s Gesamtgröße", + "FILESIZE_X": "dateigröße: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %snur lesbar [%c] %sversteckt\n[%c] %ssystem [%c] %sarchiv\n[%c] %svirtuell\n%s", + "UDRL_CHANGE_ATTRIBUTES": " (↑↓→← um Attribute zu verändern)\n", + "A_TO_CONTINUE": "( um fortzufahren)", + "A_APPLY_B_CANCEL": "( um anzuwenden, um abzubrechen)", + "A_YES_B_NO": "( ja, nein)", + "A_SELECT_B_CANCEL": "( auswählen, abbrechen)", + "HOLD_B_TO_CANCEL": "(halte B um abzubrechen)", + "FAILED_TO_SET_ATTRIBUTES": "Setzen von Attributen fehlgeschlagen!", + "NAND_IMAGE_OPTIONS": "NAND-Abbild-Optionnen...", + "CTRNAND_OPTIONS": "CTRNAND-Optionen...", + "MOUNT_FAT_IMAGE": "Als FAT-Abbild einhängen", + "CIA_IMAGE_OPTIONS": "CIA-Abbild-Optionen...", + "NCSD_IMAGE_OPTIONS": "NCSD-Abbild-Optionen...", + "NCCH_IMAGE_OPTIONS": "NCCH-Abbild-Optionen...", + "MOUNT_AS_EXEFS_IMAGE": "Als EXEFS-Abbild einhängen", + "MOUNT_AS_ROMFS_IMAGE": "Als ROMFS-Abbild einhängen", + "TMD_FILE_OPTIONS": "TMD-Datei-Optionen...", + "TMD_CDN_OPTIONS": "TMD/CDN-Optionen...", + "TMD_TWL_OPTIONS": "TMD/TWL-Optionen...", + "MANAGE_TITLE": "Titel Verwalten...", + "BOSS_FILE_OPTIONS": "BOSS-Datei-Optionen...", + "DECRYPT_NUS_CDN_FILE": "NUS/CDN-Datei entschlüsseln", + "SHOW_SMDH_TITLE_INFO": "SMDH-Titelinfo anzeigen", + "NDS_IMAGE_OPTIONS": "NDS-Abbild-Optionen...", + "GBA_IMAGE_OPTIONS": "GBA-Abbild-Optionen...", + "TICKET_OPTIONS": "Ticket-Optionen...", + "TAD_IMAGE_OPTIONS": "TAD-Abbild-Optionen...", + "SHOW_3DSX_TITLE_INFO": "3DSX-Titelinfo anzeigen", + "FIRM_IMAGE_OPTIONS": "FIRM-Abbild-Optionen...", + "AGBSAVE_OPTIONS": "AGBSAVE-Optionen...", + "DUMP_GBA_VC_SAVE": "GBA-VC-Speicherstand dumpen", + "TICKET_DB_OPTIONS": "Ticket.db-Optionen...", + "MOUNT_AS_DIFF_IMAGE": "Als DIFF-Abbild einhängen", + "MOUNT_AS_DISA_IAMGE": "Als DISA-Abbild einhängen", + "INSTALL_CIFINISH_BIN": "cifinish.bin installieren", + "TITLEKEY_OPTIONS": "Titlekey-Optionen...", + "AESKEYDB_OPTIONS": "AESkeydb-Optionen...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo-Optionen...", + "EXECUTE_GM9_SCRIPT": "GM9-Skript ausführen", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Schriftoptionen...", + "LANGUAGE_OPTIONS": "Sprachoptionen...", + "VIEW_PNG_FILE": "PNG-Datei anzeigen", + "REBUILD_NCSD_HEADER": "NCSD-Header neu erstellen", + "SHOW_IN_HEXEDITOR": "Im Hexeditor anzeigen", + "CALCULATE_SHA256": "SHA-256 berechnen", + "CALCULATE_SHA1": "SHA-1 berechnen", + "SHOW_FILE_INFO": "Datei-Info anzeigen", + "SHOW_IN_TEXTVIEWER": "Im Textbetrachter anzeigen", + "CALCULATE_CMAC": "CMAC berechnen", + "COPY_TO_OUT": "Nach %s kopieren", + "DUMP_TO_OUT": "Unter %s dumpen", + "INJECT_DATA_AT_OFFSET": "Daten @versatz injizieren", + "OPEN_THIS_FOLDER": "Dieses Verzeichnis öffnen", + "OPEN_CONTAINING_FOLDER": "Beinhaltendes Verzeichnis öffnen", + "OPEN_TITLE_FOLDER": "Titelorder öffnen", + "PATH_N_FILES_SELECTED": "%s\n(%lu Dateien ausgewählt)", + "CHECK_CURRENT_CMAC_ONLY": "Nur aktuelles CMAC überprüfen", + "VERIFY_CMAC_FOR_ALL": "CMAC für alle überprüfen", + "FIX_CMAC_FOR_ALL": "CMAC für alle reparieren", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu Dateien ok/repariert/insgesamt\n%lu/%lu haben kein CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu Dateien erfolgreich verifiziert\n%lu/%lu Dataien repariert", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu Dateien erfolgreich verifiziert\n%lu/%lu haben kein CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu Dateien erfolgreich verifiziert", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Daten von %s injizieren?\nVersatz unten eingeben.", + "FAILED_INJECTING_PATH": "Injizieren von %s fehlgeschlagen", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDS an Laufwerk einhängen", + "MOUNT_IMAGE_TO_DRIVE": "Abbild an Laufwerk einhängen", + "RESTORE_SYSNAND_SAFE": "SysNAND wiederherstellen (sicher)", + "UPDATE_EMBEDDED_BACKUP": "Eingebettetes backup aktualisieren", + "SHOW_TITLE_INFO": "Titel-Info anzeigen", + "DECRYPT_FILE": "Datei entschlüsseln (...)", + "DECRYPT_FILE_OUT": "Datei entschlüsseln (%s)", + "ENCRYPT_FILE": "Datei verschlüsseln (...)", + "ENCRYPT_FILE_OUT": "Datei verschlüsseln (%s)", + "BUILD_CIA_FROM_FILE": "CIA aus Datei erstellen", + "BUILD_CIA_STANDARD": "CIA erstellen (standard)", + "BUILD_CIA_LEGIT": "CIA erstellen (legit)", + "DUMP_CXI_NDS_FILE": "CXI/NDS-Datei dumpen", + "INSTALL_GAME_IMAGE": "Spielabbild installieren", + "INSTALL_TICKET": "Ticket installieren", + "DUMP_TICKET_FILE": "Ticket-Datei dumpen", + "UNINSTALL_TITLE": "Titel deinstallieren", + "VERIFY_FILE": "Datei verifizieren", + "TRANSFER_IMAGE_TO_CTRNAND": "Abbild auf CTRNAND übertragen", + "INJECT_TO_H_AND_S": "In G&S injizieren", + "TRIM_FILE": "Datei trimmen", + "RENAME_FILE": "Datei umbenennen", + "BUILD_XORPADS_SD": "XORpads erstrellen (auf SD)", + "BUILD_XORPADS_INPLACE": "XORpads erstellen (an Ort und Stelle)", + "EXTRACT_X": "%s extrahieren", + "INIT_X": "%s einrichten", + "INSTALL_X": "%s installieren", + "INSTALL_FIRM": "FIRM installieren", + "BOOT_FIRM": "FIRM booten", + "SET_AS_ACTIVE_FONT": "Als aktive Schriftart festlegen", + "SET_AS_ACTIVE_LANGUAGE": "Als aktive Sprache festlegen", + "DUMP_BA_VC_SAVE": "GBA-VC-Spielstand dumpen", + "INJECT_GBA_VC_SAVE": "GBA-VC-Spielstand injizieren", + "SET_AS_DEFAULT": "Als Standard festlegen", + "MOUNTING_IMAGE_FAILED": "Einhängen vom Abbild: fehlgeschlagen", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nEingehängt als Laufwerk unter %s\nPfad jetzt betreten?", + "DECRYPT_TO_OUT": "Unter %s entschlüsseln", + "DECRYPT_INPLACE": "An Ort und Stelle entschlüsseln", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu entschlüsseln?", + "TRYING_TO_DECRYPT_N_FILES": "Versuche, %lu Dateien zu entschlüsseln...", + "DECRYPTION_FAILED_CONTINUE": "Entschlüsseln fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich entschlüsselt\n%lu/%lu nicht verschlüsselt\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu Dateien erfolgreich entschlüsselt", + "N_FILES_WRITTEN_TO_OUT": "%lu Dateien in %s geschrieben", + "FILE_NOT_ENCRYPTED": "Datei ist nicht verschlüsselt", + "DECRYPTION_SUCCESS": "Entschlüsseln erfolgreich", + "DECRYPTION_FAILED": "Entschlüsseln fehlgeschlagen", + "PATH_DECRYPTED_TO_OUT": "%s\nEntschlüsselt nach %s", + "ENCRYPT_TO_OUT": "Nach %s verschlüsseln", + "ENCRYPT_INPLACE": "An Ort und Stelle verschlüsseln", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu verschlüsseln?", + "TRYING_TO_ENCRYPT_N_FILES": "Versuche, %lu Dateien zu verschlüsseln...", + "ENCRYPTION_FAILED_CONTINUE": "Verschlüsseln fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich verschlüsselt\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu Dateien erfolgreich verschlüsselt", + "ENCRYPTION_SUCCESS": "Verschlüsseln erfolgreich", + "ENCRYPTION_FAILED": "Verschlüsseln fehlgeschlagen", + "PATH_ENCRYPTED_TO_OUT": "%s\nVerschlüsselt unter %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu verarbeiten?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nErstellen von %s fehlgeschlagen\n\nForfahren?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %s-Dateien erfolgreich erstellt\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_TYPES_BUILT": "%lu/%lu %s-Dateien erfolgreich erstellt", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "Konvertierung von %lu Datei(en) fehlgeschlagen.\nVerifizierung ist empfohlen.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s unter %s erstellt", + "PATH_TYPE_BUILD_FAILED": "%s\nErstellung von %s fehlgeschlagen", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "Konvertierung von Datei fehlgeschlagen\n\nJetzt verifizieren?", + "VERIFICATION_SUCCESS": "Verifizierung erfolgreich", + "VERIFICATION_FAILED": "Verifizierung fehlgeschlagen", + "CONTENT_IS_MISSING": "Inhalt fehlt", + "INSTALL_TO_SYSNAND": "Auf SysNAND installieren", + "INSTALL_TO_EMUNAND": "Auf EmuNAND installieren", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu installieren?", + "TRYING_TO_INSTALL_N_FILES": "Versuche, alle %lu Dateien zu installieren...", + "INSTALL_FAILED_CONTINUE": "Installation fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich installiert\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_FILES_INSTALLED": "%lu/%lu Dateien erfolgreich installiert", + "INSTALL_SUCCESS": "Installation erfolgreich", + "INSTALL_FAILED": "Installation fehlgeschlagen", + "FILE_FAILED_INSTALL_VERIFY_NOW": "Installation der Datei fehlgeschlagen.\n\nJetzt verifizieren?", + "KEEP_TICKET_AND_SAVEGAME": "Ticket und Spielstand behalten", + "UNINSTALL_EVERYTHING": "Alles deinstallieren", + "ABORT_UNINSTALL": "Deinstallation abbrechen", + "UNINSTALL_N_SELECTED_TITLES": "%lu ausgewählte Titel deinstallieren?", + "UNINSTALL_SELECTED_TITLE": "Ausgewählten Titel deinstallieren?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu Titel deinstalliert", + "UNINSTALLING_PLEASE_WAIT": "Deinstallieren, bitte warten...", + "UNINSTALL_FAILED": "Deinstallation fehlgeschlagen!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Versuche, alle %lu ausgewählten Titel zu verifizieren?", + "VERIFICATION_FAILED_CONTINUE": "Verifizierung fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich verifiziert\n%lu/%lu nicht vom gleichen Typ", + "VERIFYING_FILE_PLEASE_WAIT": "Verifiziere Datei, bitte warten...", + "NAND_VALIDATION_SUCCESS": "NAND-Überprüfung erfolgreich", + "NAND_VALIDATION_FAILED": "NAND-Überprüfung fehlgeschlagen", + "DUMP_FOR_N_SELECTED_FILES": "Für alle %lu ausgewählten Dateien dumpen?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit-Tickets gedumpt.\n\nVersuchen, alle Tickets zu dumpen?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu Tickets nach %s gedumpt", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket nach %s gedumpt", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit-Ticket nicht gefunden\n\nTrotzdem dumpen?", + "DUMP_TICKET_FAILED": "Dumpen vom Ticket fehlgeschlagen!", + "BUILDING_X": "Erstelle %s...", + "BUILDING_X_SYSNAND": "Erstelle %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Erstelle %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu Dateien verarbeitet\n%lu/%lu Dateien ignoriert", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu Dateien verarbeitet", + "BUILD_DATABASE_SUCCESS": "Datenbankerstellung erfolgreich.", + "BUILD_DATABASE_FAILED": "Datenbankerstellung fehlgeschlagen.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Alle %lu ausgewählten Dateien trimmen?", + "TRIMMING_FAILED_CONTINUE": "Trimmen fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu Dateien erfolgreich getrimmt\n%lu/%lu nicht vom gleichen Typ\n%s gespeichert", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu Dateien erfolgreich getrimmt\n%s gespeichert", + "FILE_CANT_BE_TRIMMED": "Datei kann nicht getrimmt werden.", + "FILE_ALREADY_TRIMMED": "Datei ist bereits getrimmt.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nAktuelle Größe: %s\nGetrimmte Größe: %s\nUnterschied: %s\n\nDiese Datei trimmen?", + "TRIMMING_FAILED": "Trimmen fehlgeschlagen.", + "PATH_TRIMMED_BY_X": "%s\n%s getrimmt.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien umzubenennen?", + "N_OF_N_RENAMED": "%lu/%lu erfolgreich umbenannt", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Konnte nicht zum guten Namen umbenennen", + "SYSNAND_H_AND_S_INJECT": "SysNAND G&S injizieren", + "EMUNAND_H_AND_S_INJECT": "EmuNAND G&S injizieren", + "H_AND_S_INJECT_SUCCESS": "G&S-Injektion erfolgreich", + "H_AND_S_INJECT_FAILURE": "G&S-Injektion fehlgeschlagen", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu extrahieren?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich extrahiert\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu Dateien erfolgreich extrahiert", + "EXTRACTING_DOT_CODE": "Extrahiere .code, bitte warten...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extrahiert nach %s", + "DOT_CODE_EXTRACT_FAILED": ".code-Extrahierung fehlgeschlagen", + "TRANSFER_TO_SYSNAND": "Übertragung auf SysNAND", + "TRANSFER_TO_EMUNAND": "Übertragung auf EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND-Übertragung erfolgreich", + "CTRNAND_TRANSFER_FAILED": "CTRNAND-Übertragung fehlgeschlagen", + "NO_VALID_DESTINATION_FOUND": "Kein gültiges Ziel gefunden", + "NAND_RESTORE_SUCCESS": "NAND-Wiederherstellung erfolgreich", + "NAND_RESTORE_FAILED": "NAND-Wiederherstellung fehlgeschlagen", + "REBUILD_NCSD_SUCCESS": "NCSD-Neuaufbau erfolgreich", + "REBUILD_NCSD_FAILED": "NCSD-Neuaufbau fehlgeschlagen", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo Padgen Erfolg%cAusgabeverzeichnis: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo Padgen fehlgeschlagen%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Eingebettetes Backup wird aktualisiert...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup-Update: nicht erforderlich", + "BACKUP_UPDATE_COMPLETED": "Backup-Update: abgeschlossen", + "BACKUP_UPDATE_FAILED": "Backup-Update: fehlgeschlagen!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warnung: Schlüssel sind nicht verifiziert.\nFortfahren auf eigene Gefahr?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb-Initialisierung erfolgreich", + "AESKEYDB_INIT_FAILED": "AESkeydb-Initialisierung fehlgeschlagen", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb-Installation erfolgreich", + "AESKEYDB_INSTALL_FAILED": "AESkeydb-Installation fehlgeschlagen", + "INSTALL_TO_FIRM0": "Auf FIRM0 installieren", + "INSTALL_TO_FIRM1": "Auf FIRM1 installieren", + "INSTALL_TO_BOTH": "Auf beiden installieren", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nAuf SysNAND installieren?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstallation erfolgreich", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstallation fehlgeschlagen", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warnung: Führe keine Skripte aus\nnicht vertrauenswürdigen Quellen aus.\n \nSkript ausführen?", + "SCRIPT_EXECUTE_SUCCESS": "Skriptausführung erfolgreich", + "SCRIPT_EXECUTE_FAILURE": "Skriptausführung fehlgeschlagen", + "ERROR_CANNOT_VIEW_FILE": "Fehler: Datei kann nicht angezeigt werden\n(Hinweis: Möglicherweise ist sie zu groß)", + "SAVEGAME_DUMPED_TO_OUT": "Spielstand gespeichert unter %s.", + "SAVEGAME_DUMP_FAILED": "Spielstandspeicherung fehlgeschlagen!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame muss\nin der Zwischenablage sein.", + "SAVEGAME_INJECT_SUCCESS": "Savegame Injektion erfolgreich.", + "SAVEGAME_INJECT_FAILED": "Speicherspiel-Injektion fehlgeschlagen!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Schriftart wird beim nächsten Start aktiv sein", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Sprache wird beim nächsten Start aktiv sein", + "HOME_MORE_MENU_SELECT_ACTION": "HOME mehr... Menü.\nAktion auswählen:", + "SD_FORMAT_MENU": "SD-Format-Menü", + "BONUS_DRIVE_MENU": "Bonus-Laufwerk-Setup", + "SWITCH_EMUNAND": "EmuNAND wechseln", + "BUILD_SUPPORT_FILES": "Unterstützungsdateien erstellen", + "RESTORE_H_AND_S": "G&S wiederherstellen", + "SET_RTC_DATE_TIME": "RTC Datum/Uhrzeit einstellen", + "CONFGURE_BRIGHTNESS": "Helligkeit konfigurieren", + "CALIBRATE_TOUCHSCREEN": "Touchscreen kalibrieren", + "SYSTEM_INFO": "Systeminformation", + "SHOW_README": "ReadMe anzeigen", + "INITIALIZING_SD_FAILED_RETRY": "Initialisieren von SD-Karte fehlgeschlagen! Erneut versuchen?", + "SETUP_FAILED": "Einrichtung fehlgeschlagen!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Aktueller EmuNAND-Versatz ist %06lX.\nZum nächsten Versatz wechseln?", + "BUILT_IN_OUT_STATUSES": "Erstellt unter %s:\n\n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Fehlgeschlagen", + "RESTORE_H_AND_S_EMUNAND": "G&S wiederherstellen (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "G&S wiederherstellen (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "RTC Datum/Uhrzeit einstellen:", + "NEW_RTC_DATE_TIME_IS_TIME": "Neue(s) RTC-Datum/Uhrzeit ist:\n%s\n\nTipp: HOME-Menü benötigt\nmanuelles einstellen nach\nRTC-Einstellung.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen-Kalibrierung erfolgreich!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen-Kalibrierung fehlgeschlagen!", + "GODMODE9_README_TOC": "GodMode9-ReadMe-Inhaltsverzeichnis", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essenzielle-Dateien-Backup nicht gefunden.\nJetzt eins erstellen?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup im SysNAND eingebettet\nund unter %s geschrieben.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC-Datum/Uhrzeit könnte\nfalsch sein. Jetzt einstellen?", + "RESUME_GODMODE9": "GodMode9 fortsetzen", + "RESUME_BOOTLOADER": "Bootloader fortsetzen", + "SELECT_PAYLOAD": "Payload auswählen...", + "SELECT_SCRIPT": "Skript auswählen...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "System ausschalten", + "REBOOT_SYSTEM": "System neustarten", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s Bootloader-Menü.\nAktion auswählen:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader-Payloads-Menü.\nPayload auswählen:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader-Skripte-Menü.\nSkript auswählen:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "Kein bootfähiges FIRM gefunden.\nSetze GodMode9 fort...", + "OUT_OF_MEMORY": "Nicht genügend Arbeitsspeicher.", + "INVALID_DIRECTORY_OBJECT": "Ungültiges Verzeichnisobjekt", + "INVALID_ROOT_DIRECTORY": "Ungültiges Wurzelverzeichnis.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Schreibrechte wurden verändert.\nDiese wieder sperren?", + "OPEN_TITLE_MANAGER": "Titel-Verwalter öffnen", + "SEARCH_FOR_FILES": "Nach Dateien suchen...", + "FIX_CMACS_FOR_DRIVE": "CMACs für Laufwerk reparieren", + "SHOW_DIRECTORY_INFO": "Verzeichnis-Info anzeigen", + "SHOW_DRIVE_INFO": "Laufwerk-Info anzeigen", + "FAILED_SETTING_UP_TITLE_MANAGER": "Einrichtung des Titel-Verwalters fehlgeschlagen!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Suche %s?\nSuchbegriffe unten eingeben.", + "FOUND_N_RESULTS": "%lu Ergebnisse gefunden.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "CMAC-Reparatur für Laufwerk beendet.", + "FAILED_TO_ANALYZE_DRIVE": "Laufwerkanalyse fehlgeschlagen\n", + "FAILED_TO_ANALYZE_DIR": "Verzeichnisanalyse fehlgeschlagen\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "In einem virtuellem Pfad nicht erlaubt", + "DELETE_N_PATHS": "%lu Pfad(e) löschen?", + "DELETING_FILES_PLEASE_WAIT": "Lösche Dateien, bitte warte...", + "FAILED_DELETING_N_OF_N_PATHS": "Löschen von %lu/%lu Pfad(en) fehlgeschlagen", + "DELETE_FILE": "\"%s\" löschen?", + "FAILED_DELETING_PATH": "Löschen fehlgeschlagen:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Im Suchlaufwerk nicht erlaubt", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Im virtuellen Spielpfad nicht erlaubt", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Im XORpad-Laufwerk nicht erlaubt", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Im Gamecart-Laufwerk nicht erlaubt", + "NOT_ALLOWED_IN_ALIAS_PATH": "Im Alias-Pfad nicht erlaubt", + "COPY_PATHS": "Pfad(e) kopieren", + "MOVE_PATHS": "Pfad(e) verschieben", + "PASTE_FILE_HERE": "\"%s\" hier einfügen?", + "PASTE_N_PATHS_HERE": "%lu Pfade hier einfügen?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Kopieren vom Pfad fehlgeschlagen:\n%s\nDen Rest verarbeiten?", + "FAILED_COPYING_PATH": "Kopieren vom Pfad fehlgeschlagen:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Verschieben vom Pfad fehlgeschlagen:\n%s\nDen Rest verarbeiten?", + "FAILED_MOVING_PATH": "Verschieben vom Pfad fehlgeschlagen:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "%s umbenennen?\nNeuen Namen unten eingeben.", + "FAILED_RENAMING_PATH": "Umbenennen vom Pfad fehlgeschlagen:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Hier einen neuen Eintrag erstellen?\nWähle einen Typ aus.", + "CREATE_A_FOLDER": "Verzeichnis erstellen", + "CREATE_A_DUMMY_FILE": "Eine Platzhalterdatei erstellen", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Hier ein neues Verzeichnis erstellen?\nGebe unten den Namen ein.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Hier eine neue Datei erstellen?\nGebe unten den Namen ein.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Hier ein(e) neue(s) %s erstellen?\nGebe unten den Namen ein.", + "FAILED_CREATING_FOLDER_PATH": "Erstellen des Verzeichnisses fehlgeschlagen:\n%s", + "FAILED_CREATING_FILE_PATH": "Erstellen der Datei fehlgeschlagen:\n%s", + "TITLE_MANAGER": "Titel-Verwalter", + "BRICK_MY_3DS": "Meinen 3DS bricken", + "LANGUAGE": "Sprache...", + "SCRIPTS": "Skripte...", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Payloads...", + "MORE": "Mehr...", + "BRACKET_MORE": "[mehr...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME-Knopf betätigt.\nAktion auswählen:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER-Schalter betätigt.\nAktion auswählen:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD-KARTE", + "B_DRIVE_SD_CARD": "[B:] SD-KARTE", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Titel-Verwalter-Menü.\nQuelle von Titeln auswählen:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Sprachverzeichnis nicht gefunden.\n(Standardpfad: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Skriptverzeichnis nicht gefunden.\n(Standardpfad: 0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME-Sprachen... Menü.\nSprache auswählen:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME-Skripte... Menü.\nSkript auswählen:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads-Verzeichnis nicht gefunden.\n(Standardpfad: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME-Payloads... Menü.\nPayload auswählen:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unerwartetes Entfernen der SD-Karte!\n\nUm Datenverluste zu vermeiden,\nhänge die SD-Karte aus bevor du\nsie entfernst.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s Skript-Menü.\nSkript auswählen:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Als Skript-Autorunner kompiliert,\naber kein Skript wurde angegeben.\n\nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Tastaturbedienung:\n←/→ - Cursor bewegen\nR - Caps / Capslock\nX - Zeichen löschen\nY - Zeichen einfügen\nA - Bestätigen\nB - Abbrechen\n\nSELECT wechselt zur\nklassischen Eingabe", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Berühre die roten Kreuze, um\ndeinen Touchscreen zu kalibrieren.\n\nBenutze einen Touchpen für die\nbesten Ergebnisse!", + "INVALID": "UNGÜLTIG", + "TO_PROCEED_ENTER_THIS": "Um fortzufahren, gebe dies ein:", + "TO_PROCEED_HOLD_X": "Um fortzufahren, halte :", + "N_MORE": " [%d weitere]", + "CANCEL": "abbrechen", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) Schnell scrollen\nL - Eingabe leeren", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - Zeichen entfernen\nY - Zeichen einfügen", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Helligkeit verringern\n[→] Helligkeit erhöhen\n \n[X] Nutze Lautstärkeregler\n[A] Aktuelle Helligkeit einstellen\n[B] Abbrechen", + "SEARCHING_PLEASE_WAIT": "Suche, bitte warten...", + "RENAME_TO_GOOD_NAME": "In guten Namen umbenennen?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD-Karte ist schreibgeschützt!\nKann nicht fortfahren.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "Spielabbilder", + "GAMECART_SAVES": "Gamecart-Spielstände", + "IMAGES": "Abbilder", + "MEMORY_AREAS": "Speicherbereiche", + "SD_SYSTEM_DATA": "SD-Systemdaten", + "SD_CARD": "SD-Karte", + "RAM_DRIVE": "RAM-Laufwerk", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Schreiben in %s ist gesperrt!\nJetzt entsperren?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Entsperren von Schreibrechten für\n%s ist nicht erlaubt.", + "ENABLE_BASE_WRITE": "Du möchtest vielleicht die Basis-\nSchreibrechte entsperren.", + "ENABLE_SD_WRITE": "Du möchtest vielleicht die SD-Karten-\nSchreibrechte entsperren.", + "ENABLE_IMAGE_WRITE": "Du möchtest vielleicht die Abbild-\nSchreibrechte entsperren.", + "ENABLE_RAM_DRIVE_WRITE": "Du möchtest vielleicht die RAM-Laufwerk-\nSchreibrechte entsperren.", + "ENABLE_EMUNAND_0_WRITE": "Du möchtest vielleicht die EmuNAND-\nlvl0-Schreibrechte entsperren.", + "ENABLE_SYSNAND_0_WRITE": "Du möchtest vielleicht die SysNAND-\nlvl0-Schreibrechte entsperren.", + "ENABLE_EMUNAND_1_WRITE": "Du möchtest vielleicht die EmuNAND-\nlvl1-Schreibrechte entsperren.\n\nDies ermöglicht dir, wiederherstellbare\nSystemdaten, Nutzerdaten & Spielstände\nzu modifizieren.", + "ENABLE_SYSNAND_1_WRITE": "Du möchtest vielleicht die EmuNAND-\nlvl1-Schreibrechte entsperren.\n\nDies ermöglicht dir, Systemdaten,\nNutzerdaten & Spielstände zu\nmodifizieren.", + "ENABLE_GAMECART_SAVE_WRITE": "Sie möchten vielleicht die Gamecart-\nSpielstand-Schreibrechte entsperren.", + "ENABLE_SYSNAND_2_WRITE": "!Du solltest vorsichtig sein!\n\nDu möchtest vielleicht die SysNAND-\nlvl2-Schreibrechte entsperren.\n\nDies ermöglicht dir, nichtwiederherstellbare\nSystemdaten zu modifizieren!", + "ENABLE_MEMORY_WRITE": "!Du solltest vorsichtig sein!\n\nDu möchtest vielleicht die Arbeitsspeicher-\nSchreibrechte entsperren.\n\nDas Schreiben in einigen Bereichen könnte\nzu unerwarteten Ergebnissen führen.", + "ENABLE_SD_DATA_WRITE": "!DIES IST NICHT EMPFOHLEN!\n\nDu möchtest vielleicht die SD-\nDaten-Schreibrechte entsperren.\n\nAlles hier ist verschlüsselt. Es wird\nempfohlen, die A:/B: Laufwerke für\nÄnderungen an Installationen,\nNutzerdaten und Spielständen zu\ntätigen.", + "ENABLE_SYSNAND_3_WRITE": "!DIES IST DEINE EINZIGE WARNUNG!\n\nDu möchtest vielleicht die SysNAND-\nlvl3-Schreibrechte entsperren.\n\nDies ermöglicht dir, deine Bootloader-\nInstallation und/oder wichtige\nSystemdateien zu ÜBERSCHREIBEN\nund/oder deine Konsole zu BRICKEN!", + "UNLOCK_WRITE_NOT_ALLOWED": "Das Entsperren der Schreibrechte\nist nicht erlaubt.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Kann Schreibrechte nicht entsperren.\nNutze stattdessen GodMode9!", + "ERROR_SD_TOO_SMALL": "Fehler: SD-Karte ist zu klein", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNUNG!\n\nFortfahren wird diese SD-Karte\nformatieren. Dies wird ALLE Daten\nunwiderruflich löschen.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Bonus-Laufwerk formatieren?\nDies wird ALLE Daten\nunwiderruflich löschen.", + "FORMATTING_SD_PLEASE_WAIT": "Formatiere SD-Karte, bitte warten...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatiere Laufwerk, bitte warten...", + "ERROR_SD_CARD_IO_FAILURE": "Fehler: SD-Karte E/A-Fehler", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "Datei ist derzeit eingehängt.\nAushängen zum Entsperren?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Fehler: Kann Datei nicht in sich\nselbst Injizieren", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Vorgang würde über das Ende der Datei\nhinaus schreiben", + "NOT_ENOUGH_DATA_IN_FILE": "Nicht genügend Daten in der Datei", + "CANCEL_IS_NOT_ALLOWED_HERE": "Abbrechen ist hier nicht erlaubt", + "B_DETECTED_CANCEL": "B-Knopf erkannt. Abbrechen?", + "ERROR_CANNOT_APPEND_FOLDER": "Fehler: Kann ein Verzeichnis nicht anhängen", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Fehler: Überschreiben einer Datei\nmit einem Verzeichnis", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Fehler: Überschreiben eines Verzeichnisses\nmit einer Datei", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Fehler: Kann Zieldatei nicht öffnen", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Fehler: Nicht genügend Speicherplatz verfügbar", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Fehler: Nur FAT-Dateien können\nverschoben werden", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Fehler: Ziel ist Teil vom Ursprung", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Ziel ist gleich Ursprung\nEinen anderen Namen auswählen?", + "CHOOSE_NEW_NAME": "Einen neuen Namen auswählen", + "OVERWRITE_FILES": "Datei(en) überschreiben", + "SKIP_FILES": "Datei(en) überspringen", + "OVERWRITE_ALL": "Alle überschreiben", + "SKIP_ALL": "Alle überspringen", + "DESTINATION_ALREADY_EXISTS": "Ziel ist bereits vorhanden:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Einen neuen Zielnamen auswählen", + "COPY_OPERATION_IS_NOT_ALLOWED": "Kopiervorgang ist nicht zulässig", + "DESTINATION_EQUALS_ORIGIN": "Ziel ist gleich Ursprung", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Eintrag nicht gefunden: %s\nStattdessen in %s injizieren?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "Datei kleiner als verfügbarer Speicherplatz:\n%s (%s)\n%s (%s)\nFortfahren?", + "NO_USABLE_ENTRIES_FOUND": "Keine verwendbaren Einträge gefunden.", + "BEAT_NO_ERROR": "Kein Fehler", + "BEAT_END_OF_ACTION_LIST": "Ende der Aktionsliste", + "BEAT_ABORTED_BY_USER": "Vom Benutzer abgebrochen", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Fehler beim Lesen/Schreiben der Datei", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Es wurde versucht, über das Ende der Datei hinaus zu schreiben", + "BEAT_INVALID_PATCH_FILE": "Ungültige Patch-Datei", + "BEAT_INVALID_INPUT_FILE": "Ungültige Eingabedatei", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Ausgabedatei Prüfsumme stimmt nicht überein", + "BEAT_FILE_CHECKSUM_FAILED": "Datei-Prüfsumme fehlgeschlagen", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Weitere Patchdaten erwartet", + "BEAT_OUT_OF_MEMORY": "Nicht im Speicher", + "BEAT_UNKNOWN_ERROR": "Unbekannter Fehler", + "FAILED_TO_INITIALIZE_BPM_FILE": "Fehler beim Initialisieren der BPM-Datei:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Fehler beim Initialisieren der BPS-Datei:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch erfolgreich angewendet", + "PATCHING_ABORTED_BY_USER": "Patchvorgang vom Benutzer abgebrochen", + "FAILED_TO_RUN_PATCH": "Fehler beim Ausführen des Patchs:\n%s", + "DECOMPRESSING_DOT_CODE": "Dekomprimiere .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Dekomprimiere .code...\nB-Taste erkannt. Abbrechen?", + "COMPRESSING_DOT_CODE": ".code komprimieren...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": ".code komprimieren...\nB Schaltfläche erkannt. Abbrechen?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "Der Patch ist höchstwahrscheinlich nicht für diese Datei vorgesehen.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "Du hast den Patch höchstwahrscheinlich auf die Ausgabedatei angewendet.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "Der Patch ist technisch gültig,\nscheint jedoch durcheinandergebracht oder fehlerhaft zu sein.", + "PATCH_IS_INVALID": "Der Patch ist ungültig.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "Eine oder beide Dateien sind größer als 16 MB.\nDas IPS-Format unterstützt das nicht.", + "REQUESTED_FILE_PATH_WAS_INVALID": "Der angeforderte Dateipfad war ungültig.", + "PATCHING_CANCELED": "Patchen abgebrochen.", + "NOT_ENOUGH_MEMORY": "Nicht genügend Speicherplatz.", + "REGION_AMERICAS": "Amerika", + "REGION_AUSTRALIA": "Australien", + "REGION_BRAZIL": "Brasilien", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europa", + "REGION_FRANCE": "Frankreich", + "REGION_GERMANY": "Deutschland", + "REGION_ITALY": "Italien", + "REGION_JAPAN": "Japan", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spanien", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Unbekannt", + "REGION_UNITED_KINGDOM": "Vereinigtes Königreich", + "REGION_MIDDLE_EAST": "Mittlerer Osten", + "GENERATING_QR_CODE": "Generiere QR-Code...", + "REINITIALIZING_SD_CARD": "Initialisiere SD-Karte erneut...", + "DUMPING_STATE_TO_SD_CARD": "Dumpe Status auf SD-Karte...", + "PRESS_POWER_TO_TURN_OFF": "Drücke POWER um auszuschalten", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Bereinige Titel, bitte warten...", + "ERROR_NOT_NCCH_FILE": "Fehler: Nicht eine NCCH-Datei", + "ERROR_FILE_IS_TOO_SMALL": "Fehler: Datei ist zu klein", + "ATTEMPT_FIX_THIS_TIME": "Versuche, diesmal zu korrigieren", + "ATTEMPT_FIX_ALWAYS": "Immer versuchen, zu korrigieren", + "ABORT_VERIFICATION": "Verfizierung abbrechen", + "ERROR_BAD_CRYPTO_FLAGS": "Fehler: Falsche Crypto-Flags", + "ERROR_BAD_EXEFS_HEADER": "Fehler: Fehlerhafter ExeFS-Header", + "ERROR_MISSING_EXTHEADER": "Fehler: Fehlender ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Fehler: Crypto nicht eingerichtet", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH-Verifizierung fehlgeschlagen:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "erfolg", + "FAIL": "fehler", + "ERROR_NOT_NCSD_FILE": "Fehler: Nicht eine NCSD-Datei", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nInhalt%lu (%08lX@%08lX):\nVerifizierung fehlgeschlagen", + "ERROR_PROBABLY_NOT_CIA_FILE": "Fehler: Wahrscheinlich nicht eine CIA-Datei", + "ERROR_TMD_PROBABLY_CORRUPTED": "Fehler: TMD wahrscheinlich beschädigt", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerifizierung fehlgeschlagen", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Fehler: CDN-Titlekey nicht gefunden", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC-Inhalt fehlt\n\nAlle ignorieren und fortfahren?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nAbschnitt %lu Hashfehler", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9-Einstiegspunkt fehlt", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warnung: ARM11-Einstiegspunkt fehlt", + "ERROR_NOT_A_BOSS_FILE": "Fehler: Keine BOSS-Datei", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS Payload Hash-Unstimmigkeit.\n \nVersuchen Sie es zu beheben?", + "GENERIC_TICKET_PIRATE_LEGIT": "Allgemeines Ticket (\"Piratenlegit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalisiertes Ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit Ticket ist personalisiert.\nVerwendung wird nicht empfohlen.\nStandardaktion auswählen:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey nicht gefunden.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD ist nicht erlaubt.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD ist nicht erlaubt.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Inhalt ist beschädigt", + "INSERT_CONTENT_FAILED": "Inhalt nicht einfügen", + "INSTALL_CONTENT_FAILED": "Installationsinhalt fehlgeschlagen", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Installationsfehler:\nDieses System fehlt eine oder\nmehr .db-Dateien.\n \nVielleicht fehlt die SD-Karte\noder uninitialisiert?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Installationsfehler:\nDieses System fehlt die\nticket.db Datei.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Übersprungener Titel:\nTitel mit id 0004008C000CBD00\nbenötigt spezielle Compiler-Flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Fehler: Fake-signed ticket\n \nNur gültige signierte Tickets können\nim System installiert werden.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nFehler: Unbekannter cid %08lX\n \nDieses Ticket gehört nicht zu\ndieser 3DS Konsole.", + "INSTALLING_TICKET": "Ticket wird installiert...", + "POSSIBLY_BROKEN": "Möglicherweise kaputt", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Persönlicher Legit-DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Persönliche Piraten-Legit-DLC", + "PERSONAL_CUSTOM": "Persönliche Anpassung", + "PERSONAL_CUSTOM_DLC": "Persönlich angepasster DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Anpassung", + "UNIVERSAL_CUSTOM_DLC": "Universal Anpassung DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Inhalt im CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Inhalt im TMD: %lu", + "CONSOLE_ID_N": "Konsolen-ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Titel\n \nTitel-ID: %016llX\nTitelversion: %lu.%lu.%lu\nGröße des Inhalts: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerifizierung: %s", + "STATE_LEGIT": "legitim", + "STATE_ILLEGIT": "nicht legitim", + "STATE_UNKNOWN": "unbekannt", + "STATE_INVALID": "ungültig", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "anstehend\n \nmit Überprüfung fortfahren?", + "STATE_PASSED": "bestanden", + "STATE_FAILED": "fehlgeschlagen", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Ausgabedatei existiert bereits.\nAktualisieren?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exklusiv", + "FIXING_CMACS_PLEASE_WAIT": "CMACs reparieren, bitte warten...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD-Header ist ungültig", + "NAND_DUMP_MISSING_DATA": "NAND-Dump fehlende Daten", + "ERROR_CTR_MBR_IS_CORRUPT": "Fehler: CTR MBR ist beschädigt", + "ERROR_TWL_MBR_IS_CORRUPT": "Fehler: TWL MBR ist beschädigt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nFehler: CTR-Partition%lu ist beschädigt", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nFehler: TWL-Partition%lu ist beschädigt", + "NO_VALID_FIRM_FOUND": "Kein gültiges FIRM gefunden", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Fehler: NANDump ist beschädigt.\nTrotzdem fortfahren?", + "ERROR_SYSTEM_IS_LOCKED": "Fehler: System ist gesperrt.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Sicherung der wichtigen Dateien ist erforderlich.\nSoll jetzt eine erstellt werden?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNUNG!\n \nFortfahren wird das\nSysNAND mit dem angegebenen Dumpf überschreiben.\n \n(B9S/A9LH wird intakt belassen.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD beschädigt oder angepasst,\nsichere Wiederherstellung ist nicht möglich!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNUNG!\n \nNCSD unterscheidet sich zwischen Bild und lokal,\nerhöhte Schreibberechtigungen, die\n \nauf eigene Gefahr fortsetzen?", + "NOT_AN_INSTALLABLE_FIRM": "Kein installierbarer FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM Lade/Verifizierungsfehler.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu nicht gefunden oder zu klein.", + "SECTOR_0X96_CRYPTO_FAIL": "Sektor 0x96 Krypto fehlschlagen.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sektor 0x96 ist beschädigt.\n \nGeben Sie \"secret_sector.bin\"\nan, um den Sektor 0x96 zu reparieren.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sektor 0x96 ist beschädigt.\n \nSektor 0x96 während\nder Installation reparieren?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WARNUNG!\n \nFortfahren wird die\nmit FIRM im SysNAND\ninstallieren und sighax injizieren.\n \nInstallieren eines nicht unterstützten FIRM\nwird Ihre Konsole BRICKEN!", + "INSTALLING_FIRM_PLEASE_WAIT": "FIRM wird installiert, bitte warten...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!DIES IST SCHLECHT!\n \nSchreiben von Sektor 0x96 fehlgeschlagen.\nVersuchen Sie, den Fehler vor dem Neustart zu beheben!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!DIES IST SCHLECHT!\n \nFehler beim Schreiben von FIRM%lu.\nVersuchen Sie vor dem Neustart zu reparieren!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Installation wird überprüft, bitte warten...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!DIES IST SCHLECHT!\n \nFehler beim Überprüfen des Sektors 0x96.\nVersuchen Sie vor dem Neustart zu reparieren!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!DIES IST SCHLECHT!\n \nFehler beim Überprüfen von FIRM%lu.\nVersuchen Sie vor dem Neustart zu reparieren!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfekte %s ist bereits installiert!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nKein perfektes %s Image.\nKann nicht in NAND installieren!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFehler beim Schreiben von %s in NAND!", + "USE_L_R_TO_SAVE": "(Benutze L+R zum Speichern)", + "EASTER_NOT_FOUND": "(%s nicht gefunden)", + "BUILDING_TO_OUT_ARG": "Baue auf %s:\n%s...", + "EJECT_SD_CARD": "SD-Karte auswerfen...", + "INSERT_SD_CARD": "SD-Karte einlegen...", + "SCRIPTERR_UNKNOWN_CMD": "unbekannter cmd", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "schlechte Anzahl von Argumenten", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "unbekannte Flaggen", + "SCRIPTERR_ILLEGAL_FLAG": "illegale Flagge", + "SCRIPTERR_UNRESOLVED_QUOTES": "ungelöste Zitate", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "zu viele Argumente", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "Argument Expansion fehlgeschlagen", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "'not' ein Fehler", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "syntax-Fehler nach 'if'", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' ohne 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "Syntaxfehler nach 'elif'", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' ohne 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' ohne 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' Innerhalb von 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "Verzeichnis nicht gefunden", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' ohne 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' ohne 'for'", + "SCRIPTERR_FORPATH_ERROR": "Pfadfehler", + "SCRIPTERR_LABEL_NOT_FOUND": "Label nicht gefunden", + "SCRIPTERR_USER_ABORT": "Benutzerabbruch", + "SCRIPTERR_KEY_NOT_PRESSED": "Taste nicht gedrückt", + "SCRIPTERR_OUT_OF_MEMORY": "Speicherplatzmangel", + "SCRIPTERR_VAR_FAIL": "var fehlgeschlagen", + "SCRIPTERR_FORBIDDEN_DRIVE": "verbotener Laufwerk", + "SCRIPTERR_INVALID_PATH": "ungültiger Pfad", + "SCRIPTERR_FILESELECT_ABORT": "fileselect abbrechen", + "SCRIPTERR_DIRSELECT_ABORT": "dirselect abbrechen", + "SCRIPTERR_SET_FAIL": "setze Fehler", + "SCRIPTERR_CHAR_NOT_FOUND": "char nicht gefunden", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2] ist kein Zeichen", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2] muss 2 Zeichen lang sein", + "SCRIPTERR_ARG_MATCH": "arg passt überein", + "SCRIPTERR_NO_ARG_MATCH": "arg passt nicht überein", + "SCRIPTERR_PERMISSION_FAIL": "Genehmigung nicht erteilt", + "SCRIPTERR_COPY_FAIL": "Kopieren fehlgeschlagen", + "SCRIPTERR_MOVE_FAIL": "dateien verschieben", + "SCRIPTERR_INJECT_FAIL": "einfügung fehlgeschlagen", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte fehlgeschlagen", + "SCRIPTERR_FILL_FAIL": "füllen nicht möglich", + "SCRIPTERR_BAD_FILESIZE": "schlechte Dateigröße", + "SCRIPTERR_CREATE_DUMMY_FILE": "erstelle Dummy Fehler", + "SCRIPTERR_REMOVE_FAIL": "fehler entfernen", + "SCRIPTERR_MAKEDIR_FAIL": "makedir fehlgeschlagen", + "SCRIPTERR_MOUNT_FAIL": "mount fehlgeschlagen", + "SCRIPTERR_FIND_FAIL": "finde Fehler", + "SCRIPTERR_FINDNOT_FAIL": "finde nicht scheitern", + "SCRIPTERR_NO_SIZE_GIVEN": "keine Größe angegeben", + "SCRIPTERR_SIZE_TOO_BIG": "datei zu groß", + "SCRIPTERR_READ_FAIL": "lese Fehler", + "SCRIPTERR_CONVERSION_FAIL": "konvertierung fehlgeschlagen", + "SCRIPTERR_INVALID_DATA": "ungültige Daten", + "SCRIPTERR_WRITE_FAIL": "schreibfehler", + "SCRIPTERR_SHA_ARG0_FAIL": "sha arg0 gescheitert", + "SCRIPTERR_SHA_ARG1_FAIL": "sha arg1 gescheitert", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "sha stimmt nicht überein", + "SCRIPTERR_SHA_WRITE_FAIL": "sha gescheitert", + "SCRIPTERR_FILE_WRITE_FAIL": "Datei schreiben fehlgeschlagen", + "SCRIPTERR_FIXCMAC_FAILED": "fixcmac fehlgeschlagen", + "SCRIPTERR_VERIFICATION_FAILED": "Verifizierung fehlgeschlagen", + "SCRIPTERR_DECRYPT_FAILED": "Entschlüsselung fehlgeschlagen", + "SCRIPTERR_ENCRYPT_FAILED": "Verschlüsselung fehlgeschlagen", + "SCRIPTERR_BUILD_CIA_FAILED": "Build CIA fehlgeschlagen", + "SCRIPTERR_INSTALL_GAME_FAILED": "Spiel installieren fehlgeschlagen", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": "enthält nicht .code", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": "extrahieren .code fehlgeschlagen", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": "komprimieren .code fehlgeschlagen", + "SCRIPTERR_BUILD_FAILED": "Build fehlgeschlagen", + "SCRIPTERR_UNKNOWN_FILE": "unbekannte Datei", + "SCRIPTERR_APPLY_IPS_FAILD": "IPS anwenden fehlgeschlagen", + "SCRIPTERR_APPLY_BPS_FAILED": "BPS anwenden fehlgeschlagen", + "SCRIPTERR_APPLY_BPM_FAILED": "BPM anwenden fehlgeschlagen", + "SCRIPTERR_TEXTVIEWER_FAILED": "Textviewer fehlgeschlagen", + "SCRIPTERR_BAD_DUMPSIZE": "schlechte Dumpinggröße", + "SCRIPTERR_CART_INIT_FAIL": "karteninitialisierung fehlgeschlagen", + "SCRIPTERR_CART_DUMP_FAILED": "karteninitialisierung fehlgeschlagen", + "SCRIPTERR_NOT_A_DIR": "kein Verzeichnis", + "SCRIPTERR_FILE_NOT_FOUND": "Datei nicht gefunden", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "keine bootfähige FIRM", + "SCRIPTERR_SD_NOT_MOUNTED": "SD nicht mounted", + "SCRIPTERR_UNKNOWN_ERROR": "unbekannter Fehler", + "SCRIPTERR_COMMAND_SUCCESS": "Befehlserfolg", + "SCRIPTERR_CONTROL_FLOW_ERROR": "Kontrollflussfehler", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "ungeschlossene Bedingung", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "Fehlermeldung fehlgeschlagen", + "ERROR_INVALID_TEXT_DATA": "Fehler: Ungültige Textdaten", + "TEXTVIEWER_CONTROLS_DETAILS": "Textviewer-Steuerelemente:\n \n↑↓→←(+R) - Scrollen\nR+Y - Wortumbruch umschalten\nR+X - Gehe zu Zeile #\nB - Beenden\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "Aktuelle Zeile: %i\nGeben Sie unten eine neue Zeile ein.", + "PREVIEW_DISABLED": "(Vorschau deaktiviert)", + "PATH_LINE_N_ERR_LINE": "%s\nZeile %lu: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "Ende des Skripts: ungelöstes 'if'", + "END_OF_SCRIPT_UNRESOLVED_FOR": "Ende des Skripts: ungelöstes 'for'", + "SYSINFO_MODEL": "Modell: %s (%s)\n", + "SYSINFO_SERIAL": "Seriennummer: %s\n", + "SYSINFO_REGION_SYSTEM": "Region (System): %s\n", + "SYSINFO_REGION_SALES": "Region (Verkauf): %s\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "SoC-Herstellungsdatum: %s\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "Datum der Systemmontage: %s\n", + "SYSINFO_ORIGINAL_FIRMWARE": "Original-Firmware: %s\n", + "SYSINFO_FRIENDCODE_SEED": "Freundschaftscode seed: %s\n", + "SYSINFO_SD_KEYY": "SD-Schlüssel: %s\n", + "SYSINFO_NAND_CID": "NAND CID: %s\n", + "SYSINFO_SD_CID": "SD CID: %s\n", + "SYSINFO_SYSTEM_ID0": "System ID0: %s\n", + "SYSINFO_SYSTEM_ID1": "System ID1: %s\n", + "SORTING_TICKETS_PLEASE_WAIT": "Tickets werden sortiert, bitte warten...", + "LUA_NOT_INCLUDED": "This build of GodMode9 was\ncompiled without Lua support." +} diff --git a/resources/languages/en.json b/resources/languages/en.json new file mode 100644 index 000000000..e5f51c519 --- /dev/null +++ b/resources/languages/en.json @@ -0,0 +1,4 @@ +{ + "GM9_LANGUAGE": "English", + "GM9_TRANS_VER": 1 +} diff --git a/resources/languages/es.json b/resources/languages/es.json new file mode 100644 index 000000000..70d923def --- /dev/null +++ b/resources/languages/es.json @@ -0,0 +1,709 @@ +{ + "GM9_LANGUAGE": "Español", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX/%3$02lX/%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM muy grande, imposible ejecutar", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nADVERTENCIA: No ejecutes FIRMs\nde fuentes no confiables\n \n¿Ejecutar FIRM?", + "NOT_BOOTABLE_FIRM": "No es un FIRM ejecutable.", + "FIRM_ENCRYPTED": "Este FIRM está cifrado.\n\n¿Desencriptar antes de ejecutarlo?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Crear una copia en %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Intentar ejecutarlo de todas formas", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Advertencia: Estás intentando\nejecutar un Firm desde una\nubicación no soportada.", + "ROOT": "[raíz]", + "LOADING": "CARGANDO...", + "PANE_N": "PANEL #%lu", + "CURRENT": "ACTUAL", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(Disco RAM FAT)", + "GAME_VIRTUAL": "(Juego Virtual)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Imagen FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memoria Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Cartucho Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(Buscar)", + "TITLEMANAGER_VIRTUAL": "(Gest. Títulos Virtual)", + "LAB_SDCARD": "Tar. SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "CARTUCHO", + "LAB_GAME_IMAGE": "IMAGEN JUEGO", + "LAB_AESKEYDB_IMAGE": "IMAGEN AESKEYDB", + "LAB_BDRI_IMAGE": "IMAGEN BDRI", + "LAB_DISA_DIFF_IMAGE": "IMAGEN DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "MEMORIA VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "GESTOR DE TÍTULOS", + "LAB_LAST_SEARCH": "ÚLTIMA BÚSQUEDA", + "LAB_FAT_IMAGE": "IMAGEN FAT", + "LAB_BONUS_DRIVE": "DISCO EXTRA", + "LAB_RAMDRIVE": "DISCO RAM", + "LAB_NOLABEL": "SIN NOMBRE", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[PORTAPAPELES]", + "PLUS_N_MORE": "+ %lu más", + "MARK_DELETE_COPY": "L - MARCAR archivos (usar con ↑↓→←)\nX - BORRAR / [+R] RENOMBRAR\nY - COPIAR / [+R] CREAR\n", + "MARK_DELETE_PASTE": "L - MARCAR archivos (usar con ↑↓→←)\nX - BORRAR / [+R] RENOMBRAR\nY - PEGAR / [+R] CREAR\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Bloquear escritura\n", + "UNMOUNT_IMAGE": "R+X - Desmontar imagen\n", + "UNMOUNT_SD": "R+B - Desmontar Tarjeta SD\n", + "REMOUNT_SD": "R+B - Montar tarjeta SD\n", + "DIRECTORY_OPTIONS": "R+A - Opciones de carpeta\n", + "DRIVE_OPTIONS": "R+A - Opciones de disco\n", + "MAKE_SCREENSHOT": "R+L - Capturar pantalla\n", + "PREV_NEXT_PANE": "R+←→ - Cambiar de panel\n", + "CLEAR_CLIPBOARD": "SELECT - Vaciar portapapeles\n", + "RESTORE_CLIPBOARD": "SELECT - Restaurar Portapapeles\n", + "REBOOT_POWEROFF_HOME": "START - Reiniciar / [+R] Apagar\nBotón HOME - Menú HOME", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "Tamaño de RedNAND (mín)", + "GW_EMUNAND_SIZE_FULL": "Tamaño de EmuNAND GW (llena)", + "MULTINAND_SIZE_2X": "Tamaño MultiNAND (x2)", + "MULTINAND_SIZE_3X": "Tamaño MultiNAND (x3)", + "MULTINAND_SIZE_4X": "Tamaño MultiNAND (x4)", + "USER_INPUT": "Entrada del usuario...", + "AUTO": "Auto", + "16KB_CLUSTERS": "Asig. 16KB", + "32KB_CLUSTERS": "Asig. 32KB", + "64KB_CLUSTERS": "Asig. 64KB", + "SD_NOT_DETECTED": "Error: Tarjeta SD no detectada.", + "FORMAT_SD_CHOOSE_EMUNAND": "¿Formatear tarjeta SD (%lluMB)?\nEscoge tamaño de la EmuNAND:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "El tamaño de la tarjeta es %lluMB.\nIntroduce el tamaño (MB) de la EmuNAND:", + "FORMAT_SD_CHOOSE_CLUSTER": "¿Formatear tarjeta SD (%lluMB)?\nEscoge asignación de página:", + "FORMAT_SD_ENTER_LABEL": "¿Formatear tarjeta SD (%lluMB)?\nIntroduce nombre:", + "FORMAT_SD_FAILED": "¡Fallo al formatear la tarjeta SD!", + "REDNAND_TYPE": "Tipo de RedNAND", + "REDNAND_TYPE_MULTI": "Tipo de RedNAND (multiple)", + "REDNAND_TYPE_SINGLE": "Tipo de RedNAND (única)", + "GW_EMUNAND_TYPE": "Tipo de EmuNAND GW", + "DONT_SET_UP": "No configurar", + "CHOOSE_EMUNAND_TYPE": "Escoge el tipo de EmuNAND a configurar:", + "CLONE_SYSNAND_TO_REDNAND": "Clonar SysNAND a RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "¡Fallo al clonar SysNAND a EmuNAND!", + "PRESS_A_TO_CONTINUE": "Presiona para continuar", + "HEXEDITOR_CONTROLS": "Controles Edit. Hex:\n\n↑↓→←(+R) - Desplazarse\nR+Y - Cambiar vista\nX - Buscar / Ir a...\nA - Modo Edición\nA+↑↓→← - Editar valor\nB - Salir\n", + "NOT_FOUND": "¡No se encontró!", + "GO_TO_OFFSET": "Ir al offset", + "SEARCH_FOR_STRING": "Buscar hilo", + "SEARCH_FOR_DATA": "Buscar datos", + "CURRENT_OFFSET_SELECT_ACTION": "Offset actual: %08lX\nSeleccionar acción:", + "CURRENT_OFFSET_ENTER_NEW": "Offset actual: %08lX\nIntroduce nuevo offset.", + "ENTER_SEARCH_REPEAT_SEARCH": "Introduce hilo a buscar.\n(R+X para repetir búsqueda)", + "MADE_EDITS_SAVE_CHANGES": "Haz cambiado %lu valor(es).\n¿Guardar cambios al archivo?", + "FAILED_WRITING_TO_FILE": "¡Fallo al guardar cambios!", + "CALCULATING_SHA_FAILED": "¡Fallo al calcular SHA-%s!", + "SHA_VERIFICATION_PASSED": "\n¡Éxito al verificar SHA!", + "SHA_VERIFICATION_FAILED": "\nFallo al verificar SHA", + "IDENTICAL_WITH_PREVIOUS": "\nIdentico al archivo anterior:\n", + "WRITE_SHA_FILE": "\n¿Guardar en archivo .SHA?", + "WRITE_SHA1_FILE": "\n¿Guardar en archivo .SHA1?", + "CALCULATING_CMAC_FAILED": "¡Fallo al calcular CMAC!", + "CMAC_VERIFICATION_PASSED": "¡Éxito al verificar CMAC!", + "CMAC_VERIFICATION_FAILED": "¡Fallo al verificar CMAC!", + "FIX_CMAC_IN_FILE": "\n¿Corregir CMAC en archivo?", + "FIXING_CMAC_FAILED": "¡Fallo al corregir CMAC!", + "COPY_ALL_SELECTED_ITEMS": "¿Copiar los %lu elementos seleccionados?", + "FAILED_COPYING_ITEM": "Fallo al copiar elemento", + "ITEMS_COPIED_TO_OUT": "%lu elementos copiados en %s", + "PATH_COPIED_TO_OUT": "%s\nCopiado en %s", + "CART_INIT_FAILED": "¡Fallo al iniciar el cartucho!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Cartucho: %s\nTamaño detectado: %s\n\nIntroduce el tamaño del archivo volcado.", + "NDS_CART_DECRYPT_SECURE_AREA": "Cartucho: %s\nCartucho de NDS detectado\n¿Descifrar area asegurada?", + "FAILED_DUMPING_CART": "%s\nFallo al volcar el cartucho", + "PATH_DUMPED_TO_OUT": "%s\nArchivo volcado en %s", + "CREATED": "creado", + "MODIFIED": "modificado", + "ANALYZING_DRIVE": "Analizando disco, espera...", + "ANALYZING_DIR": "Analizando carpeta, espera...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu archivos y %lu subcarpetas\nTamaño total: %s\n\nEspacio libre: %s\nEspacio usado: %s\nEspacio total: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu archivos y %lu subcarpetas\nTamaño total: %s", + "FILESIZE_X": "Tamaño del archivo: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s solo lectura [%c] %s oculto\n[%c] %s sistema [%c] %s archivo\n[%c] %s virtual\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← para cambiar atributos)\n", + "A_TO_CONTINUE": "( para continuar)", + "A_APPLY_B_CANCEL": "( Aplicar, Cancelar)", + "A_YES_B_NO": "( sí, no)", + "A_SELECT_B_CANCEL": "( seleccionar, cancelar)", + "HOLD_B_TO_CANCEL": "(mantén B para cancelar)", + "FAILED_TO_SET_ATTRIBUTES": "¡Fallo al establecer atributos!", + "NAND_IMAGE_OPTIONS": "Opciones de imágen NAND...", + "CTRNAND_OPTIONS": "Opciones de CTRNAND...", + "MOUNT_FAT_IMAGE": "Montar como imagen FAT", + "CIA_IMAGE_OPTIONS": "CIA opciones de imagen...", + "NCSD_IMAGE_OPTIONS": "NCSD opciones de imagen...", + "NCCH_IMAGE_OPTIONS": "NCCH opciones de imagen...", + "MOUNT_AS_EXEFS_IMAGE": "Montar como imagen EXEFS", + "MOUNT_AS_ROMFS_IMAGE": "Montar como imagen ROMFS", + "TMD_FILE_OPTIONS": "Opciones de archivo TMD...", + "TMD_CDN_OPTIONS": "Opciones de TMD/CDN...", + "TMD_TWL_OPTIONS": "Opciones de archivo TMD/TWL...", + "MANAGE_TITLE": "Gestionar Título...", + "BOSS_FILE_OPTIONS": "Opciones de archivo BOSS...", + "DECRYPT_NUS_CDN_FILE": "Descifrar archivo NUS/CDN", + "SHOW_SMDH_TITLE_INFO": "Mostrar información de título SMDH", + "NDS_IMAGE_OPTIONS": "NDS opciones de imagen...", + "GBA_IMAGE_OPTIONS": "GBA opciones de imagen...", + "TICKET_OPTIONS": "Opciones de ticket...", + "TAD_IMAGE_OPTIONS": "TAD opciones de imagen...", + "SHOW_3DSX_TITLE_INFO": "Mostrar información del título 3DSX", + "FIRM_IMAGE_OPTIONS": "FIRM opciones de imagen...", + "AGBSAVE_OPTIONS": "Opciones AGBSAVE...", + "DUMP_GBA_VC_SAVE": "Volcar guardado de VC GBA", + "TICKET_DB_OPTIONS": "Opciones de Ticket.db...", + "MOUNT_AS_DIFF_IMAGE": "Montar como imagen DIFF", + "MOUNT_AS_DISA_IAMGE": "Montar como imagen DISA", + "INSTALL_CIFINISH_BIN": "Instalar cifinish.bin", + "TITLEKEY_OPTIONS": "Opciones de clave de título...", + "AESKEYDB_OPTIONS": "Opciones de AESkeydb...", + "BUILD_X": "Generar %s", + "NCCHINFO_OPTIONS": "Opciones de NCCHinfo...", + "EXECUTE_GM9_SCRIPT": "Ejecutar script GM9", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Opciones de fuente...", + "LANGUAGE_OPTIONS": "Opciones de idioma...", + "VIEW_PNG_FILE": "Ver archivo PNG", + "REBUILD_NCSD_HEADER": "Reconstruir cabecera NCSD", + "SHOW_IN_HEXEDITOR": "Mostrar en Hexeditor", + "CALCULATE_SHA256": "Calcular SHA-256", + "CALCULATE_SHA1": "Calcular SHA-1", + "SHOW_FILE_INFO": "Mostrar información del archivo", + "SHOW_IN_TEXTVIEWER": "Mostrar en Textviewer", + "CALCULATE_CMAC": "Calcular CMAC", + "COPY_TO_OUT": "Copia a %s", + "DUMP_TO_OUT": "Volcar a %s", + "INJECT_DATA_AT_OFFSET": "Inyectar datos @offset", + "OPEN_THIS_FOLDER": "Abrir esta carpeta", + "OPEN_CONTAINING_FOLDER": "Abrir carpeta contenedora", + "OPEN_TITLE_FOLDER": "Abrir carpeta de título", + "PATH_N_FILES_SELECTED": "%s\n(%lu archivos seleccionados)", + "CHECK_CURRENT_CMAC_ONLY": "Comprobar sólo CMAC actual", + "VERIFY_CMAC_FOR_ALL": "Verificar CMAC para todos", + "FIX_CMAC_FOR_ALL": "Corregir CMAC para todos", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu archivos correctos/corregidos/total\n%lu/%lu no tienen CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu archivos verificados\n%lu/%lu archivos corregidos", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu archivos verificados\n%lu/%lu no tienen CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu archivos verificados", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "¿Inyectar datos de %s?\nEspecifica el offset deseado.", + "FAILED_INJECTING_PATH": "Fallo al indectar %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Montar CXI/NDS a disco", + "MOUNT_IMAGE_TO_DRIVE": "Montar imagen a disco", + "RESTORE_SYSNAND_SAFE": "Restaurar SysNAND (seguro)", + "UPDATE_EMBEDDED_BACKUP": "Actualizar respaldo integrado", + "SHOW_TITLE_INFO": "Mostrar información de título", + "DECRYPT_FILE": "Descifrar archivo (...)", + "DECRYPT_FILE_OUT": "Descifrar archivo (%s)", + "ENCRYPT_FILE": "Cifrar archivo (...)", + "ENCRYPT_FILE_OUT": "Cifrar archivo (%s)", + "BUILD_CIA_FROM_FILE": "Generar CIA desde archivo", + "BUILD_CIA_STANDARD": "Generar CIA (estándar)", + "BUILD_CIA_LEGIT": "Generar CIA (legítimo)", + "DUMP_CXI_NDS_FILE": "Volcar archivo CXI/NDS", + "INSTALL_GAME_IMAGE": "Instalar imagen de juego", + "INSTALL_TICKET": "Instalar ticket", + "DUMP_TICKET_FILE": "Volcar archivo de ticket", + "UNINSTALL_TITLE": "Desinstalar título", + "VERIFY_FILE": "Verificar archivo", + "TRANSFER_IMAGE_TO_CTRNAND": "Transferir imagen a CTRNAND", + "INJECT_TO_H_AND_S": "Inyectar a S&S", + "TRIM_FILE": "Recortar archivo", + "RENAME_FILE": "Renombrar archivo", + "BUILD_XORPADS_SD": "Generar XORPads (salida DS)", + "BUILD_XORPADS_INPLACE": "Generar XORpads (en sitio)", + "EXTRACT_X": "Extraer %s", + "INIT_X": "Iniciar %s", + "INSTALL_X": "Instalar %s", + "INSTALL_FIRM": "Instalar FIRM", + "BOOT_FIRM": "Ejecutar FIRM", + "SET_AS_ACTIVE_FONT": "Establecer como fuente activa", + "SET_AS_ACTIVE_LANGUAGE": "Establecer como idioma activo", + "DUMP_BA_VC_SAVE": "Volcar guardado de VC GBA", + "INJECT_GBA_VC_SAVE": "Inyectar guardado de VC GBA", + "SET_AS_DEFAULT": "Establecer como predeterminado", + "MOUNTING_IMAGE_FAILED": "Fallo al montar imagen", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nMontado como disco %s\n¿Entrar a directorio?", + "DECRYPT_TO_OUT": "Descifrar a %s", + "DECRYPT_INPLACE": "Descfirar en sitio", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "¿Descifrar los %lu archivos seleccionados?", + "TRYING_TO_DECRYPT_N_FILES": "Intentando descifrar %lu archivos...", + "DECRYPTION_FAILED_CONTINUE": "Fallo al descifrar\n\n¿Continuar?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu archivos descifrados\n%lu/%lu sin encripción\n%lu/%lu no son del mismo tipo", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu archivos descifrados", + "N_FILES_WRITTEN_TO_OUT": "%lu archivos escritos en %s", + "FILE_NOT_ENCRYPTED": "Archivo no cifrado", + "DECRYPTION_SUCCESS": "Éxito al descifrar", + "DECRYPTION_FAILED": "Fallo al descifrar", + "PATH_DECRYPTED_TO_OUT": "%s\nDescifrado a %s", + "ENCRYPT_TO_OUT": "Cifrar a %s", + "ENCRYPT_INPLACE": "Cifrar en sitio", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "¿Intentar cifrar los %lu archivos seleccionados?", + "TRYING_TO_ENCRYPT_N_FILES": "Intentando cifrar %lu archivos...", + "ENCRYPTION_FAILED_CONTINUE": "El cifrado ha fallado\n \n¿Continuar?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu archivos cifrados ok\n%lu/%lu no son del mismo tipo", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu archivos cifrados correctamente", + "ENCRYPTION_SUCCESS": "Cifrado con éxito", + "ENCRYPTION_FAILED": "Fallo al cifrar", + "PATH_ENCRYPTED_TO_OUT": "%s\nCifrado a %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "¿Intentar procesar los %lu archivos seleccionados?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nFalló al construir %s\n \n¿Continuar?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss construidos correctamente\n%lu%lu no son del mismo tipo", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss construidos correctamente", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "Falló al convertir %lu archivo(s).\nSe recomienda verificarlos.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s construido a %s", + "PATH_TYPE_BUILD_FAILED": "%s\nFalló al construir %s", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "La conversión del archivo falló.\n \n¿Verificar ahora?", + "VERIFICATION_SUCCESS": "Verificación exitosa", + "VERIFICATION_FAILED": "Verificación fallida", + "CONTENT_IS_MISSING": "Falta el contenido", + "INSTALL_TO_SYSNAND": "Instalar a SysNAND", + "INSTALL_TO_EMUNAND": "Instalar a EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "¿Intentar instalar los %lu archivos seleccionados?", + "TRYING_TO_INSTALL_N_FILES": "Intentando instalar %lu archivos...", + "INSTALL_FAILED_CONTINUE": "Error al instalar\n \n¿Continuar?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files installed ok\n%lu/%lu not of same type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu files installed ok", + "INSTALL_SUCCESS": "Instalado exitosamente", + "INSTALL_FAILED": "Falló la instalación", + "FILE_FAILED_INSTALL_VERIFY_NOW": "la instalación del archivo falló.\n \n¿Verificar ahora?", + "KEEP_TICKET_AND_SAVEGAME": "Mantener ticket y savegame", + "UNINSTALL_EVERYTHING": "Desinstalar todo", + "ABORT_UNINSTALL": "Cancelar desinstalación", + "UNINSTALL_N_SELECTED_TITLES": "¿Desinstalar %lu títulos seleccionados?", + "UNINSTALL_SELECTED_TITLE": "¿Desinstalar título seleccionado?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu títulos desinstalados", + "UNINSTALLING_PLEASE_WAIT": "Desinstalando, espere...", + "UNINSTALL_FAILED": "¡Desinstalación fallida!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "¿Intentar verificar los %lu archivos seleccionados?", + "VERIFICATION_FAILED_CONTINUE": "Verificación fallida\n \n¿Continuar?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu archivos verificados ok\n%lu/%lu no son del mismo tipo", + "VERIFYING_FILE_PLEASE_WAIT": "Verificando archivo, espere...", + "NAND_VALIDATION_SUCCESS": "Validación de NAND exitosa", + "NAND_VALIDATION_FAILED": "Validación de NAND falló", + "DUMP_FOR_N_SELECTED_FILES": "¿Volcar para todos los %lu archivos seleccionados?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumped to %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumped to %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nTicket legítimo no encontrado.\n \n¿Volcar de todos modos?", + "DUMP_TICKET_FAILED": "Ticket de descarga fallido!", + "BUILDING_X": "Creando %s...", + "BUILDING_X_SYSNAND": "Creando %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Creando %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu archivos procesados\n%lu/%lu archivos ignorados", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu archivos procesados", + "BUILD_DATABASE_SUCCESS": "Base de datos construida exitosamente.", + "BUILD_DATABASE_FAILED": "Falló al construir la base de datos.", + "TRY_TO_TRIM_N_SELECTED_FILES": "¿Intenta recortar los %lu archivos seleccionados?", + "TRIMMING_FAILED_CONTINUE": "Recorte fallido\n\nContinuar?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu archivos recortados ok\n%lu/%lu no son del mismo tipo\n%s guardados", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu archivos recortados ok\n%s guardados", + "FILE_CANT_BE_TRIMMED": "El archivo no puede ser recortado.", + "FILE_ALREADY_TRIMMED": "Este archivo ya está recortado.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nTamaño actual: %s\nTamaño recortado: %s\nDiferencia: %s\n \n¿Recortar este archivo?", + "TRIMMING_FAILED": "Recorte fallido.", + "PATH_TRIMMED_BY_X": "%s\nRecortado por %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "¿Intentar renombrar los %lu archivos seleccionados?", + "N_OF_N_RENAMED": "%lu/%lu renombrados ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "No se pudo renombrar a un nombre válido", + "SYSNAND_H_AND_S_INJECT": "Inyección en H&S de SysNAND", + "EMUNAND_H_AND_S_INJECT": "Inyección en H&S de EmuNAND", + "H_AND_S_INJECT_SUCCESS": "H&S inyectado exitosamente", + "H_AND_S_INJECT_FAILURE": "Falló al inyectar H&S", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "¿Intentar extraer los %lu archivos seleccionados?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu archivos extraídos ok\n%lu/%lu no son del mismo tipo", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu archivos extraídos ok", + "EXTRACTING_DOT_CODE": "Extrayendo .code, espere...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extraído a %s", + "DOT_CODE_EXTRACT_FAILED": "Falló al extraer .code", + "TRANSFER_TO_SYSNAND": "Transferir a SysNAND", + "TRANSFER_TO_EMUNAND": "Transferir a SysNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND transfer success", + "CTRNAND_TRANSFER_FAILED": "CTRNAND transfer failed", + "NO_VALID_DESTINATION_FOUND": "No valid destination found", + "NAND_RESTORE_SUCCESS": "NAND restore success", + "NAND_RESTORE_FAILED": "NAND restore failed", + "REBUILD_NCSD_SUCCESS": "Rebuild NCSD success", + "REBUILD_NCSD_FAILED": "Rebuild NCSD failed", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Instalar a FIRM0", + "INSTALL_TO_FIRM1": "Instalar a FIRM1", + "INSTALL_TO_BOTH": "Instalar a ambos", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Cambiar EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restore H&S", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Falló", + "RESTORE_H_AND_S_EMUNAND": "Restaurar H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restaurar H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Ajustar fecha y hora del RTC:", + "NEW_RTC_DATE_TIME_IS_TIME": "La nueva fecha y hora del RTC es:\n%s\n \nSugerencia: HOMEMENU necesita\nun ajuste manual después de\najustar el RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Calibración correcta de la pantalla táctil!", + "TOUCHSCREEN_CALIBRATION_FAILED": "¡Error de calibración de la pantalla táctil!", + "GODMODE9_README_TOC": "Tabla de contenidos de ReadMe de GodMode9", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Copia de seguridad de archivos esenciales no encontrada.\n¿Crear una ahora?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Copia de seguridad incrustada en SysNAND\ny escrita en %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "La fecha y hora del RTC parece ser\nincorrecta. ¿Configurar ahora?", + "RESUME_GODMODE9": "Reanudar GodMode9", + "RESUME_BOOTLOADER": "Reanudar bootloader", + "SELECT_PAYLOAD": "Seleccionar payload...", + "SELECT_SCRIPT": "Seleccionar script...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "Apagar el sistema", + "REBOOT_SYSTEM": "Reiniciar sistema", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "Menú de arranque %s.\nSeleccione acción:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Menú de payloads de arranque.\nSeleccione payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Menú de scripts de arranque.\nSeleccione script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No se ha encontrado ninguna FIRM de arranque.\nReanudando GodMode9...", + "OUT_OF_MEMORY": "Sin memoria.", + "INVALID_DIRECTORY_OBJECT": "Objeto de directorio inválido", + "INVALID_ROOT_DIRECTORY": "Directorio raíz inválido.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Se cambiaron los permisos de escritura.\n¿Volver a bloquearlos?", + "OPEN_TITLE_MANAGER": "Abrir gestor de títulos", + "SEARCH_FOR_FILES": "Buscar archivos...", + "FIX_CMACS_FOR_DRIVE": "Corregir CMACs para la unidad", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "Found %lu results.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "Delete %lu path(s)?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "Failed deleting %lu/%lu path(s)", + "DELETE_FILE": "Delete \"%s\"?", + "FAILED_DELETING_PATH": "Failed deleting:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Not allowed in search drive", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Not allowed in virtual game path", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Not allowed in XORpad drive", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Not allowed in gamecart drive", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copy path(s)", + "MOVE_PATHS": "Move path(s)", + "PASTE_FILE_HERE": "Paste \"%s\" here?", + "PASTE_N_PATHS_HERE": "Paste %lu paths here?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Failed copying path:\n%s\nProcess remaining?", + "FAILED_COPYING_PATH": "Failed copying path:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Failed moving path:\n%s\nProcess remaining?", + "FAILED_MOVING_PATH": "Failed moving path:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Rename %s?\nEnter new name below.", + "FAILED_RENAMING_PATH": "Failed renaming path:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Create a folder", + "CREATE_A_DUMMY_FILE": "Create a dummy file", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Create a new folder here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Create a new file here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Failed creating folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Failed creating file:\n%s", + "TITLE_MANAGER": "Title manager", + "BRICK_MY_3DS": "Brick my 3DS", + "LANGUAGE": "Idioma...", + "SCRIPTS": "Scripts...", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Payloads...", + "MORE": "More...", + "BRACKET_MORE": "[more...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME button pressed.\nSelect action:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER button pressed.\nSelect action:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD CARD", + "B_DRIVE_SD_CARD": "[B:] SD CARD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads directory not found.\n(default path: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALID", + "TO_PROCEED_ENTER_THIS": "To proceed, enter this:", + "TO_PROCEED_HOLD_X": "To proceed, hold :", + "N_MORE": " [%d more]", + "CANCEL": "cancel", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) fast scroll\nL - clear data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - remove char\nY - insert char", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Searching, please wait...", + "RENAME_TO_GOOD_NAME": "Rename to good name?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD card is write protected!\nCan't continue.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "game images", + "GAMECART_SAVES": "gamecart saves", + "IMAGES": "images", + "MEMORY_AREAS": "memory areas", + "SD_SYSTEM_DATA": "SD system data", + "SD_CARD": "Tarjeta SD", + "RAM_DRIVE": "RAM drive", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Writing to %s is locked!\nUnlock it now?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Unlock write permission for\n%s is not allowed.", + "ENABLE_BASE_WRITE": "You want to enable base\nwriting permissions.", + "ENABLE_SD_WRITE": "You want to enable SD card\nwriting permissions.", + "ENABLE_IMAGE_WRITE": "You want to enable image\nwriting permissions.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Error: SD card is too small", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatting SD, please wait...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatting drive, please wait...", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "File is currently mounted.\nUnmount to unlock?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Error: Can't inject file into itself", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operation would write beyond end of file", + "NOT_ENOUGH_DATA_IN_FILE": "Not enough data in file", + "CANCEL_IS_NOT_ALLOWED_HERE": "Cancel is not allowed here", + "B_DETECTED_CANCEL": "B button detected. Cancel?", + "ERROR_CANNOT_APPEND_FOLDER": "Error: Cannot append a folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Error: Not enough space available", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Error: Only FAT files can be moved", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Error: Destination is part of origin", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destination equals origin\nChoose another name?", + "CHOOSE_NEW_NAME": "Choose new name", + "OVERWRITE_FILES": "Overwrite file(s)", + "SKIP_FILES": "Skip file(s)", + "OVERWRITE_ALL": "Overwrite all", + "SKIP_ALL": "Omitir todo", + "DESTINATION_ALREADY_EXISTS": "Destination already exists:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choose new destination name", + "COPY_OPERATION_IS_NOT_ALLOWED": "Copy operation is not allowed", + "DESTINATION_EQUALS_ORIGIN": "Destination equals origin", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entry not found: %s\nInject into %s instead?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "América", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brasil", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europa", + "REGION_FRANCE": "Francia", + "REGION_GERMANY": "Alemania", + "REGION_ITALY": "Italia", + "REGION_JAPAN": "Japón", + "REGION_KOREA": "Corea", + "REGION_SPAIN": "España", + "REGION_TAIWAN": "Taiwán", + "REGION_UNKNOWN": "Desconocido", + "REGION_UNITED_KINGDOM": "Reino Unido", + "REGION_MIDDLE_EAST": "Oriente Medio", + "GENERATING_QR_CODE": "Generating QR code...", + "REINITIALIZING_SD_CARD": "Reinitializing SD card...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Press POWER to turn off", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Cleaning up titles, please wait...", + "ERROR_NOT_NCCH_FILE": "Error: Not an NCCH file", + "ERROR_FILE_IS_TOO_SMALL": "Error: File is too small", + "ATTEMPT_FIX_THIS_TIME": "Attempt fix this time", + "ATTEMPT_FIX_ALWAYS": "Attempt fix always", + "ABORT_VERIFICATION": "Abort verification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "fail", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Error: Clave de título del CDN no encontrada", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC content is missing\n \nIgnore all and continue?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Error: Not a BOSS file", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS payload hash mismatch.\n \nTry to fix it?", + "GENERIC_TICKET_PIRATE_LEGIT": "Generic ticket (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalized ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nClave de título no encontrada.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD is not legit.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD is not legit.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "El contenido está corrupto", + "INSERT_CONTENT_FAILED": "Insert content failed", + "INSTALL_CONTENT_FAILED": "Install content failed", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Install error:\nThis system is missing the\nticket.db file.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Error: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", + "INSTALLING_TICKET": "Installing ticket...", + "POSSIBLY_BROKEN": "Possibly Broken", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Personal Legit DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personal Pirate Legit DLC", + "PERSONAL_CUSTOM": "Personal Custom", + "PERSONAL_CUSTOM_DLC": "Personal Custom DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Custom", + "UNIVERSAL_CUSTOM_DLC": "Universal Custom DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contents in CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contents in TMD: %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle version: %lu.%lu.%lu\nContents size: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerification: %s", + "STATE_LEGIT": "legit", + "STATE_ILLEGIT": "illegit", + "STATE_UNKNOWN": "unknown", + "STATE_INVALID": "invalid", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "pending\n \nProceed with verification?", + "STATE_PASSED": "passed", + "STATE_FAILED": "failed", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Output file already exists.\nUpdate this?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Fixing CMACs, please wait...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD header is not valid", + "NAND_DUMP_MISSING_DATA": "NAND dump missing data", + "ERROR_CTR_MBR_IS_CORRUPT": "Error: CTR MBR is corrupt", + "ERROR_TWL_MBR_IS_CORRUPT": "Error: TWL MBR is corrupt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nError: CTR partition%lu is corrupt", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nError: TWL partition%lu is corrupt", + "NO_VALID_FIRM_FOUND": "No valid FIRM found", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Error: NAND dump is corrupt.\nStill continue?", + "ERROR_SYSTEM_IS_LOCKED": "Error: System is locked.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Essential files backup is required.\nCreate one now?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD corrupt or customized,\nsafe restore is not possible!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?", + "NOT_AN_INSTALLABLE_FIRM": "Not a installable FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM load/verify error.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu not found or too small.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto fail.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!", + "INSTALLING_FIRM_PLEASE_WAIT": "Installing FIRM, please wait...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Checking installation, please wait...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfect %s is already installed!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nNot a perfect %s image.\nCannot install to NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFailed writing %s to NAND!", + "USE_L_R_TO_SAVE": "(use L+R to save)", + "EASTER_NOT_FOUND": "(%s not found)", + "BUILDING_TO_OUT_ARG": "Creando a %s: %s...", + "EJECT_SD_CARD": "Expulsar tarjeta SD..." +} diff --git a/resources/languages/fr.json b/resources/languages/fr.json new file mode 100644 index 000000000..ad4303ada --- /dev/null +++ b/resources/languages/fr.json @@ -0,0 +1,816 @@ +{ + "GM9_LANGUAGE": "Français", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX/%3$02lX/%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": " ", + "FIRM_TOO_BIG": "FIRM trop grand, impossible de démarrer", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nAttention : Ne démarrez pas\nles FIRMs provenant\nde sources non fiables.\n \nDémarrer le FIRM ?", + "NOT_BOOTABLE_FIRM": "N'est pas un FIRM démarrable.", + "FIRM_ENCRYPTED": "Le FIRM est crypté.\n \nDécrypter avant le démarrage ?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Faire une copie à %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Essayer de démarrer quand même", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Attention : Tentative de démarrage à partir d'un emplacement\nnon pris en charge.", + "ROOT": "[racine]", + "LOADING": "CHARGEMENT…", + "PANE_N": "ONGLET #%lu", + "CURRENT": "ACTUEL", + "DIR": "(dossier)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(Lecteur RAM FAT)", + "GAME_VIRTUAL": "(Jeu virtuel)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND virtuelle)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND virtuelle)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad virtuel)", + "MEMORY_VIRTUAL": "(Mémoire virtuelle)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Carte de jeu virtuelle)", + "VRAM_VIRTUAL": "(VRAM virtuelle)", + "SEARCH": "(Rechercher)", + "TITLEMANAGER_VIRTUAL": "(Gestionnaire d'applications Virtuel)", + "LAB_SDCARD": "CARTE SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUELLE", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUELLE", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUELLE", + "LAB_GAMECART": "CARTOUCHE", + "LAB_GAME_IMAGE": "IMAGE DU JEU", + "LAB_AESKEYDB_IMAGE": "IMAGE AESKEYDB", + "LAB_BDRI_IMAGE": "IMAGE BDRI", + "LAB_DISA_DIFF_IMAGE": "IMAGE DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "MÉMOIRE VIRTUELLE", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUELLE", + "LAB_TITLE_MANAGER": "GESTIONNAIRE D'APPS", + "LAB_LAST_SEARCH": "DERNIÈRE RECHERCHE", + "LAB_FAT_IMAGE": "IMAGE FAT", + "LAB_BONUS_DRIVE": "LECTEUR BONUS", + "LAB_RAMDRIVE": "MÉMOIRE RAM", + "LAB_NOLABEL": "AUCUN LABEL", + "N_BYTE": "%s octet", + "BYTE": " Octet", + "KB": " kb", + "MB": " Mb", + "GB": " Gb", + "CLIPBOARD": "[PRESSE-PAPIER]", + "PLUS_N_MORE": "+ %lu en plus", + "MARK_DELETE_COPY": "L - SÉLÉCTIONNER fichiers (avec ↑↓→←)\nX - SUPPRIMER / [+R] RENOMMER fichier(s)\nY - COPIER fichier(s) / [+R] CRÉER une entrée\n", + "MARK_DELETE_PASTE": "L - SÉLÉCTIONNER fichiers (avec ↑↓→←)\nX - SUPPRIMER / [+R] RENOMMER fichier(s)\nY - COLLER fichier(s) / [+R] CRÉER une entrée\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Verrouiller les droits d'écriture\n", + "UNMOUNT_IMAGE": "R+X - Démonter l'image\n", + "UNMOUNT_SD": "R+B - Démonter la carte SD\n", + "REMOUNT_SD": "R+B - Remonter la carte SD\n", + "DIRECTORY_OPTIONS": "R+A - Options du répertoire\n", + "DRIVE_OPTIONS": "R+A - Options du lecteur\n", + "MAKE_SCREENSHOT": "R+L - Faire une capture d'écran\n", + "PREV_NEXT_PANE": "R+←→ - Passer au volet précédent/suivant\n", + "CLEAR_CLIPBOARD": "SELECT - Vider le presse-papiers\n", + "RESTORE_CLIPBOARD": "SELECT - Restaurer le presse-papier\n", + "REBOOT_POWEROFF_HOME": "START - Redémarrer / [+R] Éteindre\nHOME - aller au menu HOME", + "NO_EMUNAND": "Aucune EmuNAND", + "REDNAND_SIZE_MIN": "Taille de la RedNAND (min)", + "GW_EMUNAND_SIZE_FULL": "Taille de l'EmuNAND GW (full)", + "MULTINAND_SIZE_2X": "Taille MultiNAND (x2)", + "MULTINAND_SIZE_3X": "Taille MultiNAND (x3)", + "MULTINAND_SIZE_4X": "Taille MultiNAND (x4)", + "USER_INPUT": "Saisie de l'utilisateur...", + "AUTO": "Auto", + "16KB_CLUSTERS": "Clusters de 16 ko", + "32KB_CLUSTERS": "Clusters de 32 ko", + "64KB_CLUSTERS": "Clusters de 64 ko", + "SD_NOT_DETECTED": "Erreur : carte SD non détectée.", + "FORMAT_SD_CHOOSE_EMUNAND": "Formater la carte SD (%lluMo) ?\nChoisissez la taille EmuNAND :", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "La taille de la carte SD est de %lluMB.\nEntrez la taille EmuNAND (Mo) ci-dessous :", + "FORMAT_SD_CHOOSE_CLUSTER": "Formater la carte SD (%lluMo) ?\nChoisissez la taille d'allocation :", + "FORMAT_SD_ENTER_LABEL": "Formater la carte SD (%lluMo) ?\nEntrez le nom :", + "FORMAT_SD_FAILED": "Échec du formatage de la Carte SD !", + "REDNAND_TYPE": "Type de la RedNAND", + "REDNAND_TYPE_MULTI": "Type de la RedNAND (multiple)", + "REDNAND_TYPE_SINGLE": "Type de la RedNAND (simple)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Ne pas configurer", + "CHOOSE_EMUNAND_TYPE": "Choisissez le type d'EmuNAND à configurer :", + "CLONE_SYSNAND_TO_REDNAND": "Cloner la SysNAND vers la RedNAND ?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Clonage de la SysNAND vers l'EmuNAND : échec !", + "PRESS_A_TO_CONTINUE": "Appuyez sur pour continuer", + "HEXEDITOR_CONTROLS": "Commandes de l'éditeur hexadécimal :\n \n↑↓→←(+R) - Défiler\nR+Y - Changer de vue\nX - Rechercher / aller à…\nA - Entrer en mode édition\nA+↑↓→← - Modifier la valeur\nB - Quitter\n", + "NOT_FOUND": "Aucun résultat!", + "GO_TO_OFFSET": "Aller à l'offset", + "SEARCH_FOR_STRING": "Recherche de chaîne", + "SEARCH_FOR_DATA": "Recherche de données", + "CURRENT_OFFSET_SELECT_ACTION": "Offset actuel: %08lX\nSélectionnez l'action:", + "CURRENT_OFFSET_ENTER_NEW": "Offset actuel: %08lX\nSaisissez le nouvel offset ci-dessous.", + "ENTER_SEARCH_REPEAT_SEARCH": "Saisissez la chaîne de recherche ci-dessous.\n(R+X pour répéter la recherche)", + "MADE_EDITS_SAVE_CHANGES": "Vous avez effectué des modifications à %lu endroits.\nEnregistrer les modifications?", + "FAILED_WRITING_TO_FILE": "Impossible d'écrire dans le fichier !", + "CALCULATING_SHA_FAILED": "Calcul SHA-%s : échec !", + "SHA_VERIFICATION_PASSED": "\nVérification SHA : réussie !", + "SHA_VERIFICATION_FAILED": "\nVérification SHA : échec !", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentique au fichier précédent :\n", + "WRITE_SHA_FILE": "\n \nÉcrire un fichier .SHA ?", + "WRITE_SHA1_FILE": "\n \nÉcrire un fichier .SHA1 ?", + "CALCULATING_CMAC_FAILED": "Calcul du CMAC : échec !", + "CMAC_VERIFICATION_PASSED": "Vérification du CMAC : réussie !", + "CMAC_VERIFICATION_FAILED": "Vérification du CMAC : échec !", + "FIX_CMAC_IN_FILE": "\n \nCorriger le CMAC du fichier ?", + "FIXING_CMAC_FAILED": "Correction du CMAC : échec !", + "COPY_ALL_SELECTED_ITEMS": "Copier les %lu éléments sélectionnés ?", + "FAILED_COPYING_ITEM": "Impossible de copier l'élément", + "ITEMS_COPIED_TO_OUT": "%lu éléments copiés vers %s", + "PATH_COPIED_TO_OUT": "%s\nCopié dans %s", + "CART_INIT_FAILED": "Échec de l'initialisation de la cartouche!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Carte : %s\nTaille détectée : %s\n\nTaille de la dump d'entrée ci-dessous.", + "NDS_CART_DECRYPT_SECURE_AREA": "Contenu : %s\nCarte NDS détecté\nDécrypter la zone sécurisée ?", + "FAILED_DUMPING_CART": "%s\nÉchec de la copie de la cartouche", + "PATH_DUMPED_TO_OUT": "%s\nDumpé vers %s", + "CREATED": "créé le", + "MODIFIED": "modifié le", + "ANALYZING_DRIVE": "Analyse du disque, veuillez patienter…", + "ANALYZING_DIR": "Analyse du dossier, veuillez patienter…", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu fichiers & %lu sous-dossiers\ntaille totale: %s\n \nespace libre: %s\nespace utilisé: %s\nespace total: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu fichiers & %lu sous-dossiers\ntaille totale: %s", + "FILESIZE_X": "taille fichier : %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %slect. seule [%c] %scaché\n[%c] %ssystème [%c] %sarchive\n[%c] %svirtuel\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← pour changer les attributs)\n", + "A_TO_CONTINUE": "( pour continuer)", + "A_APPLY_B_CANCEL": "( pour appliquer, pour annuler)", + "A_YES_B_NO": "( oui, non)", + "A_SELECT_B_CANCEL": "( sélectionner, annuler)", + "HOLD_B_TO_CANCEL": "(maintenez B pour annuler)", + "FAILED_TO_SET_ATTRIBUTES": "Impossible de définir les attributs !", + "NAND_IMAGE_OPTIONS": "Options d'image NAND…", + "CTRNAND_OPTIONS": "Options CTRNAND…", + "MOUNT_FAT_IMAGE": "Monter en tant qu'image FAT", + "CIA_IMAGE_OPTIONS": "Options d'image CIA…", + "NCSD_IMAGE_OPTIONS": "Options d'image NCSD…", + "NCCH_IMAGE_OPTIONS": "Options d'image NCCH…", + "MOUNT_AS_EXEFS_IMAGE": "Monter en tant qu'image EXEFS", + "MOUNT_AS_ROMFS_IMAGE": "Monter en tant qu'image ROMFS", + "TMD_FILE_OPTIONS": "Options de fichier TMD…", + "TMD_CDN_OPTIONS": "Options TMD/CDN…", + "TMD_TWL_OPTIONS": "Options TMD/TWL…", + "MANAGE_TITLE": "Gérer l'application...", + "BOSS_FILE_OPTIONS": "Options de fichier BOSS…", + "DECRYPT_NUS_CDN_FILE": "Décrypter fichier NUS/CDN", + "SHOW_SMDH_TITLE_INFO": "Afficher les infos SMDH de l'app", + "NDS_IMAGE_OPTIONS": "Options d'image NDS…", + "GBA_IMAGE_OPTIONS": "Options d'image GBA…", + "TICKET_OPTIONS": "Options de ticket…", + "TAD_IMAGE_OPTIONS": "Options d'image TAD…", + "SHOW_3DSX_TITLE_INFO": "Afficher les infos de l'app 3DSX", + "FIRM_IMAGE_OPTIONS": "Options d'image FIRM…", + "AGBSAVE_OPTIONS": "Options AGBSAVE…", + "DUMP_GBA_VC_SAVE": "Dumper sauvegarde GBA CV", + "TICKET_DB_OPTIONS": "Options Ticket.db…", + "MOUNT_AS_DIFF_IMAGE": "Monter en tant qu'image DIFF", + "MOUNT_AS_DISA_IAMGE": "Monter en tant qu'image DISA", + "INSTALL_CIFINISH_BIN": "Installer cifinish.bin", + "TITLEKEY_OPTIONS": "Options de Titlekey...", + "AESKEYDB_OPTIONS": "Options AESkeydb…", + "BUILD_X": "Générer %s", + "NCCHINFO_OPTIONS": "Options NCCHinfo…", + "EXECUTE_GM9_SCRIPT": "Exécuter script GM9", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Paramètres de la police…", + "LANGUAGE_OPTIONS": "Paramètres de la langue…", + "VIEW_PNG_FILE": "Voir le fichier PNG", + "REBUILD_NCSD_HEADER": "Régénérer en-tête NCSD", + "SHOW_IN_HEXEDITOR": "Éditeur hexadécimal", + "CALCULATE_SHA256": "Calculer SHA-256", + "CALCULATE_SHA1": "Calculer SHA-1", + "SHOW_FILE_INFO": "Afficher infos fichier", + "SHOW_IN_TEXTVIEWER": "Visionneuse de textes", + "CALCULATE_CMAC": "Calculer le CMAC", + "COPY_TO_OUT": "Copier vers %s", + "DUMP_TO_OUT": "Dumper vers %s", + "INJECT_DATA_AT_OFFSET": "Injecter les données dans @offset", + "OPEN_THIS_FOLDER": "Ouvrir ce dossier", + "OPEN_CONTAINING_FOLDER": "Ouvrir le dossier contenant", + "OPEN_TITLE_FOLDER": "Ouvrir le dossier de l'app", + "PATH_N_FILES_SELECTED": "%s\n(%lu fichiers sélectionnés)", + "CHECK_CURRENT_CMAC_ONLY": "Vérifier le CMAC actuel uniq.", + "VERIFY_CMAC_FOR_ALL": "Vérifier le CMAC pour tous", + "FIX_CMAC_FOR_ALL": "Corriger le CMAC pour tous", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu fichiers ok/corrigés/au total\n%lu/%lu n'ont pas de CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu fichiers vérifiés ok\n%lu/%lu fichiers corrigés", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu fichiers vérifiés ok\n%lu/%lu n'ont pas de CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu fichiers vérifiés ok", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Injecter les données de %s?\nEntrez l'offset ci-dessous.", + "FAILED_INJECTING_PATH": "Échec de l'injection de %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Monter CXI/NDS sur le lecteur", + "MOUNT_IMAGE_TO_DRIVE": "Monter l'image sur le lecteur", + "RESTORE_SYSNAND_SAFE": "Restaurer la SysNAND (sans risque)", + "UPDATE_EMBEDDED_BACKUP": "Mettre à jour la sauvegarde intégrée", + "SHOW_TITLE_INFO": "Afficher les infos de l'app", + "DECRYPT_FILE": "Déchiffrer le fichier (…)", + "DECRYPT_FILE_OUT": "Déchiffrer le fichier (%s)", + "ENCRYPT_FILE": "Chiffrer le fichier (…)", + "ENCRYPT_FILE_OUT": "Chiffrer le fichier (%s)", + "BUILD_CIA_FROM_FILE": "Créer un CIA à partir du fichier", + "BUILD_CIA_STANDARD": "Créer le CIA (standard)", + "BUILD_CIA_LEGIT": "Créer le CIA (legit)", + "DUMP_CXI_NDS_FILE": "Dumper fichier CXI/NDS", + "INSTALL_GAME_IMAGE": "Installer l'image du jeu", + "INSTALL_TICKET": "Installer le ticket", + "DUMP_TICKET_FILE": "Dumper le fichier ticket", + "UNINSTALL_TITLE": "Désinstaller l'application", + "VERIFY_FILE": "Vérifier le fichier", + "TRANSFER_IMAGE_TO_CTRNAND": "Transférer image vers CTRNAND", + "INJECT_TO_H_AND_S": "Injecter dans S&S", + "TRIM_FILE": "Tronquer le fichier", + "RENAME_FILE": "Renommer le fichier", + "BUILD_XORPADS_SD": "Créer les XORpads (carte SD)", + "BUILD_XORPADS_INPLACE": "Créer les XORpads (sur place)", + "EXTRACT_X": "Extraire %s", + "INIT_X": "Init %s", + "INSTALL_X": "Installer %s", + "INSTALL_FIRM": "Installer le FIRM", + "BOOT_FIRM": "Démarrer le FIRM", + "SET_AS_ACTIVE_FONT": "Définir comme police active", + "SET_AS_ACTIVE_LANGUAGE": "Définir comme langue active", + "DUMP_BA_VC_SAVE": "Dumper sauvegarde GBA CV", + "INJECT_GBA_VC_SAVE": "Injecter sauvegarde GBA CV", + "SET_AS_DEFAULT": "Définir par défaut", + "MOUNTING_IMAGE_FAILED": "Montage de l'image : échec", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nMonté en tant que lecteur %s\nS'y rendre tout se suite ?", + "DECRYPT_TO_OUT": "Déchiffrer vers %s", + "DECRYPT_INPLACE": "Déchiffrer en place", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Essayer de déchiffrer les %lu fichiers sélectionnés ?", + "TRYING_TO_DECRYPT_N_FILES": "Tentative de déchiffrement de %lu fichiers…", + "DECRYPTION_FAILED_CONTINUE": "Échec du déchiffrement\n \nContinuer ?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers déchiffrés ok\n%lu/%lu non chiffrés\n%lu/%lu pas du même type", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu fichiers déchiffrés ok", + "N_FILES_WRITTEN_TO_OUT": "%lu fichiers écrits vers %s", + "FILE_NOT_ENCRYPTED": "Le fichier n'est pas chiffré", + "DECRYPTION_SUCCESS": "Déchiffrement réussi", + "DECRYPTION_FAILED": "Échec du déchiffrement", + "PATH_DECRYPTED_TO_OUT": "%s\nDéchiffré vers %s", + "ENCRYPT_TO_OUT": "Chiffrer vers %s", + "ENCRYPT_INPLACE": "Chiffrer en place", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Essayer de chiffrer les %lu fichiers sélectionnés ?", + "TRYING_TO_ENCRYPT_N_FILES": "Tentative de chiffrement de %lu fichiers…", + "ENCRYPTION_FAILED_CONTINUE": "Échec du chiffrement\n \nContinuer ?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers chiffrés ok\n%lu/%lu pas du même type", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu fichiers chiffrés ok", + "ENCRYPTION_SUCCESS": "Chiffrement réussi", + "ENCRYPTION_FAILED": "Échec du chiffrement", + "PATH_ENCRYPTED_TO_OUT": "%s\nChiffré vers %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Essayer de traiter les %lu fichiers sélectionnés ?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nLa création de %s a échoué\n \nContinuer ?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss générés ok\n%lu/%lu pas du même type", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss générés ok", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "La conversion a échoué pour %s fichier(s).\nUne vérification est recommandée.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s générés vers %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s n'a pu être créé", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "conversion du fichier échouée.\n \nVérifier maintenant ?", + "VERIFICATION_SUCCESS": "Vérification réussie", + "VERIFICATION_FAILED": "Échec de la vérification", + "CONTENT_IS_MISSING": "Le contenu est manquant", + "INSTALL_TO_SYSNAND": "Installer sur la SysNAND", + "INSTALL_TO_EMUNAND": "Installer sur l'EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Essayer d'installer les %lu fichiers sélectionnés ?", + "TRYING_TO_INSTALL_N_FILES": "Tentative d'installation de %lu fichiers…", + "INSTALL_FAILED_CONTINUE": "Échec de l'installation\n \nContinuer ?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers installés ok\n%lu/%lu pas du même type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu fichiers installés ok", + "INSTALL_SUCCESS": "Installation réussie", + "INSTALL_FAILED": "Échec de l'installation", + "FILE_FAILED_INSTALL_VERIFY_NOW": "installation du fichier échouée.\n \nVérifier maintenant ?", + "KEEP_TICKET_AND_SAVEGAME": "Conserver ticket et sauvegarde", + "UNINSTALL_EVERYTHING": "Tout désinstaller", + "ABORT_UNINSTALL": "Annuler désinstallation", + "UNINSTALL_N_SELECTED_TITLES": "Désinstaller les %lu applications sélectionnés ?", + "UNINSTALL_SELECTED_TITLE": "Désinstaller l'application sélectionné ?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu applications ont été désinstallés", + "UNINSTALLING_PLEASE_WAIT": "Désinstallation, veuillez patienter…", + "UNINSTALL_FAILED": "Échec de la désinstallation !", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Essayer de vérifier les %lu fichiers sélectionnés ?", + "VERIFICATION_FAILED_CONTINUE": "Échec de la vérification\n \nContinuer ?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers vérifiés ok\n%lu/%lu pas du même type", + "VERIFYING_FILE_PLEASE_WAIT": "Vérification du fichier, veuillez patienter…", + "NAND_VALIDATION_SUCCESS": "Validation de la NAND réussie", + "NAND_VALIDATION_FAILED": "Échec de la validation de la NAND", + "DUMP_FOR_N_SELECTED_FILES": "Dumper les %lu fichiers sélectionnés ?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu tickets authentiques dumpés.\n \nTenter de dumper tous les tickets ?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumpés vers %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumpé vers %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLe ticket authentique n'a pas été trouvé.\n \nDumper quand même ?", + "DUMP_TICKET_FAILED": "Échec du dumping du ticket !", + "BUILDING_X": "Création de %s...", + "BUILDING_X_SYSNAND": "Création de %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Création de %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu fichiers traités\n%lu/%lu fichiers ignorés", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu fichiers traités", + "BUILD_DATABASE_SUCCESS": "Création de la base de données réussie.", + "BUILD_DATABASE_FAILED": "Échec de la création de la base de données.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Essayer de tronquer les %lu fichiers sélectionnés ?", + "TRIMMING_FAILED_CONTINUE": "Échec du troncage\n \nContinuer ?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu fichiers tronqués ok\n%lu/%lu pas du même type\n%s enregistrés", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu fichiers tronqués ok\n%s enregistrés", + "FILE_CANT_BE_TRIMMED": "Impossible de tronquer le fichier.", + "FILE_ALREADY_TRIMMED": "Le fichier est déjà tronqué.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nTaille actuelle : %s\nTaille tronquée : %s\nDifférence : %s\n \nTronquer ce fichier ?", + "TRIMMING_FAILED": "Échec du troncage.", + "PATH_TRIMMED_BY_X": "%s\nTronqué par %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Essayer de renommer les %lu fichiers sélectionnés ?", + "N_OF_N_RENAMED": "%lu/%lu renommés ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Impossible de renommer par un bon nom", + "SYSNAND_H_AND_S_INJECT": "Injecter dans l'app. S&S SysNAND", + "EMUNAND_H_AND_S_INJECT": "Injecter dans l'app. S&S EmuNAND", + "H_AND_S_INJECT_SUCCESS": "Injection dans S&S réussie", + "H_AND_S_INJECT_FAILURE": "Échec de l'injection dans S&S", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Essayer d'extraire les %lu fichiers sélectionnés ?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers extraits ok\n%lu/%lu pas du même type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu fichiers extraits ok", + "EXTRACTING_DOT_CODE": "Extraction de .code, veuillez patienter…", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extrait vers %s", + "DOT_CODE_EXTRACT_FAILED": "Échec de l'extraction de .code", + "TRANSFER_TO_SYSNAND": "Transférer vers lz SysNAND", + "TRANSFER_TO_EMUNAND": "Transférer vers l'EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "Transfert de la CTRNAND réussie", + "CTRNAND_TRANSFER_FAILED": "Échec du transfert de la CTRNAND", + "NO_VALID_DESTINATION_FOUND": "Aucune destination valide n'a été trouvée", + "NAND_RESTORE_SUCCESS": "Restauration de la NAND réussie", + "NAND_RESTORE_FAILED": "Échec de la restauration de la NAND", + "REBUILD_NCSD_SUCCESS": "Régénération du NCSD réussie", + "REBUILD_NCSD_FAILED": "Échec de la régénération du NCSD", + "PATH_NCCHINFO_PADGEN_SUCCESS": "NCCHinfo padgen réussi%cRépertoire de sortie : %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen a échoué%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Mettre à jour de la sauvegarde intégrée...", + "BACKUP_UPDATE_NOT_REQUIRED": "Mise à jour de la sauvegarde non nécessaire", + "BACKUP_UPDATE_COMPLETED": "Mise à jour de la sauvegarde terminée", + "BACKUP_UPDATE_FAILED": "Échec de la mise à jour de la sauvegarde!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Attention : Les clés ne sont pas vérifiées.\nPoursuivre à vos risques et périls ?", + "AESKEYDB_INIT_SUCCESS": "Succès de l'initialisation de AESkeydb", + "AESKEYDB_INIT_FAILED": "Échec de l'initialisation de AESkeydb", + "AESKEYDB_INSTALL_SUCCESS": "Succès de l'installation de AESkeydb", + "AESKEYDB_INSTALL_FAILED": "Échec de l'installation de AESkeydb", + "INSTALL_TO_FIRM0": "Installer sur FIRM0", + "INSTALL_TO_FIRM1": "Installer sur FIRM1", + "INSTALL_TO_BOTH": "Installer sur les deux", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%d ko)\nInstaller sur la SysNAND ?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%d ko)\nInstallation réussie", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nL'installation a échoué", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Attention : N'exécutez pas les scripts\nprovenant de sources non fiables.\n \nExécuter le script ?", + "SCRIPT_EXECUTE_SUCCESS": "Exécution du script réussie", + "SCRIPT_EXECUTE_FAILURE": "Échec de l'exécution du script", + "ERROR_CANNOT_VIEW_FILE": "Erreur : Impossible d'afficher ce fichier\n(Il doit être trop grand)", + "SAVEGAME_DUMPED_TO_OUT": "Sauvegarde dumpée vers %s.", + "SAVEGAME_DUMP_FAILED": "Échec du dump de la sauvegarde !", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "La sauvegarde GBA CV doit être\ndans le presse-papiers.", + "SAVEGAME_INJECT_SUCCESS": "Injection de la sauvegarde réussie.", + "SAVEGAME_INJECT_FAILED": "Échec de l'injection de la sauvegarde !", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "La police sera active au prochain démarrage", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "La langue sera appliquée au prochain démarrage", + "HOME_MORE_MENU_SELECT_ACTION": "Menu HOME : Plus d'options...\nSélectionnez une option :", + "SD_FORMAT_MENU": "Formater la Carte SD", + "BONUS_DRIVE_MENU": "Formater l'espace Bonus", + "SWITCH_EMUNAND": "Changer d'EmuNAND", + "BUILD_SUPPORT_FILES": "Créer les fichiers de support", + "RESTORE_H_AND_S": "Restaurer S&S", + "SET_RTC_DATE_TIME": "Régler date et heure HTR", + "CONFGURE_BRIGHTNESS": "Configurer la luminosité", + "CALIBRATE_TOUCHSCREEN": "Calibrer l'écran tactile", + "SYSTEM_INFO": "Infos système", + "SHOW_README": "Afficher le ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "L'initialisation de la carte SD a échoué !\nRéessayer ?", + "SETUP_FAILED": "Échec de la configuration !", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "L'offset de EmuNAND utilisée est : %06lX.\nPasser à l'EmuNAND suivante ?", + "BUILT_IN_OUT_STATUSES": "Les fichiers suivants ont été\ncrées dans %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Échec", + "RESTORE_H_AND_S_EMUNAND": "Restaurer S&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restaurer S&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Régler la date et l'heure RTC :", + "NEW_RTC_DATE_TIME_IS_TIME": "La nouvelle date et heure HTR est :\n%s\n \nRemarque : L'heure du menu HOME\ndoit être réglée manuellement\naprès le réglage de l'heure HTR.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Calibration de l'écran tactile réussie !", + "TOUCHSCREEN_CALIBRATION_FAILED": "Impossible de calibrer l'écran tactile !", + "GODMODE9_README_TOC": "Manuel de GodMode9 : Sommaire", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "La sauvegarde des fichiers essentiels n'a pas été trouvée.\nCréer la sauvegarde maintenant ?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "La sauvegarde a été intégrée dans\nla SysNAND et copiée dans %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "La date et l'heure HTR\nsemblent être erronées.\nLes régler maintenant ?", + "RESUME_GODMODE9": "Entrer dans Godmode9", + "RESUME_BOOTLOADER": "Continuer le démarrage", + "SELECT_PAYLOAD": "Sélectionner la charge utile…", + "SELECT_SCRIPT": "Sélectionner le script…", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "Éteindre le système", + "REBOOT_SYSTEM": "Redémarrer le système", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "Menu de démarrage %s.\nSélectionnez une option :", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Menu du chargeur d'amorçage\ndes charges utiles.\nSélectionner la charge utile :", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Mémoire insuffisante.", + "INVALID_DIRECTORY_OBJECT": "Le dossier n'existe plus", + "INVALID_ROOT_DIRECTORY": "Dossier de racine non valide.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Les permissions d'écritures ont été\nmodifiés. Voulez-vous les bloquer\nà nouveau?", + "OPEN_TITLE_MANAGER": "Gestionnaire d'applications", + "SEARCH_FOR_FILES": "Rechercher des titres…", + "FIX_CMACS_FOR_DRIVE": "Réparer les CMACs du lecteur", + "SHOW_DIRECTORY_INFO": "Afficher infos dossier", + "SHOW_DRIVE_INFO": "Afficher infos lecteur", + "FAILED_SETTING_UP_TITLE_MANAGER": "Le gestionnaire d'applications\nn'a pas pu s'initialiser!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Rechercher dans %s?\nEntrez la recherche ci-dessous.", + "FOUND_N_RESULTS": "%lu résultats trouvés.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Correction des CMACs terminé.", + "FAILED_TO_ANALYZE_DRIVE": "Impossible d'analyser le lecteur\n", + "FAILED_TO_ANALYZE_DIR": "Impossible d'analyser le répertoire\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Non autorisé dans le chemin virtuel", + "DELETE_N_PATHS": "Supprimer %lu chemin(s) ?", + "DELETING_FILES_PLEASE_WAIT": "Suppression des fichiers, veuillez patienter…", + "FAILED_DELETING_N_OF_N_PATHS": "Impossible de supprimer %lu/%lu chemin(s)", + "DELETE_FILE": "Supprimer « %s » ?", + "FAILED_DELETING_PATH": "Impossible de supprimer :\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Non autorisé dans le lecteur de recherche", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Non autorisé dans le chemin de jeu virtuel", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Non autorisé dans le lecteur XORpad", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Non autorisé dans le lecteur de la carte de jeu", + "NOT_ALLOWED_IN_ALIAS_PATH": "Non autorisé dans le répertoire virtuel", + "COPY_PATHS": "Copier le(s) chemin(s)", + "MOVE_PATHS": "Déplacer le(s) chemin(s)", + "PASTE_FILE_HERE": "Coller « %s » ici ?", + "PASTE_N_PATHS_HERE": "Coller les %lu chemins ici ?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Impossible de copier le chemin :\n%s\nTraiter les éléments restants ?", + "FAILED_COPYING_PATH": "Impossible de copier le chemin :\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Impossible de déplacer le chemin :\n%s\nTraiter les éléments restants ?", + "FAILED_MOVING_PATH": "Impossible de déplacer le chemin :\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Renommer %s ?\nSaisissez le nouveau nom ci-dessous.", + "FAILED_RENAMING_PATH": "Impossible de renommer le chemin :\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Créer une nouvelle entrée ici ?\nSélectionnez le type.", + "CREATE_A_FOLDER": "Créer un dossier", + "CREATE_A_DUMMY_FILE": "Créer un fichier vide", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Créer un nouveau dossier ici ?\nSaisissez le nom ci-dessous.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Créer un nouveau fichier ici ?\nSaisissez le nom ci-dessous.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Créez un nouveau %s ici ?\nEntrez sa taille ci-dessous.", + "FAILED_CREATING_FOLDER_PATH": "Impossible de créer le dossier :\n%s", + "FAILED_CREATING_FILE_PATH": "Impossible de créer le fichier :\n%s", + "TITLE_MANAGER": "Gestionnaire d'applications", + "BRICK_MY_3DS": "Bricker ma 3DS", + "LANGUAGE": "Langue…", + "SCRIPTS": "Scripts…", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Charges utiles…", + "MORE": "Plus…", + "BRACKET_MORE": "[plus…]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "Bouton HOME pressé.\nSélectionner l'action :", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "Bouton POWER pressé.\nSélectionner l'action :", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] CARTE SD", + "B_DRIVE_SD_CARD": "[B:] CARTE SD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Gestionnaire d'applications.\nSélectionnez la source des applications :", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Le dossier des langues n'a pas pu être trouvé.\n(chemin par défaut : 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Le répertoire des scripts n'a pas été trouvé.\n(chemin par défaut : 0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "Sélection de la langue.\nChoisissez la langue à utiliser :", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "Sélectionnez le script à exécuter :", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Le répertoire des charges utiles\nn'a pas été trouvé.\n(chemin par défaut : 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "Sélectionnez le firm à exécuter :", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Retrait inattendu de la carte SD !\n \nPour éviter toute perte de données,\néjectez avec R+B avant de retirer\nla carte SD.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "Menu de scripts %s.\nSélectionnez le script à exécuter :", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compilé en tant qu'exécuteur\nautomatique de script, mais\naucun script n'a été fourni.\n\nbruh", + "KEYBOARD_CONTROLS_DETAILS": "Contrôles du Clavier:\n \n←/→ - Déplacer le curseur\nR - Maj / Ver. Maj\nX - Effacer\nY - Insérer char\nA - Envoyer\nB - Annuler\n \nLe bouton SELECT passe\nsur l'interface classique", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touchez les croix rouges pour\ncalibrer l'écran tactile.\n \nUtilisez le stylet pour obtenir\nde meilleurs résultats !", + "INVALID": "INVALIDE", + "TO_PROCEED_ENTER_THIS": "Pour continuer, entrez ceci :", + "TO_PROCEED_HOLD_X": "Pour continuer, maintenez :", + "N_MORE": " [%d de plus]", + "CANCEL": "annuler", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) défilement rapide\nL - effacer les données", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - supprimer le caractère\nY - insérer le caractère", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "Temps restant: %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Baisser la luminosité\n[→] Augmenter la luminosité\n \n[X] Utiliser le curseur de volume\n[A] Régler la luminosité actuelle\n[B] Annuler", + "SEARCHING_PLEASE_WAIT": "Recherche en cours, veuillez patienter…", + "RENAME_TO_GOOD_NAME": "Renommer en un meilleur nom ?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "La carte SD est protégée en écriture !\nImpossible de continuer.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "images de la jeu", + "GAMECART_SAVES": "sauvegardes de la carte de jeu", + "IMAGES": "images", + "MEMORY_AREAS": "zones de mémoire", + "SD_SYSTEM_DATA": "Données du système SD", + "SD_CARD": "Carte SD", + "RAM_DRIVE": "Lecteur RAM", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "L'écriture dans %s est verrouillée !\nDéverrouiller maintenant ?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Le déverrouillage de\nla permission d'écriture pour\n%s n'est pas autorisé.", + "ENABLE_BASE_WRITE": "Vous souhaitez activer les\npermissions d'écriture de\nbase.", + "ENABLE_SD_WRITE": "Vous souhaitez activer les\npermissions d'écriture de\nla carte SD.", + "ENABLE_IMAGE_WRITE": "Vous souhaitez activer les\npermissions d'écriture\nd'images.", + "ENABLE_RAM_DRIVE_WRITE": "Vous devez déverrouiller les\npermissions d'écriture de la RAM.", + "ENABLE_EMUNAND_0_WRITE": "Vous voulez activer les permissions d'écriture\nde la EmuNAND niv0.", + "ENABLE_SYSNAND_0_WRITE": "Vous voulez activer les permissions d'écriture\nde la SysNAND niv0.", + "ENABLE_EMUNAND_1_WRITE": "Vous voulez activer les permissions d'écriture\nde la EmuNAND niv1.\n \nCela vous permet de modifier\nles données système récupérables,\nles données utilisateurs et les sauvegardes.", + "ENABLE_SYSNAND_1_WRITE": "Vous voulez activer les permissions d'écriture\nde la SysNAND niv1.\n \nCela vous permet de modifier\nles données système, les installations\nles données utilisateurs et les sauvegardes.", + "ENABLE_GAMECART_SAVE_WRITE": "Vous devez déverrouiller les\npermissions d'écriture de la\nsauvegarde dans la cartouche.", + "ENABLE_SYSNAND_2_WRITE": "!Mieux vaut être prudent!\n \nVous voulez activer les permissions d'écriture\nde la SysNAND niv2.\n \nCela vous permet de modifier des\ndonnées système irrécupérables!", + "ENABLE_MEMORY_WRITE": "!Faites attention!\n \nVous devez déverrouiller les\npermissions d'écriture de la\nmémoire.\n \nÉcrire dans certaines zones peut\nconduire à des résultats inattendus.", + "ENABLE_SD_DATA_WRITE": "!CECI N'EST PAS RECOMMANDÉ!\n \nVous devez déverrouiller les droits\nd'écriture des données de la SD.\n \nTout ce qui s'y trouve est chiffré.\nIl est recommandé d'utiliser les\nlecteurs [A:]/[B:] pour modifier les\nlogiciels, les données utilisateur\net les sauvegardes.", + "ENABLE_SYSNAND_3_WRITE": "!C'EST VOTRE SEUL AVERTISSEMENT!\n \nVous voulez activer les permissions d'écriture\nde la SysNAND niv3.\n \nCela vous permet d'ÉCRASER votre\ninstallation du bootloader, des fichiers\nsystème essentiels et/ou BRICK\nvotre console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Le déverrouillage des permissions\nd'écriture n'est pas autorisé.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Impossible de déverrouiller la permission d'écriture.\nUtilisez GodMode9 à la place !", + "ERROR_SD_TOO_SMALL": "Erreur : La carte SD est trop petite", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!ATTENTION!\n\nCeci va formater la carte SD.\nTOUTES les données de celle-ci\nseront DEFINITIVEMENT effacés.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Formater la partition bonus?\nCela effacera TOUTES les\ndonnées présentes dessus.", + "FORMATTING_SD_PLEASE_WAIT": "Formatage de la carte SD, veuillez patienter…", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatage du lecteur, veuillez patienter…", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "Le fichier est actuellement monté.\nDémonter pour déverrouiller ?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Erreur : Impossible d'injecter\nun fichier dans lui-même", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "L'opération écrirait au-delà de la fin du fichier", + "NOT_ENOUGH_DATA_IN_FILE": "Pas assez de données dans le fichier", + "CANCEL_IS_NOT_ALLOWED_HERE": "L'annulation n'est pas autorisée ici", + "B_DETECTED_CANCEL": "Bouton B détecté. Annuler ?", + "ERROR_CANNOT_APPEND_FOLDER": "Erreur : Impossible d'ajouter un dossier", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Erreur : un fichier possède le même nom", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Erreur : un dossier possède le même nom", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Erreur : Impossible d'ouvrir le fichier de destination", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Erreur : Pas assez d'espace disponible", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Erreur : Seuls les fichiers FAT\npeuvent être déplacés", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Erreur : La destination\nfait partie de l'origine", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "La destination équivaut à l'origine\nChoisir un autre nom ?", + "CHOOSE_NEW_NAME": "Choississez un nouveau nom", + "OVERWRITE_FILES": "Écraser le(s) fichier(s)", + "SKIP_FILES": "Ignorer le(s) fichier(s)", + "OVERWRITE_ALL": "Écraser tout", + "SKIP_ALL": "Ignorer tout", + "DESTINATION_ALREADY_EXISTS": "La destination existe déjà :\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choisissez un nouveau nom de destination", + "COPY_OPERATION_IS_NOT_ALLOWED": "L'opération de copie n'est pas autorisée", + "DESTINATION_EQUALS_ORIGIN": "La destination équivaut à l'origine", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entrée non trouvée : %s\nInjecter dans %s à la place ?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "Fichier plus petit que l'espace disponible :\n%s (%s)\n%s (%s)\nContinuer ?", + "NO_USABLE_ENTRIES_FOUND": "Aucune entrée utilisable n'a été trouvée.", + "BEAT_NO_ERROR": "Aucune erreur", + "BEAT_END_OF_ACTION_LIST": "Fin de la liste d'actions", + "BEAT_ABORTED_BY_USER": "Interrompu par l'utilisateur", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Impossible de lire/écrire le fichier", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Tentative d'écriture au-delà de la fin du fichier", + "BEAT_INVALID_PATCH_FILE": "Fichier patch invalide", + "BEAT_INVALID_INPUT_FILE": "Fichier d'entrée invalide", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Mauvaise correspondance de la\nsomme de contrôle du fichier de sortie", + "BEAT_FILE_CHECKSUM_FAILED": "Échec de la somme de contrôle du fichier", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Plus de données du patch\nétaient attendues", + "BEAT_OUT_OF_MEMORY": "Mémoire insuffisante", + "BEAT_UNKNOWN_ERROR": "Erreur inconnue", + "FAILED_TO_INITIALIZE_BPM_FILE": "Échec de l'initialisation du fichier BPM :\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Échec de l'initialisation du fichier BPS :\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Le patch a été appliqué avec succès", + "PATCHING_ABORTED_BY_USER": "Patchage interrompu par l'utilisateur", + "FAILED_TO_RUN_PATCH": "Échec de l'exécution du patch :\n%s", + "DECOMPRESSING_DOT_CODE": "Décompression de .code…", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Décompression de .code…\nBouton B détecté. Annuler ?", + "COMPRESSING_DOT_CODE": "Compression de .code…", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compression de .code…\nBouton B détecté. Annuler ?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "Le patch n'est probablement pas destiné à ce fichier.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "Vous avez probablement appliqué le patch au fichier de destination.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "Le patch est techniquement valide,\nmais semble malformé.", + "PATCH_IS_INVALID": "Le patch est invalide.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "L'un des fichiers ou les 2 sont supérieurs à 16 Mo.\nLe format IPS ne le supporte pas.", + "REQUESTED_FILE_PATH_WAS_INVALID": "Le chemin du fichier source est invalide.", + "PATCHING_CANCELED": "L'application du patch a été annulé.", + "NOT_ENOUGH_MEMORY": "Mémoire insuffisante.", + "REGION_AMERICAS": "Amériques", + "REGION_AUSTRALIA": "Australie", + "REGION_BRAZIL": "Brésil", + "REGION_CHINA": "Chine", + "REGION_EUROPE": "Europe", + "REGION_FRANCE": "France", + "REGION_GERMANY": "Allemagne", + "REGION_ITALY": "Italie", + "REGION_JAPAN": "Japon", + "REGION_KOREA": "Corée", + "REGION_SPAIN": "Espagne", + "REGION_TAIWAN": "Taïwan", + "REGION_UNKNOWN": "Inconnu", + "REGION_UNITED_KINGDOM": "Royaume-Uni", + "REGION_MIDDLE_EAST": "Moyen-Orient", + "GENERATING_QR_CODE": "Génération du QR code...", + "REINITIALIZING_SD_CARD": "Recherche de la carte SD...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Appuyez sur POWER pour éteindre", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Effacement de toutes les applications système, veuillez patienter...", + "ERROR_NOT_NCCH_FILE": "Erreur : Ceci n'est pas un fichier NCCH", + "ERROR_FILE_IS_TOO_SMALL": "Erreur : Le fichier est trop petit", + "ATTEMPT_FIX_THIS_TIME": "Essayer de réparer cette fois-ci", + "ATTEMPT_FIX_ALWAYS": "Toujours essayer de réparer", + "ABORT_VERIFICATION": "Annuler la vérification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "échec", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Erreur : Le Titlekey CDN est introuvable", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "Le contenu du DLC est manquant\n \nIgnorer tout et continuer ?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Erreur : Ceci n'est pas un fichier BOSS", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "Mauvaise correspondance du\nhachage de la charge utile BOSS.\n \nTenter de le corriger ?", + "GENERIC_TICKET_PIRATE_LEGIT": "Ticket générique (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Ticket personnalisé (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLe ticket legit est personnalisé.\nIl pourra seulement être utilisé sur cette console.\nChoisissez l'action par défaut :", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey non trouvé.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nLe TMD dans TAD n'est pas legit.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nLe TMD n'est pas legit.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Le contenu est corrompu", + "INSERT_CONTENT_FAILED": "Échec d'insertion du contenu", + "INSTALL_CONTENT_FAILED": "Échec d'installation du contenu", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Erreur d'installation :\nIl manque un ou plusieurs\nfichiers .db.\n \nLa carte SD est peut-être manquante\nou non initialisée ?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Erreur d'installation :\nCe système n'a pas de\nfichier ticket.db.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Erreur : Faux ticket signé\n \nSeuls les tickets signés valide\npeuvent être installés sur le système.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nErreur : Cid %08lX inconnu\n \nCe ticket n'appartient pas à\ncette 3DS.", + "INSTALLING_TICKET": "Installation du ticket...", + "POSSIBLY_BROKEN": "Probablement cassé", + "PERSONAL_LEGIT": "Personnel Légitime", + "PERSONAL_LEGIT_DLC": "Personnel Légitime (DLC)", + "PERSONAL_PIRATE_LEGIT": "Personnel Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personnel Pirate Legit (DLC)", + "PERSONAL_CUSTOM": "Personnel Customisé", + "PERSONAL_CUSTOM_DLC": "Personnel Customisé (DLC)", + "UNIVERSAL_LEGIT": "Universelle Légitime", + "UNIVERSAL_LEGIT_DLC": "Universelle Légitime (DLC)", + "UNIVERSAL_PIRATE_LEGIT": "Pirate Legit universel", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universelle Pirate Legit (DLC)", + "UNIVERSAL_CUSTOM": "Universelle Customisée", + "UNIVERSAL_CUSTOM_DLC": "Universelle Customisée (DLC)", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contenu du CIA : %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contenu du TMD : %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\nApplication %s %s\n \nTitle ID: %016llX\nVersion: %lu.%lu.%lu\nTaille du contenu: %s\n%s\n%s \nTicket/TMD: %s/%s\nVérification: %s", + "STATE_LEGIT": "authentique", + "STATE_ILLEGIT": "inauthentique", + "STATE_UNKNOWN": "inconnu", + "STATE_INVALID": "invalide", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "en attente\n \nProcéder à la vérification ?", + "STATE_PASSED": "réussie", + "STATE_FAILED": "échouée", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Le fichier de destination existe déjà.\nÉcraser ce fichier ?", + "DSI_ENHANCED": "Optimisé DSi", + "DSI_EXCLUSIVE": "Exclusif DSi", + "FIXING_CMACS_PLEASE_WAIT": "Réparation des CMACs,\nveuillez patienter...", + "NCSD_HEADER_IS_NOT_VALID": "L'en-tête NCSD n'est pas valide", + "NAND_DUMP_MISSING_DATA": "Il manque des données dans\nce dump de la NAND", + "ERROR_CTR_MBR_IS_CORRUPT": "Erreur : La partition CTR est corrompue", + "ERROR_TWL_MBR_IS_CORRUPT": "Erreur : La partition TWL est corrompue", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nErreur : La partition CTR%lu est corrompue", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nErreur : La partition TWL%lu est corrompue", + "NO_VALID_FIRM_FOUND": "Aucun FIRM valide n'a été trouvé", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Erreur : Le dump de la NAND\nest corrompu.\nContinuer quand même ?", + "ERROR_SYSTEM_IS_LOCKED": "Erreur : Le système est verrouillé.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "La sauvegarde des fichiers essentiels\nn'a pas été trouvée.\nCréer la sauvegarde maintenant ?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!ATTENTION!\n \nEn procédant à cette opération, la SysNAND\nsera écrasée par l'image NAND fournie.\n \n(B9S/A9LH seront laissés intacts.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "l'Image NCSD corrompue ou modifiée,\nelle ne peut pas être restaurée\nen toute sécurité!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!ATTENTION !\n \nLe NCSD diffère entre celle du fichier\net celle du système,\nDes autorisations d'écriture élevées\nsont requises\n \nContinuer à vos risques et périls ?", + "NOT_AN_INSTALLABLE_FIRM": "Ce FIRM n'est pas installable.", + "FIRM_LOAD_VERIFY_ERROR": "Erreur de chargement/vérification du FIRM.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nLe FIRM%lu est introuvable ou trop petit.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto fail.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Le secteur 0x96 est corrompu.\n \nFournissez \"secret_sector.bin\"\npour réparer le secteur 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Le secteur 0x96 est corrompu.\n \nCorriger le secteur 0x96 pendant\nl'installation ?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!ATTENTION!\n \nEn procédant, vous installerez\nle FIRM fourni sur la SysNAND\net injecterez sighax.\n \nL'installation d'un FIRM non supporté\nva BRICK votre console !", + "INSTALLING_FIRM_PLEASE_WAIT": "Installation du firm, veuillez patienter...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!!!ATTENTION!!!\n \nÉchec de l'écriture du secteur 0x96.\nEssayez de réparer avant le redémarrage !", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!!!ATTENTION!!!\n \nÉchec de l'écriture du FIRM%lu.\nEssayez de réparer avant le redémarrage !", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Vérification de l'installation,\nveuillez patienter...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!!!ATTENTION!!!\n \nLa vérification du secteur 0x96 a échoué.\nEssayez de réparer avant le redémarrage !", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!!!ATTENTION!!!\n \nLa vérification du FIRM%lu a échoué.\nEssayez de réparer avant le redémarrage !", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Le %s parfait est déjà installé!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nn'est pas une image parfaite de %s.\nImpossible d'installer sur la NAND !", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nÉchec de l'écriture du %s sur NAND !", + "USE_L_R_TO_SAVE": "(utilisez L+R pour enregistrer)", + "EASTER_NOT_FOUND": "(%s introuvable)", + "BUILDING_TO_OUT_ARG": "Building to %s:\n%s ...", + "EJECT_SD_CARD": "Ejecter la carte SD...", + "INSERT_SD_CARD": "Insérer la carte SD...", + "SCRIPTERR_UNKNOWN_CMD": "cmd inconnu", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "bad # of args", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "unrecognized flags", + "SCRIPTERR_ILLEGAL_FLAG": "illegal flag", + "SCRIPTERR_UNRESOLVED_QUOTES": "unresolved quotes", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "too many arguments", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "argument expand failed", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "'not' an error", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "syntax error after 'if'", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' without 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "erreur de syntaxe après 'elif'", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' sans 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' sans 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' dans un 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "dossier non trouvé", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' sans 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' sans 'for'", + "SCRIPTERR_FORPATH_ERROR": "forpath error", + "SCRIPTERR_LABEL_NOT_FOUND": "label not found", + "SCRIPTERR_USER_ABORT": "annulation de l'utilisateur", + "SCRIPTERR_KEY_NOT_PRESSED": "touche non pressé", + "SCRIPTERR_OUT_OF_MEMORY": "mémoire insuffisante", + "SCRIPTERR_VAR_FAIL": "échec de la variable", + "SCRIPTERR_FORBIDDEN_DRIVE": "forbidden drive", + "SCRIPTERR_INVALID_PATH": "invalid path", + "SCRIPTERR_FILESELECT_ABORT": "fileselect abort", + "SCRIPTERR_DIRSELECT_ABORT": "dirselect abort", + "SCRIPTERR_SET_FAIL": "set fail", + "SCRIPTERR_CHAR_NOT_FOUND": "char not found", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2] is not a char", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2] must be 2 chars", + "SCRIPTERR_ARG_MATCH": "arg match", + "SCRIPTERR_NO_ARG_MATCH": "no arg match", + "SCRIPTERR_PERMISSION_FAIL": "échec de permission", + "SCRIPTERR_COPY_FAIL": "échec de la copie", + "SCRIPTERR_MOVE_FAIL": "échec du déplacement", + "SCRIPTERR_INJECT_FAIL": "échec de l'injection", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte fail", + "SCRIPTERR_FILL_FAIL": "échec de remplissage", + "SCRIPTERR_BAD_FILESIZE": "mauvaise taille de fichier", + "SCRIPTERR_CREATE_DUMMY_FILE": "échec de la création du fichier", + "SCRIPTERR_REMOVE_FAIL": "échec de la suppression", + "SCRIPTERR_MAKEDIR_FAIL": "échec de création du dossier", + "SCRIPTERR_MOUNT_FAIL": "échec du montage", + "SCRIPTERR_FIND_FAIL": "find fail", + "SCRIPTERR_FINDNOT_FAIL": "findnot fail", + "SCRIPTERR_NO_SIZE_GIVEN": "aucune taille donnée", + "SCRIPTERR_SIZE_TOO_BIG": "taille trop grande", + "SCRIPTERR_READ_FAIL": "échec de la lecture", + "SCRIPTERR_CONVERSION_FAIL": "échec de la conversion", + "SCRIPTERR_INVALID_DATA": "données invalides", + "SCRIPTERR_WRITE_FAIL": "échec de l'écriture", + "SCRIPTERR_SHA_ARG0_FAIL": "sha arg0 fail", + "SCRIPTERR_SHA_ARG1_FAIL": "sha arg1 fail", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "le sha ne correspond pas", + "SCRIPTERR_SHA_WRITE_FAIL": "échec de l'écriture du sha", + "SCRIPTERR_FILE_WRITE_FAIL": "échec de l'écriture du fichier", + "SCRIPTERR_FIXCMAC_FAILED": "fixcmac failed", + "SCRIPTERR_VERIFICATION_FAILED": "échec de la vérification", + "SCRIPTERR_DECRYPT_FAILED": "le déchiffrement a échoué", + "SCRIPTERR_ENCRYPT_FAILED": "le chiffrement a échoué", + "SCRIPTERR_BUILD_CIA_FAILED": "échec de création du CIA", + "SCRIPTERR_INSTALL_GAME_FAILED": "l'installation du jeu a échoué", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": "ne contient pas de .code", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": "l'extraction du .code a échoué", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": "la compression du .code a échoué", + "SCRIPTERR_BUILD_FAILED": "build failed", + "SCRIPTERR_UNKNOWN_FILE": "fichier inconnu", + "SCRIPTERR_APPLY_IPS_FAILD": "échec de l'application du IPS", + "SCRIPTERR_APPLY_BPS_FAILED": "l'application du BPS a échoué", + "SCRIPTERR_APPLY_BPM_FAILED": "l'application du BPM a échoué", + "SCRIPTERR_TEXTVIEWER_FAILED": "échec du visualiseur de texte", + "SCRIPTERR_BAD_DUMPSIZE": "bad dumpsize", + "SCRIPTERR_CART_INIT_FAIL": "échec de l'initialisation de la cartouche", + "SCRIPTERR_CART_DUMP_FAILED": "échec de la copie de la cartouche", + "SCRIPTERR_NOT_A_DIR": "ce n'est pas un dossier", + "SCRIPTERR_FILE_NOT_FOUND": "fichier introuvable", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "ce firm n'est pas démarrable", + "SCRIPTERR_SD_NOT_MOUNTED": "Carte SD non montée", + "SCRIPTERR_UNKNOWN_ERROR": "erreur inconnue", + "SCRIPTERR_COMMAND_SUCCESS": "commande réussie", + "SCRIPTERR_CONTROL_FLOW_ERROR": "control flow error", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "unclosed conditional", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "échec du message d'erreur", + "ERROR_INVALID_TEXT_DATA": "Erreur: Données de texte invalides", + "TEXTVIEWER_CONTROLS_DETAILS": "Contrôles du visualisateur de texte:\n \n↑↓→←(+R) - Défiler\nR+Y - Activer/désactiver le retour la ligne\nR+X - Aller au numéro de ligne\nB - Quitter\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "Ligne actuelle : %i\nEntrez la nouvelle ligne ci-dessous.", + "PREVIEW_DISABLED": "(aperçu désactivé)", + "PATH_LINE_N_ERR_LINE": "%s\nligne %lu: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "end of script: unresolved 'if'", + "END_OF_SCRIPT_UNRESOLVED_FOR": "end of script: unresolved 'for'", + "SYSINFO_MODEL": "Modèle : %s (%s)\n", + "SYSINFO_SERIAL": "Numéro de série : %s\n", + "SYSINFO_REGION_SYSTEM": "Région (système) : %s\n", + "SYSINFO_REGION_SALES": "Région (vendue) : %s\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "Date de fabrication SoC : %s\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "Date d'assemblage du système : %s\n", + "SYSINFO_ORIGINAL_FIRMWARE": "Version d'origine : %s\n", + "SYSINFO_FRIENDCODE_SEED": "Friendcode seed: %s\n", + "SYSINFO_SD_KEYY": "SD keyY: %s\n", + "SYSINFO_NAND_CID": "NAND CID: %s\n", + "SYSINFO_SD_CID": "SD CID: %s\n", + "SYSINFO_SYSTEM_ID0": "ID0 Système : %s\n", + "SYSINFO_SYSTEM_ID1": "ID1 Système : %s\n", + "SORTING_TICKETS_PLEASE_WAIT": "Tri des tickets en cours, veuillez patienter...", + "LUA_NOT_INCLUDED": "This build of GodMode9 was\ncompiled without Lua support." +} diff --git a/resources/languages/id.json b/resources/languages/id.json new file mode 100644 index 000000000..fb15b62f5 --- /dev/null +++ b/resources/languages/id.json @@ -0,0 +1,816 @@ +{ + "GM9_LANGUAGE": "Bahasa Indonesia", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "(Thn-Bln-Hari) %1$s%2$02lX-%3$02lX-%4$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRM kebesaran, tak bisa boot", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nPeringatan: Jangan boot-kan FIRM\ndari sumber tidak jelas.\n \nBoot-kan FIRM?", + "NOT_BOOTABLE_FIRM": "Bukan FIRM bisa di-boot.", + "FIRM_ENCRYPTED": "FIRM terenkripsi.\n \nDekripsi-kan sebelum boot?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Buat salinan di %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Coba di-boot saja", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Peringatan: Mencoba mem-boot dari\nlokasi yang tak didukung.", + "ROOT": "[akar]", + "LOADING": "MEMUAT...", + "PANE_N": "PANEL #%lu", + "CURRENT": "SAAT INI", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(Kandar-RAM FAT)", + "GAME_VIRTUAL": "(P'mainan Maya)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Maya)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Maya)", + "IMAGE_FAT": "(Citra FAT)", + "XORPAD_VIRTUAL": "(XORpad Maya)", + "MEMORY_VIRTUAL": "(Memori Maya)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Kartrid Maya)", + "VRAM_VIRTUAL": "(VRAM Maya)", + "SEARCH": "(Cari)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Maya)", + "LAB_SDCARD": "KARTU SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND MAYA", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND MAYA", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND MAYA", + "LAB_GAMECART": "KARTRID", + "LAB_GAME_IMAGE": "CITRA P'MAINAN", + "LAB_AESKEYDB_IMAGE": "CITRA AESKEYDB", + "LAB_BDRI_IMAGE": "CITRA BDRI", + "LAB_DISA_DIFF_IMAGE": "CITRA DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "MEMORI MAYA", + "LAB_VRAM_VIRTUAL": "VRAM MAYA", + "LAB_TITLE_MANAGER": "PENGELOLA JUDUL", + "LAB_LAST_SEARCH": "CARIAN TERAKHIR", + "LAB_FAT_IMAGE": "CITRA FAT", + "LAB_BONUS_DRIVE": "KANDAR BONUS", + "LAB_RAMDRIVE": "KANDAR-RAM", + "LAB_NOLABEL": "TANPA LABEL", + "N_BYTE": "%s Bita", + "BYTE": " Bita", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[PAPAN-KLIP]", + "PLUS_N_MORE": "+ %lu lagi", + "MARK_DELETE_COPY": "L - TANDAI berkas (dengan ↑↓→←)\nX - HAPUS / [+R] UBAH NAMA berkas\nY - SALIN berkas / [+R] BUAT entri\n", + "MARK_DELETE_PASTE": "L - TANDAI berkas (dengan ↑↓→←)\nX - HAPUS / [+R] UBAH NAMA berkas\nY - TEMPEL berkas / [+R] BUAT entri\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Tutup lagi izin tulis\n", + "UNMOUNT_IMAGE": "R+X - Lepas mount citra\n", + "UNMOUNT_SD": "R+B - Lepas mount kartu SD\n", + "REMOUNT_SD": "R+B - Mount ulang kartu SD\n", + "DIRECTORY_OPTIONS": "R+A - Opsi direktori\n", + "DRIVE_OPTIONS": "R+A - Opsi kandar\n", + "MAKE_SCREENSHOT": "R+L - Tangkap layar\n", + "PREV_NEXT_PANE": "R+←→ - Pindah ke panel sblm/brkt\n", + "CLEAR_CLIPBOARD": "SELECT - Kosongkan Papan Klip\n", + "RESTORE_CLIPBOARD": "SELECT - Pulihkan Papan Klip\n", + "REBOOT_POWEROFF_HOME": "START - Boot ulang / [+R] Matikan daya\nHOME - untuk ke HOME menu", + "NO_EMUNAND": "Tak ada EmuNAND", + "REDNAND_SIZE_MIN": "Ukuran RedNAND (min)", + "GW_EMUNAND_SIZE_FULL": "Ukuran EmuNAND GW (penuh)", + "MULTINAND_SIZE_2X": "Ukuran MultiNAND (2x)", + "MULTINAND_SIZE_3X": "Ukuran MultiNAND (3x)", + "MULTINAND_SIZE_4X": "Ukuran MultiNAND (4x)", + "USER_INPUT": "Masukan pengguna...", + "AUTO": "Otomatis", + "16KB_CLUSTERS": "Gugus 16KB", + "32KB_CLUSTERS": "Gugus 32KB", + "64KB_CLUSTERS": "Gugus 64KB", + "SD_NOT_DETECTED": "Galat: Kartu SD tidak terbaca.", + "FORMAT_SD_CHOOSE_EMUNAND": "Formatkan kartu SD (%lluMB)?\nPilih ukuran EmuNAND:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "Ukuran kartu SD-nya %lluMB.\nTulis ukuran EmuNAND (MB) di bawah:", + "FORMAT_SD_CHOOSE_CLUSTER": "Formatkan kartu SD (%lluMB)?\nPilih ukuran gugusnya:", + "FORMAT_SD_ENTER_LABEL": "Formatkan kartu SD (%lluMB)?\nMasukkan label:", + "FORMAT_SD_FAILED": "Memformat SD: gagal!", + "REDNAND_TYPE": "Jenis RedNAND", + "REDNAND_TYPE_MULTI": "Jenis RedNAND (banyak)", + "REDNAND_TYPE_SINGLE": "Jenis RedNAND (tunggal)", + "GW_EMUNAND_TYPE": "Jenis EmuNAND GW", + "DONT_SET_UP": "Jangan diatur", + "CHOOSE_EMUNAND_TYPE": "Pilih jenis EmuNAND untuk diatur:", + "CLONE_SYSNAND_TO_REDNAND": "Gandakan SysNAND ke RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Mengganda SysNAND ke EmuNAND: gagal!", + "PRESS_A_TO_CONTINUE": "Tekan untuk lanjut", + "HEXEDITOR_CONTROLS": "Kendali Hexeditor:\n \n↑↓→←(+R) - Gulir\nR+Y - Ubah tampilan\nX - Cari / ke...\nA - Masuk mode sunting\nA+↑↓→← - Sunting nilai\nB - Keluar\n", + "NOT_FOUND": "Tak ditemukan!", + "GO_TO_OFFSET": "Masuk ke offset", + "SEARCH_FOR_STRING": "Cari untaian", + "SEARCH_FOR_DATA": "Cari data", + "CURRENT_OFFSET_SELECT_ACTION": "Offset saat ini: %08lX\nPilih tindakan:", + "CURRENT_OFFSET_ENTER_NEW": "Offset saat ini: %08lX\nMasukkan offset baru.", + "ENTER_SEARCH_REPEAT_SEARCH": "Tulis untaian pencarian.\n(R+X - ulangi pencarian)", + "MADE_EDITS_SAVE_CHANGES": "Anda menyunting di %lu tempat.\nTulis ubahannya ke berkas?", + "FAILED_WRITING_TO_FILE": "Gagal menulis ke berkas!", + "CALCULATING_SHA_FAILED": "Memperhitung SHA-%s: gagal!", + "SHA_VERIFICATION_PASSED": "\nVerifikasi SHA: lolos!", + "SHA_VERIFICATION_FAILED": "\nVerifikasi SHA: gagal", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentik dengan berkas sebelumnya:\n", + "WRITE_SHA_FILE": "\n \nTulis berkas .SHA?", + "WRITE_SHA1_FILE": "\n \nTulis berkas .SHA1?", + "CALCULATING_CMAC_FAILED": "Memperhitung CMAC: gagal!", + "CMAC_VERIFICATION_PASSED": "Verifikasi CMAC: lolos!", + "CMAC_VERIFICATION_FAILED": "Verifikasi CMAC: gagal!", + "FIX_CMAC_IN_FILE": "\n \nPerbaiki CMAC di berkas?", + "FIXING_CMAC_FAILED": "Memperbaiki CMAC: gagal!", + "COPY_ALL_SELECTED_ITEMS": "Salin %lu butir terpilih?", + "FAILED_COPYING_ITEM": "Gagal menyalin butir", + "ITEMS_COPIED_TO_OUT": "%lu butir disalin ke %s", + "PATH_COPIED_TO_OUT": "%s\nDisalin ke %s", + "CART_INIT_FAILED": "Inisialisasi kartrid, gagal!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Kartrid: %s\nUkuran terbaca: %s\n \nTulis ukuran dump di bawah.", + "NDS_CART_DECRYPT_SECURE_AREA": "Kartrid: %s\nKartrid NDS terbaca\nDekripsikan area aman?", + "FAILED_DUMPING_CART": "%s\nGagal men-dump kartrid", + "PATH_DUMPED_TO_OUT": "%s\nDi-dump ke %s", + "CREATED": "dibuat", + "MODIFIED": "diubah", + "ANALYZING_DRIVE": "Menganalisis kandar, mohon tunggu...", + "ANALYZING_DIR": "Menganalisis dir, mohon tunggu...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu berkas & %lu subdirektori\njumlah ukuran %s\n \nsisa kosong: %s\nruang terpakai: %s\njumlah: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu berkas & %lu subdirektori\njumlah ukuran %s", + "FILESIZE_X": "ukuran-berkas: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %shanya baca [%c] %st'sembunyi\n[%c] %ssistem [%c] %sarsip\n[%c] %smaya\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← untuk ubah atribut)\n", + "A_TO_CONTINUE": "( untuk lanjut)", + "A_APPLY_B_CANCEL": "( - terapkan, - batal)", + "A_YES_B_NO": "( iya, tidak)", + "A_SELECT_B_CANCEL": "( pilih, batal)", + "HOLD_B_TO_CANCEL": "(tahan B untuk batal)", + "FAILED_TO_SET_ATTRIBUTES": "Gagal mengatur atribut!", + "NAND_IMAGE_OPTIONS": "Opsi citra NAND...", + "CTRNAND_OPTIONS": "Opsi CTRNAND...", + "MOUNT_FAT_IMAGE": "Mount sebagai citra FAT", + "CIA_IMAGE_OPTIONS": "Opsi citra CIA...", + "NCSD_IMAGE_OPTIONS": "Opsi citra NCSD...", + "NCCH_IMAGE_OPTIONS": "Opsi citra NCCH...", + "MOUNT_AS_EXEFS_IMAGE": "Mount sebagai citra EXEFS", + "MOUNT_AS_ROMFS_IMAGE": "Mount sebagai citra ROMFS", + "TMD_FILE_OPTIONS": "Opsi berkas TMD...", + "TMD_CDN_OPTIONS": "Opsi TMD/CDN...", + "TMD_TWL_OPTIONS": "Opsi TMD/TWL...", + "MANAGE_TITLE": "Kelola Judul...", + "BOSS_FILE_OPTIONS": "Opsi berkas BOSS...", + "DECRYPT_NUS_CDN_FILE": "Dekripsikan berkas NUS/CDN", + "SHOW_SMDH_TITLE_INFO": "Tampilkan info SMDH ini", + "NDS_IMAGE_OPTIONS": "Opsi citra NDS...", + "GBA_IMAGE_OPTIONS": "Opsi citra GBA...", + "TICKET_OPTIONS": "Opsi ticket...", + "TAD_IMAGE_OPTIONS": "Opsi citra TAD...", + "SHOW_3DSX_TITLE_INFO": "Tampilkan info 3DSX ini", + "FIRM_IMAGE_OPTIONS": "Opsi citra FIRM...", + "AGBSAVE_OPTIONS": "Opsi AGBSAVE...", + "DUMP_GBA_VC_SAVE": "Dump-kan simpanan GBA VC", + "TICKET_DB_OPTIONS": "Opsi Ticket.db ...", + "MOUNT_AS_DIFF_IMAGE": "Mount sebagai citra DIFF", + "MOUNT_AS_DISA_IAMGE": "Mount sebagai citra DISA", + "INSTALL_CIFINISH_BIN": "Pasang cifinish.bin", + "TITLEKEY_OPTIONS": "Opsi Titlekey...", + "AESKEYDB_OPTIONS": "Opsi AESkeydb...", + "BUILD_X": "Bina %s", + "NCCHINFO_OPTIONS": "Opsi NCCHinfo...", + "EXECUTE_GM9_SCRIPT": "Jalankan naskah GM9", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Opsi fonta...", + "LANGUAGE_OPTIONS": "Ubah bahasa...", + "VIEW_PNG_FILE": "Lihat berkas PNG", + "REBUILD_NCSD_HEADER": "Bina ulang header NCSD", + "SHOW_IN_HEXEDITOR": "Tampilkan di Hexeditor", + "CALCULATE_SHA256": "Perhitung SHA-256", + "CALCULATE_SHA1": "Perhitung SHA-1", + "SHOW_FILE_INFO": "Tampilkan info berkas", + "SHOW_IN_TEXTVIEWER": "Tampilkan di Textviewer", + "CALCULATE_CMAC": "Perhitung CMAC", + "COPY_TO_OUT": "Salin ke %s", + "DUMP_TO_OUT": "Dump-kan ke %s", + "INJECT_DATA_AT_OFFSET": "Suntik data @offset", + "OPEN_THIS_FOLDER": "Buka folder ini", + "OPEN_CONTAINING_FOLDER": "Buka folder yang berisi", + "OPEN_TITLE_FOLDER": "Buka folder judul", + "PATH_N_FILES_SELECTED": "%s\n(%lu berkas terpilih)", + "CHECK_CURRENT_CMAC_ONLY": "Periksa CMAC saat ini saja", + "VERIFY_CMAC_FOR_ALL": "Verifikasi CMAC semuanya", + "FIX_CMAC_FOR_ALL": "Perbaiki CMAC semuanya", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu berkasnya ok/diperbaiki/ditotal\n%lu/%lu tidak ada CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu berkas terverifikasi\n%lu/%lu berkas diperbaiki", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu berkas terverifikasi\n%lu/%lu tidak ada CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu berkas terverifikasi", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Suntik data dari %s?\nTentukan offset di bawah.", + "FAILED_INJECTING_PATH": "Gagal menyuntik %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Mount-kan CXI/NDS ke kandar", + "MOUNT_IMAGE_TO_DRIVE": "Mount-kan citra ke kandar", + "RESTORE_SYSNAND_SAFE": "Pulihkan SysNAND (cara aman)", + "UPDATE_EMBEDDED_BACKUP": "Perbarui cadangan tersemat", + "SHOW_TITLE_INFO": "Tampilkan info judul", + "DECRYPT_FILE": "Dekripsikan berkas (...)", + "DECRYPT_FILE_OUT": "Dekripsikan berkas (%s)", + "ENCRYPT_FILE": "Enkripsikan berkas (...)", + "ENCRYPT_FILE_OUT": "Enkripsikan berkas (%s)", + "BUILD_CIA_FROM_FILE": "Bina CIA dari berkas", + "BUILD_CIA_STANDARD": "Bina CIA (standar)", + "BUILD_CIA_LEGIT": "Bina CIA (autentik)", + "DUMP_CXI_NDS_FILE": "Dump-kan berkas CXI/NDS", + "INSTALL_GAME_IMAGE": "Pasang citra permainan", + "INSTALL_TICKET": "Pasang ticket", + "DUMP_TICKET_FILE": "Dump-kan berkas ticket", + "UNINSTALL_TITLE": "Copot judul p'mainan", + "VERIFY_FILE": "Verifikasi berkas", + "TRANSFER_IMAGE_TO_CTRNAND": "Transfer citra ke CTRNAND", + "INJECT_TO_H_AND_S": "Suntik ke H&S", + "TRIM_FILE": "Pangkas berkas", + "RENAME_FILE": "Ubah nama berkas", + "BUILD_XORPADS_SD": "Bina XORpads (keluaran SD)", + "BUILD_XORPADS_INPLACE": "Bina XORpads (di tempat)", + "EXTRACT_X": "Ekstrak %s", + "INIT_X": "Init %s", + "INSTALL_X": "Pasang %s", + "INSTALL_FIRM": "Pasang FIRM", + "BOOT_FIRM": "Boot-kan FIRM", + "SET_AS_ACTIVE_FONT": "Atur sebagai fonta aktif", + "SET_AS_ACTIVE_LANGUAGE": "Atur sebagai bahasa aktif", + "DUMP_BA_VC_SAVE": "Dump-kan simpanan GBA VC", + "INJECT_GBA_VC_SAVE": "Suntik simpanan GBA VC", + "SET_AS_DEFAULT": "Atur sebagai bawaan", + "MOUNTING_IMAGE_FAILED": "Me-mount citra: gagal", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nDi-mount sebagai kandar %s\nLihat isi jalur?", + "DECRYPT_TO_OUT": "Dekripsikan ke %s", + "DECRYPT_INPLACE": "Dekripsi di tempat", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Mau dekripsikan %lu berkas terpilih?", + "TRYING_TO_DECRYPT_N_FILES": "Mencoba dekripsikan %lu berkas...", + "DECRYPTION_FAILED_CONTINUE": "Dekripsi, gagal\n \nLanjutkan?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terdekripsi\n%lu/%lu tidak dienkripsi\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu berkas terdekripsi", + "N_FILES_WRITTEN_TO_OUT": "%lu berkas ditulis ke %s", + "FILE_NOT_ENCRYPTED": "Berkas tidak dienkripsi", + "DECRYPTION_SUCCESS": "Dekripsi berhasil", + "DECRYPTION_FAILED": "Dekripsi, gagal", + "PATH_DECRYPTED_TO_OUT": "%s\nDidekripsi ke %s", + "ENCRYPT_TO_OUT": "Enkripsikan ke %s", + "ENCRYPT_INPLACE": "Enkripsi di tempat", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Mau enkripsikan %lu berkas terpilih?", + "TRYING_TO_ENCRYPT_N_FILES": "Mencoba enkripsikan %lu berkas...", + "ENCRYPTION_FAILED_CONTINUE": "Enkripsi, gagal\n \nLanjutkan?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terenkripsi\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu berkas terenkripsi", + "ENCRYPTION_SUCCESS": "Enkripsi berhasil", + "ENCRYPTION_FAILED": "Enkripsi, gagal", + "PATH_ENCRYPTED_TO_OUT": "%s\nDienkripsi ke %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Mau olah %lu berkas terpilih?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nBinaan %s, gagal\n \nLanjutkan?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %s terbina\n%lu/%lu bukan jenis yang sama", + "N_OF_N_TYPES_BUILT": "%lu/%lu %s terbina", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "Gagal mengonversi %lu berkas.\nDianjurkan melakukan verifikasi.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s dibina ke %s", + "PATH_TYPE_BUILD_FAILED": "%s\nBinaan %s, gagal", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "gagal mengonversi berkas.\n \nVerifikasikan?", + "VERIFICATION_SUCCESS": "Verifikasi berhasil", + "VERIFICATION_FAILED": "Verifikasi, gagal", + "CONTENT_IS_MISSING": "Konten hilang", + "INSTALL_TO_SYSNAND": "Pasang ke SysNAND", + "INSTALL_TO_EMUNAND": "Pasang ke EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Mau pasang %lu berkas terpilih?", + "TRYING_TO_INSTALL_N_FILES": "Mencoba pasang %lu berkas...", + "INSTALL_FAILED_CONTINUE": "Pemasangan, gagal\n \nLanjutkan?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terpasang\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_INSTALLED": "%lu/%lu berkas terpasang", + "INSTALL_SUCCESS": "Pemasangan berhasil", + "INSTALL_FAILED": "Pemasangan, gagal", + "FILE_FAILED_INSTALL_VERIFY_NOW": "gagal memasang berkas.\n \nVerifikasikan?", + "KEEP_TICKET_AND_SAVEGAME": "Biarkan ticket & simpanan", + "UNINSTALL_EVERYTHING": "Copot semuanya", + "ABORT_UNINSTALL": "Gugurkan pencopotan", + "UNINSTALL_N_SELECTED_TITLES": "Copot %lu judul terpilih?", + "UNINSTALL_SELECTED_TITLE": "Copot judul terpilih?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu judulnya dicopot", + "UNINSTALLING_PLEASE_WAIT": "Mencopot, mohon tunggu...", + "UNINSTALL_FAILED": "Pencopotan, gagal!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Mau verifikasikan %lu berkas terpilih?", + "VERIFICATION_FAILED_CONTINUE": "Verifikasi, gagal\n \nLanjutkan?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terverifikasi\n%lu/%lu bukan jenis yang sama", + "VERIFYING_FILE_PLEASE_WAIT": "Memverifikasi berkas, mohon tunggu...", + "NAND_VALIDATION_SUCCESS": "Pengabsahan NAND berhasil", + "NAND_VALIDATION_FAILED": "Pengabsahan NAND, gagal", + "DUMP_FOR_N_SELECTED_FILES": "Dump-kan %lu berkas terpilih?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu ticket autentik di-dump.\n \nMau coba dump semua ticket?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu ticket di-dump ke %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket di-dump ke %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nTicket autentik tak ditemukan.\n \nDi-dump saja?", + "DUMP_TICKET_FAILED": "Membuat dump ticket, gagal!", + "BUILDING_X": "Membina %s...", + "BUILDING_X_SYSNAND": "Membina %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Membina %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu berkas diolah\n%lu/%lu berkas diabaikan", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu berkas diolah", + "BUILD_DATABASE_SUCCESS": "Pangkalan data berhasil dibina.", + "BUILD_DATABASE_FAILED": "Pangkalan data gagal dibina.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Mau pangkas %lu berkas terpilih?", + "TRIMMING_FAILED_CONTINUE": "Pemangkasan, gagal\n \nLanjutkan?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu berkas terpangkas\n%lu/%lu bukan jenis yang sama\n%s disimpan", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu berkas terpangkas\n%s disimpan", + "FILE_CANT_BE_TRIMMED": "Berkas tak bisa dipangkas.", + "FILE_ALREADY_TRIMMED": "Berkas telah dipangkas.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nUkuran saat ini: %s\nSetelah pangkas: %s\nPerbedaan: %s\n \nPangkas berkas ini?", + "TRIMMING_FAILED": "Pemangkasan, gagal.", + "PATH_TRIMMED_BY_X": "%s\nDipangkas %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Mau ubah nama %lu berkas terpilih?", + "N_OF_N_RENAMED": "%lu/%lu terubah nama", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Tidak bisa diubah nama ke nama bagus", + "SYSNAND_H_AND_S_INJECT": "Suntik H&S di SysNAND", + "EMUNAND_H_AND_S_INJECT": "Suntik H&S di EmuNAND", + "H_AND_S_INJECT_SUCCESS": "H&S berhasil disuntik", + "H_AND_S_INJECT_FAILURE": "H&S gagal disuntik", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Mau ekstrak %lu berkas terpilih?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terekstrak\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu berkas terekstrak", + "EXTRACTING_DOT_CODE": "Mengekstrak .code, mohon tunggu...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s diekstrak ke %s", + "DOT_CODE_EXTRACT_FAILED": "Gagal mengekstrak .code", + "TRANSFER_TO_SYSNAND": "Transfer ke SysNAND", + "TRANSFER_TO_EMUNAND": "Transfer ke EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "Transfer CTRNAND, berhasil", + "CTRNAND_TRANSFER_FAILED": "Transfer CTRNAND, gagal", + "NO_VALID_DESTINATION_FOUND": "Tidak ada destinasi yang absah", + "NAND_RESTORE_SUCCESS": "Pemulihan NAND, berhasil", + "NAND_RESTORE_FAILED": "Pemulihan NAND, gagal", + "REBUILD_NCSD_SUCCESS": "Bina ulang NCSD, berhasil", + "REBUILD_NCSD_FAILED": "Bina ulang NCSD, gagal", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nPadgen dari NCCHinfo, berhasil%cDir keluaran: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nPadgen dari NCCHinfo, gagal%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Memperbarui cadangan tersemat...", + "BACKUP_UPDATE_NOT_REQUIRED": "Pembaruan cadangan: tak diperlukan", + "BACKUP_UPDATE_COMPLETED": "Pembaruan cadangan: selesai", + "BACKUP_UPDATE_FAILED": "Pembaruan cadangan: gagal!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Peringatan: Key belum diverifikasi.\nTanggung risiko dan lanjutkan?", + "AESKEYDB_INIT_SUCCESS": "Init dari AESkeydb, berhasil", + "AESKEYDB_INIT_FAILED": "Init dari AESkeydb, gagal", + "AESKEYDB_INSTALL_SUCCESS": "Pemasangan AESkeydb, berhasil", + "AESKEYDB_INSTALL_FAILED": "Pemasangan AESkeydb, gagal", + "INSTALL_TO_FIRM0": "Pasang ke FIRM0", + "INSTALL_TO_FIRM1": "Pasang ke FIRM1", + "INSTALL_TO_BOTH": "Pasang ke keduanya", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nPasang ke SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nPemasangan, berhasil", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nPemasangan, gagal", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Peringatan: Jangan jalankan\nnaskah dari sumber tidak jelas.\n \nLaksanakan naskah?", + "SCRIPT_EXECUTE_SUCCESS": "Eksekusi naskah, berhasil", + "SCRIPT_EXECUTE_FAILURE": "Eksekusi naskah, gagal", + "ERROR_CANNOT_VIEW_FILE": "Galat: Berkas tak bisa dilihat\n(Peunjuk: mungkin terlalu besar)", + "SAVEGAME_DUMPED_TO_OUT": "Simpanan di-dump ke %s.", + "SAVEGAME_DUMP_FAILED": "Simpanan gagal di-dump!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "Simpanan GBA VC harus\nberada di papan klip.", + "SAVEGAME_INJECT_SUCCESS": "Simpanan berhasil disuntik.", + "SAVEGAME_INJECT_FAILED": "Simpanan gagal disuntik!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Fonta akan aktif pada boot berikutnya", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Bahasa akan aktif pada boot berikutnya", + "HOME_MORE_MENU_SELECT_ACTION": "HOME - menu \"lagi...\"\nPilih tindakan:", + "SD_FORMAT_MENU": "Menu pemformatan SD", + "BONUS_DRIVE_MENU": "Penyiapan kandar bonus", + "SWITCH_EMUNAND": "Alihkan EmuNAND", + "BUILD_SUPPORT_FILES": "Bina berkas dukungan", + "RESTORE_H_AND_S": "Pulihkan H&S", + "SET_RTC_DATE_TIME": "Atur tanggal&waktu RTC", + "CONFGURE_BRIGHTNESS": "Konfigurasi kecerahan", + "CALIBRATE_TOUCHSCREEN": "Kalibrasi layar sentuh", + "SYSTEM_INFO": "Informasi sistem", + "SHOW_README": "Tampilkan ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Inisialisasi kartu SD, gagal! Coba lagi?", + "SETUP_FAILED": "Penyiapan, gagal!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Offset EmuNAND saat ini %06lX.\nBeralih ke offset berikutnya?", + "BUILT_IN_OUT_STATUSES": "Dibina di %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Gagal", + "RESTORE_H_AND_S_EMUNAND": "Pulihkan H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Pulihkan H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Atur tanggal&waktu RTC:", + "NEW_RTC_DATE_TIME_IS_TIME": "Tanggal&waktu RTC baru:\n%s\n \nPeunjuk: Waktu di HOMEMENU\nperlu disesuaikan sendiri\nsetelah mengatur RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Kalibrasi layar sentuh, berhasil!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Kalibrasi layar sentuh, gagal!", + "GODMODE9_README_TOC": "Daftar Isi dari ReadMe GodMode9", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Cadangan berkas esensial tak ditemukan.\nMau buat baru?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Cadangan disemat di SysNAND\ndan ditulis ke %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "Tanggal&waktu RTC terlihat\nsalah. Atur sekarang?", + "RESUME_GODMODE9": "Lanjut lagi GodMode9", + "RESUME_BOOTLOADER": "Lanjut lagi bootloader", + "SELECT_PAYLOAD": "Pilih payload...", + "SELECT_SCRIPT": "Pilih naskah...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "Matikan daya sistem", + "REBOOT_SYSTEM": "Boot ulang sistem", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "Menu bootloader %s.\nPilih tindakan:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Menu payload-bootloader.\nPilih payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Menu naskah-bootloader.\nPilih skrip:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "Tidak ada FIRM bisa di-boot.\nGodMode9 dilanjutkan lagi...", + "OUT_OF_MEMORY": "Kehabisan memori.", + "INVALID_DIRECTORY_OBJECT": "Objek direktori tak absah", + "INVALID_ROOT_DIRECTORY": "Direktori akar tak absah.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Izin penulisan telah diubah.\nTutup lagi izinnya?", + "OPEN_TITLE_MANAGER": "Buka pengelola judul", + "SEARCH_FOR_FILES": "Cari berkas...", + "FIX_CMACS_FOR_DRIVE": "Perbaiki CMAC untuk kandar", + "SHOW_DIRECTORY_INFO": "Tampilkan info direktori", + "SHOW_DRIVE_INFO": "Tampilkan info kandar", + "FAILED_SETTING_UP_TITLE_MANAGER": "Gagal menyiapkan pengelola judul!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Cari %s?\nTulis pencarian di bawah.", + "FOUND_N_RESULTS": "Ditemukan %lu hasil.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Perbaikan CMAC untuk kandar, selesai.", + "FAILED_TO_ANALYZE_DRIVE": "Gagal menganalisis kandar\n", + "FAILED_TO_ANALYZE_DIR": "Gagal menganalisis dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Tidak boleh di jalur maya", + "DELETE_N_PATHS": "Hapus %lu jalur?", + "DELETING_FILES_PLEASE_WAIT": "Menghapus berkas, mohon tunggu...", + "FAILED_DELETING_N_OF_N_PATHS": "Gagal menghapus %lu/%lu jalur", + "DELETE_FILE": "Hapus \"%s\"?", + "FAILED_DELETING_PATH": "Gagal menghapus:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Tidak boleh di kandar pencarian", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Tidak boleh di jalur permainan maya", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Tidak boleh di kandar XORpad", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Tidak boleh di kandar kartrid", + "NOT_ALLOWED_IN_ALIAS_PATH": "Tidak boleh di jalur alias", + "COPY_PATHS": "Salin jalur", + "MOVE_PATHS": "Pindahkan jalur", + "PASTE_FILE_HERE": "Tempel \"%s\" di sini?", + "PASTE_N_PATHS_HERE": "Tempel %lu jalur di sini?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Gagal menyalin jalur:\n%s\nOlah saja sisanya?", + "FAILED_COPYING_PATH": "Gagal menyalin jalur:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Gagal memindahkan jalur:\n%s\nOlah saja sisanya?", + "FAILED_MOVING_PATH": "Gagal memindahkan jalur:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Ubah nama %s?\nTulis nama baru di bawah.", + "FAILED_RENAMING_PATH": "Gagal mengubah nama jalur:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Buat entri baru di sini?\nPilih jenis.", + "CREATE_A_FOLDER": "Buat folder", + "CREATE_A_DUMMY_FILE": "Buat berkas kosong", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Buat folder baru di sini?\nTulis namanya di bawah.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Buat berkas baru di sini?\nTulis namanya di bawah.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Buat %s baru di sini?\nTulis ukuran berkasnya.", + "FAILED_CREATING_FOLDER_PATH": "Gagal membuat folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Gagal membuat berkas:\n%s", + "TITLE_MANAGER": "Pengelola judul", + "BRICK_MY_3DS": "Matotkan 3DS saya", + "LANGUAGE": "Bahasa...", + "SCRIPTS": "Naskah...", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Payload...", + "MORE": "Lagi...", + "BRACKET_MORE": "[lagi...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "Tombol HOME ditekan.\nPilih tindakan:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "Tombol POWER ditekan.\nPilih tindakan:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] KARTU SD", + "B_DRIVE_SD_CARD": "[B:] KARTU SD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Menu pengelola judul.\nPilih sumber judul:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Direktori bahasa tak ditemukan.\n(jalur bawaan: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Direktori naskah tak ditemukan.\n(jalur bawaan: 0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME - menu \"bahasa...\"\nPilih bahasa:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME - menu \"naskah...\"\nPilih naskah:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Direktori payload tak ditemukan.\n(jalur bawaan: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME - menu \"payload...\"\nPilih payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Kartu SD tiba-tiba terlepas!\n \nKartu SD harus dilepas mount\ndahulu agar data tidak hilang.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "Menu naskah %s.\nPilih naskah:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Dikompilasi jadi naskah auto-jalan\ntapi malah tidak ada naskah.\n \nKeliru!", + "KEYBOARD_CONTROLS_DETAILS": "Kendali Papan Ketik:\n \n←/→ - Geraki kursor\nR - Besar kecil (tahan)\nX - Hapus karakter\nY - Sisip karakter\nA - Kirim\nB - Batal\n \nSELECT - beralih ke\nprompt klasik", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Sentuh tanda bidik merah untuk\nkalibrasi layar sentuh.\n \nPakai stilus untuk hasil\nlebih bagus!", + "INVALID": "TAK ABSAH", + "TO_PROCEED_ENTER_THIS": "Untuk lanjut, tekan ini:", + "TO_PROCEED_HOLD_X": "Untuk lanjut, tahan :", + "N_MORE": " [%d lagi]", + "CANCEL": "batal", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) gulir cepat\nL - kosongkan data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - hapus karakter\nY - sisip karakter", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "Sisa %02llumnt%02lludtk", + "BRIGHTNESS_CONTROLS": "[←] Kurangi kecerahan\n[→] Tingkatkan kecerahan\n \n[X] Pakai penggeser volume\n[A] Atur kecerahan saat ini\n[B] Batal", + "SEARCHING_PLEASE_WAIT": "Mencari, mohon tunggu...", + "RENAME_TO_GOOD_NAME": "Ubah nama ke nama bagus?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "Penulisan kartu SD dikunci!\nTidak bisa lanjut.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "citra permainan", + "GAMECART_SAVES": "simpanan kartrid", + "IMAGES": "citra", + "MEMORY_AREAS": "area memori", + "SD_SYSTEM_DATA": "Data sistem SD", + "SD_CARD": "Kartu SD", + "RAM_DRIVE": "Kandar RAM", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Menulis ke %s sudah dikunci!\nBuka izinnya?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Membuka izin penulisan untuk\n%s tidak diizinkan.", + "ENABLE_BASE_WRITE": "Anda ingin mengaktifkan\nizin penulisan dasar.", + "ENABLE_SD_WRITE": "Anda ingin mengaktifkan\nizin penulisan kartu SD.", + "ENABLE_IMAGE_WRITE": "Anda ingin mengaktifkan\nizin penulisan citra.", + "ENABLE_RAM_DRIVE_WRITE": "Anda ingin mengaktifkan\nizin penulisan kandar RAM.", + "ENABLE_EMUNAND_0_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl0 EmuNAND.", + "ENABLE_SYSNAND_0_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl0 SysNAND.", + "ENABLE_EMUNAND_1_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl1 EmuNAND.\n \nIni mengizinkan data sistem\nyang bisa dipulih, data p'guna\n& simpanan bisa Anda ubah.", + "ENABLE_SYSNAND_1_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl1 SysNAND.\n \nIni mengizinkan data sistem,\npemasangan, data pengguna\n& simpanan bisa Anda ubah.", + "ENABLE_GAMECART_SAVE_WRITE": "Anda ingin mengaktifkan izin\npenulisan simpanan kartrid.", + "ENABLE_SYSNAND_2_WRITE": "!Harus hati-hati!\n \nAnda ingin mengaktifkan\nizin penulisan lvl2 SysNAND.\n \nIni mengizinkan data sistem\ntak terpulihkan bisa diubah!", + "ENABLE_MEMORY_WRITE": "!Harus hati-hati!\n \nAnda ingin mengaktifkan\nizin penulisan memori.\n \nMenulis ke area tertentu akan\nberakibat hasil yang tak terduga.", + "ENABLE_SD_DATA_WRITE": "!SANGAT TIDAK DIANJURKAN!\n \nAnda ingin mengaktifkan\nizin penulisan kartu SD.\n \nData di sini terenkripsi semua.\nDianjurkan memakai kandar\nA:/B: jika ingin memodifikasi\npemasangan, data p'guna &\nsimpanan permainan saja.", + "ENABLE_SYSNAND_3_WRITE": "!!INI PERINGATAN TERAKHIR!!\n ・ ・ ・ ・ ・ ・ ・ ・ ・ ・\nIzin penulisan lvl3 ke\nSysNAND akan diaktifkan.\n \nIni mengizikan pemasangan\nbootloader dan berkas sistem\nesensial bisa DITIMPA, dan/\natau membuat MATOT konsol!", + "UNLOCK_WRITE_NOT_ALLOWED": "Membuka izin penulisan tidak diizinkan.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Tidak bisa membuka izin tulis.\nCoba dengan GodMode9!", + "ERROR_SD_TOO_SMALL": "Galat: Ukuran kartu SD kekecilan", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!PERINGATAN!\n \nJika lanjut, kartu SD ini akan\ndiformat. SEMUA datanya\nakan dihapus permanen.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Formatkan kandar bonus?\nSEMUA datanya akan\ndihapus permanen.", + "FORMATTING_SD_PLEASE_WAIT": "Memformat kartu SD, mohon tunggu...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Memformat kandar, mohon tunggu...", + "ERROR_SD_CARD_IO_FAILURE": "Galat: I/O kartu SD, gagal", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "Berkas sedang di-mount.\nLepas mount untuk buka izin?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Galat: Tak bisa disuntik\nke berkas itu sendiri", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operasi akan menulis melebihi ujung berkas", + "NOT_ENOUGH_DATA_IN_FILE": "Tidak cukup data dalam berkas", + "CANCEL_IS_NOT_ALLOWED_HERE": "Di sini tidak diziinkan batal", + "B_DETECTED_CANCEL": "Terdeteksi tombol B. Batalkan?", + "ERROR_CANNOT_APPEND_FOLDER": "Galat: Tidak bisa membubuh folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Galat: Menimpa berkas dengan dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Galat: Menimpa dir dengan berkas", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Galat: Berkas destinasi tak bisa dibuka", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Galat: Tidak tersedia cukup ruang", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Galat: Hanya berkas FAT\nyang bisa dipindah", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Galat: Destinasi tadi\nbagian dari asalnya", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destinasi tadi sama seasalnya\nPilih nama yang lain?", + "CHOOSE_NEW_NAME": "Pilih nama baru", + "OVERWRITE_FILES": "Timpa berkas", + "SKIP_FILES": "Lewati berkas", + "OVERWRITE_ALL": "Timpa semua", + "SKIP_ALL": "Lewati semua", + "DESTINATION_ALREADY_EXISTS": "Destinasi sudah ada:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Pilih nama destinasi baru", + "COPY_OPERATION_IS_NOT_ALLOWED": "Penyalinan ini tidak diizinkan", + "DESTINATION_EQUALS_ORIGIN": "Destinasi tadi sama seasalnya", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entri tak ditemukan: %s\nSuntik ke %s saja?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "Berkas lebih kecil dari ruang yang ada:\n%s (%s)\n%s (%s)\nLanjutkan?", + "NO_USABLE_ENTRIES_FOUND": "Tidak ada entri yang bisa dipakai.", + "BEAT_NO_ERROR": "Tak ada galat", + "BEAT_END_OF_ACTION_LIST": "Ujung daftar tindakan", + "BEAT_ABORTED_BY_USER": "Digugurkan pengguna", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Gagal membaca/nulis berkas", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Berusaha menulis melebihi ujung berkas", + "BEAT_INVALID_PATCH_FILE": "Tambalan tak absah", + "BEAT_INVALID_INPUT_FILE": "Berkas masukan tak absah", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Checksum berkas\nkeluaran tak cocok", + "BEAT_FILE_CHECKSUM_FAILED": "Checksum berkas, gagal", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Diharapkan lebih banyak\ndata tambalan", + "BEAT_OUT_OF_MEMORY": "Kehabisan memori", + "BEAT_UNKNOWN_ERROR": "Galat tak diketahui", + "FAILED_TO_INITIALIZE_BPM_FILE": "Gagal me'inisialisasi berkas BPM:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Gagal me'inisialisasi berkas BPS:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Tambalan berhasil diterapkan", + "PATCHING_ABORTED_BY_USER": "Penambalan digugurkan pengguna", + "FAILED_TO_RUN_PATCH": "Gagal menjalankan tambal:\n%s", + "DECOMPRESSING_DOT_CODE": "Melepas pampat .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Melepas pampat .code...\nTombol B terdeteksi. Batalkan?", + "COMPRESSING_DOT_CODE": "Memampat .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Memampat.code...\nTombol B terdeteksi. Batalkan?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "Tambalan ini kemungkinan tidak ditujukan\nuntuk berkas ini.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "Kemungkinan Anda menerapkan tambalan\nke berkas keluaran.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "Tambalan secara teknis absah,\ntapi terlihat kacau atau amburadul.", + "PATCH_IS_INVALID": "Tambalan ini tidak absah.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "Ada satu atau dua berkas yang lebih dari 16MB.\nFormat IPS tidak mendukung ukuran itu.", + "REQUESTED_FILE_PATH_WAS_INVALID": "Jalur berkas yang diminta tidak absah.", + "PATCHING_CANCELED": "Penambalan dibatalkan.", + "NOT_ENOUGH_MEMORY": "Memori tidak cukup.", + "REGION_AMERICAS": "Amerika", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brazil", + "REGION_CHINA": "Tiongkok", + "REGION_EUROPE": "Eropa", + "REGION_FRANCE": "Prancis", + "REGION_GERMANY": "Jerman", + "REGION_ITALY": "Italia", + "REGION_JAPAN": "Jepang", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spanyol", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Tak diketahui", + "REGION_UNITED_KINGDOM": "Inggris Raya", + "REGION_MIDDLE_EAST": "Timur Tengah", + "GENERATING_QR_CODE": "Membuat kode QR...", + "REINITIALIZING_SD_CARD": "Inisialisasi ulang kartu SD...", + "DUMPING_STATE_TO_SD_CARD": "Men-dump status ke kartu SD...", + "PRESS_POWER_TO_TURN_OFF": "Tekan POWER untuk matikan daya", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Membersihkan judul, mohon tunggu...", + "ERROR_NOT_NCCH_FILE": "Galat: Bukan berkas NCCH", + "ERROR_FILE_IS_TOO_SMALL": "Galat: Ukuran berkas kekecilan", + "ATTEMPT_FIX_THIS_TIME": "Kali ini coba diperbaiki", + "ATTEMPT_FIX_ALWAYS": "Selalu coba diperbaiki", + "ABORT_VERIFICATION": "Gugurkan verifikasi", + "ERROR_BAD_CRYPTO_FLAGS": "Galat: Panji crypto buruk", + "ERROR_BAD_EXEFS_HEADER": "Galat: Header ExeFS buruk", + "ERROR_MISSING_EXTHEADER": "Galat: ExtHeader hilang", + "ERROR_CRYPTO_NOT_SET_UP": "Galat: Crypto belum disiapkan", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nVerifikasi NCCH, gagal:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "gagal", + "ERROR_NOT_NCSD_FILE": "Galat: Bukan berkas NCSD", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nKonten%lu (%08lX@%08lX):\nVerifikasi, gagal", + "ERROR_PROBABLY_NOT_CIA_FILE": "Galat: Mungkin bukan berkas CIA", + "ERROR_TMD_PROBABLY_CORRUPTED": "Galat: TMD mungkin rusak", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerifikasi, gagal", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Galat: Titlekey CDN tak ditemukan", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "Konten DLC tidak ada\n \nAbaikan semua dan lanjut?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nHash bagian %lu tak cocok", + "ARM9_ENTRYPOINT_IS_MISSING": "Titik masuk ARM9 hilang", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Peringatan: Titik masuk ARM11 hilang", + "ERROR_NOT_A_BOSS_FILE": "Galat: Bukan berkas BOSS", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "Hash payload BOSS tak cocok.\n \nMau coba perbaiki?", + "GENERIC_TICKET_PIRATE_LEGIT": "Ticket generik (\"autentik bajakan\")", + "PERSONALIZED_TICKET_LEGIT": "Ticket tepersonalisasi (autentik)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nTicket autentik dipersonalisasi.\nIni tidak dianjurkan dipakai.\nPilih tindakan bawaan:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey tak ditemukan.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD di TAD tidak autentik.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD tidak autentik.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Konten ini rusak", + "INSERT_CONTENT_FAILED": "Menyisip konten, gagal", + "INSTALL_CONTENT_FAILED": "Memasang konten, gagal", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Galat pasang:\nSistem ini kehilangan satu\natau lebih berkas .db.\n \nMungkin kartu SD hilang\natau belum inisialiasi?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Galat pasang:\nSistem ini kehilangan\nberkas ticket.db.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Judul dilewati:\nJudul ber-ID 0004008C000CBD00\nperlu panji kompilator khusus.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Galat: Ticket terdaftar-palsu\n \nHanya ticket terdaftar-absah\nyang bisa dipasang ke sistem.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nGalat: CID tak diketahui %08lX\n \nTicker ini bukan milik\nkonsol 3DS ini.", + "INSTALLING_TICKET": "Memasang ticket...", + "POSSIBLY_BROKEN": "Kemungkinan Rusak", + "PERSONAL_LEGIT": "Autentik Pribadi", + "PERSONAL_LEGIT_DLC": "DLC Autentik Pribadi", + "PERSONAL_PIRATE_LEGIT": "Autentik Bajakan Pribadi", + "PERSONAL_PIRATE_LEGIT_DLC": "DLC Autentik Bajakan Pribadi", + "PERSONAL_CUSTOM": "Kustom Pribadi", + "PERSONAL_CUSTOM_DLC": "DLC Kustom Pribadi", + "UNIVERSAL_LEGIT": "Autentik Universal", + "UNIVERSAL_LEGIT_DLC": "DLC Autentik Universal", + "UNIVERSAL_PIRATE_LEGIT": "Autentik Bajakan Universal", + "UNIVERSAL_PIRATE_LEGIT_DLC": "DLC Autentik Bajakan Universal", + "UNIVERSAL_CUSTOM": "Kustom Universal", + "UNIVERSAL_CUSTOM_DLC": "DLC Kustom Universal", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Konten di CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Konten di TMD: %lu", + "CONSOLE_ID_N": "ID Konsol: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\nJudul %s %s\n \nID judul: %016llX\nVersi judul: %lu.%lu.%lu\nUkuran konten: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerifikasi: %s", + "STATE_LEGIT": "autentik", + "STATE_ILLEGIT": "tak autentik", + "STATE_UNKNOWN": "tak diketahui", + "STATE_INVALID": "tak absah", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "menunda\n \nLanjut dengan verifikasi?", + "STATE_PASSED": "lolos", + "STATE_FAILED": "gagal", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Berkas keluaran sudah ada.\nPerbarui ini?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Memperbaiki CMAC, mohon tunggu...", + "NCSD_HEADER_IS_NOT_VALID": "Header NCSD tidak absah", + "NAND_DUMP_MISSING_DATA": "Dump dari NAND ada data hilang", + "ERROR_CTR_MBR_IS_CORRUPT": "Galat: MBR di CTR rusak", + "ERROR_TWL_MBR_IS_CORRUPT": "Galat: MBR di TWL rusak", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nGalat: Partisi CTR%lu rusak", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nGalat: Partisi TWL%lu rusak", + "NO_VALID_FIRM_FOUND": "Tidak ada FIRM yang absah", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Galat: Dump dari NAND, rusak.\nTetap lanjutkan?", + "ERROR_SYSTEM_IS_LOCKED": "Galat: Sistem dikunci.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Cadangan berkas esensial diperlukan.\nMau buat baru?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!PERINGATAN!\n \nProses ini akan menimpa SysNAND\ndengan dump yang ditaruh.\n \n(B9S/A9LH akan dibiarkan utuh)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Citra NCSD sudah rusak atau diubah suai,\npemulihan aman tidak akan bisa!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "PERINGATAN!\n \nNCSD berbeda antara citra dan lokal,\nperlu izin tulis yang lebih tinggi\n \nTanggung risiko dan lanjutkan?", + "NOT_AN_INSTALLABLE_FIRM": "Bukan FIRM bisa dipasang.", + "FIRM_LOAD_VERIFY_ERROR": "Muat/verifikasi FIRM, galat.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu tak ditemukan atau kekecilan.", + "SECTOR_0X96_CRYPTO_FAIL": "Crypto sektor 0x96, gagal.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sektor 0x96 rusak.\n \nSediakan \"secret_sector.bin\"\nuntuk perbaiki sektor 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sektor 0x96 rusak.\n \nPerbaiki sektor 0x96 selama\npemasangan?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!PERINGATAN!\n \nJika lanjut, FIRM yang ditaruh\nakan dipasang ke SysNAND\ndan menyuntik sighax.\n \nMemasang FIRM tak didukung\nakan membuat MATOT konsol!", + "INSTALLING_FIRM_PLEASE_WAIT": "Memasang FIRM, mohon tunggu...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal menulis sektor 0x96.\nPerbaiki sebelum di-boot ulang!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal menulis FIRM%lu.\nPerbaiki sebelum di-boot ulang!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Memeriksa pemasangan, mohon tunggu...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal memverif' sektor 0x96.\nPerbaiki sebelum di-boot ulang!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal memverif' FIRM%lu.\nPerbaiki sebelum di-boot ulang!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "%s sempurna telah terpasang!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nBukan citra %s sempurna.\nTak bisa dipasang ke NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nGagal menulis %s ke NAND!", + "USE_L_R_TO_SAVE": "(simpan dengan L+R)", + "EASTER_NOT_FOUND": "(%s tak ditemukan)", + "BUILDING_TO_OUT_ARG": "Membina ke %s:\n%s ...", + "EJECT_SD_CARD": "Keluarkan kartu SD...", + "INSERT_SD_CARD": "Sisipkan kartu SD...", + "SCRIPTERR_UNKNOWN_CMD": "cmd tak diketahui", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "ada # arg buruk", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "panji tak dikenali", + "SCRIPTERR_ILLEGAL_FLAG": "panji ilegal", + "SCRIPTERR_UNRESOLVED_QUOTES": "kutipan blm dipecahkan", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "terlalu banyak argumen", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "perluas argumen, gagal", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "galat kata 'not'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "galat sintaks setelah 'if'", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' tanpa 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "galat sintaks setelah 'elif'", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' tanpa 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' tanpa 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' di dalam 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "dir tak ditemukan", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' tanpa 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' tanpa 'for'", + "SCRIPTERR_FORPATH_ERROR": "galat forpath", + "SCRIPTERR_LABEL_NOT_FOUND": "label tak ditemukan", + "SCRIPTERR_USER_ABORT": "gugurkan pengguna", + "SCRIPTERR_KEY_NOT_PRESSED": "tombol belum ditekan", + "SCRIPTERR_OUT_OF_MEMORY": "kehabisan memori", + "SCRIPTERR_VAR_FAIL": "peubah gagal", + "SCRIPTERR_FORBIDDEN_DRIVE": "kandar terlarang", + "SCRIPTERR_INVALID_PATH": "jalur tidak absah", + "SCRIPTERR_FILESELECT_ABORT": "gugurkan pilih-berkas", + "SCRIPTERR_DIRSELECT_ABORT": "gugurkan pilih-dir", + "SCRIPTERR_SET_FAIL": "atur gagal", + "SCRIPTERR_CHAR_NOT_FOUND": "char tak ditemukan", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2] bukan huruf char", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2] harus 2 karakter", + "SCRIPTERR_ARG_MATCH": "arg cocok", + "SCRIPTERR_NO_ARG_MATCH": "tak ada arg cocok", + "SCRIPTERR_PERMISSION_FAIL": "izin gagal", + "SCRIPTERR_COPY_FAIL": "salin gagal", + "SCRIPTERR_MOVE_FAIL": "pindah gagal", + "SCRIPTERR_INJECT_FAIL": "gagal suntik", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte gagal", + "SCRIPTERR_FILL_FAIL": "mengisi gagal", + "SCRIPTERR_BAD_FILESIZE": "ukuran berkas buruk", + "SCRIPTERR_CREATE_DUMMY_FILE": "buat brks kosong gagal", + "SCRIPTERR_REMOVE_FAIL": "menghapus gagal", + "SCRIPTERR_MAKEDIR_FAIL": "buat dir gagal", + "SCRIPTERR_MOUNT_FAIL": "mount gagal", + "SCRIPTERR_FIND_FAIL": "cari gagal", + "SCRIPTERR_FINDNOT_FAIL": "cari not, gagal", + "SCRIPTERR_NO_SIZE_GIVEN": "tak ada ukuran", + "SCRIPTERR_SIZE_TOO_BIG": "ukuran terlalu besar", + "SCRIPTERR_READ_FAIL": "baca gagal", + "SCRIPTERR_CONVERSION_FAIL": "konversi gagal", + "SCRIPTERR_INVALID_DATA": "data tidak absah", + "SCRIPTERR_WRITE_FAIL": "tulis gagal", + "SCRIPTERR_SHA_ARG0_FAIL": "arg0 sha gagal", + "SCRIPTERR_SHA_ARG1_FAIL": "arg1 sha gagal", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "sha tidak cocok", + "SCRIPTERR_SHA_WRITE_FAIL": "tulis sha gagal", + "SCRIPTERR_FILE_WRITE_FAIL": "tulis berkas gagal", + "SCRIPTERR_FIXCMAC_FAILED": "perbaiki cmac, gagal", + "SCRIPTERR_VERIFICATION_FAILED": "verifikasi, gagal", + "SCRIPTERR_DECRYPT_FAILED": "dekripsi, gagal", + "SCRIPTERR_ENCRYPT_FAILED": "enkripsi, gagal", + "SCRIPTERR_BUILD_CIA_FAILED": "bina CIA, gagal", + "SCRIPTERR_INSTALL_GAME_FAILED": "pasang p'mainan, gagal", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": "tidak terdapat .code", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": "ekstraksi .code, gagal", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": "pemampatan .code, gagal", + "SCRIPTERR_BUILD_FAILED": "bina, gagal", + "SCRIPTERR_UNKNOWN_FILE": "berkas tak diketahui", + "SCRIPTERR_APPLY_IPS_FAILD": "menerap IPS, gagal", + "SCRIPTERR_APPLY_BPS_FAILED": "menerap BPS, gagal", + "SCRIPTERR_APPLY_BPM_FAILED": "menerap BPM, gagal", + "SCRIPTERR_TEXTVIEWER_FAILED": "textviewer, gagal", + "SCRIPTERR_BAD_DUMPSIZE": "ukuran dump buruk", + "SCRIPTERR_CART_INIT_FAIL": "init kartrid gagal", + "SCRIPTERR_CART_DUMP_FAILED": "men-dump kartrid gagal", + "SCRIPTERR_NOT_A_DIR": "bukan dir", + "SCRIPTERR_FILE_NOT_FOUND": "berkas tak ditemukan", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "bukan firm bisa di-boot", + "SCRIPTERR_SD_NOT_MOUNTED": "SD tidak di-mount", + "SCRIPTERR_UNKNOWN_ERROR": "galat tak diketahui", + "SCRIPTERR_COMMAND_SUCCESS": "perintah, berhasil", + "SCRIPTERR_CONTROL_FLOW_ERROR": "aliran kendali galat", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "syarat yang blm selesai", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "pesan galat gagal", + "ERROR_INVALID_TEXT_DATA": "Galat: Data teks tak absah", + "TEXTVIEWER_CONTROLS_DETAILS": "Kendali Textviewer:\n \n↑↓→←(+R) - Gulir\nR+Y - Ganti bungkus kata\nR+X - Ke barisan #\nB - Keluar\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "Barisan saat ini: %i\nMasukkan barisan baru.", + "PREVIEW_DISABLED": "(pratayang dinonaktif)", + "PATH_LINE_N_ERR_LINE": "%s\nbarisan %lu: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "ujung naskah: 'if' blm dipecahkan", + "END_OF_SCRIPT_UNRESOLVED_FOR": "ujung naskah: 'for' blm dipecahkan", + "SYSINFO_MODEL": "Model: %s (%s)\n", + "SYSINFO_SERIAL": "Serial: %s\n", + "SYSINFO_REGION_SYSTEM": "Daerah (sistem): %s\n", + "SYSINFO_REGION_SALES": "Daerah (penjualan): %s\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "Tanggal manufaktur SoC: %s\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "Tanggal perakitan sistem: %s\n", + "SYSINFO_ORIGINAL_FIRMWARE": "Firmware asli: %s\n", + "SYSINFO_FRIENDCODE_SEED": "Seed kode teman: %s\n", + "SYSINFO_SD_KEYY": "KeyY SD: %s\n", + "SYSINFO_NAND_CID": "CID NAND: %s\n", + "SYSINFO_SD_CID": "CID SD: %s\n", + "SYSINFO_SYSTEM_ID0": "ID0 sistem: %s\n", + "SYSINFO_SYSTEM_ID1": "ID1 sistem: %s\n", + "SORTING_TICKETS_PLEASE_WAIT": "Mengurut ticket, mohon tunggu...", + "LUA_NOT_INCLUDED": "This build of GodMode9 was\ncompiled without Lua support." +} diff --git a/resources/languages/it.json b/resources/languages/it.json new file mode 100644 index 000000000..39493f4c5 --- /dev/null +++ b/resources/languages/it.json @@ -0,0 +1,636 @@ +{ + "GM9_LANGUAGE": "Italiano", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX/%3$02lX/%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM troppo grande, non può essere avviato", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nAttenzione: Non avviare FIRM\nAvviare FIRM?", + "NOT_BOOTABLE_FIRM": "Non un FIRM avviabile.", + "FIRM_ENCRYPTED": "FIRM è criptato.\n\nDecriptare prima dell'avvio?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Fare una copia in %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Provare comunque ad avviare il sistema", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Attenzione: Tentativo di avvio da una posizione\nnon supportato.", + "ROOT": "[radice]", + "LOADING": "CARICAMENTO...", + "PANE_N": "PANE #%lu", + "CURRENT": "CORRENTE", + "DIR": "(ele)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Gioco Virtuale)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtuale)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtuale)", + "IMAGE_FAT": "(Immagine FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtuale)", + "MEMORY_VIRTUAL": "(Memoria Virtuale)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtuale)", + "VRAM_VIRTUAL": "(VRAM Virtuale)", + "SEARCH": "(Ricerca)", + "TITLEMANAGER_VIRTUAL": "(TitoloManager Virtuale)", + "LAB_SDCARD": "SDCARD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "GAME IMAGE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB IMAGE", + "LAB_BDRI_IMAGE": "BDRI IMAGE", + "LAB_DISA_DIFF_IMAGE": "IMMAGINE DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "MEMORIA VIRTUALE", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUALE", + "LAB_TITLE_MANAGER": "GESTORE TITOLI", + "LAB_LAST_SEARCH": "ULTIMA RICERCA", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "SENZA ETICHETTA", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[APPUNTI]", + "PLUS_N_MORE": "+ %lu altro", + "MARK_DELETE_COPY": "L - MARCA I FILE (usa con ↑↓→←)\nX - ELIMINA / [+R] RINOMINA file\nY - COPIA i file / [+R] CREA voce\n", + "MARK_DELETE_PASTE": "L - MARCA I FILE (usa con ↑↓→←)\nX - ELIMINA / [+R] RINOMINA file\nY - COPIA i file / [+R] CREA voce\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Riabilita i permessi di scrittura\n", + "UNMOUNT_IMAGE": "R+X - Smonta immagine\n", + "UNMOUNT_SD": "R+B - Smonta scheda SD\n", + "REMOUNT_SD": "R+\\B - Rimonta scheda SD", + "DIRECTORY_OPTIONS": "R+A - Opzioni cartella\n", + "DRIVE_OPTIONS": "R+A - Opzioni Drive\n", + "MAKE_SCREENSHOT": "R+L - Cattura schermata", + "PREV_NEXT_PANE": "R+←→ - Passa al precedente/successivo", + "CLEAR_CLIPBOARD": "SELEZIONA - Cancella appunti\n", + "RESTORE_CLIPBOARD": "SELECT - Ripristina appunti\n", + "REBOOT_POWEROFF_HOME": "START - Riavvia / [+R] Spegni\npremi HOME per il menu HOME", + "NO_EMUNAND": "Nessun EmuNAND", + "REDNAND_SIZE_MIN": "Dimensione RedNAND (min)", + "GW_EMUNAND_SIZE_FULL": "Dimensione GW EmuNAND (max)", + "MULTINAND_SIZE_2X": "Dimensione MultiNAND (2x)", + "MULTINAND_SIZE_3X": "Dimensione MultiNAND (3x)", + "MULTINAND_SIZE_4X": "Dimensione MultiNAND (4x)", + "USER_INPUT": "Input utente...", + "AUTO": "Auto", + "16KB_CLUSTERS": "Cluster da 16KB", + "32KB_CLUSTERS": "Cluster da 32KB", + "64KB_CLUSTERS": "Cluster da 64KB", + "SD_NOT_DETECTED": "Errore: Scheda SD non rilevata.", + "FORMAT_SD_CHOOSE_EMUNAND": "Formatta scheda SD (%lluMB)?\nScegli dimensione EmuNAND:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "La dimensione della scheda SD è %lluMB.\nInserisci la dimensione di EmuNAND (MB) qui:", + "FORMAT_SD_CHOOSE_CLUSTER": "Formatta scheda SD (%lluMB)?\nScegli la dimensione del cluster:", + "FORMAT_SD_ENTER_LABEL": "Formatta SD card (%lluMB)?\nInserisci nome:", + "FORMAT_SD_FAILED": "Formattazione non riuscita!", + "REDNAND_TYPE": "Tipo di RedNAND", + "REDNAND_TYPE_MULTI": "Tipo di RedNAND (multi)", + "REDNAND_TYPE_SINGLE": "Tipo di RedNAND (singolo)", + "GW_EMUNAND_TYPE": "Tipo GW EmuNAND", + "DONT_SET_UP": "Non impostare", + "CHOOSE_EMUNAND_TYPE": "Scegliere il tipo di EmuNAND da impostare:", + "CLONE_SYSNAND_TO_REDNAND": "Clonare SysNAND in RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Clonazione di SysNAND su EmuNAND: fallita!", + "PRESS_A_TO_CONTINUE": "Premere per continuare", + "HEXEDITOR_CONTROLS": "Controlli Hexeditor:\n\n↑↓→←(+R) - Pergamena\nR+Y - Vista dell'interruttore\nX - Ricerca / andare...\nA - Entrare in modalità di modifica\nA+↑↓→← - Valore di modifica\nB - Uscita", + "NOT_FOUND": "Non trovato!", + "GO_TO_OFFSET": "Andare a compensare", + "SEARCH_FOR_STRING": "Cerca la stringa", + "SEARCH_FOR_DATA": "Ricerca dei dati", + "CURRENT_OFFSET_SELECT_ACTION": "Offset attuale: %08lX\nSelezionare l'azione:", + "CURRENT_OFFSET_ENTER_NEW": "Offset attuale: %08lX\nInserire il nuovo offset qui sotto.", + "ENTER_SEARCH_REPEAT_SEARCH": "Immettere la stringa di ricerca qui sotto.\n(R+X per ripetere la ricerca)", + "MADE_EDITS_SAVE_CHANGES": "Hai apportato modifiche in %lu luogo(hi).\nScrivere le modifiche sul file?", + "FAILED_WRITING_TO_FILE": "Scrittura fallita sul file!", + "CALCULATING_SHA_FAILED": "Calcolo di SHA-%s: fallito!", + "SHA_VERIFICATION_PASSED": "\nVerifica SHA: superata!", + "SHA_VERIFICATION_FAILED": "\nVerifica SHA: fallita", + "IDENTICAL_WITH_PREVIOUS": "\n\nIdentico al file precedente:", + "WRITE_SHA_FILE": "\n\nScrivere il file .SHA?", + "WRITE_SHA1_FILE": "\n\nScrivere il file .SHA1?", + "CALCULATING_CMAC_FAILED": "Calcolo del CMAC: fallito!", + "CMAC_VERIFICATION_PASSED": "Verifica CMAC: superata!", + "CMAC_VERIFICATION_FAILED": "Verifica CMAC: fallita!", + "FIX_CMAC_IN_FILE": "\n\nCorreggere il CMAC nel file?", + "FIXING_CMAC_FAILED": "Correzione del CMAC: fallita!", + "COPY_ALL_SELECTED_ITEMS": "Copiare tutti gli elementi %lu selezionati?", + "FAILED_COPYING_ITEM": "Copia dell'elemento non riuscita", + "ITEMS_COPIED_TO_OUT": "Gli elementi di %lu copiati in %s", + "PATH_COPIED_TO_OUT": "%s\nCopiato in %s", + "CART_INIT_FAILED": "L'avvio del carrello è fallito!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Carrello: %s\nDimensione rilevata: %s\n \nDimensione del dump in ingresso sotto.", + "NDS_CART_DECRYPT_SECURE_AREA": "Carrello: %s\nRilevato carrello NDS\nDecriptare l'area protetta?", + "FAILED_DUMPING_CART": "%s\nCarrello di scarico fallito", + "PATH_DUMPED_TO_OUT": "%s\nScaricato in %s", + "CREATED": "creato", + "MODIFIED": "modificato", + "ANALYZING_DRIVE": "Analisi dell'unità, attendere...", + "ANALYZING_DIR": "Analisi della dir, attendere...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu file e %lu sottodirectory\ndimensione totale %s\n \nspazio libero: %s\nspazio utilizzato: %s\nspazio totale: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu file e %lu sottodirectory\ndimensione totale %s", + "FILESIZE_X": "dimensionefile: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sdi sola lettura [%c] %snascosto\n[%c] %ssistema [%c] %sarchivio\n[%c] %svirtuale\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← per modificare gli attributi)", + "A_TO_CONTINUE": "( per continuare)", + "A_APPLY_B_CANCEL": "( per applicare, per annullare)", + "A_YES_B_NO": "( sì, no)", + "A_SELECT_B_CANCEL": "( seleziona, annulla)", + "HOLD_B_TO_CANCEL": "(tenere premuto B per annullare)", + "FAILED_TO_SET_ATTRIBUTES": "Impossibile impostare gli attributi!", + "NAND_IMAGE_OPTIONS": "Opzioni immagine NAND...", + "CTRNAND_OPTIONS": "Opzioni CTRNAND...", + "MOUNT_FAT_IMAGE": "Monta come immagine FAT", + "CIA_IMAGE_OPTIONS": "Opzioni di immagine CIA...", + "NCSD_IMAGE_OPTIONS": "Opzioni immagine NCSD...", + "NCCH_IMAGE_OPTIONS": "Opzioni immagine NCCH...", + "MOUNT_AS_EXEFS_IMAGE": "Monta come immagine EXEFS", + "MOUNT_AS_ROMFS_IMAGE": "Monta come immagine ROMFS", + "TMD_FILE_OPTIONS": "Opzioni file TMD...", + "TMD_CDN_OPTIONS": "Opzioni TMD/CDN...", + "TMD_TWL_OPTIONS": "Opzioni TMD/TWL...", + "MANAGE_TITLE": "Gestisci Titolo...", + "BOSS_FILE_OPTIONS": "Opzioni file BOSS...", + "DECRYPT_NUS_CDN_FILE": "Decifra il file NUS/CDN", + "SHOW_SMDH_TITLE_INFO": "Mostra info dell'SMDH", + "NDS_IMAGE_OPTIONS": "Opzioni immagine NDS...", + "GBA_IMAGE_OPTIONS": "Opzioni immagine GBA...", + "TICKET_OPTIONS": "Opzioni ticket...", + "TAD_IMAGE_OPTIONS": "Opzioni immagine TAD...", + "SHOW_3DSX_TITLE_INFO": "Mostra info titolo 3DSX", + "FIRM_IMAGE_OPTIONS": "Opzioni immagine FIRM...", + "AGBSAVE_OPTIONS": "Opzioni AGBSAVE...", + "DUMP_GBA_VC_SAVE": "Esegui il dump del salvataggio GBA VC", + "TICKET_DB_OPTIONS": "Opzioni Ticket.db...", + "MOUNT_AS_DIFF_IMAGE": "Monta come immagine DIFF", + "MOUNT_AS_DISA_IAMGE": "Monta come immagine DISA", + "INSTALL_CIFINISH_BIN": "Installa cifinish.bin", + "TITLEKEY_OPTIONS": "Opzioni ticket...", + "AESKEYDB_OPTIONS": "Opzioni AESkeydb...", + "BUILD_X": "Costruisci %s", + "NCCHINFO_OPTIONS": "Opzioni NCCHinfo...", + "EXECUTE_GM9_SCRIPT": "Esegui script GM9", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Opzioni caratteri...", + "LANGUAGE_OPTIONS": "Opzioni Lingua...", + "VIEW_PNG_FILE": "Visualizza file PNG", + "REBUILD_NCSD_HEADER": "Ricostruisci l'intestazione NCSD", + "SHOW_IN_HEXEDITOR": "Mostra nel Hexeditor", + "CALCULATE_SHA256": "Calcola SHA-256", + "CALCULATE_SHA1": "Calcola SHA-1", + "SHOW_FILE_INFO": "Mostra info del file", + "SHOW_IN_TEXTVIEWER": "Mostra in visualizzatore di testo", + "CALCULATE_CMAC": "Calcola CMAC", + "COPY_TO_OUT": "Copia in %s", + "DUMP_TO_OUT": "Esporta in %s", + "INJECT_DATA_AT_OFFSET": "Inject dati @offset", + "OPEN_THIS_FOLDER": "Apri questa cartella", + "OPEN_CONTAINING_FOLDER": "Apri cartella contenente", + "OPEN_TITLE_FOLDER": "Apri cartella titolo", + "PATH_N_FILES_SELECTED": "%s\n(%lu file selezionati)", + "CHECK_CURRENT_CMAC_ONLY": "Controlla solo CMAC corrente", + "VERIFY_CMAC_FOR_ALL": "Verificare il CMAC per tutti", + "FIX_CMAC_FOR_ALL": "Fissare il CMAC per tutti", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu file ok/fissati/totali\n\"%lu/%lu\" non hanno CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu file verificati ok\n%lu/%lu file sistemati", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu file verificati ok\n%lu/%lu non hanno CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu file verificati ok", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Fare l'inject di dati da %s?\nSpecifica l'offset sotto.", + "FAILED_INJECTING_PATH": "Injecting fallito %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Monta file CXI/NDS sul disco", + "MOUNT_IMAGE_TO_DRIVE": "Monta l'immagine sul disco", + "RESTORE_SYSNAND_SAFE": "Ripristino di SysNAND (sicuro)", + "UPDATE_EMBEDDED_BACKUP": "Aggiorna backup incorporato", + "SHOW_TITLE_INFO": "Visualizza informazioni del titolo", + "DECRYPT_FILE": "Decripta il file (...)", + "DECRYPT_FILE_OUT": "Decripta il file (%s)", + "ENCRYPT_FILE": "Cripta il file (...)", + "ENCRYPT_FILE_OUT": "Cripta il file (%s)", + "BUILD_CIA_FROM_FILE": "Crea il CIA dal file", + "BUILD_CIA_STANDARD": "Crea CIA (standard)", + "BUILD_CIA_LEGIT": "Crea CIA (legit)", + "DUMP_CXI_NDS_FILE": "Dumpa file CXI/NDS", + "INSTALL_GAME_IMAGE": "Installa immagine del gioco", + "INSTALL_TICKET": "Installa il ticket", + "DUMP_TICKET_FILE": "Dumpa il file del ticket", + "UNINSTALL_TITLE": "Disinstalla il titolo", + "VERIFY_FILE": "Verifica il file", + "TRANSFER_IMAGE_TO_CTRNAND": "Trasferisci l'immagine nella CTRNAND", + "INJECT_TO_H_AND_S": "Inject a I&S", + "TRIM_FILE": "Taglia il file", + "RENAME_FILE": "Rinomina il file", + "BUILD_XORPADS_SD": "Crea XORpads (Output SD)", + "BUILD_XORPADS_INPLACE": "Crea XORpads (nell'attuale posizione)", + "EXTRACT_X": "Estratto %s", + "INIT_X": "Init %s", + "INSTALL_X": "Installa %s", + "INSTALL_FIRM": "Installa FIRM", + "BOOT_FIRM": "", + "SET_AS_ACTIVE_FONT": "Imposta come carattere attivo", + "SET_AS_ACTIVE_LANGUAGE": "Imposta come lingua attiva", + "DUMP_BA_VC_SAVE": "Copia il salvataggio GBA VC", + "INJECT_GBA_VC_SAVE": "Inietta il salvataggio GBA VC", + "SET_AS_DEFAULT": "Imposta come predefinito", + "MOUNTING_IMAGE_FAILED": "Montaggi immagine: fallito", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nMontato come unità %s\nInserire il percorso ora?", + "DECRYPT_TO_OUT": "Decrypt to %s", + "DECRYPT_INPLACE": "Decrypt inplace", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Try to decrypt all %lu selected files?", + "TRYING_TO_DECRYPT_N_FILES": "Trying to decrypt %lu files...", + "DECRYPTION_FAILED_CONTINUE": "Decryption failed\n \nContinue?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files decrypted ok\n%lu/%lu not encrypted\n%lu/%lu not of same type", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu files decrypted ok", + "N_FILES_WRITTEN_TO_OUT": "%lu files written to %s", + "FILE_NOT_ENCRYPTED": "File is not encrypted", + "DECRYPTION_SUCCESS": "Decryption success", + "DECRYPTION_FAILED": "Decryption failed", + "PATH_DECRYPTED_TO_OUT": "%s\nDecrypted to %s", + "ENCRYPT_TO_OUT": "Encrypt to %s", + "ENCRYPT_INPLACE": "Encrypt inplace", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Try to encrypt all %lu selected files?", + "TRYING_TO_ENCRYPT_N_FILES": "Trying to encrypt %lu files...", + "ENCRYPTION_FAILED_CONTINUE": "Encryption failed\n \nContinue?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files encrypted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu files encrypted ok", + "ENCRYPTION_SUCCESS": "Encryption success", + "ENCRYPTION_FAILED": "Encryption failed", + "PATH_ENCRYPTED_TO_OUT": "%s\nEncrypted to %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Try to process all %lu selected files?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nBuild %s failed\n \nContinue?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss built ok\n%lu/%lu not of same type", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss built ok", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu file(s) failed conversion.\nVerification is recommended.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s built to %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s build failed", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "file failed conversion.\n \nVerify now?", + "VERIFICATION_SUCCESS": "Verification success", + "VERIFICATION_FAILED": "Verification failed", + "CONTENT_IS_MISSING": "Content is missing", + "INSTALL_TO_SYSNAND": "Install to SysNAND", + "INSTALL_TO_EMUNAND": "Install to EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Try to install all %lu selected files?", + "TRYING_TO_INSTALL_N_FILES": "Trying to install %lu files...", + "INSTALL_FAILED_CONTINUE": "Install failed\n \nContinue?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu file installati ok\n%lu/%lu non dello stesso tipo", + "N_OF_N_FILES_INSTALLED": "%lu/%lu file installati ok", + "INSTALL_SUCCESS": "Successo dell'installazione", + "INSTALL_FAILED": "Installazione fallita", + "FILE_FAILED_INSTALL_VERIFY_NOW": "l'installazione dei file è fallita\n \nVerificare ora?", + "KEEP_TICKET_AND_SAVEGAME": "Mantieni ticket e salvataggi", + "UNINSTALL_EVERYTHING": "Disinstalla tutto", + "ABORT_UNINSTALL": "Interrompi la disinstallazione", + "UNINSTALL_N_SELECTED_TITLES": "Disinstallare %lu i titoli selezionati?", + "UNINSTALL_SELECTED_TITLE": "Disinstallare il titolo selezionato?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu titoli disinstallati", + "UNINSTALLING_PLEASE_WAIT": "Disinstallazione, attendere prego...", + "UNINSTALL_FAILED": "Disinstallazione fallita!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Provare a verificare tutti %lu i file selezionati?", + "VERIFICATION_FAILED_CONTINUE": "Verifica fallita\n \nContinuare?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu file verificati ok\n%lu/%lu non dello stesso tipo", + "VERIFYING_FILE_PLEASE_WAIT": "Verifying file, please wait...", + "NAND_VALIDATION_SUCCESS": "NAND validation success", + "NAND_VALIDATION_FAILED": "NAND validation failed", + "DUMP_FOR_N_SELECTED_FILES": "Provare a verificare tutti %lu i file selezionati?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumped to %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumped to %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit ticket not found.\n \nDump anyways?", + "DUMP_TICKET_FAILED": "Dump ticket failed!", + "BUILDING_X": "Building %s...", + "BUILDING_X_SYSNAND": "Building %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Building %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu files processed", + "BUILD_DATABASE_SUCCESS": "Build database success.", + "BUILD_DATABASE_FAILED": "Build database failed.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Try to trim all %lu selected files?", + "TRIMMING_FAILED_CONTINUE": "Trimming failed\n \nContinue?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu files trimmed ok\n%lu/%lu not of same type\n%s saved", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu files trimmed ok\n%s saved", + "FILE_CANT_BE_TRIMMED": "File can't be trimmed.", + "FILE_ALREADY_TRIMMED": "File is already trimmed.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?", + "TRIMMING_FAILED": "Trimming failed.", + "PATH_TRIMMED_BY_X": "%s\nTrimmed by %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Try to rename all %lu selected files?", + "N_OF_N_RENAMED": "%lu/%lu renamed ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Could not rename to good name", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S inject", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S inject", + "H_AND_S_INJECT_SUCCESS": "H&S inject success", + "H_AND_S_INJECT_FAILURE": "H&S inject failure", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Try to extract all %lu selected files?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files extracted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu files extracted ok", + "EXTRACTING_DOT_CODE": "Extracting .code, please wait...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extracted to %s", + "DOT_CODE_EXTRACT_FAILED": ".code extract failed", + "TRANSFER_TO_SYSNAND": "Transfer to SysNAND", + "TRANSFER_TO_EMUNAND": "Transfer to EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND transfer success", + "CTRNAND_TRANSFER_FAILED": "CTRNAND transfer failed", + "NO_VALID_DESTINATION_FOUND": "No valid destination found", + "NAND_RESTORE_SUCCESS": "NAND restore success", + "NAND_RESTORE_FAILED": "NAND restore failed", + "REBUILD_NCSD_SUCCESS": "Rebuild NCSD success", + "REBUILD_NCSD_FAILED": "Rebuild NCSD failed", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Install to FIRM0", + "INSTALL_TO_FIRM1": "Install to FIRM1", + "INSTALL_TO_BOTH": "Install to both", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Switch EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restore H&S", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "Restore H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restore H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Set RTC date&time:", + "NEW_RTC_DATE_TIME_IS_TIME": "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen calibration success!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen calibration failed!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC date&time seems to be\nwrong. Set it now?", + "RESUME_GODMODE9": "Resume GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Select payload...", + "SELECT_SCRIPT": "Select script...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "Poweroff system", + "REBOOT_SYSTEM": "Reboot system", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader payloads menu.\nSelect payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Out of memory.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Open title manager", + "SEARCH_FOR_FILES": "Search for files...", + "FIX_CMACS_FOR_DRIVE": "Fix CMACs for drive", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "Found %lu results.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "Delete %lu path(s)?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "Failed deleting %lu/%lu path(s)", + "DELETE_FILE": "Delete \"%s\"?", + "FAILED_DELETING_PATH": "Failed deleting:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Not allowed in search drive", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Not allowed in virtual game path", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Not allowed in XORpad drive", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Not allowed in gamecart drive", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copy path(s)", + "MOVE_PATHS": "Move path(s)", + "PASTE_FILE_HERE": "Paste \"%s\" here?", + "PASTE_N_PATHS_HERE": "Paste %lu paths here?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Failed copying path:\n%s\nProcess remaining?", + "FAILED_COPYING_PATH": "Failed copying path:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Failed moving path:\n%s\nProcess remaining?", + "FAILED_MOVING_PATH": "Failed moving path:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Rename %s?\nEnter new name below.", + "FAILED_RENAMING_PATH": "Failed renaming path:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Create a folder", + "CREATE_A_DUMMY_FILE": "Create a dummy file", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Create a new folder here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Create a new file here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Failed creating folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Failed creating file:\n%s", + "TITLE_MANAGER": "Title manager", + "BRICK_MY_3DS": "Brick my 3DS", + "LANGUAGE": "Language...", + "SCRIPTS": "Scripts...", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Payloads...", + "MORE": "More...", + "BRACKET_MORE": "[more...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME button pressed.\nSelect action:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER button pressed.\nSelect action:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD CARD", + "B_DRIVE_SD_CARD": "[B:] SD CARD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads directory not found.\n(default path: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALID", + "TO_PROCEED_ENTER_THIS": "To proceed, enter this:", + "TO_PROCEED_HOLD_X": "To proceed, hold :", + "N_MORE": " [%d more]", + "CANCEL": "cancel", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) fast scroll\nL - clear data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - remove char\nY - insert char", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Searching, please wait...", + "RENAME_TO_GOOD_NAME": "Rename to good name?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD card is write protected!\nCan't continue.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "game images", + "GAMECART_SAVES": "gamecart saves", + "IMAGES": "images", + "MEMORY_AREAS": "memory areas", + "SD_SYSTEM_DATA": "SD system data", + "SD_CARD": "SD card", + "RAM_DRIVE": "RAM drive", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Writing to %s is locked!\nUnlock it now?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Unlock write permission for\n%s is not allowed.", + "ENABLE_BASE_WRITE": "You want to enable base\nwriting permissions.", + "ENABLE_SD_WRITE": "You want to enable SD card\nwriting permissions.", + "ENABLE_IMAGE_WRITE": "You want to enable image\nwriting permissions.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Error: SD card is too small", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatting SD, please wait...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatting drive, please wait...", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "File is currently mounted.\nUnmount to unlock?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Error: Can't inject file into itself", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operation would write beyond end of file", + "NOT_ENOUGH_DATA_IN_FILE": "Not enough data in file", + "CANCEL_IS_NOT_ALLOWED_HERE": "Cancel is not allowed here", + "B_DETECTED_CANCEL": "B button detected. Cancel?", + "ERROR_CANNOT_APPEND_FOLDER": "Error: Cannot append a folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Error: Not enough space available", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Error: Only FAT files can be moved", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Error: Destination is part of origin", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destination equals origin\nChoose another name?", + "CHOOSE_NEW_NAME": "Choose new name", + "OVERWRITE_FILES": "Overwrite file(s)", + "SKIP_FILES": "Skip file(s)", + "OVERWRITE_ALL": "Overwrite all", + "SKIP_ALL": "Skip all", + "DESTINATION_ALREADY_EXISTS": "Destination already exists:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choose new destination name", + "COPY_OPERATION_IS_NOT_ALLOWED": "Copy operation is not allowed", + "DESTINATION_EQUALS_ORIGIN": "Destination equals origin", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entry not found: %s\nInject into %s instead?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "Americas", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brazil", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europe", + "REGION_FRANCE": "France", + "REGION_GERMANY": "Germany", + "REGION_ITALY": "Italy", + "REGION_JAPAN": "Japan", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spain", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Unknown", + "REGION_UNITED_KINGDOM": "United Kingdom", + "REGION_MIDDLE_EAST": "Middle East", + "GENERATING_QR_CODE": "Generating QR code...", + "REINITIALIZING_SD_CARD": "Reinitializing SD card...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Press POWER to turn off", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Cleaning up titles, please wait...", + "ERROR_NOT_NCCH_FILE": "Error: Not an NCCH file", + "ERROR_FILE_IS_TOO_SMALL": "Error: File is too small", + "ATTEMPT_FIX_THIS_TIME": "Attempt fix this time", + "ATTEMPT_FIX_ALWAYS": "Attempt fix always", + "ABORT_VERIFICATION": "Abort verification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "fail", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Errore: Chiave di titolo CDN non trovata", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC content is missing\n \nIgnore all and continue?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Error: Not a BOSS file", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS payload hash mismatch.\n \nTry to fix it?", + "GENERIC_TICKET_PIRATE_LEGIT": "Generic ticket (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalized ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nChiave di titolo non trovata." +} diff --git a/resources/languages/ja-KANA.json b/resources/languages/ja-KANA.json new file mode 100644 index 000000000..6b9f0efcb --- /dev/null +++ b/resources/languages/ja-KANA.json @@ -0,0 +1,271 @@ +{ + "GM9_LANGUAGE": "にほんご", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lXねん%3$02lXがつ%4$02lXにち %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRMがおおきすぎるので、きどうできません。", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nちゅうい: しんらいできないソースから\nFIRMをきどうしないでください。\n \nFIRMをきどうしますか?", + "NOT_BOOTABLE_FIRM": "%s\nきどうできるFIRMではありません。", + "FIRM_ENCRYPTED": "FIRMがあんごうかされています。\n \nきどうまえにふくごうかしますか?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "%s/temp.firmにコピーをさくせいしますか?", + "TRY_BOOT_ANYWAYS": "とにかくきどうしてみる", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "けいこく: サポートされていない\nばしょからブートしようとしています。", + "ROOT": "[root]", + "LOADING": "ロードちゅう…", + "PANE_N": "ペイン %lu", + "CURRENT": "げんざい", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMドライブFAT)", + "GAME_VIRTUAL": "(ゲームバーチャル)", + "SYSNAND_FAT": "(システムNAND FAT)", + "SYSNAND_VIRTUAL": "(システムNAND バーチャル)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND バーチャル)", + "IMAGE_FAT": "(イメージFAT)", + "XORPAD_VIRTUAL": "(XORパッドバーチャル)", + "MEMORY_VIRTUAL": "(メモリバーチャル)", + "ALIAS_FAT": "(エイリアスFAT)", + "GAMECART_VIRTUAL": "(ゲームカートバーチャル)", + "VRAM_VIRTUAL": "(VRAMバーチャル)", + "SEARCH": "(けんさく)", + "TITLEMANAGER_VIRTUAL": "(タイトルマネージャーバーチャル)", + "LAB_SDCARD": "SDカード", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "ゲームカード", + "LAB_GAME_IMAGE": "ゲームイメージ", + "LAB_AESKEYDB_IMAGE": "AESKEYDBイメージ", + "LAB_BDRI_IMAGE": "BDRIイメージ", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFFイメージ", + "LAB_MEMORY_VIRTUAL": "メモリバーチャル", + "LAB_VRAM_VIRTUAL": "VRAMバーチャル", + "LAB_TITLE_MANAGER": "タイトルマネージャー", + "LAB_LAST_SEARCH": "まえのけんさく", + "LAB_FAT_IMAGE": "FATイメージ", + "LAB_BONUS_DRIVE": "ボーナスドライブ", + "LAB_RAMDRIVE": "RAMドライブ", + "LAB_NOLABEL": "ラベルなし", + "N_BYTE": "%sバイト", + "BYTE": "バイト", + "KB": "kB", + "MB": "MB", + "GB": "GB", + "CLIPBOARD": "[クリップボード]", + "PLUS_N_MORE": "+ と%luこ", + "MARK_DELETE_COPY": "L - ファイルをマーク (↑↓→←をしよう)\nX - ファイルをさくじょ / [+R] なまえをへんこう\nY - ファイルをコピー / [+R] エントリをさくせい\n", + "MARK_DELETE_PASTE": "L - ファイルをマーク (↑↓→←をしよう)\nX - ファイルをさくじょ / [+R] なまえをへんこう\nY - ファイルをはりつける / [+R] エントリをさくせい\n", + "RELOCK_WRITE_PERMISSION": "R+Y - かきこみのきょかをさいロック\n", + "UNMOUNT_IMAGE": "R+X - イメージをマウントかいじょ\n", + "UNMOUNT_SD": "R+B - SDカードをマウントかいじょ\n", + "REMOUNT_SD": "R+B - SDカードをさいマウント\n", + "DIRECTORY_OPTIONS": "R+A - ディレクトリオプション\n", + "DRIVE_OPTIONS": "R+A - ドライブオプション\n", + "MAKE_SCREENSHOT": "R+L - スクリーンショットをさくせい\n", + "PREV_NEXT_PANE": "R+←→ - まえ・つぎのペインにきりかえる\n", + "CLEAR_CLIPBOARD": "SELECT - クリップポードのしょうきょ\n", + "RESTORE_CLIPBOARD": "SELECT - クリップボードのふくげん\n", + "REBOOT_POWEROFF_HOME": "START - さいきどう / [+R] でんげんオフ\nホームボタンでホームメニュー", + "NO_EMUNAND": "EmuNANDなし", + "REDNAND_SIZE_MIN": "RedNANDサイズ(さいてい)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNANDサイズ(フル)", + "MULTINAND_SIZE_2X": "マルチNANDサイズ(2x)", + "MULTINAND_SIZE_3X": "マルチNANDサイズ(3x)", + "MULTINAND_SIZE_4X": "マルチNANDサイズ(4x)", + "USER_INPUT": "ユーザーにゅうりょく…", + "AUTO": "じどう", + "16KB_CLUSTERS": "16KBクラスター", + "32KB_CLUSTERS": "32KBクラスター", + "64KB_CLUSTERS": "64KBクラスター", + "SD_NOT_DETECTED": "エラー: SDカードをけんしゅつされませんでした。", + "FORMAT_SD_CHOOSE_EMUNAND": "SDカード(%lluMB)をフォーマットしますか?\nEmuNANDサイズをせんたくしてください。", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SDカードサイズは%lluMBです。\nEmuNANDサイズ(MB)をいかににゅうりょくしてください。", + "FORMAT_SD_CHOOSE_CLUSTER": "SDカード(%lluMB)をフォーマットしますか?\nクラスターサイズをせんたくしてください。", + "FORMAT_SD_ENTER_LABEL": "SDカード(%lluMB)をフォーマットしますか?\nラベルをにゅうりょくしてください。", + "FORMAT_SD_FAILED": "SDのフォーマット: しっぱい!", + "REDNAND_TYPE": "RedNANDタイプ", + "REDNAND_TYPE_MULTI": "RedNANDタイプ(ふくすう)", + "REDNAND_TYPE_SINGLE": "RedNANDタイプ(たんいつ)", + "GW_EMUNAND_TYPE": "GW EmuNANDタイプ", + "DONT_SET_UP": "せっていしない", + "CHOOSE_EMUNAND_TYPE": "せんたくされるEmuNANDタイプをせんたくしてください。", + "CLONE_SYSNAND_TO_REDNAND": "RedNANDにSysNANDをコピーしますか?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "EmuNANDにシステムNANDをコピー:  しっぱい!", + "PRESS_A_TO_CONTINUE": "をおしてつづける", + "HEXEDITOR_CONTROLS": "16しんエディタのコントロール:\n \n↑↓→←(+R) - スクロール\nR+Y - ひょうじをきりかえる\nX - けんさく・いどう…\nA - へんしゅうモードにする\nA+↑↓→← - あたいをへんしゅう\nB - しゅうりょう\n", + "NOT_FOUND": "ありません!", + "GO_TO_OFFSET": "オフセットへいどう", + "SEARCH_FOR_STRING": "もじれつでけんさく", + "SEARCH_FOR_DATA": "データでけんさく", + "CURRENT_OFFSET_SELECT_ACTION": "げんざいのオフセット: %08lX\nアクションをせんたく:", + "CURRENT_OFFSET_ENTER_NEW": "げんざいのオフセット: %08lX\nいかにあたらしいオフセットをにゅうりょくしてください。", + "ENTER_SEARCH_REPEAT_SEARCH": "いかにけんさくするもじれつをにゅうりょくしてください。\n(R+Xでけんさくをくりかえします)", + "MADE_EDITS_SAVE_CHANGES": "%luこのばしょがへんこうされました。\nへんこうをファイルにかきこみますか?", + "FAILED_WRITING_TO_FILE": "ファイルへのかきこみにしっぱいしました!", + "CALCULATING_SHA_FAILED": "SHA-%sのけいさん: しっぱい!", + "SHA_VERIFICATION_PASSED": "\nSHAけんしょう: せいこう!", + "SHA_VERIFICATION_FAILED": "\nSHAけんしょう: しっぱい", + "IDENTICAL_WITH_PREVIOUS": "\n \nまえのファイルとおなじです。\n", + "WRITE_SHA_FILE": "\n \n.SHAファイルをさくせいしますか?", + "WRITE_SHA1_FILE": "\n \n.SHA1ファイルをさくせいしますか?", + "CALCULATING_CMAC_FAILED": "CMACのけいさん: しっぱい!", + "CMAC_VERIFICATION_PASSED": "CMACけんしょう: せいこう!", + "CMAC_VERIFICATION_FAILED": "CMACけんしょう: しっぱい!", + "FIX_CMAC_IN_FILE": "\n \nファイルにCMACをしゅうせいしますか?", + "FIXING_CMAC_FAILED": "CMACのしゅうせい: しっぱいしました!", + "COPY_ALL_SELECTED_ITEMS": "%luこのせんたくされたこうもくをすべてコピーしますか?", + "FAILED_COPYING_ITEM": "項目のコピーにしっぱいしました", + "ITEMS_COPIED_TO_OUT": "%luこのこうもくは%sにコピーしました", + "PATH_COPIED_TO_OUT": "%s\n%sにコピーしました", + "CART_INIT_FAILED": "カードのしょきかにしっぱいしました!", + "CART_DETECTED_SIZE_INPUT_BELOW": "カード: %s\nけんしゅつされたサイズ: %s\n \nいかにダンプサイズをにゅうりょくしてください。", + "NDS_CART_DECRYPT_SECURE_AREA": "カード: %s\nNDSカードが検出\nセキュアエリアをふくごうかしますか?", + "FAILED_DUMPING_CART": "%s\nカードのダンプにしっぱいしました", + "PATH_DUMPED_TO_OUT": "%s\n%sにダンプしました", + "CREATED": "さくせいび", + "MODIFIED": "こうしんび", + "ANALYZING_DRIVE": "ドライブをぶんせきしています、しばらくおまちください。", + "ANALYZING_DIR": "フォルダをぶんせきしています、おまちください。", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%luファイルと%luフォルダ\n%sごうけいサイズ\n \nあきようりょう:%s\nしようようりょう:%s\nごうけいようりょう:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%luファイルと%luフォルダ\n%sごうけいサイズ", + "FILESIZE_X": "ファイルサイズ: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sよみとりせんよう [%c] %sかくし\n[%c] %sシステム [%c] %sアーカイブ\n[%c] %sバーチャル\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→←でぞくせいをへんこうする)\n", + "A_TO_CONTINUE": "(でつづける)", + "A_APPLY_B_CANCEL": "(でてきよう、でキャンセル)", + "A_YES_B_NO": "(はい、いいえ)", + "A_SELECT_B_CANCEL": "(せんたく、キャンセル)", + "HOLD_B_TO_CANCEL": "(Bをながおしでキャンセル)", + "FAILED_TO_SET_ATTRIBUTES": "ぞくせいのせっていにしっぱいしました!", + "NAND_IMAGE_OPTIONS": "NANDイメージオプション…", + "CTRNAND_OPTIONS": "CTRNANDオプション…", + "MOUNT_FAT_IMAGE": "FATイメージとしてマウント", + "CIA_IMAGE_OPTIONS": "CIAイメージオプション…", + "NCSD_IMAGE_OPTIONS": "NCSDイメージオプション…", + "NCCH_IMAGE_OPTIONS": "NCCHイメージオプション…", + "MOUNT_AS_EXEFS_IMAGE": "EXEFSイメージとしてマウント", + "MOUNT_AS_ROMFS_IMAGE": "ROMFSイメージとしてマウント", + "TMD_FILE_OPTIONS": "TMDファイルオプション…", + "TMD_CDN_OPTIONS": "TMD/CDNオプション…", + "TMD_TWL_OPTIONS": "TMD/TWLオプション…", + "MANAGE_TITLE": "タイトルをかんり…", + "BOSS_FILE_OPTIONS": "BOSSファイルオプション…", + "DECRYPT_NUS_CDN_FILE": "NUS/CDNファイルをふくごうか", + "SHOW_SMDH_TITLE_INFO": "SMDHタイトルのじょうほうをひょうじ", + "NDS_IMAGE_OPTIONS": "NDSイメージオプション…", + "GBA_IMAGE_OPTIONS": "GBAイメージオプション…", + "TICKET_OPTIONS": "チケットオプション…", + "TAD_IMAGE_OPTIONS": "TADイメージオプション…", + "SHOW_3DSX_TITLE_INFO": "3DSXタイトルのじょうほうをひょうじ", + "FIRM_IMAGE_OPTIONS": "FIRMイメージオプション…", + "AGBSAVE_OPTIONS": "AGBSAVEオプション…", + "DUMP_GBA_VC_SAVE": "GBA VCのセーブをダンプ", + "TICKET_DB_OPTIONS": "Ticket.dbオプション…", + "MOUNT_AS_DIFF_IMAGE": "DIFFイメージとしてマウント", + "MOUNT_AS_DISA_IAMGE": "DISAイメージとしてマウント", + "INSTALL_CIFINISH_BIN": "cifinish.binをインストール", + "TITLEKEY_OPTIONS": "タイトルキーオプション…", + "AESKEYDB_OPTIONS": "AESkeydbオプション…", + "BUILD_X": "%sをさくせい", + "NCCHINFO_OPTIONS": "NCCHinfoオプション…", + "EXECUTE_GM9_SCRIPT": "GM9スクリプトをじっこう", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "フォントオプション…", + "LANGUAGE_OPTIONS": "言語オプション…", + "VIEW_PNG_FILE": "PNGファイルをひょうじ", + "REBUILD_NCSD_HEADER": "NCSDヘッダーをさいさくせい", + "SHOW_IN_HEXEDITOR": "16しんエディタでひょうじ", + "CALCULATE_SHA256": "SHA-256をけいさん", + "CALCULATE_SHA1": "SHA-1をけいさん", + "SHOW_FILE_INFO": "ファイルじょうほうをひょうじ", + "SHOW_IN_TEXTVIEWER": "テキストビューアーでひょうじ", + "CALCULATE_CMAC": "CMACをけいさん", + "COPY_TO_OUT": "%sにコピー", + "DUMP_TO_OUT": "%sにダンプ", + "INJECT_DATA_AT_OFFSET": "オフセットにデータをそうにゅう", + "OPEN_THIS_FOLDER": "このフォルダをひらく", + "OPEN_CONTAINING_FOLDER": "がんゆうフォルダをひらく", + "OPEN_TITLE_FOLDER": "タイトルフォルダをひらく", + "PATH_N_FILES_SELECTED": "%s\n(%luこのせんたくされたファイル)", + "CHECK_CURRENT_CMAC_ONLY": "げんざいのCMACのみをかくにんする", + "VERIFY_CMAC_FOR_ALL": "すべてのCMACをかくにんする", + "FIX_CMAC_FOR_ALL": "すべてのCMACをしゅうせいする", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%luファイルがOK/しゅうせい/ごうけい\n%lu/%luがCMACなし", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%luファイルがけんしょうずみ\n%lu/%luファイルがしゅうせいずみ", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%luファイルがけんしょうずみ\n%lu/%luファイルがCMACなし", + "N_OF_N_FILES_VERIFIED": "%lu/%luファイルがけんしょうずみ", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "%sからデータをそうにゅうしますか?\nいかにオフセットをにゅうりょくしてください。", + "FAILED_INJECTING_PATH": "%sのそうにゅうにしっぱいしました", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDSをドライブにマウント", + "MOUNT_IMAGE_TO_DRIVE": "イメージをドライブにマウント", + "RESTORE_SYSNAND_SAFE": "システムNANDをふくげん(あんぜん)", + "UPDATE_EMBEDDED_BACKUP": "うめこみバックアップをこうしん", + "SHOW_TITLE_INFO": "タイトルじょうほうをひょうじ", + "DECRYPT_FILE": "ファイルをふくごうか (...)", + "DECRYPT_FILE_OUT": "ファイルをふくごうか(%sへ)", + "ENCRYPT_FILE": "ファイルをあんごうか (...)", + "ENCRYPT_FILE_OUT": "ファイルをあんごうか(%sへ)", + "BUILD_CIA_FROM_FILE": "ファイルからCIAをさくせい", + "BUILD_CIA_STANDARD": "CIAをさくせい(ひょうじゅん)", + "BUILD_CIA_LEGIT": "CIAをさくせい(ごうほう)", + "DUMP_CXI_NDS_FILE": "CXI/NDSファイルをダンプ", + "INSTALL_GAME_IMAGE": "ゲームイメージをインストール", + "INSTALL_TICKET": "チケットをインストール", + "DUMP_TICKET_FILE": "チケットファイルをダンプ", + "UNINSTALL_TITLE": "タイトルをアンインストール", + "VERIFY_FILE": "ファイルをけんしょう", + "TRANSFER_IMAGE_TO_CTRNAND": "CTRNANDにイメージをてんそう", + "INJECT_TO_H_AND_S": "けんこうとあんぜんにそうにゅう", + "TRIM_FILE": "ファイルをトリミング", + "RENAME_FILE": "ファイルのなまえをへんこう", + "BUILD_XORPADS_SD": "XORパッドをさくせい(SDからしゅつりょく)", + "BUILD_XORPADS_INPLACE": "XORパッドをさくせい(コピーしない)", + "EXTRACT_X": "%sをかいとう", + "INIT_X": "%sをせってい", + "INSTALL_X": "%sをインストール", + "INSTALL_FIRM": "FIRMをインストール", + "BOOT_FIRM": "FIRMをきどう", + "SET_AS_ACTIVE_FONT": "しようされるフォントにせってい", + "SET_AS_ACTIVE_LANGUAGE": "しようされるげんごにせってい", + "DUMP_BA_VC_SAVE": "GBC VCセーブをダンプ", + "INJECT_GBA_VC_SAVE": "GBA VCセーブをそうにゅう", + "SET_AS_DEFAULT": "デフォルトとしてせってい", + "MOUNTING_IMAGE_FAILED": "イメージをマウント:しっぱいしました", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nトライブ%sとしてマウントしました\nいますぐドライブにいどうしますか?", + "DECRYPT_TO_OUT": "%sにふくごう", + "DECRYPT_INPLACE": "コピーしないでふくごう", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "%luこのせんたくしたすべてのファイルをふくごうしますか?", + "TRYING_TO_DECRYPT_N_FILES": "%luこのファイルをふくごうしています…", + "DECRYPTION_FAILED_CONTINUE": "ふくごうかにしっぱいしました\n \nつづけますか?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイルふくごうかずみ\n%lu/%luファイルあんごうかされていない\n%lu/%luおなじしゅるいではない", + "N_OF_N_FILES_DECRYPTED": "%lu/%luファイルふくごうずみ", + "N_FILES_WRITTEN_TO_OUT": "%2$sに%1$luこファイルがかきこみました", + "FILE_NOT_ENCRYPTED": "ファイルはあんごうかされていません", + "DECRYPTION_SUCCESS": "ふくごうかがせいこうしました", + "DECRYPTION_FAILED": "ふくごうかにしっぱいしました", + "PATH_DECRYPTED_TO_OUT": "%s\n%sにふくごうしました", + "ENCRYPT_TO_OUT": "%sにあんごうか", + "ENCRYPT_INPLACE": "コピーしないであんごうか", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "%luこのせんたくしたすべてのファイルをあんごうかしますか?", + "TRYING_TO_ENCRYPT_N_FILES": "%luこのファイルをあんごうかしています。", + "ENCRYPTION_FAILED_CONTINUE": "あんごうかにしっぱいしました\n \nつづけますか?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイルあんごうかずみ\n%lu/%luおなじしゅるいではない", + "N_OF_N_FILES_ENCRYPTED": "%lu/%luファイルあんごうかずみ", + "ENCRYPTION_SUCCESS": "あんごうかがせいこうしました", + "ENCRYPTION_FAILED": "あんごうかにしっぱいしました", + "PATH_ENCRYPTED_TO_OUT": "%s\n%sにあんごうかしました", + "TRY_TO_PROCESS_N_SELECTED_FILES": "%luこのせんたくしたすべてのファイルをしょりしますか?" +} diff --git a/resources/languages/ja.json b/resources/languages/ja.json new file mode 100644 index 000000000..8bf012f33 --- /dev/null +++ b/resources/languages/ja.json @@ -0,0 +1,816 @@ +{ + "GM9_LANGUAGE": "日本語", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lX年%3$02lX月%4$02lX日 %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRMが大きすぎるので、起動できません。", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\n注意: 信頼できないソースから\nFIRMを起動しないでください。\n \nFIRMを起動しますか?", + "NOT_BOOTABLE_FIRM": "%s\n起動できるFIRMではありません。", + "FIRM_ENCRYPTED": "FIRMが暗号化されています。\n \n起動前に復号化しますか?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "%s/temp.firmにコピーを作成しますか?", + "TRY_BOOT_ANYWAYS": "とにかく起動してみる", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "警告: サポートされていない\n場所からブートしようとしています。", + "ROOT": "[root]", + "LOADING": "ロード中…", + "PANE_N": "ペイン %lu", + "CURRENT": "現在", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMドライブFAT)", + "GAME_VIRTUAL": "(ゲームバーチャル)", + "SYSNAND_FAT": "(システムNAND FAT)", + "SYSNAND_VIRTUAL": "(システムNAND バーチャル)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND バーチャル)", + "IMAGE_FAT": "(イメージFAT)", + "XORPAD_VIRTUAL": "(XORパッドバーチャル)", + "MEMORY_VIRTUAL": "(メモリバーチャル)", + "ALIAS_FAT": "(エイリアスFAT)", + "GAMECART_VIRTUAL": "(ゲームカートバーチャル)", + "VRAM_VIRTUAL": "(VRAMバーチャル)", + "SEARCH": "(検索)", + "TITLEMANAGER_VIRTUAL": "(タイトルマネージャーバーチャル)", + "LAB_SDCARD": "SDカード", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "ゲームカート", + "LAB_GAME_IMAGE": "ゲームイメージ", + "LAB_AESKEYDB_IMAGE": "AESKEYDBイメージ", + "LAB_BDRI_IMAGE": "BDRIイメージ", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFFイメージ", + "LAB_MEMORY_VIRTUAL": "メモリバーチャル", + "LAB_VRAM_VIRTUAL": "VRAMバーチャル", + "LAB_TITLE_MANAGER": "タイトルマネージャー", + "LAB_LAST_SEARCH": "前検索", + "LAB_FAT_IMAGE": "FATイメージ", + "LAB_BONUS_DRIVE": "ボーナスドライブ", + "LAB_RAMDRIVE": "RAMドライブ", + "LAB_NOLABEL": "ラベルなし", + "N_BYTE": "%sバイト", + "BYTE": "バイト", + "KB": "kB", + "MB": "MB", + "GB": "GB", + "CLIPBOARD": "[クリップボード]", + "PLUS_N_MORE": "+ と%lu個", + "MARK_DELETE_COPY": "L - ファイルをマーク (↑↓→←と使用)\nX - ファイルを削除 / [+R] 名前を変更\nY - ファイルをコピー / [+R] エントリを作成\n", + "MARK_DELETE_PASTE": "L - ファイルをマーク (↑↓→←と使用)\nX - ファイルを削除 / [+R] 名前を変更\nY - ファイルを貼り付ける / [+R] エントリを作成\n", + "RELOCK_WRITE_PERMISSION": "R+Y - 書き込みの許可を再ロック\n", + "UNMOUNT_IMAGE": "R+X - イメージをマウント解除\n", + "UNMOUNT_SD": "R+B - SDカードをマウント解除\n", + "REMOUNT_SD": "R+B - SDカードを再マウント\n", + "DIRECTORY_OPTIONS": "R+A - ディレクトリオプション\n", + "DRIVE_OPTIONS": "R+A - ドライブオプション\n", + "MAKE_SCREENSHOT": "R+L - スクリーンショットを作成\n", + "PREV_NEXT_PANE": "R+←→ - 前・次のペインに切り替える\n", + "CLEAR_CLIPBOARD": "SELECT - クリップポードの消去\n", + "RESTORE_CLIPBOARD": "SELECT - クリップボードの復元\n", + "REBOOT_POWEROFF_HOME": "START - 再起動 / [+R] 電源オフ\nHOMEボタンでHOMEメニュー", + "NO_EMUNAND": "EmuNANDなし", + "REDNAND_SIZE_MIN": "RedNANDサイズ(最低)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNANDサイズ(フル)", + "MULTINAND_SIZE_2X": "マルチNANDサイズ(2x)", + "MULTINAND_SIZE_3X": "マルチNANDサイズ(3x)", + "MULTINAND_SIZE_4X": "マルチNANDサイズ(4x)", + "USER_INPUT": "ユーザー入力…", + "AUTO": "自動", + "16KB_CLUSTERS": "16KBクラスター", + "32KB_CLUSTERS": "32KBクラスター", + "64KB_CLUSTERS": "64KBクラスター", + "SD_NOT_DETECTED": "エラー: SDカードを検出されない", + "FORMAT_SD_CHOOSE_EMUNAND": "SDカード(%lluMB)をフォーマットしますか?\nEmuNANDサイズを選択さてください。", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SDカードサイズは%lluMB。\nEmuNANDサイズ(MB)をいかに入力してください。", + "FORMAT_SD_CHOOSE_CLUSTER": "SDカード(%lluMB)をフォーマットしますか?\nクラスターサイズを選択してください。", + "FORMAT_SD_ENTER_LABEL": "SDカード(%lluMB)をフォーマットしますか?\nラベルを入力してください。", + "FORMAT_SD_FAILED": "SDのフォーマット: 失敗!", + "REDNAND_TYPE": "RedNANDタイプ", + "REDNAND_TYPE_MULTI": "RedNANDタイプ(複数)", + "REDNAND_TYPE_SINGLE": "RedNANDタイプ(単一)", + "GW_EMUNAND_TYPE": "GW EmuNANDタイプ", + "DONT_SET_UP": "設定しない", + "CHOOSE_EMUNAND_TYPE": "設定されるEmuNANDタイプを選択してください。", + "CLONE_SYSNAND_TO_REDNAND": "RedNANDにSysNANDをコピーしますか?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "EmuNANDにシステムNANDをコピー:  失敗!", + "PRESS_A_TO_CONTINUE": "を押して続ける", + "HEXEDITOR_CONTROLS": "16進エディタのコントロール:\n \n↑↓→←(+R) - スクロール\nR+Y - 表示を切り替える\nX - 検索・移動…\nA - 編集モードにする\nA+↑↓→← - 値を編集\nB - 終了\n", + "NOT_FOUND": "ありません!", + "GO_TO_OFFSET": "オフセットへ移動", + "SEARCH_FOR_STRING": "文字列で検索", + "SEARCH_FOR_DATA": "データで検索", + "CURRENT_OFFSET_SELECT_ACTION": "現在のオフセット: %08lX\nアクションを選択:", + "CURRENT_OFFSET_ENTER_NEW": "現在のオフセット: %08lX\n以下に新しいオフセットを入力してください。", + "ENTER_SEARCH_REPEAT_SEARCH": "以下に検索する文字列を入力してください。\n(R+Xで検索を繰り返します)", + "MADE_EDITS_SAVE_CHANGES": "%lu個の場所が変更されました。\n変更をファイルに書き込みますか?", + "FAILED_WRITING_TO_FILE": "ファイルへの書き込みに失敗しました!", + "CALCULATING_SHA_FAILED": "SHA-%sの計算: 失敗!", + "SHA_VERIFICATION_PASSED": "\nSHA検証: 成功!", + "SHA_VERIFICATION_FAILED": "\nSHA検証: 失敗", + "IDENTICAL_WITH_PREVIOUS": "\n \n前ファイルと同じです。\n", + "WRITE_SHA_FILE": "\n \n.SHAファイルを作成しますか?", + "WRITE_SHA1_FILE": "\n \n.SHA1ファイルを作成しますか?", + "CALCULATING_CMAC_FAILED": "CMACの計算: 失敗!", + "CMAC_VERIFICATION_PASSED": "CMAC検証: 成功!", + "CMAC_VERIFICATION_FAILED": "CMAC検証: 失敗!", + "FIX_CMAC_IN_FILE": "\n \nファイルにCMACを修正します?", + "FIXING_CMAC_FAILED": "CMACの修正: 失敗しました!", + "COPY_ALL_SELECTED_ITEMS": "%lu個の選択された項目をすべてコピーしますか?", + "FAILED_COPYING_ITEM": "項目をコピーに失敗しました", + "ITEMS_COPIED_TO_OUT": "%lu個の項目は%sにコピーしました", + "PATH_COPIED_TO_OUT": "%s\n%sにコピーしました", + "CART_INIT_FAILED": "カートの初期化に失敗しました!", + "CART_DETECTED_SIZE_INPUT_BELOW": "カート: %s\n検出されたサイズ: %s\n \n以下にダンプサイズを入力してください。", + "NDS_CART_DECRYPT_SECURE_AREA": "カート: %s\nNDSカートが検出\nセキュアエリアを復号化します?", + "FAILED_DUMPING_CART": "%s\nカートをダンプに失敗しました", + "PATH_DUMPED_TO_OUT": "%s\n%sにダンプしました", + "CREATED": "作成日", + "MODIFIED": "更新日", + "ANALYZING_DRIVE": "ドライブを分析中。お待ちください。", + "ANALYZING_DIR": "フォルダを分析中。お待ちください。", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%luファイルと%luフォルダ\n%s合計サイズ\n \n空き容量:%s\n使用容量:%s\n合計容量:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%luファイルと%luフォルダ\n%s合計サイズ", + "FILESIZE_X": "ファイルサイズ: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s読み取り専用 [%c] %s隠し\n[%c] %sシステム [%c] %sアーカイブ\n[%c] %sバーチャル\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→←で属性を変更する)\n", + "A_TO_CONTINUE": "(で続ける)", + "A_APPLY_B_CANCEL": "(で適用、でキャンセル)", + "A_YES_B_NO": "(はい、いいえ)", + "A_SELECT_B_CANCEL": "(選択、キャンセル)", + "HOLD_B_TO_CANCEL": "(Bを長押しするとキャンセル)", + "FAILED_TO_SET_ATTRIBUTES": "属性の設定に失敗しました!", + "NAND_IMAGE_OPTIONS": "NANDイメージオプション…", + "CTRNAND_OPTIONS": "CTRNANDオプション…", + "MOUNT_FAT_IMAGE": "FATイメージとしてマウント", + "CIA_IMAGE_OPTIONS": "CIAイメージオプション…", + "NCSD_IMAGE_OPTIONS": "NCSDイメージオプション…", + "NCCH_IMAGE_OPTIONS": "NCCHイメージオプション…", + "MOUNT_AS_EXEFS_IMAGE": "EXEFSイメージとしてマウント", + "MOUNT_AS_ROMFS_IMAGE": "ROMFSイメージとしてマウント", + "TMD_FILE_OPTIONS": "TMDファイルオプション…", + "TMD_CDN_OPTIONS": "TMD/CDNオプション…", + "TMD_TWL_OPTIONS": "TMD/TWLオプション…", + "MANAGE_TITLE": "タイトルを管理…", + "BOSS_FILE_OPTIONS": "BOSSファイルオプション…", + "DECRYPT_NUS_CDN_FILE": "NUS/CDNファイルを復号化", + "SHOW_SMDH_TITLE_INFO": "SMDHタイトルの情報を表示", + "NDS_IMAGE_OPTIONS": "NDSイメージオプション…", + "GBA_IMAGE_OPTIONS": "GBAイメージオプション…", + "TICKET_OPTIONS": "チケットオプション…", + "TAD_IMAGE_OPTIONS": "TADイメージオプション…", + "SHOW_3DSX_TITLE_INFO": "3DSXタイトルの情報を表示", + "FIRM_IMAGE_OPTIONS": "FIRMイメージオプション…", + "AGBSAVE_OPTIONS": "AGBSAVEオプション…", + "DUMP_GBA_VC_SAVE": "GBA VCのセーブをダンプ", + "TICKET_DB_OPTIONS": "Ticket.dbオプション…", + "MOUNT_AS_DIFF_IMAGE": "DIFFイメージとしてマウント", + "MOUNT_AS_DISA_IAMGE": "DISAイメージとしてマウント", + "INSTALL_CIFINISH_BIN": "cifinish.binをインストール", + "TITLEKEY_OPTIONS": "タイトルキーオプション…", + "AESKEYDB_OPTIONS": "AESkeydbオプション…", + "BUILD_X": "%sを作成", + "NCCHINFO_OPTIONS": "NCCHinfoオプション…", + "EXECUTE_GM9_SCRIPT": "GM9スクリプトを実行", + "EXECUTE_LUA_SCRIPT": "Luaスクリプトを実行", + "FONT_OPTIONS": "フォントオプション…", + "LANGUAGE_OPTIONS": "言語オプション…", + "VIEW_PNG_FILE": "PNGファイルを表示", + "REBUILD_NCSD_HEADER": "NCSDヘッダーを再作成", + "SHOW_IN_HEXEDITOR": "16進エディタで表示", + "CALCULATE_SHA256": "SHA-256を計算", + "CALCULATE_SHA1": "SHA-1を計算", + "SHOW_FILE_INFO": "ファイル情報を表示", + "SHOW_IN_TEXTVIEWER": "テキストビューアーで表示", + "CALCULATE_CMAC": "CMACを計算", + "COPY_TO_OUT": "%sにコピー", + "DUMP_TO_OUT": "%sにダンプ", + "INJECT_DATA_AT_OFFSET": "オフセットにデータを挿入", + "OPEN_THIS_FOLDER": "このフォルダを開く", + "OPEN_CONTAINING_FOLDER": "含有フォルダを開く", + "OPEN_TITLE_FOLDER": "タイトルフォルダを開く", + "PATH_N_FILES_SELECTED": "%s\n(%lu個の選択されたファイル)", + "CHECK_CURRENT_CMAC_ONLY": "現在のCMACのみを確認する", + "VERIFY_CMAC_FOR_ALL": "すべてのCMACを確認する", + "FIX_CMAC_FOR_ALL": "すべてのCMACを修正する", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%luファイルがOK/修正/合計\n%lu/%luがCMACなし", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%luファイル検証済み\n%lu/%luファイル修正済み", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%luファイル検証済み\n%lu/%luファイルCMACなし", + "N_OF_N_FILES_VERIFIED": "%lu/%luファイル検証済み", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "%sからデータを挿入しますか?\n以下にオフセットを入力してください。", + "FAILED_INJECTING_PATH": "%sの挿入に失敗しました", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDSをドライブにマウント", + "MOUNT_IMAGE_TO_DRIVE": "イメージをドライブにマウント", + "RESTORE_SYSNAND_SAFE": "システムNANDを復元 (安全)", + "UPDATE_EMBEDDED_BACKUP": "埋め込みバックアップを更新", + "SHOW_TITLE_INFO": "タイトル情報を表示", + "DECRYPT_FILE": "ファイルを復号化", + "DECRYPT_FILE_OUT": "ファイルを復号化 (%sへ)", + "ENCRYPT_FILE": "ファイルを暗号化", + "ENCRYPT_FILE_OUT": "ファイルを暗号化 (%sへ)", + "BUILD_CIA_FROM_FILE": "ファイルからCIAを作成", + "BUILD_CIA_STANDARD": "CIAを作成 (標準)", + "BUILD_CIA_LEGIT": "CIAを作成 (合法)", + "DUMP_CXI_NDS_FILE": "CXI/NDSファイルをダンプ", + "INSTALL_GAME_IMAGE": "ゲームイメージをインストール", + "INSTALL_TICKET": "チケットをインストール", + "DUMP_TICKET_FILE": "チケットファイルをダンプ", + "UNINSTALL_TITLE": "タイトルをアンインストール", + "VERIFY_FILE": "ファイルを検証", + "TRANSFER_IMAGE_TO_CTRNAND": "CTRNANDにイメージを転送", + "INJECT_TO_H_AND_S": "健康と安全に挿入", + "TRIM_FILE": "ファイルをトリミング", + "RENAME_FILE": "ファイルの名前を変更", + "BUILD_XORPADS_SD": "XORパッドを作成 (SD出力)", + "BUILD_XORPADS_INPLACE": "XORパッドを作成 (コピーしない)", + "EXTRACT_X": "%sを解凍", + "INIT_X": "%sを設定", + "INSTALL_X": "%sをインストール", + "INSTALL_FIRM": "FIRMをインストール", + "BOOT_FIRM": "FIRMを起動", + "SET_AS_ACTIVE_FONT": "使用されるフォントに設定", + "SET_AS_ACTIVE_LANGUAGE": "使用される言語に設定", + "DUMP_BA_VC_SAVE": "GBC VCセーブをダンプ", + "INJECT_GBA_VC_SAVE": "GBA VCセーブを注入", + "SET_AS_DEFAULT": "デフォルトとして設定", + "MOUNTING_IMAGE_FAILED": "イメージをマウント: 失敗", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nトライブ%sとしてマウントしました\n今すぐドライブに移動しますか?", + "DECRYPT_TO_OUT": "%sに復号", + "DECRYPT_INPLACE": "コピーしないで復号", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを復号しますか?", + "TRYING_TO_DECRYPT_N_FILES": "%lu個のファイルを復号しよう中…", + "DECRYPTION_FAILED_CONTINUE": "復号化に失敗しました\n \n続けますか?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル復号済み\n%lu/%luファイル暗号されない\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_DECRYPTED": "%lu/%luファイル復号済み", + "N_FILES_WRITTEN_TO_OUT": "%2$sに%1$lu個ファイルが書き込みました", + "FILE_NOT_ENCRYPTED": "ファイルは暗号されていません", + "DECRYPTION_SUCCESS": "復号化が成功しました", + "DECRYPTION_FAILED": "復号化に失敗しました", + "PATH_DECRYPTED_TO_OUT": "%s\n%sに復号しました", + "ENCRYPT_TO_OUT": "%sに暗号", + "ENCRYPT_INPLACE": "コピーしないで暗号", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを暗号しますか?", + "TRYING_TO_ENCRYPT_N_FILES": "%lu個のファイルを暗号しよう中。", + "ENCRYPTION_FAILED_CONTINUE": "暗号化に失敗しました\n \n続けますか?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル暗号済み\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_ENCRYPTED": "%lu/%luファイル暗号済み", + "ENCRYPTION_SUCCESS": "暗号化が成功しました", + "ENCRYPTION_FAILED": "暗号化に失敗しました", + "PATH_ENCRYPTED_TO_OUT": "%s\n%sに暗号しました", + "TRY_TO_PROCESS_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを処理しますか?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\n%sを作成に失敗しました\n \n続けますか?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %s作成済み\n%lu/%lu同じ種類でない", + "N_OF_N_TYPES_BUILT": "%lu/%lu %s作成済み", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu個ファイルの変換に失敗しました。\n検証をおすすまします。", + "PATH_TYPE_BUILT_TO_OUT": "%1$s\n%3$sへ%2$sが作成しました", + "PATH_TYPE_BUILD_FAILED": "%s\n%sの作成に失敗しました", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "ファイルの変換に失敗しました。\n \n今すぐ検証しますか?", + "VERIFICATION_SUCCESS": "検証が成功しました", + "VERIFICATION_FAILED": "検証に失敗しました", + "CONTENT_IS_MISSING": "コンテンツがありません", + "INSTALL_TO_SYSNAND": "システムNANDにインストール", + "INSTALL_TO_EMUNAND": "EmuNANDにインストール", + "TRY_TO_INSTALL_N_SELECTED_FILES": "%lu個の選択したすべてのファイルをインストールしますか?", + "TRYING_TO_INSTALL_N_FILES": "%lu個のファイルをインストールしよう中。", + "INSTALL_FAILED_CONTINUE": "インストールに失敗しました\n \n続けますか?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイルインストール済み\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_INSTALLED": "%lu/%luファイルインストール済み", + "INSTALL_SUCCESS": "インストールが成功しました", + "INSTALL_FAILED": "インストールに失敗しました", + "FILE_FAILED_INSTALL_VERIFY_NOW": "ファイルのインストールに失敗しました。\n \n今すぐ検証しますか?", + "KEEP_TICKET_AND_SAVEGAME": "チケットとセーブゲームを保存する", + "UNINSTALL_EVERYTHING": "すべてをアンインストールする", + "ABORT_UNINSTALL": "アンインストールを中止する", + "UNINSTALL_N_SELECTED_TITLES": "%lu個の選択されたタイトルをすべてアンインストールしますか?", + "UNINSTALL_SELECTED_TITLE": "選択されたタイトルをアンインストールしますか?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%luタイトルアンインストール済み", + "UNINSTALLING_PLEASE_WAIT": "アンインストール中。お待ちください。", + "UNINSTALL_FAILED": "アンインストールに失敗しました!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを検証しますか?", + "VERIFICATION_FAILED_CONTINUE": "検証に失敗しました\n \n続けますか?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル検証済み\n%lu/%lu同じ種類でない", + "VERIFYING_FILE_PLEASE_WAIT": "ファイルを検証中。お待ちください。", + "NAND_VALIDATION_SUCCESS": "NAND検証が成功しました", + "NAND_VALIDATION_FAILED": "NAND検証に失敗しました", + "DUMP_FOR_N_SELECTED_FILES": "%lu個の選択したすべてのファイルでダンプしますか?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu合法チケットをダンプしました。\n \nすべてのチッケトをダンプしようしますか?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%luチケットが%sにダンプしました。", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nチケットが%sにダンプしました", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\n合法チケットがありません。\n \nとにかくダンプしますか?", + "DUMP_TICKET_FAILED": "チケットをダンプに失敗しました!", + "BUILDING_X": "%sを作成中…", + "BUILDING_X_SYSNAND": "%sを作成中… (システムNAND)", + "BUILDING_X_EMUNAND": "%sを作成中… (EmuNAND)", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%luファイル処理済み\n%lu/%luファイル無視済み", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%luファイル処理済み", + "BUILD_DATABASE_SUCCESS": "データベースを作成が成功しました。", + "BUILD_DATABASE_FAILED": "データベースを作成に失敗しました。", + "TRY_TO_TRIM_N_SELECTED_FILES": "%lu個の選択したすべてのファイルをトリミングしますか?", + "TRIMMING_FAILED_CONTINUE": "トリミングに失敗しました\n \n続けますか?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%luファイルトリミング済み\n%lu/%lu同じ種類でない\n%s保存された", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%luファイルトリミング済み\n%s保存された", + "FILE_CANT_BE_TRIMMED": "ファイルをトリミングできません。", + "FILE_ALREADY_TRIMMED": "ファイルが既にトリミングされています。", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\n現在サイズ: %s\nトリミングサイズ: %s\n差分: %s\n \nファイルをトリミングしますか?", + "TRIMMING_FAILED": "トリミングに失敗しました。", + "PATH_TRIMMED_BY_X": "%s\n%sでトリミングしました。", + "TRY_TO_RENAME_N_SELECTED_FILES": "%lu個の選択したすべてのファイルの名前を変更しますか?", + "N_OF_N_RENAMED": "%lu/%lu名前変更済み", + "COULD_NOT_RENAME_TO_GOOD_NAME": "名前を良い名前に変更できませんでした", + "SYSNAND_H_AND_S_INJECT": "システムNANDの健康と安全に挿入", + "EMUNAND_H_AND_S_INJECT": "EmuNANDの健康と安全に挿入", + "H_AND_S_INJECT_SUCCESS": "健康と安全に挿入が成功しました", + "H_AND_S_INJECT_FAILURE": "健康と安全に挿入に失敗しました", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを解凍しますか?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル解凍済み\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_EXTRACTED": "%lu/%luファイル解凍済み", + "EXTRACTING_DOT_CODE": ".codeを解凍中。お待ちください。", + "PATH_EXT_EXTRACTED_TO_OUT": "%1$s\n%3$sへ%2$sを解凍しました", + "DOT_CODE_EXTRACT_FAILED": ".codeの解凍に失敗しました", + "TRANSFER_TO_SYSNAND": "システムNANDへ転送", + "TRANSFER_TO_EMUNAND": "EmuNANDへ転送", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND転送が成功しました", + "CTRNAND_TRANSFER_FAILED": "CTRNAND転送に失敗しました", + "NO_VALID_DESTINATION_FOUND": "有効な移動先がありません", + "NAND_RESTORE_SUCCESS": "NAND復元が成功しました", + "NAND_RESTORE_FAILED": "NAND復元に失敗しました", + "REBUILD_NCSD_SUCCESS": "NCSDの再作成が成功しました", + "REBUILD_NCSD_FAILED": "NCSDの再作成に失敗しました", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfoのパッド作成が成功しました%c出力場所: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfoのパッド作成に失敗しました%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "埋め込みバックアップを更新中…", + "BACKUP_UPDATE_NOT_REQUIRED": "バックアップ更新: 不要", + "BACKUP_UPDATE_COMPLETED": "バックアップ更新: 成功", + "BACKUP_UPDATE_FAILED": "バックアップ更新: 失敗!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "警告: キーが検証されていません。\n自己責任で続けますか?", + "AESKEYDB_INIT_SUCCESS": "AESkeydbを設定が成功しました", + "AESKEYDB_INIT_FAILED": "AESkeydbを設定に失敗しました", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydbをインストールが成功しました", + "AESKEYDB_INSTALL_FAILED": "AESkeydbをインストールに失敗しました", + "INSTALL_TO_FIRM0": "FIRM0にインストール", + "INSTALL_TO_FIRM1": "FIRM1にインストール", + "INSTALL_TO_BOTH": "両方にインストール", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nシステムNANDにインストールしますか?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nインストール成功", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nインストール失敗", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "警告: 信頼できないソースから\nスクリプトを実行しないでください。\n \nスクリプトを実行しますか?", + "SCRIPT_EXECUTE_SUCCESS": "スクリプト実行成功", + "SCRIPT_EXECUTE_FAILURE": "スクリプト実行失敗", + "ERROR_CANNOT_VIEW_FILE": "エラー: ファイルを表示できません\n(ヒント: 大きすぎるかもしれません)", + "SAVEGAME_DUMPED_TO_OUT": "セーブゲームは%sにダンプしました。", + "SAVEGAME_DUMP_FAILED": "セーブゲームをダンプに失敗しました!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VCセーブゲームは\nクリップボードにある必要があります。", + "SAVEGAME_INJECT_SUCCESS": "セーブゲームを注入が成功しました。", + "SAVEGAME_INJECT_FAILED": "セーブゲームを注入に失敗しました!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "フォントは次の起動時に使用になります", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "言語は次の起動時に使用になります", + "HOME_MORE_MENU_SELECT_ACTION": "HOMEのその他…メニュー\nアクションを選択:", + "SD_FORMAT_MENU": "SDフォーマットメニュー", + "BONUS_DRIVE_MENU": "ボーナスドライブのセットアップ", + "SWITCH_EMUNAND": "EmuNANDを切り替える", + "BUILD_SUPPORT_FILES": "サポートファイルを作成", + "RESTORE_H_AND_S": "健康と安全を復元", + "SET_RTC_DATE_TIME": "RTCの日時を設定", + "CONFGURE_BRIGHTNESS": "明るさを設定", + "CALIBRATE_TOUCHSCREEN": "タッチスクリーンを調整", + "SYSTEM_INFO": "システム情報", + "SHOW_README": "READMEを表示", + "INITIALIZING_SD_FAILED_RETRY": "SDカードの初期化に失敗しました!再試行しますか?", + "SETUP_FAILED": "設定に失敗しました!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "現在のEmuNANDオフセットは%06lXです。\n次のオフセットに切り替えますか?", + "BUILT_IN_OUT_STATUSES": "%sに作成しました。\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (システムとEmu)", + "OK_SYS": "OK (システム)", + "FAILED": "失敗", + "RESTORE_H_AND_S_EMUNAND": "健康と安全を復元(EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "健康と安全を復元(システムNAND)", + "TITLE_SET_RTC_DATE_TIME": "RTCの日時を設定:", + "NEW_RTC_DATE_TIME_IS_TIME": "新しいRTC日時は:\n%s\n \nヒント: HOMEメニューの時刻は、\nRTCを設定した後、\n手動で調整する必要があります。", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "タッチスクリーン調整が成功しました!", + "TOUCHSCREEN_CALIBRATION_FAILED": "タッチスクリーン調整に失敗しました!", + "GODMODE9_README_TOC": "GodMode9 READMEの目次", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "必須ファイルのバックアップがありません。\n今すぐ作成しますか?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "バックアップはシステムNANDに埋め取れ、\n%sに書き込みました。", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC日時が間違っているようです。\n今すぐ設定しますか?", + "RESUME_GODMODE9": "GodMode9へ続ける", + "RESUME_BOOTLOADER": "ブートローダーへ続ける", + "SELECT_PAYLOAD": "ペイロードを選択…", + "SELECT_SCRIPT": "スクリプトを選択…", + "SELECT_LUA_SCRIPT": "Luaスクリプトを選択…", + "POWEROFF_SYSTEM": "本体を電源オフ", + "REBOOT_SYSTEM": "本体を再起動", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%sブートローダーメニュー\nアクションを選択:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "ブートローダーのペイロードメニュー\nペイロードを選択:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "ブートローダーのスクリプトメニュー\nスクリプトを選択:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "起動可能なFIRMがありません。\nGodMode9を開始中...", + "OUT_OF_MEMORY": "メモリ不足です。", + "INVALID_DIRECTORY_OBJECT": "無効なディレクトリオブジェクト", + "INVALID_ROOT_DIRECTORY": "無効なルートディレクトリ", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "書き込み権限が変更されました。\n再ロックしますか?", + "OPEN_TITLE_MANAGER": "タイトルマネージャーを開く", + "SEARCH_FOR_FILES": "ファイルを検索…", + "FIX_CMACS_FOR_DRIVE": "ドライブのCMACを修正", + "SHOW_DIRECTORY_INFO": "ディレクトリ情報を表示", + "SHOW_DRIVE_INFO": "ドライブ情報を表示", + "FAILED_SETTING_UP_TITLE_MANAGER": "タイトルマネージャーの設定に失敗しました!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "%sを検索しますか?\n以下に検索を入力してください。", + "FOUND_N_RESULTS": "%lu件の結果が見つかりました。", + "FIX_CMACS_FOR_DRIVE_FINISHED": "ドライブのCMACを修正が完了しました。", + "FAILED_TO_ANALYZE_DRIVE": "ドライブを解析に失敗しました\n", + "FAILED_TO_ANALYZE_DIR": "ドライブを解析に失敗しました\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "バーチャルパスでは不可", + "DELETE_N_PATHS": "%lu個のパスを削除しますか?", + "DELETING_FILES_PLEASE_WAIT": "ファイルを削除中。お待ちください。", + "FAILED_DELETING_N_OF_N_PATHS": "%lu/%luパスの削除に失敗しました", + "DELETE_FILE": "「%s」を削除しますか?", + "FAILED_DELETING_PATH": "%s\nの削除に失敗しました。", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "検索ドライブでは不可", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "バーチャルゲームパスでは不可", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "XORパッドドライブでは不可", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "ゲームカートドライブでは不可", + "NOT_ALLOWED_IN_ALIAS_PATH": "エイリアスパスでは不可", + "COPY_PATHS": "パスをコピー", + "MOVE_PATHS": "パスを移動", + "PASTE_FILE_HERE": "ここに「%s」を貼り付けますか?", + "PASTE_N_PATHS_HERE": "%lu個パスをここに貼り付けますか?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "%s\nのコピーに失敗しました。\n残りを処理しますか?", + "FAILED_COPYING_PATH": "%s\nのコピーに失敗しました。", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "%s\nの移動に失敗しました。\n残りを処理しますか?", + "FAILED_MOVING_PATH": "%s\nの移動に失敗しました。", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "%sの名前を変更しますか?\n新しい名前を以下に入力してください。", + "FAILED_RENAMING_PATH": "%s\nの名前を変更に失敗しました。", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "ここで新しいエントリを作成しますか?\nタイプを選択してください。", + "CREATE_A_FOLDER": "フォルダを作成", + "CREATE_A_DUMMY_FILE": "空きファイルを作成", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "ここで新しいフォルダを作成しますか?\n以下に名前を入力してください。", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "ここで新しいファイルを作成しますか?\n以下に名前を入力してください。", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "ここで新しい%sを作成しますか?\n以下にファイルサイズを入力してください。", + "FAILED_CREATING_FOLDER_PATH": "%s\nフォルダの作成に失敗しました。", + "FAILED_CREATING_FILE_PATH": "%s\nファイルの作成に失敗しました。", + "TITLE_MANAGER": "タイトルマネージャー", + "BRICK_MY_3DS": "3DSをBRICKする", + "LANGUAGE": "言語…", + "SCRIPTS": "スクリプト…", + "LUA_SCRIPTS": "Luaスクリプト…", + "PAYLOADS": "ペイロード…", + "MORE": "その他…", + "BRACKET_MORE": "[さらに…]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOMEボタンが押された。\nアクションを選択:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWERボタンが押された。\nアクションを選択:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SDカード", + "B_DRIVE_SD_CARD": "[B:] SDカード", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "タイトルマネージャーメニュー\nタイトル元を選択してください。", + "LANGUAGES_DIRECTORY_NOT_FOUND": "言語フォルダがありません。\n(デフォルトパス:0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "スクリプトフォルダがありません。\n(デフォルトパス:0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Luaスクリプトフォルダがありません。\n(デフォルトパス:0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOMEの言語…メニュー\n言語を選択:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOMEのスクリプト…メニュー\nスクリプトを選択:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOMEのLuaスクリプト…メニュー\nスクリプトを選択:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "ペイロードフォルダがありません。\n(デフォルトパス:0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOMEのペイロード…メニュー\nペイロードを選択:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "‼予期しないSDカードの取り出し‼\n \nデータの損失を防ぐために、SDカードを取り出す前に\nマウントを解除してください。", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%sのスクリプト…メニュー\nスクリプトを選択:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "スクリプト自動実行機としてコンパイルされましたが、\nスクリプトが含まれませんでした。\n \nバカ!", + "KEYBOARD_CONTROLS_DETAILS": "キーボードのコントロール:\n \n←/→ - カーソルを移動\nR - 大文字・小文字(ロック)\nX - 文字を削除\nY - 文字を挿入\nA - 送信\nB - キャンセル\n \nSELECTで古いプロンプトに切り替わる", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "赤い十字をタッチして、\nタッチスクリーンを調整してください。\n \n最良の結果を得るには、\nタッチペンを使用してください!", + "INVALID": "無効", + "TO_PROCEED_ENTER_THIS": "続けるには、これを入力してください。", + "TO_PROCEED_HOLD_X": "続けるには、を長押してください。", + "N_MORE": " [と%d個]", + "CANCEL": "キャンセル", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) 高速スクロール\nL - データをクリア", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - 文字を削除\nY - 文字を挿入", + "ETA_N_HOUR_N_MIN_N_SEC": "残り%02llu時%02llu分%02llu秒", + "ETA_N_MIN_N_SEC": "残り%02llu分%02llu秒", + "BRIGHTNESS_CONTROLS": "[→] 明るさを上げる\n[←] 明るさを下げる\n \n[X] 音量スライダーでコントロール\n[A] 現在の明るさを設定\n[B] キャンセル", + "SEARCHING_PLEASE_WAIT": "検索中です。お待ちください。", + "RENAME_TO_GOOD_NAME": "名前を良い名前に変更しますか?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SDカードが書き込み禁止になっている!\n続行できません。", + "SYSNAND_LVL_N": "システムNAND(レベル%lu)", + "EMUNAND_LVL_N": "EmuNAND(レベル%lu)", + "GAME_IMAGES": "ゲームイメージ", + "GAMECART_SAVES": "ゲームカートセーブ", + "IMAGES": "イメージ", + "MEMORY_AREAS": "メモリ領域", + "SD_SYSTEM_DATA": "SDシステムデータ", + "SD_CARD": "SDカード", + "RAM_DRIVE": "RAMドライブ", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "%sへの書き込みがロックされています!\n今すぐロックを解除しますか?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "%sの書き込み権限のロックを\n解除することができません。", + "ENABLE_BASE_WRITE": "普通の書き込み権限を有効にしたい。", + "ENABLE_SD_WRITE": "SDカードの書き込み権限を有効にしたい。", + "ENABLE_IMAGE_WRITE": "イメージの書き込み権限を有効にしたい。", + "ENABLE_RAM_DRIVE_WRITE": "RAMドライブの書き込み権限を有効にしたい。", + "ENABLE_EMUNAND_0_WRITE": "EmuNANDレベル0の書き込み権限を有効にしたい。", + "ENABLE_SYSNAND_0_WRITE": "システムNANDレベル0の書き込み権限を有効にしたい。", + "ENABLE_EMUNAND_1_WRITE": "EmuNANDレベル1の書き込み権限を有効にしたい。\n \nこれにより、回復可能なシステムデータ、ユーザー\nデータ、セーブゲームを変更するが許可になります。", + "ENABLE_SYSNAND_1_WRITE": "EmuNANDレベル1の書き込み権限を有効にしたい。\n \nこれにより、システムデータ、インストール、ユーザー\nデータ、セーブゲームを変更するが許可になります。", + "ENABLE_GAMECART_SAVE_WRITE": "ゲームカートのセーブの書き込み権限を有効にしたい。", + "ENABLE_SYSNAND_2_WRITE": "‼気をつけて‼\n \nシステムNANDレベル2の書き込み権限を有効にしたい。\n \nこれにより、回復不能なシステムデータを\n変更するが許可になります!", + "ENABLE_MEMORY_WRITE": "‼気をつけて‼\n \nメモリの書き込み権限を有効にしたい。\n \n特定の地域に書き込むと、予期せぬ\n結果に繋がら可能性があります。", + "ENABLE_SD_DATA_WRITE": " ・・・・・・・・・・・\n‼これはおすすめしません‼\n \nSDデータの書き込み権限を有効にしたい。\n\nここはすべて暗号化されています。\nインストール、ユーザーデータ、セーブゲームの変更では\n代わりに、A:/B:ドライブを使用するをおすすめします。", + "ENABLE_SYSNAND_3_WRITE": " ・ ・ ・ ・ ・ ・ ・ ・ ・ ・\n‼ こ れ は 唯 一 の 警 告 で す ‼\n‼ THIS IS THE ONLY WARNING ‼\n \nシステムNANDレベル3の書き込み権限を有効にしたい。\n \nこれにより、ブートローダーと必須システムファイルを\n・上書きする・や本体を・BRICKする・(壊す)\nが許可になります!", + "UNLOCK_WRITE_NOT_ALLOWED": "書き込み権限のロックを解除することができません。", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "書き込み権限の解除ができません。\n代わりにGodMode9をお試しください。", + "ERROR_SD_TOO_SMALL": "エラー: SDカードが小さすぎます", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": " ・ ・\n‼ 警 告 ‼\n \n続けると、このSDをフォーマットします。\nこれにより、・すべて・のデータを元に戻せない削除されます。", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "ボーナスドライブをフォーマットしますか?\nこれにより、・すべて・のデータを元に戻せない削除されます。", + "FORMATTING_SD_PLEASE_WAIT": "SDをフォーマット中。お待ちください。", + "FORMATTING_DRIVE_PLEASE_WAIT": "ドライブをフォーマット中。お待ちください。", + "ERROR_SD_CARD_IO_FAILURE": "エラー: SDカード入出力失敗", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "ファイルは現在マウントされています。\nマウントを解除してロックを解除しますか?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "エラー: ファイルを自体に挿入できません", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "操作はファイルの終わりを超えて書き込まれます", + "NOT_ENOUGH_DATA_IN_FILE": "ファイル内のデータが不足しています", + "CANCEL_IS_NOT_ALLOWED_HERE": "ここではキャンセルができません", + "B_DETECTED_CANCEL": "Bボタンが検出されました。キャンセルしますか?", + "ERROR_CANNOT_APPEND_FOLDER": "エラー: フォルダを追加できません", + "ERROR_OVERWRITING_FILE_WITH_DIR": "エラー: ファイルをフォルダで上書きする", + "ERROR_OVERWRITING_DIR_WITH_FILE": "エラー: フォルダをファイルで上書きする", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "エラー: ファイル先を開くことができません", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "エラー: 空き容量が不足しています", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "エラー: FATファイルのみを移動できます", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "エラー: 先は元の一部です", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "先は元と同じです。\n別の名前を選択しますか?", + "CHOOSE_NEW_NAME": "新しい名前を選択", + "OVERWRITE_FILES": "ファイルを上書き", + "SKIP_FILES": "ファイルをスキップ", + "OVERWRITE_ALL": "すべて上書き", + "SKIP_ALL": "すべてスキップ", + "DESTINATION_ALREADY_EXISTS": "%s\nは既に存在します。", + "CHOOSE_NEW_DESTINATION_NAME": "パス先の新しい名前を選択してください", + "COPY_OPERATION_IS_NOT_ALLOWED": "コピー操作は許可されていません", + "DESTINATION_EQUALS_ORIGIN": "先は元と同じです。", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "%sがありません。\n代わりに、 %sに挿入しますか?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "利用可能な領域より小さいファイル。\n%s (%s)\n%s (%s)\n続けますか?", + "NO_USABLE_ENTRIES_FOUND": "使用可能なエントリがありません。", + "BEAT_NO_ERROR": "エラーなし", + "BEAT_END_OF_ACTION_LIST": "アクションリストの最後", + "BEAT_ABORTED_BY_USER": "ユーザーによる中止", + "BEAT_FAILED_TO_READ_WRITE_FILE": "ファイルの読み取り・書き込みに失敗しました", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "ファイルの終わりを越えて書き込もうとした", + "BEAT_INVALID_PATCH_FILE": "無効なパッチファイル", + "BEAT_INVALID_INPUT_FILE": "無効な入力ファイル", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "出力ファイルのチェックサムが一致しません", + "BEAT_FILE_CHECKSUM_FAILED": "ファイルのチェックサムに失敗しました", + "BEAT_EXPECTED_MORE_PATCH_DATA": "より多くのパッチデータを予期しています", + "BEAT_OUT_OF_MEMORY": "メモリ不足です", + "BEAT_UNKNOWN_ERROR": "不明なエラー", + "FAILED_TO_INITIALIZE_BPM_FILE": "%s\nのBPMファイルの初期化に失敗しました。", + "FAILED_TO_INITIALIZE_BPS_FILE": "%s\nのBPSファイルの初期化に失敗しました。", + "PATCH_SUCCESSFULLY_APPLIED": "パッチが正常に当てました", + "PATCHING_ABORTED_BY_USER": "ユーザーによってパッチが中止されました", + "FAILED_TO_RUN_PATCH": "%s\nのパッチの実行に失敗しました。", + "DECOMPRESSING_DOT_CODE": ".codeを解凍中…", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": ".codeを解凍中…\nBボタンが検出されました。キャンセルしますか?", + "COMPRESSING_DOT_CODE": ".codeを圧縮中…", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": ".codeを圧縮中…\nBボタンが検出されました。キャンセルしますか?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "パッチはおそらくこのファイルに意図されていません。", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "出力ファイルにパッチをおそらく当てました。", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "パッチは技術的に有効ですが、\nスクランブルや不正ようです。", + "PATCH_IS_INVALID": "パッチは無効です。", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "一つまたは両方のファイルが16MBより大きい。\nIPSフォーマットはそれをサポートしていません。", + "REQUESTED_FILE_PATH_WAS_INVALID": "要求されたファイルパスが無効です。", + "PATCHING_CANCELED": "パッチの当てがキャンセルしました。", + "NOT_ENOUGH_MEMORY": "メモリ不足です。", + "REGION_AMERICAS": "アメリカ", + "REGION_AUSTRALIA": "オーストラリア", + "REGION_BRAZIL": "ブラジル", + "REGION_CHINA": "中国", + "REGION_EUROPE": "ヨーロッパ", + "REGION_FRANCE": "フランス", + "REGION_GERMANY": "ドイツ", + "REGION_ITALY": "イタリア", + "REGION_JAPAN": "日本", + "REGION_KOREA": "韓国", + "REGION_SPAIN": "スペイン", + "REGION_TAIWAN": "台湾", + "REGION_UNKNOWN": "不明", + "REGION_UNITED_KINGDOM": "イギリス", + "REGION_MIDDLE_EAST": "中東", + "GENERATING_QR_CODE": "QRコードの生成…", + "REINITIALIZING_SD_CARD": "SDカードを再初期化中…", + "DUMPING_STATE_TO_SD_CARD": "SDカードに状態をダンプ中…", + "PRESS_POWER_TO_TURN_OFF": "POWERを押して電源オフにする", + "CLEANING_UP_TITLES_PLEASE_WAIT": "タイトルをクリーンアップ中。お待ちください。", + "ERROR_NOT_NCCH_FILE": "エラー: NCCHファイルではない", + "ERROR_FILE_IS_TOO_SMALL": "エラー: ファイルが小さすぎます", + "ATTEMPT_FIX_THIS_TIME": "今回、修正を試みます", + "ATTEMPT_FIX_ALWAYS": "常、修正を試みます", + "ABORT_VERIFICATION": "検証を中止", + "ERROR_BAD_CRYPTO_FLAGS": "エラー: 不正な暗号化フラグ", + "ERROR_BAD_EXEFS_HEADER": "エラー: 不正なExeFSヘッダ", + "ERROR_MISSING_EXTHEADER": "エラー: ExtHeaderがありません", + "ERROR_CRYPTO_NOT_SET_UP": "エラー: 暗号化が設定されていません", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCHの検証に失敗しました。\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "OK", + "FAIL": "失敗", + "ERROR_NOT_NCSD_FILE": "エラー: NCSDファイルではない", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%1$s\nコンテンツ第%2$lu個(%4$08lXで%3$08lX):\n検証に失敗しました", + "ERROR_PROBABLY_NOT_CIA_FILE": "エラー: おそらくNCSDファイルではない", + "ERROR_TMD_PROBABLY_CORRUPTED": "エラー: TMDがおそらく破損しています", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%1$s\nID第%2$lu個(%4$08lXで%3$08lX):\n検証に失敗しました", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "エラー: CDNのタイトルキーがありません", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLCコンテンツがありません\n \nすべてを無視して続けますか?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\n第%lu部のハッシュが一致しません", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9のエントリポイントがありません", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "警告: ARM11のエントリポイントがありません", + "ERROR_NOT_A_BOSS_FILE": "エラー: BOSSファイルではない", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSSペイロードのハッシュが一致しません。\n \n修正してみますか?", + "GENERIC_TICKET_PIRATE_LEGIT": "一般的なチケット(\"海賊合法\")", + "PERSONALIZED_TICKET_LEGIT": "個人的なチケット(合法)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID第%016llX個\n合法のチケットは個人的です。\nこれを使用することはおすすめしません。\nデフォルトのアクションを選択してください。", + "ID_N_TITLEKEY_NOT_FOUND": "ID第%016llX個\nタイトルキーがありません。", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID第%016llX個\nTADのTMDは合法ではない。", + "ID_N_TMD_NOT_LEGIT": "ID第%016llX個\nTMDは合法ではない。", + "ID_N_DOT_N_STATUS": "ID第%016llX.%08lX個\n%s", + "CONTENT_IS_CORRUPT": "コンテンツが破損しています", + "INSERT_CONTENT_FAILED": "コンテンツを挿入に失敗しました", + "INSTALL_CONTENT_FAILED": "コンテンツをインストールに失敗しました", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "インストールエラー:\nこの本体には、1つ以上の.dbファイルがありません。\n \nもしかしSDカードがなくなりまたは\n初期化されていませんことができますか?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "インストールエラー:\nこの本体には、ticket.dbファイルがありません。", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "タイトルをスキップしました。\nID 0004008C000CBD00のタイトルは、特別な\nコンパイラフラグ必要があります。", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "エラー: 偽署名付きチケット\n \n有効な署名付きチケットのみは、\n本体にインストールできます。", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nエラー: 不明なCID %08lX\n \nチケットはこの3DS本体に属していません。", + "INSTALLING_TICKET": "チケットをインストール中…", + "POSSIBLY_BROKEN": "破損の可能性あり", + "PERSONAL_LEGIT": "個人的な合法", + "PERSONAL_LEGIT_DLC": "個人的な合法DLC", + "PERSONAL_PIRATE_LEGIT": "個人的な海賊合法", + "PERSONAL_PIRATE_LEGIT_DLC": "個人的な海賊合法DLC", + "PERSONAL_CUSTOM": "個人的なカスタム", + "PERSONAL_CUSTOM_DLC": "個人的なカスタムDLC", + "UNIVERSAL_LEGIT": "普遍的な合法", + "UNIVERSAL_LEGIT_DLC": "普遍的な合法DLC", + "UNIVERSAL_PIRATE_LEGIT": "普遍的な海賊合法", + "UNIVERSAL_PIRATE_LEGIT_DLC": "普遍的な海賊合法DLC", + "UNIVERSAL_CUSTOM": "普遍的なカスタム", + "UNIVERSAL_CUSTOM_DLC": "普遍的なカスタムDLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "CIAのコンテンツ数: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "TMDのコンテンツ数: %lu個", + "CONSOLE_ID_N": "本体ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%sの%sタイトル\n \nタイトルID: %016llX\nタイトルバージョン: %lu.%lu.%lu\nコンテンツサイズ: %s\n%s\n%s \nチケット/TMD: %s/%s\n検証: %s", + "STATE_LEGIT": "合法", + "STATE_ILLEGIT": "非合法", + "STATE_UNKNOWN": "不明", + "STATE_INVALID": "無効", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "未決\n \n検証に続けますか?", + "STATE_PASSED": "合格", + "STATE_FAILED": "失敗", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "出力ファイルがすでに存在する。\nこれを更新しますか?", + "DSI_ENHANCED": "DSi対応", + "DSI_EXCLUSIVE": "DSi専用", + "FIXING_CMACS_PLEASE_WAIT": "CMACを修正中。お待ちください。", + "NCSD_HEADER_IS_NOT_VALID": "NCSDヘッダーが無効です", + "NAND_DUMP_MISSING_DATA": "NANDダンプはデータ欠落しています", + "ERROR_CTR_MBR_IS_CORRUPT": "エラー: CTR MBRが破損しています", + "ERROR_TWL_MBR_IS_CORRUPT": "エラー: TWL MBRが破損しています", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nエラー: CTRパーティション第%luが破損しています", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nエラー: TWLパーティション第%luが破損しています", + "NO_VALID_FIRM_FOUND": "有効なFIRMがありません", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "エラー: NANDダンプが破損しています。\nまだ続けますか?", + "ERROR_SYSTEM_IS_LOCKED": "エラー: 本体がロックされています", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "必須ファイルのバックアップ必要があります。\n今すぐ作成しますか?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": " ・ ・\n‼ 警 告 ‼\n \n続けると、システムNANDが与えられたダンプで上書きされます。\n \n(B9S/A9LHはそのまま残ります)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "イメージのNCSDが破損またはカスタムです。\n安全な復元はできません!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": " ・ ・\n‼ 警 告 ‼\n\nNCSDはイメージとローカルで異なるので、\n昇格書き込み権限必要があります。\n\n自己責任で続けますか?", + "NOT_AN_INSTALLABLE_FIRM": "インストール可能なFIRMではない。", + "FIRM_LOAD_VERIFY_ERROR": "FIRMの読み取り・検証失敗。", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%luがありませんまたは小さすぎます。", + "SECTOR_0X96_CRYPTO_FAIL": "セクタ0x96暗号化に失敗しました。", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "セクタ0x96が破損しています。\n \nセクタ0x96を修正するには、\n「secret_sector.bin」を与えてください。", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "セクタ0x96が破損しています。\n \nインストール中にセクタ0x96を修正しますか?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": " ・ ・\n‼ 警 告 ‼\n \n続けると、与えられたFIRMをシステムNANDに\nインストールし、sighaxを挿入します。\n \nサポートされていないFIRMをインストールすると、\n本体をBRICKします!(壊れます!)", + "INSTALLING_FIRM_PLEASE_WAIT": "インストール中。お待ちください。", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nセクタ0x96の書き込みに失敗しました。\n再起動する前に修正してみてください!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nFIRM%luの書き込みに失敗しました。\n再起動する前に修正してみてください!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "インストールを確認中。お待ちください。", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nセクタ0x96の検証に失敗しました。\n再起動する前に修正してみてください!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nFIRM%luの検証に失敗しました。\n再起動する前に修正してみてください!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "完全な%sはインストール済みです。", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\n完全な%sイメージではない。\nNANDにインストールできません!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\n%sをNANDへの書き込みに失敗しました!", + "USE_L_R_TO_SAVE": "(L+Rで保存)", + "EASTER_NOT_FOUND": "(%sがありません)", + "BUILDING_TO_OUT_ARG": "%sに作成中…\n%s", + "EJECT_SD_CARD": "SDカードを取り出す…", + "INSERT_SD_CARD": "SDカードを挿入…", + "SCRIPTERR_UNKNOWN_CMD": "不明コマンド", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "不正な引数数", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "不明フラグ", + "SCRIPTERR_ILLEGAL_FLAG": "禁止フラグ", + "SCRIPTERR_UNRESOLVED_QUOTES": "未解決な引用符", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "多すぎる引数", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "引数展開失敗", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "「not」エラー", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "「if」後の構文エラー", + "SCRIPTERR_ELIF_WITHOUT_IF": "「if」のない「elif」", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "「elif」後の構文エラー", + "SCRIPTERR_ELSE_WITHOUT_IF": "「if」のない「else」", + "SCRIPTERR_END_WITHOUT_IF": "「if」のない「end」", + "SCRIPTERR_FOR_INSIDE_FOR": "「for」の中「for」", + "SCRIPTERR_DIR_NOT_FOUND": "フォルダありません", + "SCRIPTERR_FOR_WITHOUT_NEXT": "「next」のない「for」", + "SCRIPTERR_NEXT_WITHOUT_FOR": "「for」のない「next」", + "SCRIPTERR_FORPATH_ERROR": "forpathエラー", + "SCRIPTERR_LABEL_NOT_FOUND": "ラベルありません", + "SCRIPTERR_USER_ABORT": "ユーザー中止", + "SCRIPTERR_KEY_NOT_PRESSED": "キー押されていない", + "SCRIPTERR_OUT_OF_MEMORY": "メモリ不足", + "SCRIPTERR_VAR_FAIL": "変数失敗", + "SCRIPTERR_FORBIDDEN_DRIVE": "禁止ドライブ", + "SCRIPTERR_INVALID_PATH": "無効パス", + "SCRIPTERR_FILESELECT_ABORT": "ファイル選択中止", + "SCRIPTERR_DIRSELECT_ABORT": "フォルダ選択中止", + "SCRIPTERR_SET_FAIL": "設定失敗", + "SCRIPTERR_CHAR_NOT_FOUND": "charありません", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2]はcharではない", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2]は2文字でなければなりません", + "SCRIPTERR_ARG_MATCH": "引数一致", + "SCRIPTERR_NO_ARG_MATCH": "引数不一致", + "SCRIPTERR_PERMISSION_FAIL": "権限失敗", + "SCRIPTERR_COPY_FAIL": "コピー失敗", + "SCRIPTERR_MOVE_FAIL": "移動失敗", + "SCRIPTERR_INJECT_FAIL": "注入失敗", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte失敗", + "SCRIPTERR_FILL_FAIL": "埋め失敗", + "SCRIPTERR_BAD_FILESIZE": "無効ファイルサイズ", + "SCRIPTERR_CREATE_DUMMY_FILE": "ダミー作成失敗", + "SCRIPTERR_REMOVE_FAIL": "削除失敗", + "SCRIPTERR_MAKEDIR_FAIL": "フォルダ作成失敗", + "SCRIPTERR_MOUNT_FAIL": "マウント失敗", + "SCRIPTERR_FIND_FAIL": "検索失敗", + "SCRIPTERR_FINDNOT_FAIL": "not検索失敗", + "SCRIPTERR_NO_SIZE_GIVEN": "サイズありません", + "SCRIPTERR_SIZE_TOO_BIG": "多すぎるサイズ", + "SCRIPTERR_READ_FAIL": "読み込み失敗", + "SCRIPTERR_CONVERSION_FAIL": "変換失敗", + "SCRIPTERR_INVALID_DATA": "無効データ", + "SCRIPTERR_WRITE_FAIL": "書き込み失敗", + "SCRIPTERR_SHA_ARG0_FAIL": "SHA第0引数失敗", + "SCRIPTERR_SHA_ARG1_FAIL": "SHA第1引数失敗", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "SHA不一致", + "SCRIPTERR_SHA_WRITE_FAIL": "SHA書き込み失敗", + "SCRIPTERR_FILE_WRITE_FAIL": "ファイル書き込み失敗", + "SCRIPTERR_FIXCMAC_FAILED": "CMAC修正失敗", + "SCRIPTERR_VERIFICATION_FAILED": "検証失敗", + "SCRIPTERR_DECRYPT_FAILED": "復号失敗", + "SCRIPTERR_ENCRYPT_FAILED": "暗号失敗", + "SCRIPTERR_BUILD_CIA_FAILED": "CIA作成失敗", + "SCRIPTERR_INSTALL_GAME_FAILED": "ゲームインストール失敗", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": ".code含まない", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": ".code解凍失敗", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": ".code圧縮失敗", + "SCRIPTERR_BUILD_FAILED": "作成失敗", + "SCRIPTERR_UNKNOWN_FILE": "不明ファイル", + "SCRIPTERR_APPLY_IPS_FAILD": "IPS当てる失敗", + "SCRIPTERR_APPLY_BPS_FAILED": "BPS当てる失敗", + "SCRIPTERR_APPLY_BPM_FAILED": "BPM当てる失敗", + "SCRIPTERR_TEXTVIEWER_FAILED": "テキストビューアー失敗", + "SCRIPTERR_BAD_DUMPSIZE": "不良ダンプサイズ", + "SCRIPTERR_CART_INIT_FAIL": "カート初期化失敗", + "SCRIPTERR_CART_DUMP_FAILED": "カートダンプ失敗", + "SCRIPTERR_NOT_A_DIR": "フォルダではない", + "SCRIPTERR_FILE_NOT_FOUND": "ファイルありません", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "起動できるFIRMではない", + "SCRIPTERR_SD_NOT_MOUNTED": "SDマウントされていない", + "SCRIPTERR_UNKNOWN_ERROR": "不明なエラー", + "SCRIPTERR_COMMAND_SUCCESS": "コマンド成功", + "SCRIPTERR_CONTROL_FLOW_ERROR": "制御流れエラー", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "未解決条件付き", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "エラーメッセージ失敗", + "ERROR_INVALID_TEXT_DATA": "エラー: 無効なテキストデータ", + "TEXTVIEWER_CONTROLS_DETAILS": "テキストビューアーのコントロル\n \n↑↓→←(+R) - スクロール\nR+Y - ワードラップを切り替え\nR+X - 行番号に移動\nB - 終了\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "現在の行: %i\n以下に新しい行を入力してください。", + "PREVIEW_DISABLED": "(プレビュー無効)", + "PATH_LINE_N_ERR_LINE": "%s\n第%lu行: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "スクリプトの終わり: 未解決の「if」", + "END_OF_SCRIPT_UNRESOLVED_FOR": "スクリプトの終わり: 未解決の「for」", + "SYSINFO_MODEL": "モデル: %s (%s)\n", + "SYSINFO_SERIAL": "シリアル: %s\n", + "SYSINFO_REGION_SYSTEM": "地域(本体): %s\n", + "SYSINFO_REGION_SALES": "地域(販売): %s\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "SoC製造日: %s\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "本体組立日:  %s\n", + "SYSINFO_ORIGINAL_FIRMWARE": "元のファームウェア: %s\n", + "SYSINFO_FRIENDCODE_SEED": "フレンドコードのシード: %s\n", + "SYSINFO_SD_KEYY": "SDキーY: %s\n", + "SYSINFO_NAND_CID": "NAND CID: %s\n", + "SYSINFO_SD_CID": "SD CID: %s\n", + "SYSINFO_SYSTEM_ID0": "本体ID0: %s\n", + "SYSINFO_SYSTEM_ID1": "本体ID1: %s\n", + "SORTING_TICKETS_PLEASE_WAIT": "チケットを並べ替えています。お待ちください。", + "LUA_NOT_INCLUDED": "このGodMode9のビルドは、Luaを\nサポートせずにコンパイルされています。" +} diff --git a/resources/languages/nl.json b/resources/languages/nl.json new file mode 100644 index 000000000..e4214b010 --- /dev/null +++ b/resources/languages/nl.json @@ -0,0 +1,706 @@ +{ + "GM9_LANGUAGE": "Nederlands", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX-%3$02lX-%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM te groot, kan niet opstarten", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nOpgepast: start geen FIRMs\nop van onbetrouwbare bronnen.\n\nStart FIRM op?", + "NOT_BOOTABLE_FIRM": "Geen opstartbare FIRM.", + "FIRM_ENCRYPTED": "FIRM is versleuteld.\n\nOntsleutelen voor het opstarten?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Kopiëren naar %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Probeer toch op te starten", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Opgepast: poging om op te starten\nvan een niet-ondersteunde locatie.", + "ROOT": "[root]", + "LOADING": "LADEN...", + "PANE_N": "PANEEL #%lu", + "CURRENT": "HUIDIGE", + "DIR": "(map)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAM-schijf FAT)", + "GAME_VIRTUAL": "(Game Virtueel)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtueel)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtueel)", + "IMAGE_FAT": "(Schijfkopie FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtueel)", + "MEMORY_VIRTUAL": "(Geheugen Virtueel)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Spelkaart Virtueel)", + "VRAM_VIRTUAL": "(VRAM Virtueel)", + "SEARCH": "(Zoeken)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtueel)", + "LAB_SDCARD": "SDKAART", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUEEL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUEEL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUEEL", + "LAB_GAMECART": "SPELKAART", + "LAB_GAME_IMAGE": "GAMEKOPIE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB KOPIE", + "LAB_BDRI_IMAGE": "BDRI-KOPIE", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF-KOPIE", + "LAB_MEMORY_VIRTUAL": "GEHEUGEN VIRTUEEL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUEEL", + "LAB_TITLE_MANAGER": "Beheer titels", + "LAB_LAST_SEARCH": "LAATSTE ZOEKOPDRACHT", + "LAB_FAT_IMAGE": "FAT-schijfkopie", + "LAB_BONUS_DRIVE": "BONUS-SCHIJF", + "LAB_RAMDRIVE": "RAM-schijf", + "LAB_NOLABEL": "GEENLABEL", + "N_BYTE": "%s Bytes", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[KLEMBORD]", + "PLUS_N_MORE": "+ %lu meer", + "MARK_DELETE_COPY": "L - MARKEER bestand (gebruiken met ↑↓→←)\nX - VERWIJDER / [+R] HERNOEM bestand\nY - KOPIEER bestand / [+R] MAAK nieuw bestand", + "MARK_DELETE_PASTE": "L - MARKEER bestand (gebruiken met ↑↓→←)\nX - VERWIJDER / [+R] HERNOEM bestand\nY - PLAK bestand / [+R] MAAK nieuw bestand", + "RELOCK_WRITE_PERMISSION": "R+Y - Schrijfrechten opnieuw vergrendelen\n", + "UNMOUNT_IMAGE": "R+X - Ontkoppel schijfkopie", + "UNMOUNT_SD": "R+B - Ontkoppel SD-kaart", + "REMOUNT_SD": "R+B - Herplaats SD-kaart", + "DIRECTORY_OPTIONS": "R+A - Mapopties", + "DRIVE_OPTIONS": "R+A - Schijfopties", + "MAKE_SCREENSHOT": "R+L - Maak een screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Ga naar vorig/volgend paneel", + "CLEAR_CLIPBOARD": "SELECT - Wis klembord", + "RESTORE_CLIPBOARD": "SELECT - Herstel klembord", + "REBOOT_POWEROFF_HOME": "START - Herstart / [+R] Sluit af\nHOME-knop voor HOME-menu", + "NO_EMUNAND": "Geen EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND-grootte (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND-grootte (volledig)", + "MULTINAND_SIZE_2X": "MultiNAND-grootte (2x)", + "MULTINAND_SIZE_3X": "MultiNAND-grootte (3x)", + "MULTINAND_SIZE_4X": "MultiNAND-grootte (4x)", + "USER_INPUT": "Gebruikersinvoer...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Fout: SD-kaart niet gedetecteerd.", + "FORMAT_SD_CHOOSE_EMUNAND": "Formatteer SD-kaart (%lluMB)?\nKies EmuNAND-grootte:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD-kaartgrootte is %lluMB.\nVoer hieronder de EmuNAND-grootte (MB) in:", + "FORMAT_SD_CHOOSE_CLUSTER": "Formatteer SD-kaart (%lluMB)?\nKies clustergrootte:", + "FORMAT_SD_ENTER_LABEL": "Formatteer SD-kaart (%lluMB)?\nVoer label in:", + "FORMAT_SD_FAILED": "SD formatteren: mislukt!", + "REDNAND_TYPE": "RedNAND-type", + "REDNAND_TYPE_MULTI": "RedNAND-type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND-type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND-type", + "DONT_SET_UP": "Niet instellen", + "CHOOSE_EMUNAND_TYPE": "Kies EmuNAND-type om in te stellen:", + "CLONE_SYSNAND_TO_REDNAND": "SysNAND naar RedNAND kopiëren?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Kopiëren van SysNAND naar EmuNAND: mislukt!", + "PRESS_A_TO_CONTINUE": "Druk op om verder te gaan", + "HEXEDITOR_CONTROLS": "Hex-editor toetsen:\n\n↑↓→←(+R) - Scroll\nR+Y - Wissel van beeld\nX - Zoek / ga...\nA - Open bewerkingsmodus\nA+↑↓→← - Waarde aanpassen\nB - Afsluiten", + "NOT_FOUND": "Niet gevonden!", + "GO_TO_OFFSET": "Ga naar offset", + "SEARCH_FOR_STRING": "Zoek naar tekst", + "SEARCH_FOR_DATA": "Zoek naar gegevens", + "CURRENT_OFFSET_SELECT_ACTION": "Huidige offset: %08lX\nSelecteer actie:", + "CURRENT_OFFSET_ENTER_NEW": "Huidige offset: %08lX\nVul hieronder de nieuwe offset in.", + "ENTER_SEARCH_REPEAT_SEARCH": "Voer de zoekterm hieronder in.\n(R+X om zoekopdracht te herhalen)", + "MADE_EDITS_SAVE_CHANGES": "Je maakte bewerkingen op %lu plaats(en).\nWijzigingen naar bestand opslaan?", + "FAILED_WRITING_TO_FILE": "Schrijven naar bestand mislukt!", + "CALCULATING_SHA_FAILED": "Berekenen van SHA-%s mislukt!", + "SHA_VERIFICATION_PASSED": "\nSHA-verificatie: geslaagd!", + "SHA_VERIFICATION_FAILED": "\nSHA-verificatie: mislukt", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentiek aan het vorige bestand:\n", + "WRITE_SHA_FILE": "\n \nSchrijf .SHA bestand?", + "WRITE_SHA1_FILE": "\n \nSchrijf .SHA1 bestand?", + "CALCULATING_CMAC_FAILED": "Berekenen van CMAC: mislukt!", + "CMAC_VERIFICATION_PASSED": "CMAC-verificatie: geslaagd!", + "CMAC_VERIFICATION_FAILED": "CMAC-verificatie: mislukt!", + "FIX_CMAC_IN_FILE": "\nRepareer CMAC in bestand?", + "FIXING_CMAC_FAILED": "CMAC repareren: mislukt!", + "COPY_ALL_SELECTED_ITEMS": "Alle %lu geselecteerde items kopiëren?", + "FAILED_COPYING_ITEM": "Kopiëren van item mislukt", + "ITEMS_COPIED_TO_OUT": "%lu items gekopieerd naar %s", + "PATH_COPIED_TO_OUT": "%s\nGekopieerd naar %s", + "CART_INIT_FAILED": "Spelkaartinitialisatie mislukt!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Spelkaart: %s\nGedetecteerde grootte: %s\n \nVoer de dumpgrootte hieronder in.", + "NDS_CART_DECRYPT_SECURE_AREA": "Spelkaart: %s\nNDS-kaart gedetecteerd\nDecrypteer de 'secure area'?", + "FAILED_DUMPING_CART": "%s\nDumpen spelkaart mislukt", + "PATH_DUMPED_TO_OUT": "%s\nGedumpt naar %s", + "CREATED": "gemaakt", + "MODIFIED": "gewijzigd", + "ANALYZING_DRIVE": "Schijf analyseren, even geduld...", + "ANALYZING_DIR": "Map analyseren, even geduld...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu bestanden & %lu mappen\ntotale grootte %s\n \nvrije ruimte: %s\ngebruikte ruimte: %s\ntotaal: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu bestanden & %lu mappen\ntotale grootte %s", + "FILESIZE_X": "bestandsgrootte: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %salleen lezen [%c] %sverborgen\n[%c] %ssysteem [%c] %sarchief\n[%c] %svirtueel\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← om attributen te wijzigen)\n", + "A_TO_CONTINUE": "( om verder te gaan)", + "A_APPLY_B_CANCEL": "( om toe te passen, om te annuleren)", + "A_YES_B_NO": "( ja, nee)", + "A_SELECT_B_CANCEL": "( selecteer, annuleer)", + "HOLD_B_TO_CANCEL": "(houd B ingedrukt om te annuleren)", + "FAILED_TO_SET_ATTRIBUTES": "Attributen instellen mislukt!", + "NAND_IMAGE_OPTIONS": "NAND-schijfkopieinstellingen...", + "CTRNAND_OPTIONS": "CTRNAND-instellingen...", + "MOUNT_FAT_IMAGE": "Koppel als FAT-schijfkopie", + "CIA_IMAGE_OPTIONS": "CIA-schijfkopieinstellingen...", + "NCSD_IMAGE_OPTIONS": "NCSD-schijfkopieinstellingen...", + "NCCH_IMAGE_OPTIONS": "NCCH-schijfkopieinstellingen...", + "MOUNT_AS_EXEFS_IMAGE": "Koppel als EXEFS-schijfkopie", + "MOUNT_AS_ROMFS_IMAGE": "Koppel als ROMFS-schijfkopie", + "TMD_FILE_OPTIONS": "TMD-bestandsinstellingen...", + "TMD_CDN_OPTIONS": "TMD/CDN-instellingen...", + "TMD_TWL_OPTIONS": "TMD/TWL-instellingen...", + "MANAGE_TITLE": "Titel beheren...", + "BOSS_FILE_OPTIONS": "BOSS-bestandsinstellingen...", + "DECRYPT_NUS_CDN_FILE": "Decodeer NUS/CDN-bestand", + "SHOW_SMDH_TITLE_INFO": "Toon SMDH titelinfo", + "NDS_IMAGE_OPTIONS": "NDS-schijfkopieinstellingen...", + "GBA_IMAGE_OPTIONS": "GBA-schijfkopieinstellingen...", + "TICKET_OPTIONS": "Ticketinstellingen...", + "TAD_IMAGE_OPTIONS": "TAD-schijfkopieinstellingen...", + "SHOW_3DSX_TITLE_INFO": "Toon 3DSX titelinfo", + "FIRM_IMAGE_OPTIONS": "FIRM-schijfkopieinstellingen...", + "AGBSAVE_OPTIONS": "AGBSAVE-instellingen...", + "DUMP_GBA_VC_SAVE": "Dump GBA VC save", + "TICKET_DB_OPTIONS": "Ticket.db-instellingen...", + "MOUNT_AS_DIFF_IMAGE": "Koppel als DIFF-schijfkopie", + "MOUNT_AS_DISA_IAMGE": "Koppel als DISA-kopie", + "INSTALL_CIFINISH_BIN": "Installeer cifinish.bin", + "TITLEKEY_OPTIONS": "Ticketinstellingen...", + "AESKEYDB_OPTIONS": "AESkeydb-instellingen...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo-instellingen...", + "EXECUTE_GM9_SCRIPT": "GM9-script uitvoeren", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Lettertype-instellingen...", + "LANGUAGE_OPTIONS": "Taalinstellingen...", + "VIEW_PNG_FILE": "PNG-bestand bekijken", + "REBUILD_NCSD_HEADER": "Herbouw NCSD-header", + "SHOW_IN_HEXEDITOR": "Toon in Hexeditor", + "CALCULATE_SHA256": "Bereken SHA-256", + "CALCULATE_SHA1": "Bereken SHA-1", + "SHOW_FILE_INFO": "Toon bestandsinfo", + "SHOW_IN_TEXTVIEWER": "Toon in Tekstviewer", + "CALCULATE_CMAC": "Bereken CMAC", + "COPY_TO_OUT": "Kopiëren naar %s", + "DUMP_TO_OUT": "Dumpen naar %s", + "INJECT_DATA_AT_OFFSET": "Gegevens injecteren @offset", + "OPEN_THIS_FOLDER": "Open deze map", + "OPEN_CONTAINING_FOLDER": "Open bijbehorende map", + "OPEN_TITLE_FOLDER": "Open titel-map", + "PATH_N_FILES_SELECTED": "%s\n(%lu bestanden geselecteerd)", + "CHECK_CURRENT_CMAC_ONLY": "Controleer alleen de huidige CMAC", + "VERIFY_CMAC_FOR_ALL": "Controleer CMAC voor alle", + "FIX_CMAC_FOR_ALL": "Herstel CMAC voor alle", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu bestanden ok/gefixt/totaal\n%lu/%lu hebben geen CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu bestanden ok geverifieerd\n%lu/%lu bestanden opgelost", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu bestanden ok geverifieerd\n%lu/%lu hebben geen CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu bestanden ok geverifieerd", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Injecteer gegevens van %s?\nSpecificeer de offset hieronder.", + "FAILED_INJECTING_PATH": "%s injecteren mislukt", + "MOUNT_CXI_NDS_TO_DRIVE": "Koppel CXI/NDS naar schijf", + "MOUNT_IMAGE_TO_DRIVE": "Koppel kopie naar schijf", + "RESTORE_SYSNAND_SAFE": "Herstel SysNAND (veilig)", + "UPDATE_EMBEDDED_BACKUP": "Ingesloten back-up bijwerken", + "SHOW_TITLE_INFO": "Toon titelinfo", + "DECRYPT_FILE": "Decodeer bestand (...)", + "DECRYPT_FILE_OUT": "Decodeer bestand (%s)", + "ENCRYPT_FILE": "Versleutel bestand (...)", + "ENCRYPT_FILE_OUT": "Versleutel bestand (%s)", + "BUILD_CIA_FROM_FILE": "Bouw CIA vanuit bestand", + "BUILD_CIA_STANDARD": "Bouw CIA (standaard)", + "BUILD_CIA_LEGIT": "Bouw CIA (legitiem)", + "DUMP_CXI_NDS_FILE": "Dump CXI/NDS-bestand", + "INSTALL_GAME_IMAGE": "Installeer game-kopie", + "INSTALL_TICKET": "Installeer ticket", + "DUMP_TICKET_FILE": "Dump ticket-bestand", + "UNINSTALL_TITLE": "Deïnstalleer titel", + "VERIFY_FILE": "Verifieer bestand", + "TRANSFER_IMAGE_TO_CTRNAND": "Kopie verplaatsen naar CTRNAND", + "INJECT_TO_H_AND_S": "Injecteer naar H&S", + "TRIM_FILE": "Trim bestand", + "RENAME_FILE": "Hernoem bestand", + "BUILD_XORPADS_SD": "Bouw XORpads (SD-uitgang)", + "BUILD_XORPADS_INPLACE": "Bouw XORpads (inplaats)", + "EXTRACT_X": "%s uitpakken", + "INIT_X": "Init %s", + "INSTALL_X": "Installeer %s", + "INSTALL_FIRM": "Installeer FIRM", + "BOOT_FIRM": "Start FIRM", + "SET_AS_ACTIVE_FONT": "Instellen als actief lettertype", + "SET_AS_ACTIVE_LANGUAGE": "Instellen als actieve taal", + "DUMP_BA_VC_SAVE": "Dump GBA VC save", + "INJECT_GBA_VC_SAVE": "Injecteer GBA VC save", + "SET_AS_DEFAULT": "Instellen als standaard", + "MOUNTING_IMAGE_FAILED": "Kopie koppelen: mislukt", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nGekoppeld als schijf %s\nNu het pad in gaan?", + "DECRYPT_TO_OUT": "Decodeer naar %s", + "DECRYPT_INPLACE": "Decodeer inplaats", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Proberen alle %lu bestanden te ontsleutelen?", + "TRYING_TO_DECRYPT_N_FILES": "%lu bestanden aan het proberen te ontsleutelen...", + "DECRYPTION_FAILED_CONTINUE": "Ontsleuteling mislukt\n\nDoorgaan?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu bestanden goed ontsleuteld\n%lu/%lu niet versleuteld\n%lu/%lu niet van hetzelfde type", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu bestanden goed ontsleuteld", + "N_FILES_WRITTEN_TO_OUT": "%lu bestanden naar %s geschreven", + "FILE_NOT_ENCRYPTED": "Bestand is niet versleuteld", + "DECRYPTION_SUCCESS": "Ontsleuteling gelukt", + "DECRYPTION_FAILED": "Ontsleuteling mislukt", + "PATH_DECRYPTED_TO_OUT": "%s\nOntsleuteld naar %s", + "ENCRYPT_TO_OUT": "Versleutelen naar %s", + "ENCRYPT_INPLACE": "Inplaats versleutelen", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Proberen alle %lu geselecteerde bestanden te versleutelen?", + "TRYING_TO_ENCRYPT_N_FILES": "%lu bestanden aan het proberen te versleutelen...", + "ENCRYPTION_FAILED_CONTINUE": "Versleuteling mislukt\n\nDoorgaan?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu bestanden ok versleuteld\n%lu/%lu niet van hetzelfde type", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu bestanden ok versleuteld", + "ENCRYPTION_SUCCESS": "Versleuteling gelukt", + "ENCRYPTION_FAILED": "Versleuteling mislukt", + "PATH_ENCRYPTED_TO_OUT": "%s\nVersleuteld naar %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Proberen om alle %lu geselecteerde bestanden te verwerken?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nBuild %s mislukt\nDoorgaan?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss ok gebouwd\n%lu/%lu niet van hetzelfde type", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss ok gebouwd", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "Conversie van %lu bestand(en) mislukt.\nVerificatie is aanbevolen.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s gebouwd naar %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s build mislukt", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "bestandsconversie mislukt.\n \nNu verifiëren?", + "VERIFICATION_SUCCESS": "Verificatie geslaagd", + "VERIFICATION_FAILED": "Verificatie mislukt", + "CONTENT_IS_MISSING": "Inhoud ontbreekt", + "INSTALL_TO_SYSNAND": "Installeren naar SysNAND", + "INSTALL_TO_EMUNAND": "Installeren naar EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Proberen alle %lu geselecteerde bestanden te installeren?", + "TRYING_TO_INSTALL_N_FILES": "Proberen %lu bestanden te installeren...", + "INSTALL_FAILED_CONTINUE": "Installatie mislukt\n \nDoorgaan?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu bestanden ok geïnstalleerd\n%lu/%lu niet van hetzelfde type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu bestanden ok geïnstalleerd", + "INSTALL_SUCCESS": "Installatie geslaagd", + "INSTALL_FAILED": "Installatie mislukt", + "FILE_FAILED_INSTALL_VERIFY_NOW": "bestand installatie mislukt.\n \nNu verifiëren?", + "KEEP_TICKET_AND_SAVEGAME": "Behoud ticket & savegame", + "UNINSTALL_EVERYTHING": "Alles deïnstalleren", + "ABORT_UNINSTALL": "Deïnstallatie afbreken", + "UNINSTALL_N_SELECTED_TITLES": "%lu geselecteerde titels verwijderen?", + "UNINSTALL_SELECTED_TITLE": "Geselecteerde titel verwijderen?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu titels verwijderd", + "UNINSTALLING_PLEASE_WAIT": "Deïnstalleren, even geduld...", + "UNINSTALL_FAILED": "Deïnstallatie mislukt!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Proberen alle %lu geselecteerde bestanden te verifiëren?", + "VERIFICATION_FAILED_CONTINUE": "Verificatie mislukt\n \nDoorgaan?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu bestanden ok geverifieerd\n%lu/%lu niet van hetzelfde type", + "VERIFYING_FILE_PLEASE_WAIT": "Bestand verifiëren, even geduld...", + "NAND_VALIDATION_SUCCESS": "NAND validatie geslaagd", + "NAND_VALIDATION_FAILED": "NAND validatie mislukt", + "DUMP_FOR_N_SELECTED_FILES": "Dump voor alle %lu geselecteerde bestanden?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legitieme tickets gedumpt.\n \nPoging om alle tickets te dumpen?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets gedumpt naar %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket gedumpt naar %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit ticket niet gevonden.\n \nToch dumpen?", + "DUMP_TICKET_FAILED": "Dump ticket mislukt!", + "BUILDING_X": "Bouwen %s...", + "BUILDING_X_SYSNAND": "Bouwen %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Bouwen %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu bestanden verwerkt\n%lu/%lu bestanden genegeerd", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu bestanden verwerkt", + "BUILD_DATABASE_SUCCESS": "Bouw database succesvol.", + "BUILD_DATABASE_FAILED": "Bouw database mislukt.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Proberen om alle %lu geselecteerde bestanden te trimmen?", + "TRIMMING_FAILED_CONTINUE": "Trimmen mislukt\n \nDoorgaan?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu bestanden ok getrimd\n%lu/%lu niet van hetzelfde type\n%s opgeslagen", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu bestanden ok getrimd\n%s opgeslagen", + "FILE_CANT_BE_TRIMMED": "Bestand kan niet worden getrimd.", + "FILE_ALREADY_TRIMMED": "Bestand is al getrimd.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nHuidige grootte: %s\nGetrimde grootte: %s\nVerschil: %s\n \nDit bestand trimmen?", + "TRIMMING_FAILED": "Trimmen mislukt.", + "PATH_TRIMMED_BY_X": "%s\nGetrimd met %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Proberen om alle %lu geselecteerde bestanden te hernoemen?", + "N_OF_N_RENAMED": "%lu/%lu ok hernoemd", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Kon naam niet wijzigen naar goede naam", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S injectie", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S injectie", + "H_AND_S_INJECT_SUCCESS": "H&S injectie succes", + "H_AND_S_INJECT_FAILURE": "H&S injectie mislukt", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Proberen om alle %lu geselecteerde bestanden uit te pakken?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu bestanden ok uitgepakt\n%lu/%lu niet van hetzelfde type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu bestanden ok uitgepakt", + "EXTRACTING_DOT_CODE": ".code uitpakken even geduld...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s uitgepakt naar %s", + "DOT_CODE_EXTRACT_FAILED": ".code uitpakken mislukt", + "TRANSFER_TO_SYSNAND": "Overzetten naar SysNAND", + "TRANSFER_TO_EMUNAND": "Overzetten naar SysNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND overdracht gelukt", + "CTRNAND_TRANSFER_FAILED": "CTRNAND overdracht mislukt", + "NO_VALID_DESTINATION_FOUND": "Geen geldige bestemming gevonden", + "NAND_RESTORE_SUCCESS": "NAND herstellen gelukt", + "NAND_RESTORE_FAILED": "NAND herstellen mislukt", + "REBUILD_NCSD_SUCCESS": "Opnieuw opbouwen NCSD geslaagd", + "REBUILD_NCSD_FAILED": "Opnieuw opbouwen NCSD mislukt", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Install to FIRM0", + "INSTALL_TO_FIRM1": "Install to FIRM1", + "INSTALL_TO_BOTH": "Install to both", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Switch EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restore H&S", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "Restore H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restore H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Set RTC date&time:", + "NEW_RTC_DATE_TIME_IS_TIME": "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen calibration success!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen calibration failed!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC date&time seems to be\nwrong. Set it now?", + "RESUME_GODMODE9": "Resume GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Select payload...", + "SELECT_SCRIPT": "Select script...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "Poweroff system", + "REBOOT_SYSTEM": "Reboot system", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader payloads menu.\nSelect payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Out of memory.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Open title manager", + "SEARCH_FOR_FILES": "Search for files...", + "FIX_CMACS_FOR_DRIVE": "Fix CMACs for drive", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "Found %lu results.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "Delete %lu path(s)?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "Failed deleting %lu/%lu path(s)", + "DELETE_FILE": "Delete \"%s\"?", + "FAILED_DELETING_PATH": "Failed deleting:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Not allowed in search drive", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Not allowed in virtual game path", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Not allowed in XORpad drive", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Not allowed in gamecart drive", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copy path(s)", + "MOVE_PATHS": "Move path(s)", + "PASTE_FILE_HERE": "Paste \"%s\" here?", + "PASTE_N_PATHS_HERE": "Paste %lu paths here?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Failed copying path:\n%s\nProcess remaining?", + "FAILED_COPYING_PATH": "Failed copying path:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Failed moving path:\n%s\nProcess remaining?", + "FAILED_MOVING_PATH": "Failed moving path:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Rename %s?\nEnter new name below.", + "FAILED_RENAMING_PATH": "Failed renaming path:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Create a folder", + "CREATE_A_DUMMY_FILE": "Create a dummy file", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Create a new folder here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Create a new file here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Failed creating folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Failed creating file:\n%s", + "TITLE_MANAGER": "Title manager", + "BRICK_MY_3DS": "Brick my 3DS", + "LANGUAGE": "Language...", + "SCRIPTS": "Scripts...", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Payloads...", + "MORE": "More...", + "BRACKET_MORE": "[more...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME button pressed.\nSelect action:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER button pressed.\nSelect action:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD CARD", + "B_DRIVE_SD_CARD": "[B:] SD CARD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads directory not found.\n(default path: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALID", + "TO_PROCEED_ENTER_THIS": "To proceed, enter this:", + "TO_PROCEED_HOLD_X": "To proceed, hold :", + "N_MORE": " [%d more]", + "CANCEL": "cancel", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) fast scroll\nL - clear data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - remove char\nY - insert char", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Searching, please wait...", + "RENAME_TO_GOOD_NAME": "Rename to good name?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD card is write protected!\nCan't continue.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "game images", + "GAMECART_SAVES": "gamecart saves", + "IMAGES": "images", + "MEMORY_AREAS": "memory areas", + "SD_SYSTEM_DATA": "SD system data", + "SD_CARD": "SD card", + "RAM_DRIVE": "RAM drive", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Writing to %s is locked!\nUnlock it now?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Unlock write permission for\n%s is not allowed.", + "ENABLE_BASE_WRITE": "You want to enable base\nwriting permissions.", + "ENABLE_SD_WRITE": "You want to enable SD card\nwriting permissions.", + "ENABLE_IMAGE_WRITE": "You want to enable image\nwriting permissions.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Error: SD card is too small", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatting SD, please wait...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatting drive, please wait...", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "File is currently mounted.\nUnmount to unlock?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Error: Can't inject file into itself", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operation would write beyond end of file", + "NOT_ENOUGH_DATA_IN_FILE": "Not enough data in file", + "CANCEL_IS_NOT_ALLOWED_HERE": "Cancel is not allowed here", + "B_DETECTED_CANCEL": "B button detected. Cancel?", + "ERROR_CANNOT_APPEND_FOLDER": "Error: Cannot append a folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Error: Not enough space available", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Error: Only FAT files can be moved", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Error: Destination is part of origin", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destination equals origin\nChoose another name?", + "CHOOSE_NEW_NAME": "Choose new name", + "OVERWRITE_FILES": "Overwrite file(s)", + "SKIP_FILES": "Skip file(s)", + "OVERWRITE_ALL": "Overwrite all", + "SKIP_ALL": "Skip all", + "DESTINATION_ALREADY_EXISTS": "Destination already exists:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choose new destination name", + "COPY_OPERATION_IS_NOT_ALLOWED": "Copy operation is not allowed", + "DESTINATION_EQUALS_ORIGIN": "Destination equals origin", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entry not found: %s\nInject into %s instead?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "Americas", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brazil", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europa", + "REGION_FRANCE": "Frankrijk", + "REGION_GERMANY": "Duitsland", + "REGION_ITALY": "Italië", + "REGION_JAPAN": "Japan", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spanje", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Onbekend", + "REGION_UNITED_KINGDOM": "Verenigd Koninkrijk", + "REGION_MIDDLE_EAST": "Midden-Oosten", + "GENERATING_QR_CODE": "QR-code genereren...", + "REINITIALIZING_SD_CARD": "SD-kaart herinitialiseren...", + "DUMPING_STATE_TO_SD_CARD": "Status naar SD-kaart dumpen...", + "PRESS_POWER_TO_TURN_OFF": "Druk op POWER om uit te schakelen", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Titels aan het opschonen, even geduld...", + "ERROR_NOT_NCCH_FILE": "Fout: Geen NCCH bestand", + "ERROR_FILE_IS_TOO_SMALL": "Fout: Bestand is te klein", + "ATTEMPT_FIX_THIS_TIME": "Probeer reparatie deze keer", + "ATTEMPT_FIX_ALWAYS": "Probeer reparatie altijd", + "ABORT_VERIFICATION": "Verificatie afbreken", + "ERROR_BAD_CRYPTO_FLAGS": "Fout: Slechte crypto-markeringen", + "ERROR_BAD_EXEFS_HEADER": "Fout: Slechte ExeFS header", + "ERROR_MISSING_EXTHEADER": "Fout: ExtHeader ontbreekt", + "ERROR_CRYPTO_NOT_SET_UP": "Fout: Crypto niet ingesteld", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verificatie mislukt:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "mislukt", + "ERROR_NOT_NCSD_FILE": "Fout: Geen NCSD-bestand", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nInhoud%lu (%08lX@%08lX):\nVerificatie mislukt", + "ERROR_PROBABLY_NOT_CIA_FILE": "Fout: waarschijnlijk geen CIA-bestand", + "ERROR_TMD_PROBABLY_CORRUPTED": "Fout: TMD is waarschijnlijk beschadigd", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerificatie mislukt", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Fout: CDN-titelsleutel niet gevonden", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC-inhoud ontbreekt\n \nAlles negeren en doorgaan?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSectie %lu hash komt niet overeen", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 ingangspunt ontbreekt", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Waarschuwing: ARM11 ingangspunt ontbreekt", + "ERROR_NOT_A_BOSS_FILE": "Fout: Geen BOSS-bestand", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS payload hash komt niet overeen.\n \nProberen om het op te lossen?", + "GENERIC_TICKET_PIRATE_LEGIT": "Algemeen ticket (\"piratenlegit\")", + "PERSONALIZED_TICKET_LEGIT": "Gepersonaliseerd ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is gepersonaliseerd.\nHet gebruik hiervan wordt niet aanbevolen.\nKies standaardactie:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitelsleutel niet gevonden.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD is niet legitiem.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD is niet legitiem.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Inhoud is beschadigd", + "INSERT_CONTENT_FAILED": "Invoegen inhoud mislukt", + "INSTALL_CONTENT_FAILED": "Install content failed", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Install error:\nThis system is missing the\nticket.db file.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Error: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", + "INSTALLING_TICKET": "Installing ticket...", + "POSSIBLY_BROKEN": "Possibly Broken", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Personal Legit DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personal Pirate Legit DLC", + "PERSONAL_CUSTOM": "Personal Custom", + "PERSONAL_CUSTOM_DLC": "Personal Custom DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Custom", + "UNIVERSAL_CUSTOM_DLC": "Universal Custom DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contents in CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contents in TMD: %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle version: %lu.%lu.%lu\nContents size: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerification: %s", + "STATE_LEGIT": "legit", + "STATE_ILLEGIT": "illegit", + "STATE_UNKNOWN": "unknown", + "STATE_INVALID": "invalid", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "pending\n \nProceed with verification?", + "STATE_PASSED": "passed", + "STATE_FAILED": "failed", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Output file already exists.\nUpdate this?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Fixing CMACs, please wait...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD header is not valid", + "NAND_DUMP_MISSING_DATA": "NAND dump missing data", + "ERROR_CTR_MBR_IS_CORRUPT": "Error: CTR MBR is corrupt", + "ERROR_TWL_MBR_IS_CORRUPT": "Error: TWL MBR is corrupt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nError: CTR partition%lu is corrupt", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nError: TWL partition%lu is corrupt", + "NO_VALID_FIRM_FOUND": "No valid FIRM found", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Error: NAND dump is corrupt.\nStill continue?", + "ERROR_SYSTEM_IS_LOCKED": "Error: System is locked.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Essential files backup is required.\nCreate one now?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD corrupt or customized,\nsafe restore is not possible!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?", + "NOT_AN_INSTALLABLE_FIRM": "Not a installable FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM load/verify error.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu niet gevonden of te klein.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto mislukt.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sector 0x96 is beschadigd.\n \nGeef \"secret_sector.bin\" op\nom sector 0x96 vast te stellen.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sector 0x96 is beschadigd.\n \nSector 0x96 repareren tijdens\nde installatie?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WAARSCHUWING!\n \nDoorgaan zal de\nopgegeven FIRM installeren naar de SysNAND\nand sighax injecteren.\n \nHet installeren van een niet-ondersteunde FIRM\nzal je console BRICKEN!", + "INSTALLING_FIRM_PLEASE_WAIT": "FIRM installeren, even geduld...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!DIT IS SLECHT!\n \nSector 0x96 schrijven mislukt.\nProbeer te repareren voordat je opnieuw opstart!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "DIT IS SLECHT!\n \nFIRM%lu schrijven mislukt.\nProbeer te repareren voordat je opnieuw opstart!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Installatie controleren, even geduld...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfect %s is already installed!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nNot a perfect %s image.\nCannot install to NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFailed writing %s to NAND!", + "USE_L_R_TO_SAVE": "(gebruik L+R om op te slaan)" +} diff --git a/resources/languages/pl.json b/resources/languages/pl.json new file mode 100644 index 000000000..8124c34fe --- /dev/null +++ b/resources/languages/pl.json @@ -0,0 +1,127 @@ +{ + "GM9_LANGUAGE": "Polski", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX.%3$02lX.%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": " ", + "FIRM_TOO_BIG": "FIRM za duży, nie można uruchomić", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nOstrzeżenie: Nie uruchamiaj FIRM-ów\nz niezaufanych źródeł.\n \nUruchomić FIRM?", + "NOT_BOOTABLE_FIRM": "Nie bootowalny FIRM.", + "FIRM_ENCRYPTED": "FIRM jest zaszyfrowany.\n \nOdszyfrować przed uruchomieniem?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Zrób kopię w %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Spróbuj uruchomić mimo to", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Ostrzeżenie: Próba rozruchu z\nnieobsługiwanej lokalizacji.", + "ROOT": "[root]", + "LOADING": "ŁADOWANIE...", + "PANE_N": "SEKTOR #%lu", + "CURRENT": "BIEŻĄCY", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Game Virtual)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memory Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(Szukaj)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "SDCARD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "GAME IMAGE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB IMAGE", + "LAB_BDRI_IMAGE": "BDRI IMAGE", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF IMAGE", + "LAB_MEMORY_VIRTUAL": "MEMORY VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "ZARZĄDZANIE TYTUŁAMI", + "LAB_LAST_SEARCH": "OSTATNIE WYSZUKIWANIE", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[CLIPBOARD]", + "PLUS_N_MORE": "+ %lu więcej", + "MARK_DELETE_COPY": "L - OZNACZ pliki (używaj z ↑↓→←)\nX - USUŃ / [+R] ZMIEŃ NAZWĘ pliku(ów)\nY - KOPIUJ pliki / [+R] STWÓRZ wpis\n", + "MARK_DELETE_PASTE": "L - OZNACZ pliki (używaj z ↑↓→←)\nX - USUŃ / [+R] ZMIEŃ NAZWĘ pliku(ów)\nY - WKLEJ pliki / [+R] STWÓRZ wpis\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Zablokuj uprawnienia do zapisu\n", + "UNMOUNT_IMAGE": "R+X - Odmontuj obraz\n", + "UNMOUNT_SD": "R+B - Odmontuj kartę SD\n", + "REMOUNT_SD": "R+B - Zamontuj kartę SD\n", + "DIRECTORY_OPTIONS": "R+A - Opcje katalogu\n", + "DRIVE_OPTIONS": "R+A - Opcje napędu\n", + "MAKE_SCREENSHOT": "R+L - Zrób zrzut ekranu\n", + "PREV_NEXT_PANE": "R+←→ - Przełączanie do poprzedniego/kolejnego sektora\n", + "CLEAR_CLIPBOARD": "SELECT - Wyczyść schowek\n", + "RESTORE_CLIPBOARD": "SELECT - Przywróć schowek\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Don't set up", + "CHOOSE_EMUNAND_TYPE": "Choose EmuNAND type to set up:", + "CLONE_SYSNAND_TO_REDNAND": "Clone SysNAND to RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Klonowanie SysNAND do EmuNAND: nie powiodło się!", + "PRESS_A_TO_CONTINUE": "Naciśnij aby kontynuować", + "HEXEDITOR_CONTROLS": "Sterowanie Hexeditor:\n \n↑↓→←(+R) - Przewijanie\nR+Y - Przełączanie widoku\nX - Wyszukiwanie / przejdź do...\nA - Wejście w tryb edycji\nA+↑↓→← - Edycja wartości\nB - Wyjście\n", + "NOT_FOUND": "Nie znaleziono!", + "GO_TO_OFFSET": "Przejdź do offsetu", + "SEARCH_FOR_STRING": "Wyszukaj ciąg znaków", + "SEARCH_FOR_DATA": "Szukaj danych", + "CURRENT_OFFSET_SELECT_ACTION": "Bieżący offset: %08lX\nWybierz akcję:", + "CURRENT_OFFSET_ENTER_NEW": "Bieżący offset: %08lX\nWpisz poniżej nowe przesunięcie.", + "ENTER_SEARCH_REPEAT_SEARCH": "Wprowadź tekst wyszukiwania poniżej.\n(R+X, aby powtórzyć wyszukiwanie)", + "MADE_EDITS_SAVE_CHANGES": "Dokonałeś edycji w %lu miejscach.\nZapisać zmiany do pliku?", + "FAILED_WRITING_TO_FILE": "Nieudany zapis do pliku!", + "CALCULATING_SHA_FAILED": "Obliczanie SHA-%s: nie udało się!", + "SHA_VERIFICATION_PASSED": "\nWeryfikacja SHA: zaliczona!", + "SHA_VERIFICATION_FAILED": "\nWeryfikacja SHA: nieudana", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentycznie jak w poprzednim pliku:\n", + "WRITE_SHA_FILE": "\n \nZapisać plik .SHA?", + "WRITE_SHA1_FILE": "\n \nZapisać plik .SHA1?", + "CALCULATING_CMAC_FAILED": "Obliczanie CMAC: nie udało się!", + "CMAC_VERIFICATION_PASSED": "Weryfikacja CMAC: zaliczona!", + "CMAC_VERIFICATION_FAILED": "Weryfikacja CMAC: nie powiodła się!" +} diff --git a/resources/languages/ru.json b/resources/languages/ru.json new file mode 100644 index 000000000..9ebc91ed1 --- /dev/null +++ b/resources/languages/ru.json @@ -0,0 +1,158 @@ +{ + "GM9_LANGUAGE": "Русский", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX.%3$02lX.%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": " ", + "FIRM_TOO_BIG": "FIRM слишком большой, невозможно загрузить", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dкб)\nПредупреждение: Не загружайте FIRM\nиз ненадежных источников.\n \nЗагрузить FIRM?", + "NOT_BOOTABLE_FIRM": "Не запускаемый FIRM.", + "FIRM_ENCRYPTED": "FIRM зашифрован.\n \nРасшифровать перед запуском?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Сделать копию в %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Все равно попытаться запустить", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Предупреждение: Попытка запуска с неподдерживаемого расположения.", + "ROOT": "[root]", + "LOADING": "ЗАГРУЗКА...", + "PANE_N": "ВКЛАДКА #%lu", + "CURRENT": "ТЕКУЩИЙ", + "DIR": "(папка)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Виртуальная Game)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(Виртуальный SysNAND)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(Виртуальный EmuNAND)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(Виртуальный XORpad)", + "MEMORY_VIRTUAL": "(Виртуальная Память)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Виртуальный Картридж)", + "VRAM_VIRTUAL": "(Виртуальная VRAM)", + "SEARCH": "(Поиск)", + "TITLEMANAGER_VIRTUAL": "(Виртуальный TitleManager)", + "LAB_SDCARD": "КАРТА ПАМЯТИ SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "ВИРТУАЛЬНЫЙ SYSNAND", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "ВИРТУАЛЬНЫЙ EMUNAND", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "ВИРТУАЛЬНЫЙ IMGNAND", + "LAB_GAMECART": "КАРТРИДЖ", + "LAB_GAME_IMAGE": "ИГРОВОЙ ДИСК", + "LAB_AESKEYDB_IMAGE": "ДИСК AESKEYDB", + "LAB_BDRI_IMAGE": "ДИСК BDRI", + "LAB_DISA_DIFF_IMAGE": "ДИСК DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "ВИРТУАЛЬНАЯ ПАМЯТЬ", + "LAB_VRAM_VIRTUAL": "ВИРТУАЛЬНАЯ VRAM", + "LAB_TITLE_MANAGER": "TITLE MANAGER", + "LAB_LAST_SEARCH": "LAST SEARCH", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[CLIPBOARD]", + "PLUS_N_MORE": "+ %lu more", + "MARK_DELETE_COPY": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n", + "MARK_DELETE_PASTE": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Relock write permissions\n", + "UNMOUNT_IMAGE": "R+X - Unmount image\n", + "UNMOUNT_SD": "R+B - Unmount SD card\n", + "REMOUNT_SD": "R+B - Remount SD card\n", + "DIRECTORY_OPTIONS": "R+A - Directory options\n", + "DRIVE_OPTIONS": "R+A - Drive options\n", + "MAKE_SCREENSHOT": "R+L - Make a Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Switch to prev/next pane\n", + "CLEAR_CLIPBOARD": "SELECT - Clear Clipboard\n", + "RESTORE_CLIPBOARD": "SELECT - Restore Clipboard\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Don't set up", + "CHOOSE_EMUNAND_TYPE": "Choose EmuNAND type to set up:", + "CLONE_SYSNAND_TO_REDNAND": "Clone SysNAND to RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Клонирование SysNAND в EmuNAND: не удалось!", + "PRESS_A_TO_CONTINUE": "Нажмите чтобы продолжить", + "HEXEDITOR_CONTROLS": "Управление Hexeditor:\n \n↑↓→←(+R) - Прокрутка\nR+Y - Переключение вида\nX - Поиск / переход к...\nA - Войти в режим редактирования\nA+↑↓→← - Редактировать значение\nB - Выйти\n", + "NOT_FOUND": "Не найдено!", + "GO_TO_OFFSET": "Перейти к offset", + "SEARCH_FOR_STRING": "Поиск строки", + "SEARCH_FOR_DATA": "Поиск данных", + "CURRENT_OFFSET_SELECT_ACTION": "Текущий offset: %08lX\nВыберите действие:", + "CURRENT_OFFSET_ENTER_NEW": "Текущий offset: %08lX\nВведите новый offset ниже.", + "ENTER_SEARCH_REPEAT_SEARCH": "Введите искомую строку ниже.\n(R+X чтобы повторить поиск)", + "MADE_EDITS_SAVE_CHANGES": "Вы внесли правки в %lu месте(ах).\nЗаписать изменения в файл?", + "FAILED_WRITING_TO_FILE": "Ошибка записи в файл!", + "CALCULATING_SHA_FAILED": "Вычисление SHA-%s: ошибка!", + "SHA_VERIFICATION_PASSED": "\nПроверка SHA: пройдена!", + "SHA_VERIFICATION_FAILED": "\nПроверка SHA: ошибка", + "IDENTICAL_WITH_PREVIOUS": "\n \nИдентично предыдущему файлу:\n", + "WRITE_SHA_FILE": "\n \nЗаписать .SHA файл?", + "WRITE_SHA1_FILE": "\n \nЗаписать .SHA1 файл?", + "CALCULATING_CMAC_FAILED": "Вычисление CMAC: ошибка!", + "CMAC_VERIFICATION_PASSED": "Проверка CMAC: пройдена!", + "CMAC_VERIFICATION_FAILED": "Проверка CMAC: ошибка!", + "FIX_CMAC_IN_FILE": "\n \nИсправить CMAC в файле?", + "FIXING_CMAC_FAILED": "Исправление CMAC: ошибка!", + "COPY_ALL_SELECTED_ITEMS": "Копировать все %lu выбранный(х) элемент(а/ов)?", + "FAILED_COPYING_ITEM": "Ошибка копирования элемента", + "ITEMS_COPIED_TO_OUT": "%lu элементов скопировано в %s", + "PATH_COPIED_TO_OUT": "%s\nСкопировано в %s", + "CART_INIT_FAILED": "Ошибка инициализации карты!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Картридж: %s\nОбнаруженный размер: %s\n \nВведите размер дампа ниже.", + "NDS_CART_DECRYPT_SECURE_AREA": "Картридж: %s\nКартридж NDS обнаружен\nРасшифровать защищенную область?", + "FAILED_DUMPING_CART": "%s\nНе удалось сдампить картридж", + "PATH_DUMPED_TO_OUT": "%s\nСдамплено в %s", + "CREATED": "создано", + "MODIFIED": "изменен", + "ANALYZING_DRIVE": "Анализ диска, пожалуйста, подождите...", + "ANALYZING_DIR": "Анализ папки, пожалуйста, подождите...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu файлов и %lu подпапок\n%s общий размер\n \nсвободно места: %s\nместа используется: %s\nместа всего: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu файлов и %lu подпапок\n%s общий размер", + "FILESIZE_X": "размер файла: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sread-only [%c] %shidden\n[%c] %ssystem [%c] %sarchive\n[%c] %svirtual\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← чтобы изменить атрибуты)\n", + "A_TO_CONTINUE": "( чтобы продолжить)", + "A_APPLY_B_CANCEL": "( чтобы применить, чтобы отменить)", + "A_YES_B_NO": "( да, нет)", + "A_SELECT_B_CANCEL": "( выбрать, отмена)", + "HOLD_B_TO_CANCEL": "(удерживайте B для отмены)", + "FAILED_TO_SET_ATTRIBUTES": "Не удалось установить атрибуты!", + "NAND_IMAGE_OPTIONS": "Параметры NAND образа...", + "CTRNAND_OPTIONS": "Параметры CTRNAND...", + "MOUNT_FAT_IMAGE": "Смонтировать как FAT образ", + "CIA_IMAGE_OPTIONS": "Параметры CIA образа...", + "NCSD_IMAGE_OPTIONS": "Параметры NCSD образа..." +} diff --git a/resources/languages/ry.json b/resources/languages/ry.json new file mode 100644 index 000000000..5a7ff5813 --- /dev/null +++ b/resources/languages/ry.json @@ -0,0 +1,254 @@ +{ + "GM9_LANGUAGE": "琉球諸語", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lXさ%3$02lXがち%4$02lXんかいち %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRMがまぎさくとぅ、きどうなやびらん。", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nちゅうい:しんらいならんソースから\nFIRMきどうさんぐーとぅーくぃみそーれー。\n \nFIRMきどうさびーが?", + "NOT_BOOTABLE_FIRM": "%s\n起動ないるFIRMっしぇーあいびらん。", + "FIRM_ENCRYPTED": "FIRMが暗号化さりとーいびーん。\n \n起動めーに復号化さびーが?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "%s/temp.firmんかいコピー作成さびーが?", + "TRY_BOOT_ANYWAYS": "ぬーんでぃ起動しんーじゅん", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "警告: サポートさりてぃうぅらん\nばすからブートさんでぃそーいびーん。", + "ROOT": "[root]", + "LOADING": "読み込み中…", + "PANE_N": "ペイン %lu", + "CURRENT": "現在", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMドライブFAT)", + "GAME_VIRTUAL": "(ゲームバーチャル)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memory Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(検索)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "SDカード", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "ゲームカード", + "LAB_GAME_IMAGE": "ゲームイメージ", + "LAB_AESKEYDB_IMAGE": "AESKEYDBイメージ", + "LAB_BDRI_IMAGE": "BDRIイメージ", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFFイメージ", + "LAB_MEMORY_VIRTUAL": "メモリバーチャル", + "LAB_VRAM_VIRTUAL": "VRAMバーチャル", + "LAB_TITLE_MANAGER": "タイトルマネージャー", + "LAB_LAST_SEARCH": "前検索", + "LAB_FAT_IMAGE": "FATイメージ", + "LAB_BONUS_DRIVE": "ボーナスドライブ", + "LAB_RAMDRIVE": "RAMドライブ", + "LAB_NOLABEL": "ラベルなし", + "N_BYTE": "%sバイト", + "BYTE": " バイト", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[クリップボード]", + "PLUS_N_MORE": "+ んでぃ%lu個", + "MARK_DELETE_COPY": "L - ファイルマーク (↑↓→←使用)\nX - ファイル削除 / [+R] なめー変更\nY - ファイルコピー / [+R] エントリ作成", + "MARK_DELETE_PASTE": "L - ファイルマーク (↑↓→←んでぃ使用)\nX - ファイル削除 / [+R] なめー変更\nY - ファイル貼いちきーん / [+R] エントリ作成", + "RELOCK_WRITE_PERMISSION": "R+Y - 書き込みぬ許可再ロック", + "UNMOUNT_IMAGE": "R+X - Unmount image\n", + "UNMOUNT_SD": "R+B - Unmount SD card\n", + "REMOUNT_SD": "R+B - Remount SD card\n", + "DIRECTORY_OPTIONS": "R+A - Directory options\n", + "DRIVE_OPTIONS": "R+A - Drive options\n", + "MAKE_SCREENSHOT": "R+L - Make a Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Switch to prev/next pane\n", + "CLEAR_CLIPBOARD": "SELECT - Clear Clipboard\n", + "RESTORE_CLIPBOARD": "SELECT - Restore Clipboard\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "設定さん", + "CHOOSE_EMUNAND_TYPE": "設定しーんEmuNANDタイプ選択しみそーれー。", + "CLONE_SYSNAND_TO_REDNAND": "RedNANDんかいSysNANDコピーさびーが?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "EmuNANDんかいシステムNANDコピー:  しーやんじゃびたん!", + "PRESS_A_TO_CONTINUE": "うち続きーん", + "HEXEDITOR_CONTROLS": "16進エディタぬコントロール:\n \n↑↓→←(+R) - スクロール\nR+Y - 表示切り替いーん\nX - 検索・移動…\nA - 編集モードなすん\nA+↑↓→← - 値編集\nB - 終了\n", + "NOT_FOUND": "あいびらん!", + "GO_TO_OFFSET": "オフセットんかい移動", + "SEARCH_FOR_STRING": "文字列っし検索", + "SEARCH_FOR_DATA": "データっし検索", + "CURRENT_OFFSET_SELECT_ACTION": "現在ぬオフセット: %08lX\nアクション選択:", + "CURRENT_OFFSET_ENTER_NEW": "現在ぬオフセット: %08lX\n以下にみーさるオフセット入力しみそーれー。", + "ENTER_SEARCH_REPEAT_SEARCH": "以下に検索する文字列入力しみそーれー。\n(R+Xっし検索繰いけーさびーる)", + "MADE_EDITS_SAVE_CHANGES": "%lu個ぬばすぬ変更さりやびたん。\n変更ファイルんかい書ちくまびーが?", + "FAILED_WRITING_TO_FILE": "ファイルんかいぬ書き込みんかいしーやんじゃびたん!", + "CALCULATING_SHA_FAILED": "SHA-%sぬさんみん: しーやんじゃびたん!", + "SHA_VERIFICATION_PASSED": "\nSHA検証: でぃかさびたん!", + "SHA_VERIFICATION_FAILED": "\nSHA検証: しーやんじゃびたん", + "IDENTICAL_WITH_PREVIOUS": "\n \n前ファイルとぅいぬやいびーん:\n", + "WRITE_SHA_FILE": "\n \n.SHAファイル作成さびーが?", + "WRITE_SHA1_FILE": "\n \n.SHA1ファイル作成さびーが?", + "CALCULATING_CMAC_FAILED": "CMACぬさんみん: しーやんじゃびたん!", + "CMAC_VERIFICATION_PASSED": "CMAC検証: でぃかさびたん!", + "CMAC_VERIFICATION_FAILED": "CMAC検証: しーやんじゃびたん!", + "FIX_CMAC_IN_FILE": "\n \nファイルんかいCMAC修正さびーが?", + "FIXING_CMAC_FAILED": "CMACぬ修正: しーやんじゃびたん!", + "COPY_ALL_SELECTED_ITEMS": "%lu個ぬ選択さったる項目まじりコピーさびーが?", + "FAILED_COPYING_ITEM": "項目ぬコピーんかいしーやんじゃびたん", + "ITEMS_COPIED_TO_OUT": "%lu個ぬ項目ー%sんかいコピーさびたん", + "PATH_COPIED_TO_OUT": "%s\n%sんかいコピーさびたん", + "CART_INIT_FAILED": "カードぬ初期化んかいしーやんじゃびたん!", + "CART_DETECTED_SIZE_INPUT_BELOW": "カード: %s\n検出さったるサイズ: %s\n \n以下にダンプサイズ入力しみそーれー。", + "NDS_CART_DECRYPT_SECURE_AREA": "カード: %s\nNDSカードぬ検出さりやびたん\nセキュアエリア復号化さびーが?", + "FAILED_DUMPING_CART": "%s\nカードぬダンプんかいしーやんじゃびたん", + "PATH_DUMPED_TO_OUT": "%s\n%sんかいダンプさびたん", + "CREATED": "作成日", + "MODIFIED": "更新日", + "ANALYZING_DRIVE": "ドライブ分析そーいびーん、いちゅた待っちくぃみそーれー。", + "ANALYZING_DIR": "フォルダ分析そーいびーん。いちゅた待っちくぃみそーれー。", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%luファイルとぅ%luフォルダ\n%s合計サイズ\n \n空き容量:%s\n使用容量:%s\n合計容量:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%luファイルとぅ%luフォルダ\n%s合計サイズ", + "FILESIZE_X": "ファイルサイズ: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s読み取り専用 [%c] %s隠し\n[%c] %sシステム [%c] %sアーカイブ\n[%c] %sバーチャル\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→←っし属性変更すん)\n", + "A_TO_CONTINUE": "(っし続きーん)", + "A_APPLY_B_CANCEL": "(っし適用、っしキャンセル)", + "A_YES_B_NO": "(はい、うぅーうぅー)", + "A_SELECT_B_CANCEL": "(選択、キャンセル)", + "HOLD_B_TO_CANCEL": "(B長押しーしキャンセル)", + "FAILED_TO_SET_ATTRIBUTES": "属性ぬ設定んかいしーやんじゃびたん!", + "NAND_IMAGE_OPTIONS": "NAND image options...", + "CTRNAND_OPTIONS": "CTRNAND options...", + "MOUNT_FAT_IMAGE": "Mount as FAT image", + "CIA_IMAGE_OPTIONS": "CIA image options...", + "NCSD_IMAGE_OPTIONS": "NCSD image options...", + "NCCH_IMAGE_OPTIONS": "NCCH image options...", + "MOUNT_AS_EXEFS_IMAGE": "Mount as EXEFS image", + "MOUNT_AS_ROMFS_IMAGE": "Mount as ROMFS image", + "TMD_FILE_OPTIONS": "TMD file options...", + "TMD_CDN_OPTIONS": "TMD/CDN options...", + "TMD_TWL_OPTIONS": "TMD/TWL options...", + "MANAGE_TITLE": "Manage Title...", + "BOSS_FILE_OPTIONS": "BOSS file options...", + "DECRYPT_NUS_CDN_FILE": "Decrypt NUS/CDN file", + "SHOW_SMDH_TITLE_INFO": "Show SMDH title info", + "NDS_IMAGE_OPTIONS": "NDS image options...", + "GBA_IMAGE_OPTIONS": "GBA image options...", + "TICKET_OPTIONS": "Ticket options...", + "TAD_IMAGE_OPTIONS": "TAD image options...", + "SHOW_3DSX_TITLE_INFO": "Show 3DSX title info", + "FIRM_IMAGE_OPTIONS": "FIRM image options...", + "AGBSAVE_OPTIONS": "AGBSAVE options...", + "DUMP_GBA_VC_SAVE": "Dump GBA VC save", + "TICKET_DB_OPTIONS": "Ticket.db options...", + "MOUNT_AS_DIFF_IMAGE": "Mount as DIFF image", + "MOUNT_AS_DISA_IAMGE": "Mount as DISA image", + "INSTALL_CIFINISH_BIN": "Install cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey options...", + "AESKEYDB_OPTIONS": "AESkeydb options...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo options...", + "EXECUTE_GM9_SCRIPT": "Execute GM9 script", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Font options...", + "LANGUAGE_OPTIONS": "Language options...", + "VIEW_PNG_FILE": "View PNG file", + "REBUILD_NCSD_HEADER": "Rebuild NCSD header", + "SHOW_IN_HEXEDITOR": "Show in Hexeditor", + "CALCULATE_SHA256": "Calculate SHA-256", + "CALCULATE_SHA1": "Calculate SHA-1", + "SHOW_FILE_INFO": "Show file info", + "SHOW_IN_TEXTVIEWER": "Show in Textviewer", + "CALCULATE_CMAC": "Calculate CMAC", + "COPY_TO_OUT": "Copy to %s", + "DUMP_TO_OUT": "Dump to %s", + "INJECT_DATA_AT_OFFSET": "Inject data @offset", + "OPEN_THIS_FOLDER": "Open this folder", + "OPEN_CONTAINING_FOLDER": "Open containing folder", + "OPEN_TITLE_FOLDER": "Open title folder", + "PATH_N_FILES_SELECTED": "%s\n(%lu files selected)", + "CHECK_CURRENT_CMAC_ONLY": "Check current CMAC only", + "VERIFY_CMAC_FOR_ALL": "まじりぬCMAC確認すん", + "FIX_CMAC_FOR_ALL": "まじりぬCMAC修正すん", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%luファイルぬOK/修正/合計\n%lu/%luぬCMAC無し", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%luファイル検証済み\n%lu/%luファイル修正済み", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%luファイル検証済み\n%lu/%luファイルCMAC無し", + "N_OF_N_FILES_VERIFIED": "%lu/%luファイル検証済み", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "%sからデータ挿入さびーが?\n以下にオフセット入力しみそーれー。", + "FAILED_INJECTING_PATH": "%sぬ挿入んかいしーやんじゃびたん", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDSドライブんかいマウント", + "MOUNT_IMAGE_TO_DRIVE": "イメージドライブんかいマウント", + "RESTORE_SYSNAND_SAFE": "システムNAND復元 (安全)", + "UPDATE_EMBEDDED_BACKUP": "埋み込みバックアップ更新", + "SHOW_TITLE_INFO": "タイトル情報表示", + "DECRYPT_FILE": "ファイル復号化 (...)", + "DECRYPT_FILE_OUT": "ファイル復号化 (%sんかい)", + "ENCRYPT_FILE": "ファイル暗号化 (...)", + "ENCRYPT_FILE_OUT": "ファイル暗号化 (%sんかい)", + "BUILD_CIA_FROM_FILE": "ファイルからCIA作成", + "BUILD_CIA_STANDARD": "CIA作成 (標準)", + "BUILD_CIA_LEGIT": "CIA作成 (合法)", + "DUMP_CXI_NDS_FILE": "CXI/NDSファイルダンプ", + "INSTALL_GAME_IMAGE": "ゲームイメージをインストール", + "INSTALL_TICKET": "チケットインストール", + "DUMP_TICKET_FILE": "チケットファイルダンプ", + "UNINSTALL_TITLE": "タイトルアンインストール", + "VERIFY_FILE": "ファイル検証", + "TRANSFER_IMAGE_TO_CTRNAND": "CTRNANDんかいイメージ転送", + "INJECT_TO_H_AND_S": "がんじゅーんでぃ安全に挿入", + "TRIM_FILE": "ファイルトリミング", + "RENAME_FILE": "ファイルぬなめー変更", + "BUILD_XORPADS_SD": "XORパッド作成 (SDんかい出力)", + "BUILD_XORPADS_INPLACE": "XORパッド作成 (コピーさん)", + "EXTRACT_X": "%s解凍", + "INIT_X": "%s設定", + "INSTALL_X": "%sインストール", + "INSTALL_FIRM": "FIRMインストール", + "BOOT_FIRM": "FIRM起動", + "SET_AS_ACTIVE_FONT": "使用するフォントんかい設定", + "SET_AS_ACTIVE_LANGUAGE": "使用する言語んかい設定", + "DUMP_BA_VC_SAVE": "GBC VCセーブダンプ", + "INJECT_GBA_VC_SAVE": "GBA VCセーブ挿入", + "SET_AS_DEFAULT": "デフォルトとぅしてぃ設定", + "MOUNTING_IMAGE_FAILED": "イメージマウント: しーやんじゃびたん", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nドライブ%sとぅしてぃマウントさびたん\nなまちゃーきドライブんかい移動さびーが?", + "DECRYPT_TO_OUT": "%sんかい復号", + "DECRYPT_INPLACE": "コピーさんぐーとぅー復号", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "%lu個ぬ選択さるまじりぬファイル復号さびーが?", + "TRYING_TO_DECRYPT_N_FILES": "%lu個ぬファイル復号そーいびーん…", + "DECRYPTION_FAILED_CONTINUE": "復号化んかいしーやんじゃびたん\n \n続きやびーが?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル復号済み\n%lu/%luファイル暗号さりらん\n%lu/%luいぬ種類やあらん" +} diff --git a/resources/languages/source.json b/resources/languages/source.json new file mode 100644 index 000000000..48e040a08 --- /dev/null +++ b/resources/languages/source.json @@ -0,0 +1,816 @@ +{ + "GM9_LANGUAGE": "[LANGUAGE NAME]", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lX-%3$02lX-%4$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRM too big, can't boot", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nWarning: Do not boot FIRMs\nfrom untrusted sources.\n \nBoot FIRM?", + "NOT_BOOTABLE_FIRM": "Not a bootable FIRM.", + "FIRM_ENCRYPTED": "FIRM is encrypted.\n \nDecrypt before boot?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Make a copy at %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Try to boot anyways", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Warning: Trying to boot from an\nunsupported location.", + "ROOT": "[root]", + "LOADING": "LOADING...", + "PANE_N": "PANE #%lu", + "CURRENT": "CURRENT", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Game Virtual)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memory Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(Search)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "SDCARD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "GAME IMAGE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB IMAGE", + "LAB_BDRI_IMAGE": "BDRI IMAGE", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF IMAGE", + "LAB_MEMORY_VIRTUAL": "MEMORY VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "TITLE MANAGER", + "LAB_LAST_SEARCH": "LAST SEARCH", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[CLIPBOARD]", + "PLUS_N_MORE": "+ %lu more", + "MARK_DELETE_COPY": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n", + "MARK_DELETE_PASTE": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Relock write permissions\n", + "UNMOUNT_IMAGE": "R+X - Unmount image\n", + "UNMOUNT_SD": "R+B - Unmount SD card\n", + "REMOUNT_SD": "R+B - Remount SD card\n", + "DIRECTORY_OPTIONS": "R+A - Directory options\n", + "DRIVE_OPTIONS": "R+A - Drive options\n", + "MAKE_SCREENSHOT": "R+L - Make a Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Switch to prev/next pane\n", + "CLEAR_CLIPBOARD": "SELECT - Clear Clipboard\n", + "RESTORE_CLIPBOARD": "SELECT - Restore Clipboard\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Don't set up", + "CHOOSE_EMUNAND_TYPE": "Choose EmuNAND type to set up:", + "CLONE_SYSNAND_TO_REDNAND": "Clone SysNAND to RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Cloning SysNAND to EmuNAND: failed!", + "PRESS_A_TO_CONTINUE": "Press to continue", + "HEXEDITOR_CONTROLS": "Hexeditor Controls:\n \n↑↓→←(+R) - Scroll\nR+Y - Switch view\nX - Search / goto...\nA - Enter edit mode\nA+↑↓→← - Edit value\nB - Exit\n", + "NOT_FOUND": "Not found!", + "GO_TO_OFFSET": "Go to offset", + "SEARCH_FOR_STRING": "Search for string", + "SEARCH_FOR_DATA": "Search for data", + "CURRENT_OFFSET_SELECT_ACTION": "Current offset: %08lX\nSelect action:", + "CURRENT_OFFSET_ENTER_NEW": "Current offset: %08lX\nEnter new offset below.", + "ENTER_SEARCH_REPEAT_SEARCH": "Enter search string below.\n(R+X to repeat search)", + "MADE_EDITS_SAVE_CHANGES": "You made edits in %lu place(s).\nWrite changes to file?", + "FAILED_WRITING_TO_FILE": "Failed writing to file!", + "CALCULATING_SHA_FAILED": "Calculating SHA-%s: failed!", + "SHA_VERIFICATION_PASSED": "\nSHA verification: passed!", + "SHA_VERIFICATION_FAILED": "\nSHA verification: failed", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentical with previous file:\n", + "WRITE_SHA_FILE": "\n \nWrite .SHA file?", + "WRITE_SHA1_FILE": "\n \nWrite .SHA1 file?", + "CALCULATING_CMAC_FAILED": "Calculating CMAC: failed!", + "CMAC_VERIFICATION_PASSED": "CMAC verification: passed!", + "CMAC_VERIFICATION_FAILED": "CMAC verification: failed!", + "FIX_CMAC_IN_FILE": "\n \nFix CMAC in file?", + "FIXING_CMAC_FAILED": "Fixing CMAC: failed!", + "COPY_ALL_SELECTED_ITEMS": "Copy all %lu selected items?", + "FAILED_COPYING_ITEM": "Failed copying item", + "ITEMS_COPIED_TO_OUT": "%lu items copied to %s", + "PATH_COPIED_TO_OUT": "%s\nCopied to %s", + "CART_INIT_FAILED": "Cart init failed!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Cart: %s\nDetected size: %s\n \nInput dump size below.", + "NDS_CART_DECRYPT_SECURE_AREA": "Cart: %s\nNDS cart detected\nDecrypt the secure area?", + "FAILED_DUMPING_CART": "%s\nFailed dumping cart", + "PATH_DUMPED_TO_OUT": "%s\nDumped to %s", + "CREATED": "created", + "MODIFIED": "modified", + "ANALYZING_DRIVE": "Analyzing drive, please wait...", + "ANALYZING_DIR": "Analyzing dir, please wait...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu files & %lu subdirs\n%s total size\n \nspace free: %s\nspace used: %s\nspace total: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu files & %lu subdirs\n%s total size", + "FILESIZE_X": "filesize: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sread-only [%c] %shidden\n[%c] %ssystem [%c] %sarchive\n[%c] %svirtual\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← to change attributes)\n", + "A_TO_CONTINUE": "( to continue)", + "A_APPLY_B_CANCEL": "( to apply, to cancel)", + "A_YES_B_NO": "( yes, no)", + "A_SELECT_B_CANCEL": "( select, cancel)", + "HOLD_B_TO_CANCEL": "(hold B to cancel)", + "FAILED_TO_SET_ATTRIBUTES": "Failed to set attributes!", + "NAND_IMAGE_OPTIONS": "NAND image options...", + "CTRNAND_OPTIONS": "CTRNAND options...", + "MOUNT_FAT_IMAGE": "Mount as FAT image", + "CIA_IMAGE_OPTIONS": "CIA image options...", + "NCSD_IMAGE_OPTIONS": "NCSD image options...", + "NCCH_IMAGE_OPTIONS": "NCCH image options...", + "MOUNT_AS_EXEFS_IMAGE": "Mount as EXEFS image", + "MOUNT_AS_ROMFS_IMAGE": "Mount as ROMFS image", + "TMD_FILE_OPTIONS": "TMD file options...", + "TMD_CDN_OPTIONS": "TMD/CDN options...", + "TMD_TWL_OPTIONS": "TMD/TWL options...", + "MANAGE_TITLE": "Manage Title...", + "BOSS_FILE_OPTIONS": "BOSS file options...", + "DECRYPT_NUS_CDN_FILE": "Decrypt NUS/CDN file", + "SHOW_SMDH_TITLE_INFO": "Show SMDH title info", + "NDS_IMAGE_OPTIONS": "NDS image options...", + "GBA_IMAGE_OPTIONS": "GBA image options...", + "TICKET_OPTIONS": "Ticket options...", + "TAD_IMAGE_OPTIONS": "TAD image options...", + "SHOW_3DSX_TITLE_INFO": "Show 3DSX title info", + "FIRM_IMAGE_OPTIONS": "FIRM image options...", + "AGBSAVE_OPTIONS": "AGBSAVE options...", + "DUMP_GBA_VC_SAVE": "Dump GBA VC save", + "TICKET_DB_OPTIONS": "Ticket.db options...", + "MOUNT_AS_DIFF_IMAGE": "Mount as DIFF image", + "MOUNT_AS_DISA_IAMGE": "Mount as DISA image", + "INSTALL_CIFINISH_BIN": "Install cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey options...", + "AESKEYDB_OPTIONS": "AESkeydb options...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo options...", + "EXECUTE_GM9_SCRIPT": "Execute GM9 script", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "Font options...", + "LANGUAGE_OPTIONS": "Language options...", + "VIEW_PNG_FILE": "View PNG file", + "REBUILD_NCSD_HEADER": "Rebuild NCSD header", + "SHOW_IN_HEXEDITOR": "Show in Hexeditor", + "CALCULATE_SHA256": "Calculate SHA-256", + "CALCULATE_SHA1": "Calculate SHA-1", + "SHOW_FILE_INFO": "Show file info", + "SHOW_IN_TEXTVIEWER": "Show in Textviewer", + "CALCULATE_CMAC": "Calculate CMAC", + "COPY_TO_OUT": "Copy to %s", + "DUMP_TO_OUT": "Dump to %s", + "INJECT_DATA_AT_OFFSET": "Inject data @offset", + "OPEN_THIS_FOLDER": "Open this folder", + "OPEN_CONTAINING_FOLDER": "Open containing folder", + "OPEN_TITLE_FOLDER": "Open title folder", + "PATH_N_FILES_SELECTED": "%s\n(%lu files selected)", + "CHECK_CURRENT_CMAC_ONLY": "Check current CMAC only", + "VERIFY_CMAC_FOR_ALL": "Verify CMAC for all", + "FIX_CMAC_FOR_ALL": "Fix CMAC for all", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu files ok/fixed/total\n%lu/%lu have no CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu files verified ok\n%lu/%lu files fixed", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu files verified ok\n%lu/%lu have no CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu files verified ok", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Inject data from %s?\nSpecify offset below.", + "FAILED_INJECTING_PATH": "Failed injecting %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Mount CXI/NDS to drive", + "MOUNT_IMAGE_TO_DRIVE": "Mount image to drive", + "RESTORE_SYSNAND_SAFE": "Restore SysNAND (safe)", + "UPDATE_EMBEDDED_BACKUP": "Update embedded backup", + "SHOW_TITLE_INFO": "Show title info", + "DECRYPT_FILE": "Decrypt file (...)", + "DECRYPT_FILE_OUT": "Decrypt file (%s)", + "ENCRYPT_FILE": "Encrypt file (...)", + "ENCRYPT_FILE_OUT": "Encrypt file (%s)", + "BUILD_CIA_FROM_FILE": "Build CIA from file", + "BUILD_CIA_STANDARD": "Build CIA (standard)", + "BUILD_CIA_LEGIT": "Build CIA (legit)", + "DUMP_CXI_NDS_FILE": "Dump CXI/NDS file", + "INSTALL_GAME_IMAGE": "Install game image", + "INSTALL_TICKET": "Install ticket", + "DUMP_TICKET_FILE": "Dump ticket file", + "UNINSTALL_TITLE": "Uninstall title", + "VERIFY_FILE": "Verify file", + "TRANSFER_IMAGE_TO_CTRNAND": "Transfer image to CTRNAND", + "INJECT_TO_H_AND_S": "Inject to H&S", + "TRIM_FILE": "Trim file", + "RENAME_FILE": "Rename file", + "BUILD_XORPADS_SD": "Build XORpads (SD output)", + "BUILD_XORPADS_INPLACE": "Build XORpads (inplace)", + "EXTRACT_X": "Extract %s", + "INIT_X": "Init %s", + "INSTALL_X": "Install %s", + "INSTALL_FIRM": "Install FIRM", + "BOOT_FIRM": "Boot FIRM", + "SET_AS_ACTIVE_FONT": "Set as active font", + "SET_AS_ACTIVE_LANGUAGE": "Set as active language", + "DUMP_BA_VC_SAVE": "Dump GBA VC save", + "INJECT_GBA_VC_SAVE": "Inject GBA VC save", + "SET_AS_DEFAULT": "Set as default", + "MOUNTING_IMAGE_FAILED": "Mounting image: failed", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nMounted as drive %s\nEnter path now?", + "DECRYPT_TO_OUT": "Decrypt to %s", + "DECRYPT_INPLACE": "Decrypt inplace", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Try to decrypt all %lu selected files?", + "TRYING_TO_DECRYPT_N_FILES": "Trying to decrypt %lu files...", + "DECRYPTION_FAILED_CONTINUE": "Decryption failed\n \nContinue?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files decrypted ok\n%lu/%lu not encrypted\n%lu/%lu not of same type", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu files decrypted ok", + "N_FILES_WRITTEN_TO_OUT": "%lu files written to %s", + "FILE_NOT_ENCRYPTED": "File is not encrypted", + "DECRYPTION_SUCCESS": "Decryption success", + "DECRYPTION_FAILED": "Decryption failed", + "PATH_DECRYPTED_TO_OUT": "%s\nDecrypted to %s", + "ENCRYPT_TO_OUT": "Encrypt to %s", + "ENCRYPT_INPLACE": "Encrypt inplace", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Try to encrypt all %lu selected files?", + "TRYING_TO_ENCRYPT_N_FILES": "Trying to encrypt %lu files...", + "ENCRYPTION_FAILED_CONTINUE": "Encryption failed\n \nContinue?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files encrypted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu files encrypted ok", + "ENCRYPTION_SUCCESS": "Encryption success", + "ENCRYPTION_FAILED": "Encryption failed", + "PATH_ENCRYPTED_TO_OUT": "%s\nEncrypted to %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Try to process all %lu selected files?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nBuild %s failed\n \nContinue?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss built ok\n%lu/%lu not of same type", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss built ok", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu file(s) failed conversion.\nVerification is recommended.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s built to %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s build failed", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "file failed conversion.\n \nVerify now?", + "VERIFICATION_SUCCESS": "Verification success", + "VERIFICATION_FAILED": "Verification failed", + "CONTENT_IS_MISSING": "Content is missing", + "INSTALL_TO_SYSNAND": "Install to SysNAND", + "INSTALL_TO_EMUNAND": "Install to EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Try to install all %lu selected files?", + "TRYING_TO_INSTALL_N_FILES": "Trying to install %lu files...", + "INSTALL_FAILED_CONTINUE": "Install failed\n \nContinue?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files installed ok\n%lu/%lu not of same type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu files installed ok", + "INSTALL_SUCCESS": "Install success", + "INSTALL_FAILED": "Install failed", + "FILE_FAILED_INSTALL_VERIFY_NOW": "file failed install.\n \nVerify now?", + "KEEP_TICKET_AND_SAVEGAME": "Keep ticket & savegame", + "UNINSTALL_EVERYTHING": "Uninstall everything", + "ABORT_UNINSTALL": "Abort uninstall", + "UNINSTALL_N_SELECTED_TITLES": "Uninstall %lu selected titles?", + "UNINSTALL_SELECTED_TITLE": "Uninstall selected title?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu titles uninstalled", + "UNINSTALLING_PLEASE_WAIT": "Uninstalling, please wait...", + "UNINSTALL_FAILED": "Uninstall failed!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Try to verify all %lu selected files?", + "VERIFICATION_FAILED_CONTINUE": "Verification failed\n \nContinue?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files verified ok\n%lu/%lu not of same type", + "VERIFYING_FILE_PLEASE_WAIT": "Verifying file, please wait...", + "NAND_VALIDATION_SUCCESS": "NAND validation success", + "NAND_VALIDATION_FAILED": "NAND validation failed", + "DUMP_FOR_N_SELECTED_FILES": "Dump for all %lu selected files?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumped to %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumped to %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit ticket not found.\n \nDump anyways?", + "DUMP_TICKET_FAILED": "Dump ticket failed!", + "BUILDING_X": "Building %s...", + "BUILDING_X_SYSNAND": "Building %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Building %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu files processed", + "BUILD_DATABASE_SUCCESS": "Build database success.", + "BUILD_DATABASE_FAILED": "Build database failed.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Try to trim all %lu selected files?", + "TRIMMING_FAILED_CONTINUE": "Trimming failed\n \nContinue?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu files trimmed ok\n%lu/%lu not of same type\n%s saved", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu files trimmed ok\n%s saved", + "FILE_CANT_BE_TRIMMED": "File can't be trimmed.", + "FILE_ALREADY_TRIMMED": "File is already trimmed.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?", + "TRIMMING_FAILED": "Trimming failed.", + "PATH_TRIMMED_BY_X": "%s\nTrimmed by %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Try to rename all %lu selected files?", + "N_OF_N_RENAMED": "%lu/%lu renamed ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Could not rename to good name", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S inject", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S inject", + "H_AND_S_INJECT_SUCCESS": "H&S inject success", + "H_AND_S_INJECT_FAILURE": "H&S inject failure", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Try to extract all %lu selected files?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files extracted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu files extracted ok", + "EXTRACTING_DOT_CODE": "Extracting .code, please wait...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extracted to %s", + "DOT_CODE_EXTRACT_FAILED": ".code extract failed", + "TRANSFER_TO_SYSNAND": "Transfer to SysNAND", + "TRANSFER_TO_EMUNAND": "Transfer to EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND transfer success", + "CTRNAND_TRANSFER_FAILED": "CTRNAND transfer failed", + "NO_VALID_DESTINATION_FOUND": "No valid destination found", + "NAND_RESTORE_SUCCESS": "NAND restore success", + "NAND_RESTORE_FAILED": "NAND restore failed", + "REBUILD_NCSD_SUCCESS": "Rebuild NCSD success", + "REBUILD_NCSD_FAILED": "Rebuild NCSD failed", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Install to FIRM0", + "INSTALL_TO_FIRM1": "Install to FIRM1", + "INSTALL_TO_BOTH": "Install to both", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Switch EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restore H&S", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "Restore H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restore H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Set RTC date&time:", + "NEW_RTC_DATE_TIME_IS_TIME": "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen calibration success!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen calibration failed!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC date&time seems to be\nwrong. Set it now?", + "RESUME_GODMODE9": "Resume GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Select payload...", + "SELECT_SCRIPT": "Select script...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "Poweroff system", + "REBOOT_SYSTEM": "Reboot system", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader payloads menu.\nSelect payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Out of memory.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Open title manager", + "SEARCH_FOR_FILES": "Search for files...", + "FIX_CMACS_FOR_DRIVE": "Fix CMACs for drive", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "Found %lu results.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "Delete %lu path(s)?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "Failed deleting %lu/%lu path(s)", + "DELETE_FILE": "Delete \"%s\"?", + "FAILED_DELETING_PATH": "Failed deleting:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Not allowed in search drive", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Not allowed in virtual game path", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Not allowed in XORpad drive", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Not allowed in gamecart drive", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copy path(s)", + "MOVE_PATHS": "Move path(s)", + "PASTE_FILE_HERE": "Paste \"%s\" here?", + "PASTE_N_PATHS_HERE": "Paste %lu paths here?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Failed copying path:\n%s\nProcess remaining?", + "FAILED_COPYING_PATH": "Failed copying path:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Failed moving path:\n%s\nProcess remaining?", + "FAILED_MOVING_PATH": "Failed moving path:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Rename %s?\nEnter new name below.", + "FAILED_RENAMING_PATH": "Failed renaming path:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Create a folder", + "CREATE_A_DUMMY_FILE": "Create a dummy file", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Create a new folder here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Create a new file here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Failed creating folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Failed creating file:\n%s", + "TITLE_MANAGER": "Title manager", + "BRICK_MY_3DS": "Brick my 3DS", + "LANGUAGE": "Language...", + "SCRIPTS": "Scripts...", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Payloads...", + "MORE": "More...", + "BRACKET_MORE": "[more...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME button pressed.\nSelect action:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER button pressed.\nSelect action:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD CARD", + "B_DRIVE_SD_CARD": "[B:] SD CARD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads directory not found.\n(default path: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALID", + "TO_PROCEED_ENTER_THIS": "To proceed, enter this:", + "TO_PROCEED_HOLD_X": "To proceed, hold :", + "N_MORE": " [%d more]", + "CANCEL": "cancel", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) fast scroll\nL - clear data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - remove char\nY - insert char", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Searching, please wait...", + "RENAME_TO_GOOD_NAME": "Rename to good name?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD card is write protected!\nCan't continue.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "game images", + "GAMECART_SAVES": "gamecart saves", + "IMAGES": "images", + "MEMORY_AREAS": "memory areas", + "SD_SYSTEM_DATA": "SD system data", + "SD_CARD": "SD card", + "RAM_DRIVE": "RAM drive", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Writing to %s is locked!\nUnlock it now?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Unlock write permission for\n%s is not allowed.", + "ENABLE_BASE_WRITE": "You want to enable base\nwriting permissions.", + "ENABLE_SD_WRITE": "You want to enable SD card\nwriting permissions.", + "ENABLE_IMAGE_WRITE": "You want to enable image\nwriting permissions.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Error: SD card is too small", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatting SD, please wait...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatting drive, please wait...", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "File is currently mounted.\nUnmount to unlock?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Error: Can't inject file into itself", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operation would write beyond end of file", + "NOT_ENOUGH_DATA_IN_FILE": "Not enough data in file", + "CANCEL_IS_NOT_ALLOWED_HERE": "Cancel is not allowed here", + "B_DETECTED_CANCEL": "B button detected. Cancel?", + "ERROR_CANNOT_APPEND_FOLDER": "Error: Cannot append a folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Error: Not enough space available", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Error: Only FAT files can be moved", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Error: Destination is part of origin", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destination equals origin\nChoose another name?", + "CHOOSE_NEW_NAME": "Choose new name", + "OVERWRITE_FILES": "Overwrite file(s)", + "SKIP_FILES": "Skip file(s)", + "OVERWRITE_ALL": "Overwrite all", + "SKIP_ALL": "Skip all", + "DESTINATION_ALREADY_EXISTS": "Destination already exists:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choose new destination name", + "COPY_OPERATION_IS_NOT_ALLOWED": "Copy operation is not allowed", + "DESTINATION_EQUALS_ORIGIN": "Destination equals origin", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entry not found: %s\nInject into %s instead?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "Americas", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brazil", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europe", + "REGION_FRANCE": "France", + "REGION_GERMANY": "Germany", + "REGION_ITALY": "Italy", + "REGION_JAPAN": "Japan", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spain", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Unknown", + "REGION_UNITED_KINGDOM": "United Kingdom", + "REGION_MIDDLE_EAST": "Middle East", + "GENERATING_QR_CODE": "Generating QR code...", + "REINITIALIZING_SD_CARD": "Reinitializing SD card...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Press POWER to turn off", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Cleaning up titles, please wait...", + "ERROR_NOT_NCCH_FILE": "Error: Not an NCCH file", + "ERROR_FILE_IS_TOO_SMALL": "Error: File is too small", + "ATTEMPT_FIX_THIS_TIME": "Attempt fix this time", + "ATTEMPT_FIX_ALWAYS": "Attempt fix always", + "ABORT_VERIFICATION": "Abort verification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "fail", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Error: CDN titlekey not found", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC content is missing\n \nIgnore all and continue?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Error: Not a BOSS file", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS payload hash mismatch.\n \nTry to fix it?", + "GENERIC_TICKET_PIRATE_LEGIT": "Generic ticket (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalized ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey not found.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD is not legit.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD is not legit.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Content is corrupt", + "INSERT_CONTENT_FAILED": "Insert content failed", + "INSTALL_CONTENT_FAILED": "Install content failed", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Install error:\nThis system is missing the\nticket.db file.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Error: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", + "INSTALLING_TICKET": "Installing ticket...", + "POSSIBLY_BROKEN": "Possibly Broken", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Personal Legit DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personal Pirate Legit DLC", + "PERSONAL_CUSTOM": "Personal Custom", + "PERSONAL_CUSTOM_DLC": "Personal Custom DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Custom", + "UNIVERSAL_CUSTOM_DLC": "Universal Custom DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contents in CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contents in TMD: %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle version: %lu.%lu.%lu\nContents size: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerification: %s", + "STATE_LEGIT": "legit", + "STATE_ILLEGIT": "illegit", + "STATE_UNKNOWN": "unknown", + "STATE_INVALID": "invalid", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "pending\n \nProceed with verification?", + "STATE_PASSED": "passed", + "STATE_FAILED": "failed", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Output file already exists.\nUpdate this?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Fixing CMACs, please wait...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD header is not valid", + "NAND_DUMP_MISSING_DATA": "NAND dump missing data", + "ERROR_CTR_MBR_IS_CORRUPT": "Error: CTR MBR is corrupt", + "ERROR_TWL_MBR_IS_CORRUPT": "Error: TWL MBR is corrupt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nError: CTR partition%lu is corrupt", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nError: TWL partition%lu is corrupt", + "NO_VALID_FIRM_FOUND": "No valid FIRM found", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Error: NAND dump is corrupt.\nStill continue?", + "ERROR_SYSTEM_IS_LOCKED": "Error: System is locked.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Essential files backup is required.\nCreate one now?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD corrupt or customized,\nsafe restore is not possible!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?", + "NOT_AN_INSTALLABLE_FIRM": "Not a installable FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM load/verify error.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu not found or too small.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto fail.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!", + "INSTALLING_FIRM_PLEASE_WAIT": "Installing FIRM, please wait...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Checking installation, please wait...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfect %s is already installed!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nNot a perfect %s image.\nCannot install to NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFailed writing %s to NAND!", + "USE_L_R_TO_SAVE": "(use L+R to save)", + "EASTER_NOT_FOUND": "(%s not found)", + "BUILDING_TO_OUT_ARG": "Building to %s:\n%s ...", + "EJECT_SD_CARD": "Eject SD card...", + "INSERT_SD_CARD": "Insert SD card...", + "SCRIPTERR_UNKNOWN_CMD": "unknown cmd", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "bad # of args", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "unrecognized flags", + "SCRIPTERR_ILLEGAL_FLAG": "illegal flag", + "SCRIPTERR_UNRESOLVED_QUOTES": "unresolved quotes", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "too many arguments", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "argument expand failed", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "'not' an error", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "syntax error after 'if'", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' without 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "syntax error after 'elif'", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' without 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' without 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' inside 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "dir not found", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' without 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' without 'for'", + "SCRIPTERR_FORPATH_ERROR": "forpath error", + "SCRIPTERR_LABEL_NOT_FOUND": "label not found", + "SCRIPTERR_USER_ABORT": "user abort", + "SCRIPTERR_KEY_NOT_PRESSED": "key not pressed", + "SCRIPTERR_OUT_OF_MEMORY": "out of memory", + "SCRIPTERR_VAR_FAIL": "var fail", + "SCRIPTERR_FORBIDDEN_DRIVE": "forbidden drive", + "SCRIPTERR_INVALID_PATH": "invalid path", + "SCRIPTERR_FILESELECT_ABORT": "fileselect abort", + "SCRIPTERR_DIRSELECT_ABORT": "dirselect abort", + "SCRIPTERR_SET_FAIL": "set fail", + "SCRIPTERR_CHAR_NOT_FOUND": "char not found", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2] is not a char", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2] must be 2 chars", + "SCRIPTERR_ARG_MATCH": "arg match", + "SCRIPTERR_NO_ARG_MATCH": "no arg match", + "SCRIPTERR_PERMISSION_FAIL": "permission fail", + "SCRIPTERR_COPY_FAIL": "copy fail", + "SCRIPTERR_MOVE_FAIL": "move fail", + "SCRIPTERR_INJECT_FAIL": "inject fail", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte fail", + "SCRIPTERR_FILL_FAIL": "fill fail", + "SCRIPTERR_BAD_FILESIZE": "bad filesize", + "SCRIPTERR_CREATE_DUMMY_FILE": "create dummy fail", + "SCRIPTERR_REMOVE_FAIL": "remove fail", + "SCRIPTERR_MAKEDIR_FAIL": "makedir fail", + "SCRIPTERR_MOUNT_FAIL": "mount fail", + "SCRIPTERR_FIND_FAIL": "find fail", + "SCRIPTERR_FINDNOT_FAIL": "findnot fail", + "SCRIPTERR_NO_SIZE_GIVEN": "no size given", + "SCRIPTERR_SIZE_TOO_BIG": "size too big", + "SCRIPTERR_READ_FAIL": "read fail", + "SCRIPTERR_CONVERSION_FAIL": "conversion fail", + "SCRIPTERR_INVALID_DATA": "invalid data", + "SCRIPTERR_WRITE_FAIL": "write fail", + "SCRIPTERR_SHA_ARG0_FAIL": "sha arg0 fail", + "SCRIPTERR_SHA_ARG1_FAIL": "sha arg1 fail", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "sha does not match", + "SCRIPTERR_SHA_WRITE_FAIL": "sha write fail", + "SCRIPTERR_FILE_WRITE_FAIL": "file write fail", + "SCRIPTERR_FIXCMAC_FAILED": "fixcmac failed", + "SCRIPTERR_VERIFICATION_FAILED": "verification failed", + "SCRIPTERR_DECRYPT_FAILED": "decrypt failed", + "SCRIPTERR_ENCRYPT_FAILED": "encrypt failed", + "SCRIPTERR_BUILD_CIA_FAILED": "build CIA failed", + "SCRIPTERR_INSTALL_GAME_FAILED": "install game failed", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": "does not contain .code", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": "extract .code failed", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": "compress .code failed", + "SCRIPTERR_BUILD_FAILED": "build failed", + "SCRIPTERR_UNKNOWN_FILE": "unknown file", + "SCRIPTERR_APPLY_IPS_FAILD": "apply IPS failed", + "SCRIPTERR_APPLY_BPS_FAILED": "apply BPS failed", + "SCRIPTERR_APPLY_BPM_FAILED": "apply BPM failed", + "SCRIPTERR_TEXTVIEWER_FAILED": "textviewer failed", + "SCRIPTERR_BAD_DUMPSIZE": "bad dumpsize", + "SCRIPTERR_CART_INIT_FAIL": "cart init fail", + "SCRIPTERR_CART_DUMP_FAILED": "cart dump failed", + "SCRIPTERR_NOT_A_DIR": "not a dir", + "SCRIPTERR_FILE_NOT_FOUND": "file not found", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "not a bootable firm", + "SCRIPTERR_SD_NOT_MOUNTED": "SD not mounted", + "SCRIPTERR_UNKNOWN_ERROR": "unknown error", + "SCRIPTERR_COMMAND_SUCCESS": "command success", + "SCRIPTERR_CONTROL_FLOW_ERROR": "control flow error", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "unclosed conditional", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "error message fail", + "ERROR_INVALID_TEXT_DATA": "Error: Invalid text data", + "TEXTVIEWER_CONTROLS_DETAILS": "Textviewer Controls:\n \n↑↓→←(+R) - Scroll\nR+Y - Toggle wordwrap\nR+X - Goto line #\nB - Exit\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "Current line: %i\nEnter new line below.", + "PREVIEW_DISABLED": "(preview disabled)", + "PATH_LINE_N_ERR_LINE": "%s\nline %lu: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "end of script: unresolved 'if'", + "END_OF_SCRIPT_UNRESOLVED_FOR": "end of script: unresolved 'for'", + "SYSINFO_MODEL": "Model: %s (%s)\r\n", + "SYSINFO_SERIAL": "Serial: %s\r\n", + "SYSINFO_REGION_SYSTEM": "Region (system): %s\r\n", + "SYSINFO_REGION_SALES": "Region (sales): %s\r\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "SoC manufacturing date: %s\r\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "System assembly date: %s\r\n", + "SYSINFO_ORIGINAL_FIRMWARE": "Original firmware: %s\r\n", + "SYSINFO_FRIENDCODE_SEED": "Friendcode seed: %s\r\n", + "SYSINFO_SD_KEYY": "SD keyY: %s\r\n", + "SYSINFO_NAND_CID": "NAND CID: %s\r\n", + "SYSINFO_SD_CID": "SD CID: %s\r\n", + "SYSINFO_SYSTEM_ID0": "System ID0: %s\r\n", + "SYSINFO_SYSTEM_ID1": "System ID1: %s\r\n", + "SORTING_TICKETS_PLEASE_WAIT": "Sorting tickets, please wait ...", + "LUA_NOT_INCLUDED": "This build of GodMode9 was\ncompiled without Lua support." +} diff --git a/resources/languages/zh-CN.json b/resources/languages/zh-CN.json new file mode 100644 index 000000000..10cae0256 --- /dev/null +++ b/resources/languages/zh-CN.json @@ -0,0 +1,816 @@ +{ + "GM9_LANGUAGE": "简体中文", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lX-%3$02lX-%4$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRM太大,无法启动", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\n警告:请勿使用非授信来源的FIRM启动。\n \n启动FIRM吗?", + "NOT_BOOTABLE_FIRM": "非可启动的FIRM。", + "FIRM_ENCRYPTED": "FIRM已加密.\n \n需要在启动前解密吗?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "在 %s/temp.firm 上创建一个副本", + "TRY_BOOT_ANYWAYS": "尝试以任意方式启动", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "警告:尝试从不支持的位置启动。", + "ROOT": "[root]", + "LOADING": "正在加载...", + "PANE_N": "窗格 #%lu", + "CURRENT": "当前", + "DIR": "(目录)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(内存驱动器 FAT)", + "GAME_VIRTUAL": "(游戏虚拟)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND 虚拟)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND 虚拟)", + "IMAGE_FAT": "(镜像 FAT)", + "XORPAD_VIRTUAL": "(XORpad 虚拟)", + "MEMORY_VIRTUAL": "(内存虚拟)", + "ALIAS_FAT": "(别名 FAT)", + "GAMECART_VIRTUAL": "(游戏卡带虚拟)", + "VRAM_VIRTUAL": "(VRAM 虚拟)", + "SEARCH": "(搜索)", + "TITLEMANAGER_VIRTUAL": "(应用管理器 虚拟)", + "LAB_SDCARD": "SD 卡", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND 虚拟", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND 虚拟", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "游戏卡带", + "LAB_GAME_IMAGE": "游戏镜像", + "LAB_AESKEYDB_IMAGE": "AESKEYDB 镜像", + "LAB_BDRI_IMAGE": "BDRI 镜像", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF 镜像", + "LAB_MEMORY_VIRTUAL": "内存虚拟", + "LAB_VRAM_VIRTUAL": "VRAM 虚拟", + "LAB_TITLE_MANAGER": "应用管理器", + "LAB_LAST_SEARCH": "最后的搜索", + "LAB_FAT_IMAGE": "FAT 镜像", + "LAB_BONUS_DRIVE": "BONUS 驱动器", + "LAB_RAMDRIVE": "内存驱动器", + "LAB_NOLABEL": "无标签", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[剪贴板]", + "PLUS_N_MORE": "+ %lu 更多", + "MARK_DELETE_COPY": "L - 标记文件 (使用 ↑↓→←)\nX - 删除 / [+R] 重命名文件\nY - 复制文件 / [+R] 创建条目\n", + "MARK_DELETE_PASTE": "L - 标记文件 (使用 ↑↓→←)\nX - 删除 / [+R] 重命名文件\nY - 粘贴文件 / [+R] 创建条目\n", + "RELOCK_WRITE_PERMISSION": "R+Y - 重新锁定写入权限\n", + "UNMOUNT_IMAGE": "R+X - 卸载镜像\n", + "UNMOUNT_SD": "R+B - 卸载SD卡\n", + "REMOUNT_SD": "R+B - 重新挂载SD卡\n", + "DIRECTORY_OPTIONS": "R+A - 目录选项\n", + "DRIVE_OPTIONS": "R+A - 驱动器选项\n", + "MAKE_SCREENSHOT": "R+L - 截图\n", + "PREV_NEXT_PANE": "R+←→ - 切换到上一个/下一个PANE\n", + "CLEAR_CLIPBOARD": "SELECT - 清除剪贴板\n", + "RESTORE_CLIPBOARD": "SELECT - 还原剪贴板\n", + "REBOOT_POWEROFF_HOME": "START - 重新启动 / [+R] 关机\n按HOME键显示HOME菜单", + "NO_EMUNAND": "不存在EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND 大小 (最小)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND 大小 (完整)", + "MULTINAND_SIZE_2X": "MultiNAND 大小 (2x)", + "MULTINAND_SIZE_3X": "MultiNAND 大小 (3x)", + "MULTINAND_SIZE_4X": "MultiNAND 大小 (4x)", + "USER_INPUT": "用户输入...", + "AUTO": "自动", + "16KB_CLUSTERS": "16KB 簇", + "32KB_CLUSTERS": "32KB 簇", + "64KB_CLUSTERS": "64KB 簇", + "SD_NOT_DETECTED": "错误:未检测到SD卡。", + "FORMAT_SD_CHOOSE_EMUNAND": "想要格式化SD卡(%lluMB)吗?\n请选择EmuNAND大小:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD卡容量为 %lluMB。\n请在下方输入EmuNAND大小(MB):", + "FORMAT_SD_CHOOSE_CLUSTER": "想要格式化SD卡(%lluMB)吗?\n请选择簇大小:", + "FORMAT_SD_ENTER_LABEL": "想要格式化SD卡(%lluMB)吗?\n请输入卷标:", + "FORMAT_SD_FAILED": "格式化SD卡:失败!", + "REDNAND_TYPE": "RedNAND类型", + "REDNAND_TYPE_MULTI": "RedNAND类型(多个)", + "REDNAND_TYPE_SINGLE": "RedNAND类型(单个)", + "GW_EMUNAND_TYPE": "GW EmuNAND类型", + "DONT_SET_UP": "不设置", + "CHOOSE_EMUNAND_TYPE": "请选择要设置的EmuNAND类型:", + "CLONE_SYSNAND_TO_REDNAND": "要将SysNAND克隆到RedNAND吗?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "将SysNAND克隆到EmuNAND:失败!", + "PRESS_A_TO_CONTINUE": "按继续", + "HEXEDITOR_CONTROLS": "Hexeditor操作:\n \n↑↓→←(+R) - 滚动\nR+Y - 切换视图\nX - 搜索 / 跳转...\nA - 进入编辑模式\nA+↑↓→← - 编辑数值\nB - 退出\n", + "NOT_FOUND": "未找到!", + "GO_TO_OFFSET": "跳转到偏移地址", + "SEARCH_FOR_STRING": "搜索字符串", + "SEARCH_FOR_DATA": "搜索数据", + "CURRENT_OFFSET_SELECT_ACTION": "当前偏移地址:%08lX\n请选择操作:", + "CURRENT_OFFSET_ENTER_NEW": "当前偏移地址:%08lX\n请在下方输入新的偏移地址。", + "ENTER_SEARCH_REPEAT_SEARCH": "请在下方输入要搜索的字符串。\n(R+X再次搜索)", + "MADE_EDITS_SAVE_CHANGES": "你进行了%lu处编辑。\n是否要将这些修改写入文件?", + "FAILED_WRITING_TO_FILE": "写入文件失败!", + "CALCULATING_SHA_FAILED": "计算SHA-%s:失败!", + "SHA_VERIFICATION_PASSED": "\nSHA校验:通过!", + "SHA_VERIFICATION_FAILED": "\nSHA校验:失败", + "IDENTICAL_WITH_PREVIOUS": "\n与上一个文件相同:\n", + "WRITE_SHA_FILE": "\n \n要写入.SHA文件吗?", + "WRITE_SHA1_FILE": "\n \n要写入.SHA1文件吗?", + "CALCULATING_CMAC_FAILED": "计算CMAC:失败!", + "CMAC_VERIFICATION_PASSED": "CMAC效验:通过!", + "CMAC_VERIFICATION_FAILED": "CMAC校验:失败!", + "FIX_CMAC_IN_FILE": "\n \n要修复文件中的CMAC吗?", + "FIXING_CMAC_FAILED": "修复CMAC:失败!", + "COPY_ALL_SELECTED_ITEMS": "是否复制所有%lu 个选定项?", + "FAILED_COPYING_ITEM": "复制项目失败", + "ITEMS_COPIED_TO_OUT": "将%lu个项目复制到%s", + "PATH_COPIED_TO_OUT": "%s\n复制到%s", + "CART_INIT_FAILED": "卡带初始化失败!", + "CART_DETECTED_SIZE_INPUT_BELOW": "卡带:%s\n检测大小:%s\n \n请在下方输入转储大小.", + "NDS_CART_DECRYPT_SECURE_AREA": "卡带:%s\n检测到为NDS卡带\n是否解密安全区?", + "FAILED_DUMPING_CART": "%s\n转储卡带失败", + "PATH_DUMPED_TO_OUT": "%s\n转储到%s", + "CREATED": "已创建", + "MODIFIED": "已修改", + "ANALYZING_DRIVE": "正在分析驱动器,请稍候...", + "ANALYZING_DIR": "正在分析目录,请稍候...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu个文件& %lu个子目录\n总计大小%s \n \n空闲空间:%s\n已用空间:%s\n总计空间:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu个文件&%lu个子目录\n总计大小%s", + "FILESIZE_X": "文件大小:%s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s只读 [%c] %s隐藏\n[%c] %s系统 [%c] %s压缩\n[%c] %s虚拟\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← 改变文件属性)\n", + "A_TO_CONTINUE": "( 继续)", + "A_APPLY_B_CANCEL": "( 应用, 取消)", + "A_YES_B_NO": "( 是, 否)", + "A_SELECT_B_CANCEL": "( 选择, 取消)", + "HOLD_B_TO_CANCEL": "(按住B取消)", + "FAILED_TO_SET_ATTRIBUTES": "属性设置失败!", + "NAND_IMAGE_OPTIONS": "NAND镜像选项...", + "CTRNAND_OPTIONS": "CTRNAND选项...", + "MOUNT_FAT_IMAGE": "挂载为FAT镜像", + "CIA_IMAGE_OPTIONS": "CIA镜像选项...", + "NCSD_IMAGE_OPTIONS": "NCSD镜像选项...", + "NCCH_IMAGE_OPTIONS": "NCCH镜像选项...", + "MOUNT_AS_EXEFS_IMAGE": "挂载为EXEFS镜像", + "MOUNT_AS_ROMFS_IMAGE": "挂载为ROMFS镜像", + "TMD_FILE_OPTIONS": "TMD文件选项...", + "TMD_CDN_OPTIONS": "TMD/CDN选项...", + "TMD_TWL_OPTIONS": "TMD/TWL选项...", + "MANAGE_TITLE": "管理Title...", + "BOSS_FILE_OPTIONS": "BOSS文件选项...", + "DECRYPT_NUS_CDN_FILE": "解密NUS/CDN文件", + "SHOW_SMDH_TITLE_INFO": "显示SMDH标题信息", + "NDS_IMAGE_OPTIONS": "NDS镜像选项...", + "GBA_IMAGE_OPTIONS": "GBA镜像选项...", + "TICKET_OPTIONS": "Ticket选择...", + "TAD_IMAGE_OPTIONS": "TAD镜像选项...", + "SHOW_3DSX_TITLE_INFO": "显示3DSX标题信息", + "FIRM_IMAGE_OPTIONS": "FIRM镜像选项...", + "AGBSAVE_OPTIONS": "AGBSAVE选项...", + "DUMP_GBA_VC_SAVE": "转存GBA VC记录", + "TICKET_DB_OPTIONS": "Ticket.db选项...", + "MOUNT_AS_DIFF_IMAGE": "挂载为DIFF镜像", + "MOUNT_AS_DISA_IAMGE": "挂载为DISA镜像", + "INSTALL_CIFINISH_BIN": "安装cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey选项...", + "AESKEYDB_OPTIONS": "AESkeydb选项...", + "BUILD_X": "构建%s", + "NCCHINFO_OPTIONS": "NCCHinfo选项...", + "EXECUTE_GM9_SCRIPT": "执行GM9脚本", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "字体选项...", + "LANGUAGE_OPTIONS": "语言选项...", + "VIEW_PNG_FILE": "查看PNG文件", + "REBUILD_NCSD_HEADER": "重新构建NCSD头", + "SHOW_IN_HEXEDITOR": "在Hexeditor中显示", + "CALCULATE_SHA256": "计算SHA-256", + "CALCULATE_SHA1": "计算SHA-1", + "SHOW_FILE_INFO": "显示文件信息", + "SHOW_IN_TEXTVIEWER": "在文本查看器中显示", + "CALCULATE_CMAC": "计算CMAC", + "COPY_TO_OUT": "复制到%s", + "DUMP_TO_OUT": "转储到%s", + "INJECT_DATA_AT_OFFSET": "在指定偏移地址注入数据", + "OPEN_THIS_FOLDER": "打开此文件夹", + "OPEN_CONTAINING_FOLDER": "打开所在文件夹", + "OPEN_TITLE_FOLDER": "打开标题文件夹", + "PATH_N_FILES_SELECTED": "%s\n(已选择%lu个文件)", + "CHECK_CURRENT_CMAC_ONLY": "仅检查当前的CMAC", + "VERIFY_CMAC_FOR_ALL": "效验所有的CMAC", + "FIX_CMAC_FOR_ALL": "修复所有CMAC", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu个文件 正常/修复/总计\n%lu/%lu 不存在CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu个文件效验正常\n%lu/%lu个文件已修复", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu个文件效验正常\n%lu/%lu不存在CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu个文件校验正常", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "要从%s中注入数据吗?\n请在下方指定偏移地址。", + "FAILED_INJECTING_PATH": "注入%s失败", + "MOUNT_CXI_NDS_TO_DRIVE": "将CXI/NDS挂载至驱动器", + "MOUNT_IMAGE_TO_DRIVE": "将镜像挂载至驱动器", + "RESTORE_SYSNAND_SAFE": "恢复SysNAND(安全)", + "UPDATE_EMBEDDED_BACKUP": "更新嵌入式备份", + "SHOW_TITLE_INFO": "显示Title信息", + "DECRYPT_FILE": "解密文件(...)", + "DECRYPT_FILE_OUT": "解密文件(%s)", + "ENCRYPT_FILE": "加密文件(...)", + "ENCRYPT_FILE_OUT": "加密文件(%s)", + "BUILD_CIA_FROM_FILE": "从文件构建CIA", + "BUILD_CIA_STANDARD": "构建CIA(标准)", + "BUILD_CIA_LEGIT": "构建CIA(合法)", + "DUMP_CXI_NDS_FILE": "转储CXI/NDS文件", + "INSTALL_GAME_IMAGE": "安装游戏镜像", + "INSTALL_TICKET": "安装Ticket", + "DUMP_TICKET_FILE": "转储Ticket文件", + "UNINSTALL_TITLE": "卸载Title", + "VERIFY_FILE": "校验文件", + "TRANSFER_IMAGE_TO_CTRNAND": "将镜像迁移至CTRNAND", + "INJECT_TO_H_AND_S": "注入“安全使用须知”", + "TRIM_FILE": "精简文件", + "RENAME_FILE": "重命名文件", + "BUILD_XORPADS_SD": "构建XORpads(输出至SD卡)", + "BUILD_XORPADS_INPLACE": "构建XORpads(输出至当前位置)", + "EXTRACT_X": "提取%s", + "INIT_X": "初始化%s", + "INSTALL_X": "安装%s", + "INSTALL_FIRM": "安装FIRM", + "BOOT_FIRM": "启动FIRM", + "SET_AS_ACTIVE_FONT": "设置为活动字体", + "SET_AS_ACTIVE_LANGUAGE": "设置为活动语言", + "DUMP_BA_VC_SAVE": "转储GBA VC记录", + "INJECT_GBA_VC_SAVE": "注入GBA VC记录", + "SET_AS_DEFAULT": "设为默认", + "MOUNTING_IMAGE_FAILED": "挂载镜像:失败", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\n已挂载为驱动器%s\n是否要打开该路径?", + "DECRYPT_TO_OUT": "解密至%s", + "DECRYPT_INPLACE": "解密至当前位置", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "是否要尝试解密所有的%lu个选中文件?", + "TRYING_TO_DECRYPT_N_FILES": "正在尝试解密%lu个文件...", + "DECRYPTION_FAILED_CONTINUE": "解密失败\n \n是否继续?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu个文件解密成功\n%lu/%lu个文件未加密\n%lu/%lu个文件非同类型文件", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu个文件解密成功", + "N_FILES_WRITTEN_TO_OUT": "%lu个文件写入到%s", + "FILE_NOT_ENCRYPTED": "文件未加密", + "DECRYPTION_SUCCESS": "解密成功", + "DECRYPTION_FAILED": "解密失败", + "PATH_DECRYPTED_TO_OUT": "%s\n解密到%s", + "ENCRYPT_TO_OUT": "加密到%s", + "ENCRYPT_INPLACE": "加密到当前位置", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "是否要尝试加密所有的%lu个选中文件?", + "TRYING_TO_ENCRYPT_N_FILES": "正在尝试加密 %lu 个文件...", + "ENCRYPTION_FAILED_CONTINUE": "加密失败\n \n是否继续?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 个文件加密成功\n%lu/%lu 个文件非同一类型", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu 个文件加密成功", + "ENCRYPTION_SUCCESS": "加密成功", + "ENCRYPTION_FAILED": "加密失败", + "PATH_ENCRYPTED_TO_OUT": "%s\n已加密至 %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "是否要尝试处理所有的%lu个选中文件?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\n构建 %s 失败\n \n是否继续?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %s 构建完成\n%lu/%lu 个文件非同一类型", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss 构建完成", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu 个文件转换失败。\n建议进行校验。", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s 已构建至 %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s 构建失败", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "文件转换失败。\n \n是否立刻校验?", + "VERIFICATION_SUCCESS": "校验成功", + "VERIFICATION_FAILED": "校验失败", + "CONTENT_IS_MISSING": "内容缺失", + "INSTALL_TO_SYSNAND": "安装到 SysNAND", + "INSTALL_TO_EMUNAND": "安装到 EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "是否尝试安装全部选中的 %lu 个文件?", + "TRYING_TO_INSTALL_N_FILES": "正在尝试安装 %lu 个文件...", + "INSTALL_FAILED_CONTINUE": "安装失败\n \n是否继续?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 个文件安装成功\n%lu/%lu 个文件非同一类型", + "N_OF_N_FILES_INSTALLED": "%lu/%lu 个文件安装成功", + "INSTALL_SUCCESS": "安装成功", + "INSTALL_FAILED": "安装失败", + "FILE_FAILED_INSTALL_VERIFY_NOW": "文件安装失败。\n \n是否立刻验证?", + "KEEP_TICKET_AND_SAVEGAME": "保留Ticket和游戏记录", + "UNINSTALL_EVERYTHING": "全部卸载", + "ABORT_UNINSTALL": "中止卸载", + "UNINSTALL_N_SELECTED_TITLES": "卸载这 %lu 个选中的应用吗?", + "UNINSTALL_SELECTED_TITLE": "要卸载选中的应用吗?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu 个应用已卸载", + "UNINSTALLING_PLEASE_WAIT": "正在卸载, 请稍候...", + "UNINSTALL_FAILED": "卸载失败!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "是否要尝试校验所有的%lu个选中文件?", + "VERIFICATION_FAILED_CONTINUE": "校验失败\n \n是否继续?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 个文件校验完成\n%lu/%lu 个文件非同一类型", + "VERIFYING_FILE_PLEASE_WAIT": "正在校验文件, 请稍候...", + "NAND_VALIDATION_SUCCESS": "NAND校验成功", + "NAND_VALIDATION_FAILED": "NAND校验失败", + "DUMP_FOR_N_SELECTED_FILES": "是否要转储所有的%lu个选中文件?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "已转储 %lu/%lu 个合法Ticket\n\n是否尝试转储所有的Ticket?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu 个Ticket已转储至 %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket 已转储至 %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\n未找到合法Ticket.\n \n是否强制转储?", + "DUMP_TICKET_FAILED": "转储Ticket失败!", + "BUILDING_X": "正在构建 %s...", + "BUILDING_X_SYSNAND": "正在构建 %s (SysNAND)", + "BUILDING_X_EMUNAND": "正在构建 %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu 个文件已处理\n%lu/%lu 个文件已忽略", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu 个文件已处理", + "BUILD_DATABASE_SUCCESS": "构建数据库成功。", + "BUILD_DATABASE_FAILED": "构建数据库失败。", + "TRY_TO_TRIM_N_SELECTED_FILES": "是否要尝试精简所有的%lu个选中文件?", + "TRIMMING_FAILED_CONTINUE": "精简失败\n \n是否继续?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu个文件精简成功\n%lu/%lu个文件非同一类型\n%s saved", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu个文件精简成功\n%s 已保存", + "FILE_CANT_BE_TRIMMED": "文件无法精简。", + "FILE_ALREADY_TRIMMED": "文件已被精简。", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\n当前大小: %s\n精简大小: %s\n相差: %s\n \n要精简此文件吗?", + "TRIMMING_FAILED": "精简失败", + "PATH_TRIMMED_BY_X": "%s\n由 %s 精简.", + "TRY_TO_RENAME_N_SELECTED_FILES": "是否要尝试重命名所有的%lu个选中文件?", + "N_OF_N_RENAMED": "%lu/%lu 重命名成功", + "COULD_NOT_RENAME_TO_GOOD_NAME": "无法重命名为有效名称", + "SYSNAND_H_AND_S_INJECT": "注入 SysNAND 的\"安全使用须知\"", + "EMUNAND_H_AND_S_INJECT": "注入 EmuNAND 的\"安全使用须知\"", + "H_AND_S_INJECT_SUCCESS": "\"安全使用须知\"注入成功", + "H_AND_S_INJECT_FAILURE": "\"安全使用须知\"注入失败", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "是否要尝试提取所有的%lu个选中文件?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 个文件提取成功\n%lu/%lu 不属于同一类型", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu个文件提取成功", + "EXTRACTING_DOT_CODE": "正在提取 .code, 请稍候...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s 已提取至 %s", + "DOT_CODE_EXTRACT_FAILED": ".code 提取失败", + "TRANSFER_TO_SYSNAND": "迁移到SysNAND", + "TRANSFER_TO_EMUNAND": "迁移到EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND迁移成功", + "CTRNAND_TRANSFER_FAILED": "CTRNAND迁移失败", + "NO_VALID_DESTINATION_FOUND": "未找到有效的目标", + "NAND_RESTORE_SUCCESS": "NAND 恢复成功", + "NAND_RESTORE_FAILED": "NAND 恢复失败", + "REBUILD_NCSD_SUCCESS": "重新构建NCSD成功", + "REBUILD_NCSD_FAILED": "重新构建NCSD失败", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen 成功%c输出目录: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen 失败%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "正在更新嵌入式备份...", + "BACKUP_UPDATE_NOT_REQUIRED": "备份更新: 不需要", + "BACKUP_UPDATE_COMPLETED": "备份更新: 已完成", + "BACKUP_UPDATE_FAILED": "备份更新: 失败!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "警告: 密钥未经验证。\n继续使用风险自负, 是否继续?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb 初始化成功", + "AESKEYDB_INIT_FAILED": "AESkeydb 初始化失败", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb 安装成功", + "AESKEYDB_INSTALL_FAILED": "AESkeydb 安装失败", + "INSTALL_TO_FIRM0": "安装到 FIRM0", + "INSTALL_TO_FIRM1": "安装到 FIRM1", + "INSTALL_TO_BOTH": "两个都安装", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\n是否安装到 SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\n安装成功", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\n安装失败", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "警告:请勿运行非授信来源的脚本.\n\n是否要执行脚本?", + "SCRIPT_EXECUTE_SUCCESS": "脚本执行成功", + "SCRIPT_EXECUTE_FAILURE": "脚本执行失败", + "ERROR_CANNOT_VIEW_FILE": "错误: 无法查看文件\n(提示: 可能文件太大)", + "SAVEGAME_DUMPED_TO_OUT": "游戏记录已转储至 %s", + "SAVEGAME_DUMP_FAILED": "游戏记录转储失败!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC 游戏记录必须\n在剪贴板中。", + "SAVEGAME_INJECT_SUCCESS": "游戏记录注入成功!", + "SAVEGAME_INJECT_FAILED": "游戏记录注入失败!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "字体将在下次启动时生效", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "语言将在下次启动时生效", + "HOME_MORE_MENU_SELECT_ACTION": "HOME 更多... 菜单.\n请选择操作:", + "SD_FORMAT_MENU": "SD卡格式化菜单", + "BONUS_DRIVE_MENU": "Bonus 驱动器设置", + "SWITCH_EMUNAND": "切换EmuNAND", + "BUILD_SUPPORT_FILES": "构建支持文件", + "RESTORE_H_AND_S": "恢复\"安全使用须知\"", + "SET_RTC_DATE_TIME": "设置 RTC 日期和时间", + "CONFGURE_BRIGHTNESS": "设置亮度", + "CALIBRATE_TOUCHSCREEN": "校准触摸屏", + "SYSTEM_INFO": "系统信息", + "SHOW_README": "显示自述文件", + "INITIALIZING_SD_FAILED_RETRY": "初始化 SD 卡失败! 是否重试?", + "SETUP_FAILED": "设置失败!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "当前 EmuNAND 偏移位置为 %06lX。\n是否切换到下一个偏移位置?", + "BUILT_IN_OUT_STATUSES": "内置 %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "确定 (Sys&Emu)", + "OK_SYS": "确定 (Sys)", + "FAILED": "失败", + "RESTORE_H_AND_S_EMUNAND": "恢复\"安全使用须知\" (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "恢复\"安全使用须知\" (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "设置 RTC 日期和时间:", + "NEW_RTC_DATE_TIME_IS_TIME": "新 RTC 日期和时间为:\n%s\n \n提示: 设置 RTC 后, \nHomeMENU 时间需要\n手动调整。", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "触摸屏校准成功!", + "TOUCHSCREEN_CALIBRATION_FAILED": "触摸屏校准失败!", + "GODMODE9_README_TOC": "GodMode9 自述目录", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "未发现重要文件备份。\n是否立刻创建?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "备份SysNAND的嵌入式文件\n并写入到 %s。", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC日期和时间似乎不正确。\n需要设置吗?", + "RESUME_GODMODE9": "恢复 GodMode9", + "RESUME_BOOTLOADER": "恢复引导程序", + "SELECT_PAYLOAD": "选择 payload...", + "SELECT_SCRIPT": "选择脚本...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "系统关机", + "REBOOT_SYSTEM": "系统重启", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s 引导程序菜单.\n请选择操作:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "引导程序 payload 菜单.\n请选择 payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "引导程序脚本菜单.\n请选择脚本:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "未找到可启动的 FIRM。\n正在恢复 GodMode9...", + "OUT_OF_MEMORY": "内存不足。", + "INVALID_DIRECTORY_OBJECT": "无效的目录对象", + "INVALID_ROOT_DIRECTORY": "无效的根目录。", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "写入权限已更改。\n是否重新锁定?", + "OPEN_TITLE_MANAGER": "打开应用管理器", + "SEARCH_FOR_FILES": "查找文件...", + "FIX_CMACS_FOR_DRIVE": "修复驱动器的 CMAC", + "SHOW_DIRECTORY_INFO": "显示目录信息", + "SHOW_DRIVE_INFO": "显示驱动器信息", + "FAILED_SETTING_UP_TITLE_MANAGER": "设置应用管理器失败!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "要搜索 %s 吗?\n请在下方输入搜索内容。", + "FOUND_N_RESULTS": "找到 %lu 个结果。", + "FIX_CMACS_FOR_DRIVE_FINISHED": "修复驱动器CMAC完成。", + "FAILED_TO_ANALYZE_DRIVE": "分析驱动器失败\n", + "FAILED_TO_ANALYZE_DIR": "分析目录失败\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "在虚拟路径中不允许", + "DELETE_N_PATHS": "删除以下 %lu 个路径?", + "DELETING_FILES_PLEASE_WAIT": "正在删除文件, 请稍候…", + "FAILED_DELETING_N_OF_N_PATHS": "删除 %lu/%lu 个路径失败", + "DELETE_FILE": "要删除 “%s” 吗?", + "FAILED_DELETING_PATH": "删除失败: \n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "不允许在搜索驱动器中使用", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "不允许在虚拟游戏路径中使用", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "不允许在 XORpad 驱动器中使用", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "不允许在游戏卡带驱动器中使用", + "NOT_ALLOWED_IN_ALIAS_PATH": "不允许在别名路径中使用", + "COPY_PATHS": "复制路径", + "MOVE_PATHS": "移动路径", + "PASTE_FILE_HERE": "将\"%s\"粘贴到这里吗?", + "PASTE_N_PATHS_HERE": "将 %lu 个路径粘贴到这里吗?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "复制路径失败:\n%s\n是否处理剩余路径?", + "FAILED_COPYING_PATH": "复制路径失败:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "移动路径失败:\n%s\n是否处理剩余路径?", + "FAILED_MOVING_PATH": "移动路径失败:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "需要重命名 %s 吗?\n请在下方输入新文件名.", + "FAILED_RENAMING_PATH": "重命名路径失败:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "要在此处创建新条目吗?\n请选择类型。", + "CREATE_A_FOLDER": "新建文件夹", + "CREATE_A_DUMMY_FILE": "创建空白文件", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "要在此新建文件夹吗?\n请在下放输入文件夹名称。", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "要在在此新建文件吗?\n请在下放输入文件名。", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "要在此新建 %s 吗?\n请在下方输入文件大小。", + "FAILED_CREATING_FOLDER_PATH": "创建文件夹失败:\n%s", + "FAILED_CREATING_FILE_PATH": "创建文件失败:\n%s", + "TITLE_MANAGER": "Title 管理器", + "BRICK_MY_3DS": "让我的3DS变砖", + "LANGUAGE": "语言...", + "SCRIPTS": "脚本...", + "LUA_SCRIPTS": "Lua scripts...", + "PAYLOADS": "Payload...", + "MORE": "更多...", + "BRACKET_MORE": "[更多...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME键被按下.\n请选择操作:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "电源键被按下.\n请选择操作:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD 卡", + "B_DRIVE_SD_CARD": "[B:] SD 卡", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "应用管理器菜单。\n请选择应用源:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "未找到语言目录。\n(默认路径:0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "未找到脚本目录。\n(默认路径:0:/gm9/%s)", + "LUA_SCRIPTS_DIRECTORY_NOT_FOUND": "Lua scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "主页语言...菜单。\n请选择语言:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME 脚本...菜单。\n请选择脚本:", + "HOME_LUA_SCRIPTS_MENU_SELECT_SCRIPT": "HOME Lua scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "未找到 Payload 目录。\n(默认路径:0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "首页Payload...菜单。\n请选择Payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!SD 卡被意外移除!\n \n为了防止数据丢失,\n在弹出SD 卡前请先卸载.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s 脚本菜单。\n请选择脚本:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "已编译为脚本自动运行程序,\n但却未提供脚本.\n\n犯傻了吧!", + "KEYBOARD_CONTROLS_DETAILS": "键盘控制:\n \n←/→ - 移动光标\nR - 大写 / 大写锁定\nX - 删除字符\nY - 插入字符\nA - 提交\nB - 取消\n \n按 SELECT 切换到\n经典提示符", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "请触摸红色十字准线\n来校准触摸屏。\n \n使用触控笔可获得最佳\n效果!", + "INVALID": "无效", + "TO_PROCEED_ENTER_THIS": "若要继续操作,请输入:", + "TO_PROCEED_HOLD_X": "若要继续操作,请按住 :", + "N_MORE": " [%d 更多]", + "CANCEL": "取消", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) 快速滚动\nL - 清除数据", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - 删除字符\nY - 插入字符", + "ETA_N_HOUR_N_MIN_N_SEC": "ETA %02lluh%02llum%02llus", + "ETA_N_MIN_N_SEC": "预计 %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] 降低亮度\n[→] 增加亮度\n \n[X] 使用音量滑杆控制\n[A] 设置当前亮度\n[B] 取消", + "SEARCHING_PLEASE_WAIT": "正在搜索,请等待...", + "RENAME_TO_GOOD_NAME": "要重命名为正常名称吗?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD 卡已写入受保护!\n无法继续。", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "游戏镜像", + "GAMECART_SAVES": "游戏卡带记录", + "IMAGES": "镜像", + "MEMORY_AREAS": "内存区域", + "SD_SYSTEM_DATA": "SD 系统数据", + "SD_CARD": "SD 卡", + "RAM_DRIVE": "内存驱动器", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "写入 %s 已被锁定!\n要立刻解锁吗?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "不允许解锁\n%s 的写入权限。", + "ENABLE_BASE_WRITE": "您应该启用基础\n写入权限。", + "ENABLE_SD_WRITE": "您应该启用 SD 卡\n的写入权限。", + "ENABLE_IMAGE_WRITE": "您应该启用镜像\n的写入权限。", + "ENABLE_RAM_DRIVE_WRITE": "您应该启用内存驱动器\n的写入权限。", + "ENABLE_EMUNAND_0_WRITE": "您应该启用 EmuNAND\nlvl0 的写入权限。", + "ENABLE_SYSNAND_0_WRITE": "您应该启用 SysNAND\nlvl0 的写入权限。", + "ENABLE_EMUNAND_1_WRITE": "您应该启用 EmuNAND\nlvl1 的写入权限。\n \n这样您就可以修改\n可恢复的系统数据、\n用户数据和游戏记录。", + "ENABLE_SYSNAND_1_WRITE": "您应该启用 SysNAND\nlvl1 的写入权限。\n \n这样您就可以修改\n可恢复的系统数据、\n安装数据、用户数据\n和游戏记录。", + "ENABLE_GAMECART_SAVE_WRITE": "您应该启用游戏卡带\n记录写入权限。", + "ENABLE_SYSNAND_2_WRITE": "!最好小心点!\n \n您应该启用 SysNAND\nlvl2 的写入权限。\n \n这样就可以修改\n不可恢复的系统数据!", + "ENABLE_MEMORY_WRITE": "!最好小心点!\n \n您应该启用内存\n的写入权限。\n \n写入某些区域可能会\n导致意想不到的结果。", + "ENABLE_SD_DATA_WRITE": "!不建议这样做!\n \n您应该启用 SD 数据\n的写入权限。\n \n这里所有文件都是加密的。\n建议使用\nA:/B: 驱动器来修改\n安装程序、用户数据\n和游戏记录。", + "ENABLE_SYSNAND_3_WRITE": "!这是唯一的警告!\n \n您需要启用 SysNAND\nlvl3 的写入权限。\n \n这将使您能够覆盖\n您安装的引导程序、\n重要系统文件和/或\n让你的设备变砖!", + "UNLOCK_WRITE_NOT_ALLOWED": "不允许解锁写入权限。", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "无法解锁写入权限。\n请使用 GodMode9 重试!", + "ERROR_SD_TOO_SMALL": "错误:SD 卡太小", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "警告!\n \n该操作将格式化此 SD 卡。\n这将不可逆的删除它的\n所有数据.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "要格式化Bonus驱动器吗?\n这将不可逆地删除\n上面的所有数据。", + "FORMATTING_SD_PLEASE_WAIT": "正在格式化 SD 卡,请稍候...", + "FORMATTING_DRIVE_PLEASE_WAIT": "正在格式化驱动器,请稍候...", + "ERROR_SD_CARD_IO_FAILURE": "错误:SD 卡输入/输出失败", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "文件已被挂载。\n是否要卸载以解锁?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "错误:无法将文件注入其自身", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "操作将写入文件末尾之外", + "NOT_ENOUGH_DATA_IN_FILE": "文件中没有足够数据", + "CANCEL_IS_NOT_ALLOWED_HERE": "此处不允许取消", + "B_DETECTED_CANCEL": "检测到按下B键。是否取消?", + "ERROR_CANNOT_APPEND_FOLDER": "错误:无法附加文件夹", + "ERROR_OVERWRITING_FILE_WITH_DIR": "错误:用目录覆盖文件", + "ERROR_OVERWRITING_DIR_WITH_FILE": "错误:用文件覆盖目录", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "错误:无法打开目标文件", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "错误:可用空间不足", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "错误:只能移动 FAT 文件", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "错误:目标是源文件的一部分。", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "目标和源相同\n要选择另一个名称吗?", + "CHOOSE_NEW_NAME": "选择新名称", + "OVERWRITE_FILES": "覆盖文件", + "SKIP_FILES": "跳过文件", + "OVERWRITE_ALL": "全部覆盖", + "SKIP_ALL": "全部跳过", + "DESTINATION_ALREADY_EXISTS": "目标已存在:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "选择新的目标名称", + "COPY_OPERATION_IS_NOT_ALLOWED": "不允许复制操作", + "DESTINATION_EQUALS_ORIGIN": "目标和源相同", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "未找到条目: %s\n是否改为注入 %s?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "文件小于可用空间:\n%s (%s)\n%s (%s)\n是否继续?", + "NO_USABLE_ENTRIES_FOUND": "未找到可用条目。", + "BEAT_NO_ERROR": "没有错误", + "BEAT_END_OF_ACTION_LIST": "操作列表末尾", + "BEAT_ABORTED_BY_USER": "由用户中止", + "BEAT_FAILED_TO_READ_WRITE_FILE": "读/写文件失败", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "试图写入超出文件末尾的内容", + "BEAT_INVALID_PATCH_FILE": "无效的补丁文件", + "BEAT_INVALID_INPUT_FILE": "无效的输入文件", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "输出文件校验不匹配", + "BEAT_FILE_CHECKSUM_FAILED": "文件校验失败", + "BEAT_EXPECTED_MORE_PATCH_DATA": "需要更多补丁数据", + "BEAT_OUT_OF_MEMORY": "内存不足", + "BEAT_UNKNOWN_ERROR": "未知错误", + "FAILED_TO_INITIALIZE_BPM_FILE": "初始化 BPM 文件失败:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "初始化 BPS 文件失败:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "补丁应用成功", + "PATCHING_ABORTED_BY_USER": "补丁被用户中止", + "FAILED_TO_RUN_PATCH": "运行补丁失败:\n%s", + "DECOMPRESSING_DOT_CODE": "正在解压 .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "正在解压 .code...\n检测到按下 B 键。是否取消?", + "COMPRESSING_DOT_CODE": "正在压缩 .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "正在压缩 .code...\n检测到按下 B 键。是否取消?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "该补丁可能不是为该文件设计的。", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "您很可能在输出文件上打了补丁。", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "该补丁在技术上是有效的,\n但似乎有乱码或格式不正确。", + "PATCH_IS_INVALID": "该补丁无效。", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "单个或两个文件都大于 16MB。\nIPS 格式无法支持。", + "REQUESTED_FILE_PATH_WAS_INVALID": "请求的文件路径无效。", + "PATCHING_CANCELED": "补丁已取消。", + "NOT_ENOUGH_MEMORY": "内存不足.", + "REGION_AMERICAS": "美国", + "REGION_AUSTRALIA": "澳大利亚", + "REGION_BRAZIL": "巴西", + "REGION_CHINA": "中国", + "REGION_EUROPE": "欧洲", + "REGION_FRANCE": "法国", + "REGION_GERMANY": "德国", + "REGION_ITALY": "意大利", + "REGION_JAPAN": "日本", + "REGION_KOREA": "韩国", + "REGION_SPAIN": "西班牙", + "REGION_TAIWAN": "台湾省", + "REGION_UNKNOWN": "未知", + "REGION_UNITED_KINGDOM": "英国", + "REGION_MIDDLE_EAST": "中东", + "GENERATING_QR_CODE": "正在生成 QR 码...", + "REINITIALIZING_SD_CARD": "重新初始化 SD 卡...", + "DUMPING_STATE_TO_SD_CARD": "将状态转储至 SD 卡...", + "PRESS_POWER_TO_TURN_OFF": "按电源键关机", + "CLEANING_UP_TITLES_PLEASE_WAIT": "正在清理应用,请稍候...", + "ERROR_NOT_NCCH_FILE": "错误:非 NCCH 文件", + "ERROR_FILE_IS_TOO_SMALL": "错误:文件太小", + "ATTEMPT_FIX_THIS_TIME": "此次尝试修复", + "ATTEMPT_FIX_ALWAYS": "总是尝试修复", + "ABORT_VERIFICATION": "校验中止", + "ERROR_BAD_CRYPTO_FLAGS": "错误:错误的加密标志", + "ERROR_BAD_EXEFS_HEADER": "错误:错误的 ExeFS 文件头", + "ERROR_MISSING_EXTHEADER": "错误:缺少 ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "错误:加密标记未设置", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH 校验失败:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "确定", + "FAIL": "失败", + "ERROR_NOT_NCSD_FILE": "错误:非 NCSD 文件", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\n内容%lu (%08lX@%08lX):\n校验失败", + "ERROR_PROBABLY_NOT_CIA_FILE": "错误:可能不是 CIA 文件", + "ERROR_TMD_PROBABLY_CORRUPTED": "错误:TMD 可能已损坏", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\n校验失败", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "错误:未找到 CDN titlekey", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC 内容缺少\n \n忽略所有并继续?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\n%lu 处哈希值不匹配", + "ARM9_ENTRYPOINT_IS_MISSING": "缺少 ARM9 程序入口", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "警告:缺少 ARM11 程序入口点", + "ERROR_NOT_A_BOSS_FILE": "错误:非 BOSS 文件", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS 的 Payload 哈希值不匹配。\n \n是否尝试修复?", + "GENERIC_TICKET_PIRATE_LEGIT": "通用Ticket (\"盗版合法\")", + "PERSONALIZED_TICKET_LEGIT": "个人Ticket (合法)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\n合法Ticket是个人提供的。\n不建议使用。\n请选择默认操作:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\n未找到 Titlekey。", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTAD 中的 TMD 不合法。", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD 不合法.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "内容已损坏", + "INSERT_CONTENT_FAILED": "插入内容失败", + "INSTALL_CONTENT_FAILED": "安装内容失败", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "安装错误:\n系统缺少一个或\n多个 .db 文件。\n \n可能 SD 卡缺失\n或未初始化?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "安装错误:\n系统缺少\nticket.db 文件。", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "跳过Titile:\nID为0004008C000CBD00的Title\n需要特殊的编译标志。", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "错误:伪签名Ticket\n \n只有拥有效签名的Ticket\n才能安装到系统中。", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\n错误:未知的 cid %08lX\n \n此 Ticket 不属于\n此 3DS 设备。", + "INSTALLING_TICKET": "正在安装Ticket...", + "POSSIBLY_BROKEN": "可能已损坏", + "PERSONAL_LEGIT": "个人合法", + "PERSONAL_LEGIT_DLC": "个人合法 DLC", + "PERSONAL_PIRATE_LEGIT": "个人盗版合法", + "PERSONAL_PIRATE_LEGIT_DLC": "个人盗版合法 DLC", + "PERSONAL_CUSTOM": "个人自定义", + "PERSONAL_CUSTOM_DLC": "个人自定义 DLC", + "UNIVERSAL_LEGIT": "通用合法", + "UNIVERSAL_LEGIT_DLC": "通用合法 DLC", + "UNIVERSAL_PIRATE_LEGIT": "通用盗版合法", + "UNIVERSAL_PIRATE_LEGIT_DLC": "通用盗版合法 DLC", + "UNIVERSAL_CUSTOM": "通用自定义", + "UNIVERSAL_CUSTOM_DLC": "通用自定义 DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "CIA 中的内容: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "TMD 中的内容: %lu", + "CONSOLE_ID_N": "设备 ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle 版本: %lu.%lu.%lu\n内容大小: %s\n%s\n%s \nTicket/TMD: %s/%s\n校验: %s", + "STATE_LEGIT": "合法", + "STATE_ILLEGIT": "非法", + "STATE_UNKNOWN": "未知", + "STATE_INVALID": "无效", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "待定\n \n是否继续校验?", + "STATE_PASSED": "通过", + "STATE_FAILED": "失败", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "输出文件已存在。\n需要更新吗?", + "DSI_ENHANCED": "DSi 增强", + "DSI_EXCLUSIVE": "DSi 独占", + "FIXING_CMACS_PLEASE_WAIT": "正在修复CMAC,请稍候...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD 文件头无效", + "NAND_DUMP_MISSING_DATA": "NAND 转储丢失数据", + "ERROR_CTR_MBR_IS_CORRUPT": "错误:CTR MBR 已损坏", + "ERROR_TWL_MBR_IS_CORRUPT": "错误:TWL MBR 已损坏", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\n错误:CTR 分区%lu 已损坏", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\n错误:TWL 分区%lu 已损坏", + "NO_VALID_FIRM_FOUND": "未找到有效的 FIRM", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "错误:NAND 转储已损坏。\n是否继续?", + "ERROR_SYSTEM_IS_LOCKED": "错误:系统已锁定。", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "需要备份基础文件。\n是否立刻创建?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!警告!\n \n继续操作将使用提供的转储\n覆盖SysNAND\n \n(B9S/A9LH 将保持不变)。", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "镜像 NCSD 已经损坏或被自定义,\n已无法进行安全恢复!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \n镜像和本地的 NCSD 不同,\n需要提升写入权限\n \n有风险也要继续吗?", + "NOT_AN_INSTALLABLE_FIRM": "非可安装的 FIRM。", + "FIRM_LOAD_VERIFY_ERROR": "FIRM 加载/校验错误。", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu 未找到或太小。", + "SECTOR_0X96_CRYPTO_FAIL": "0x96扇区加密失败。", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "0x96 扇区已损坏。\n \n请提供 \"secret_sector.bin\"\n以修复 0x96 扇区。", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "0x96 扇区已损坏。\n \n是否在安装过程中\n修复扇区 0x96?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!警告!\n \n继续操作将会将提供的\nFIRM 安装到 SysNAND\n并注入 sighax。\n \n安装不支持的 FIRM\n将导致设备变砖!", + "INSTALLING_FIRM_PLEASE_WAIT": "正在安装 FIRM,请稍候...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!这很糟糕!\n \n写入0x96扇区失败。\n请在重启前尝试修复!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!这很糟糕!\n \n写入 FIRM%lu 失败。\n请在重启前尝试修复!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "正在安装检测,请稍候...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!这很糟糕!\n \n校验0x96扇区失败。\n请在重启前尝试修复!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!这很糟糕!\n \n校验 FIRM%lu 失败。\n请在重启前尝试修复!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "完整的 %s 已安装完毕!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\n不是完整的 %s 镜像。\n无法安装到 NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\n将 %s 写入 NAND 失败!", + "USE_L_R_TO_SAVE": "(使用 L+R 保存)", + "EASTER_NOT_FOUND": "(%s 未找到)", + "BUILDING_TO_OUT_ARG": "构建至 %s:\n%s...", + "EJECT_SD_CARD": "弹出 SD 卡...", + "INSERT_SD_CARD": "插入 SD 卡...", + "SCRIPTERR_UNKNOWN_CMD": "未知的 cmd", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "错误的#参数", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "无法识别的标识", + "SCRIPTERR_ILLEGAL_FLAG": "非法标识", + "SCRIPTERR_UNRESOLVED_QUOTES": "未解析的引号", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "参数过多", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "参数展开失败", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "'不是'错误", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "'if' 后的语法错误", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' 没有 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "'elif' 后的语法错误", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' 没有 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' 没有 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' 嵌套 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "找不到目录", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' 没有 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' 没有 'for'", + "SCRIPTERR_FORPATH_ERROR": "forpath 错误", + "SCRIPTERR_LABEL_NOT_FOUND": "标签未找到", + "SCRIPTERR_USER_ABORT": "用户中止", + "SCRIPTERR_KEY_NOT_PRESSED": "未按键", + "SCRIPTERR_OUT_OF_MEMORY": "内存不足", + "SCRIPTERR_VAR_FAIL": "var 失败", + "SCRIPTERR_FORBIDDEN_DRIVE": "禁止的驱动器", + "SCRIPTERR_INVALID_PATH": "无效路径", + "SCRIPTERR_FILESELECT_ABORT": "文件选择中止", + "SCRIPTERR_DIRSELECT_ABORT": "目录选择中止", + "SCRIPTERR_SET_FAIL": "设置失败", + "SCRIPTERR_CHAR_NOT_FOUND": "找不到字符", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2] 不是字符", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2] 必须是 2 个字符", + "SCRIPTERR_ARG_MATCH": "参数匹配", + "SCRIPTERR_NO_ARG_MATCH": "没有参数匹配", + "SCRIPTERR_PERMISSION_FAIL": "权限失败", + "SCRIPTERR_COPY_FAIL": "复制失败", + "SCRIPTERR_MOVE_FAIL": "移动失败", + "SCRIPTERR_INJECT_FAIL": "注入失败", + "SCRIPTERR_FILLBYTE_FAIL": "填充字节失败", + "SCRIPTERR_FILL_FAIL": "填充失败", + "SCRIPTERR_BAD_FILESIZE": "文件大小错误", + "SCRIPTERR_CREATE_DUMMY_FILE": "创建空白文件失败", + "SCRIPTERR_REMOVE_FAIL": "删除失败", + "SCRIPTERR_MAKEDIR_FAIL": "创建目录失败", + "SCRIPTERR_MOUNT_FAIL": "挂载失败", + "SCRIPTERR_FIND_FAIL": "查找失败", + "SCRIPTERR_FINDNOT_FAIL": "findnot 失败", + "SCRIPTERR_NO_SIZE_GIVEN": "未指定大小", + "SCRIPTERR_SIZE_TOO_BIG": "尺寸过大", + "SCRIPTERR_READ_FAIL": "读取失败", + "SCRIPTERR_CONVERSION_FAIL": "转换失败", + "SCRIPTERR_INVALID_DATA": "无效数据", + "SCRIPTERR_WRITE_FAIL": "写入失败", + "SCRIPTERR_SHA_ARG0_FAIL": "sha arg0 失败", + "SCRIPTERR_SHA_ARG1_FAIL": "sha arg1 失败", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "sha 不匹配", + "SCRIPTERR_SHA_WRITE_FAIL": "sha 写入失败", + "SCRIPTERR_FILE_WRITE_FAIL": "文件写入失败", + "SCRIPTERR_FIXCMAC_FAILED": "修复 cmac 失败", + "SCRIPTERR_VERIFICATION_FAILED": "校验失败", + "SCRIPTERR_DECRYPT_FAILED": "解密失败", + "SCRIPTERR_ENCRYPT_FAILED": "加密失败", + "SCRIPTERR_BUILD_CIA_FAILED": "构建 CIA 失败", + "SCRIPTERR_INSTALL_GAME_FAILED": "安装游戏失败", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": "未包含 .code", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": "提取 .code 失败", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": "压缩 .code 失败", + "SCRIPTERR_BUILD_FAILED": "构建失败。", + "SCRIPTERR_UNKNOWN_FILE": "未知文件", + "SCRIPTERR_APPLY_IPS_FAILD": "应用 IPS 失败", + "SCRIPTERR_APPLY_BPS_FAILED": "应用 BPS 失败", + "SCRIPTERR_APPLY_BPM_FAILED": "应用 BPM 失败", + "SCRIPTERR_TEXTVIEWER_FAILED": "文本查看器失败", + "SCRIPTERR_BAD_DUMPSIZE": "错误的转储大小", + "SCRIPTERR_CART_INIT_FAIL": "卡带初始化失败!", + "SCRIPTERR_CART_DUMP_FAILED": "卡带转储失败", + "SCRIPTERR_NOT_A_DIR": "不是目录", + "SCRIPTERR_FILE_NOT_FOUND": "文件未找到", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "非可启动的FIRM", + "SCRIPTERR_SD_NOT_MOUNTED": "未挂载 SD卡", + "SCRIPTERR_UNKNOWN_ERROR": "未知错误", + "SCRIPTERR_COMMAND_SUCCESS": "命令成功", + "SCRIPTERR_CONTROL_FLOW_ERROR": "控制流错误", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "未结束的条件", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "错误信息失败", + "ERROR_INVALID_TEXT_DATA": "错误:无效的文本数据", + "TEXTVIEWER_CONTROLS_DETAILS": "Textviewer 操作:\n \n↑↓→←(+R) - 滚动\nR+Y - 切换自动换行\nR+X - 转到某行 #\nB - 退出\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "当前行: %i\n请在下方输入新的行号.", + "PREVIEW_DISABLED": "(预览已禁用)", + "PATH_LINE_N_ERR_LINE": "%s\n行 %lu: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "脚本结束:未解决的 'if'", + "END_OF_SCRIPT_UNRESOLVED_FOR": "脚本结束:未解决的 'for'", + "SYSINFO_MODEL": "型号: %s (%s)\n", + "SYSINFO_SERIAL": "序列号: %s\n", + "SYSINFO_REGION_SYSTEM": "区域 (系统): %s\n", + "SYSINFO_REGION_SALES": "区域 (销售): %s\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "SoC 制造日期: %s\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "系统装配日期: %s\n", + "SYSINFO_ORIGINAL_FIRMWARE": "原始固件: %s\n", + "SYSINFO_FRIENDCODE_SEED": "好友码种子: %s\n", + "SYSINFO_SD_KEYY": "SD keyY: %s\n", + "SYSINFO_NAND_CID": "NAND CID: %s\n", + "SYSINFO_SD_CID": "SD CID: %s\n", + "SYSINFO_SYSTEM_ID0": "系统 ID0: %s\n", + "SYSINFO_SYSTEM_ID1": "系统 ID1: %s\n", + "SORTING_TICKETS_PLEASE_WAIT": "正在整理Ticket,请稍候...", + "LUA_NOT_INCLUDED": "This build of GodMode9 was\ncompiled without Lua support." +} diff --git a/resources/languages/zh-TW.json b/resources/languages/zh-TW.json new file mode 100644 index 000000000..b1fd17492 --- /dev/null +++ b/resources/languages/zh-TW.json @@ -0,0 +1,435 @@ +{ + "GM9_LANGUAGE": "中文(繁體)", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lX-%3$02lX-%4$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRM 太大,無法啓動", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\n警告:請勿從不受信任的來源啟動 FIRM。\n \n要啟動 FIRM 嗎?", + "NOT_BOOTABLE_FIRM": "不是可啟動的FIRM。", + "FIRM_ENCRYPTED": "FRIM已被加密。\n\n要在啟動前解密嗎?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "複製一份副本至 %s/temp.firm", + "TRY_BOOT_ANYWAYS": "仍嘗試啟動", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "警告:正在嘗試從不支援的位置啟動。", + "ROOT": "[根目錄]", + "LOADING": "載入中……", + "PANE_N": "窗格 #%lu", + "CURRENT": "當前", + "DIR": "(目錄)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(遊戲虛擬磁碟區)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND 虛擬磁碟區)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND 虛擬磁碟區)", + "IMAGE_FAT": "(映像檔 FAT)", + "XORPAD_VIRTUAL": "(XORpad 虛擬磁碟區)", + "MEMORY_VIRTUAL": "(記憶體虛擬磁碟區)", + "ALIAS_FAT": "(別名 FAT)", + "GAMECART_VIRTUAL": "(遊戲卡匣虛擬磁碟區)", + "VRAM_VIRTUAL": "(VRAM 虛擬磁碟區)", + "SEARCH": "(搜尋)", + "TITLEMANAGER_VIRTUAL": "(軟體管理虛擬磁碟區)", + "LAB_SDCARD": "SD 卡", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND 虛擬磁碟區", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND 虛擬磁碟區", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND 虛擬磁碟區", + "LAB_GAMECART": "遊戲卡匣", + "LAB_GAME_IMAGE": "遊戲映像", + "LAB_AESKEYDB_IMAGE": "AESKEYDB 映像", + "LAB_BDRI_IMAGE": "BDRI 映像", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF 映像", + "LAB_MEMORY_VIRTUAL": "記憶體虛擬磁碟區", + "LAB_VRAM_VIRTUAL": "VRAM 虛擬磁碟區", + "LAB_TITLE_MANAGER": "軟體管理", + "LAB_LAST_SEARCH": "最後一次的搜尋", + "LAB_FAT_IMAGE": "FAT 映像", + "LAB_BONUS_DRIVE": "BONUS 磁碟區", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "無標籤", + "N_BYTE": "%s 位元組", + "BYTE": " 位元組", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[剪貼簿]", + "PLUS_N_MORE": "+ %lu 已省略", + "MARK_DELETE_COPY": "L - 標示檔案 (與 ↑↓→← 搭配使用)\nX - 刪除 / [+R] 重新命名檔案\nY - 複製檔案 / [+R] 建立項目\n", + "MARK_DELETE_PASTE": "L - 標示檔案 (與 ↑↓→← 搭配使用)\nX - 刪除 / [+R] 重新命名檔案\nY - 貼上檔案 / [+R] 建立項目\n", + "RELOCK_WRITE_PERMISSION": "R+Y - 重新鎖定寫入權限\n", + "UNMOUNT_IMAGE": "R+X - 卸載映像\n", + "UNMOUNT_SD": "R+B - 卸載 SD 卡\n", + "REMOUNT_SD": "R+B - 重新掛載 SD 卡\n", + "DIRECTORY_OPTIONS": "R+A - 目錄選項\n", + "DRIVE_OPTIONS": "R+A - 磁碟區選項\n", + "MAKE_SCREENSHOT": "R+L - 擷取螢幕\n", + "PREV_NEXT_PANE": "R+←→ - 切換到上一個/下一個窗格\n", + "CLEAR_CLIPBOARD": "SELECT - 清除剪貼簿\n", + "RESTORE_CLIPBOARD": "SELECT - 還原剪貼簿\n", + "REBOOT_POWEROFF_HOME": "START - 重新開機 / [+R] 關機\n使用 HOME 按鈕開啟 HOME 選單", + "NO_EMUNAND": "無 EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND 大小 (最小)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND 大小 (完整)", + "MULTINAND_SIZE_2X": "MultiNAND 大小 (2x)", + "MULTINAND_SIZE_3X": "MultiNAND 大小 (3x)", + "MULTINAND_SIZE_4X": "MultiNAND 大小 (4x)", + "USER_INPUT": "使用者輸入……", + "AUTO": "自動", + "16KB_CLUSTERS": "16KB 叢集大小", + "32KB_CLUSTERS": "32KB 叢集大小", + "64KB_CLUSTERS": "64KB 叢集大小", + "SD_NOT_DETECTED": "錯誤:未偵測到 SD 卡。", + "FORMAT_SD_CHOOSE_EMUNAND": "格式化 SD 卡 (%lluMB)?\n選擇 EmuNAND 大小:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD 卡大小為 %lluMB。\n在下方輸入 EmuNAND 大小 (MB):", + "FORMAT_SD_CHOOSE_CLUSTER": "格式化 SD 卡 (%lluMB)?\n選擇叢集大小:", + "FORMAT_SD_ENTER_LABEL": "格式化 SD 卡 (%lluMB)?\n輸入磁碟區標籤:", + "FORMAT_SD_FAILED": "格式化 SD:失敗!", + "REDNAND_TYPE": "RedNAND 類型", + "REDNAND_TYPE_MULTI": "RedNAND 類型 (多重)", + "REDNAND_TYPE_SINGLE": "RedNAND 類型 (單一)", + "GW_EMUNAND_TYPE": "GW EmuNAND 類型", + "DONT_SET_UP": "不要設定", + "CHOOSE_EMUNAND_TYPE": "選擇要設定的 EmuNAND 類型:", + "CLONE_SYSNAND_TO_REDNAND": "將 SysNAND 複製到 RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "將 SysNAND 複製到 EmuNAND:失敗!", + "PRESS_A_TO_CONTINUE": "按 已繼續", + "HEXEDITOR_CONTROLS": "十六進位編輯器操作:\n \n↑↓→←(+R) - 捲動\nR+Y - 切換檢視模式\nX - 搜尋 / 前往...\nA - 進入編輯模式\nA+↑↓→← - 編輯數值\nB - 退出\n", + "NOT_FOUND": "未找到!", + "GO_TO_OFFSET": "前往指定偏移量", + "SEARCH_FOR_STRING": "搜尋指定字串", + "SEARCH_FOR_DATA": "搜尋指定數據", + "CURRENT_OFFSET_SELECT_ACTION": "目前的偏移量: %08lX\n選擇動作:", + "CURRENT_OFFSET_ENTER_NEW": "目前的偏移量: %08lX\n在下方輸入新的偏移量。", + "ENTER_SEARCH_REPEAT_SEARCH": "在下方輸入要搜尋的字串。\n(R+X 重複搜尋)", + "MADE_EDITS_SAVE_CHANGES": "您在 %lu 的地方進行了編輯。\n將變更寫入檔案?", + "FAILED_WRITING_TO_FILE": "寫入檔案失敗!", + "CALCULATING_SHA_FAILED": "計算 SHA-%s 失敗!", + "SHA_VERIFICATION_PASSED": "\nSHA驗證:通過!", + "SHA_VERIFICATION_FAILED": "\nSHA驗證:失敗", + "IDENTICAL_WITH_PREVIOUS": "\n與先前的檔案相同:\n", + "WRITE_SHA_FILE": "\n \n寫入 .SHA 檔案?", + "WRITE_SHA1_FILE": "\n \n寫入 .SHA1 檔案?", + "CALCULATING_CMAC_FAILED": "計算 CMAC:失敗!", + "CMAC_VERIFICATION_PASSED": "CMAC 驗證:通過!", + "CMAC_VERIFICATION_FAILED": "CMAC 驗證:失敗!", + "FIX_CMAC_IN_FILE": "\n \n修正檔案的 CMAC?", + "FIXING_CMAC_FAILED": "修正 CMAC:失敗!", + "COPY_ALL_SELECTED_ITEMS": "複製所有選取的 %lu 個項目?", + "FAILED_COPYING_ITEM": "複製失敗", + "ITEMS_COPIED_TO_OUT": "%lu 個項目已複製到 %s", + "PATH_COPIED_TO_OUT": "%s\n已複製到 %s", + "CART_INIT_FAILED": "卡匣初始化失敗!", + "CART_DETECTED_SIZE_INPUT_BELOW": "卡匣:%s\n偵測到的大小:%s\n\n在下方輸入備份大小。", + "NDS_CART_DECRYPT_SECURE_AREA": "卡匣:%s\n偵測到為 NDS 卡匣\n要解密安全區嗎?", + "FAILED_DUMPING_CART": "%s\n導出卡匣失敗", + "PATH_DUMPED_TO_OUT": "%s\n已導出至 %s", + "CREATED": "建立日期", + "MODIFIED": "修改日期", + "ANALYZING_DRIVE": "正在分析磁碟區中,請稍候……", + "ANALYZING_DIR": "正在分析目錄中,請稍候……", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu 個檔案和 %lu 個子目錄\n總計大小 %s\n \n可用空間:%s\n已使用空間:%s\n總空間:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu 個檔案和 %lu 個子目錄\n總計大小 %s", + "FILESIZE_X": "檔案大小:%s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s 唯讀 [%c] %s 隱藏\n[%c] %s 系統 [%c] %s 封存\n[%c] %s 虛擬\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← 變更屬性)\n", + "A_TO_CONTINUE": "( 繼續)", + "A_APPLY_B_CANCEL": "( 套用, 取消)", + "A_YES_B_NO": "( 是, 否)", + "A_SELECT_B_CANCEL": "( 選取, 取消)", + "HOLD_B_TO_CANCEL": "(按住 B 取消)", + "FAILED_TO_SET_ATTRIBUTES": "設定屬性失敗!", + "NAND_IMAGE_OPTIONS": "NAND 映像選項……", + "CTRNAND_OPTIONS": "CTRNAND 選項……", + "MOUNT_FAT_IMAGE": "掛載爲 FAT 映像", + "CIA_IMAGE_OPTIONS": "CIA 映像選項……", + "NCSD_IMAGE_OPTIONS": "NCSD 映像選項……", + "NCCH_IMAGE_OPTIONS": "NCCH 映像選項……", + "MOUNT_AS_EXEFS_IMAGE": "掛載為 EXEFS 映像", + "MOUNT_AS_ROMFS_IMAGE": "掛載為 ROMFS 映像", + "TMD_FILE_OPTIONS": "TMD 檔案選項……", + "TMD_CDN_OPTIONS": "TMD/CDN 選項……", + "TMD_TWL_OPTIONS": "TMD/TWL 選項……", + "MANAGE_TITLE": "管理軟體……", + "BOSS_FILE_OPTIONS": "BOSS 檔案選項……", + "DECRYPT_NUS_CDN_FILE": "解密 NUS/CDN 檔案", + "SHOW_SMDH_TITLE_INFO": "顯示 SMDH 軟體資訊", + "NDS_IMAGE_OPTIONS": "NDS 映像選項……", + "GBA_IMAGE_OPTIONS": "GBA 映像選項……", + "TICKET_OPTIONS": "Ticket 選項……", + "TAD_IMAGE_OPTIONS": "TAD 映像選項……", + "SHOW_3DSX_TITLE_INFO": "顯示 3DSX 軟體資訊", + "FIRM_IMAGE_OPTIONS": "FIRM 映像選項……", + "AGBSAVE_OPTIONS": "AGBSAVE 選項……", + "DUMP_GBA_VC_SAVE": "導出 GBA VC 存檔", + "TICKET_DB_OPTIONS": "Ticket.db 選項……", + "MOUNT_AS_DIFF_IMAGE": "掛載為 DIFF 映像", + "MOUNT_AS_DISA_IAMGE": "掛載爲 DISA 映像", + "INSTALL_CIFINISH_BIN": "安裝 cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey 選項……", + "AESKEYDB_OPTIONS": "AESkeydb 選項……", + "BUILD_X": "建立 %s", + "NCCHINFO_OPTIONS": "NCCHinfo 選項……", + "EXECUTE_GM9_SCRIPT": "執行 GM9 指令碼", + "EXECUTE_LUA_SCRIPT": "Execute Lua script", + "FONT_OPTIONS": "字型選項……", + "LANGUAGE_OPTIONS": "語言選項……", + "VIEW_PNG_FILE": "檢視 PNG 檔案", + "REBUILD_NCSD_HEADER": "重建 NCSD 標頭", + "SHOW_IN_HEXEDITOR": "在十六進制編輯器中顯示", + "CALCULATE_SHA256": "計算 SHA-256", + "CALCULATE_SHA1": "計算 SHA-1", + "SHOW_FILE_INFO": "顯示檔案資訊", + "SHOW_IN_TEXTVIEWER": "在文字檢視器中顯示", + "CALCULATE_CMAC": "計算 CMAC", + "COPY_TO_OUT": "複製到 %s", + "DUMP_TO_OUT": "導出至 %s", + "INJECT_DATA_AT_OFFSET": "將資料注入至指定偏移量", + "OPEN_THIS_FOLDER": "開啟此資料夾", + "OPEN_CONTAINING_FOLDER": "開啟存放資料夾", + "OPEN_TITLE_FOLDER": "開啟軟體資料夾", + "PATH_N_FILES_SELECTED": "%s\n(已選取 %lu 個檔案)", + "CHECK_CURRENT_CMAC_ONLY": "僅檢查目前的 CMAC", + "VERIFY_CMAC_FOR_ALL": "驗證所有 CMAC", + "FIX_CMAC_FOR_ALL": "修正所有 CMAC", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu 個檔案驗證無誤/已修正/總計\n%lu/%lu 個檔案沒有 CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu 檔案驗證無誤\n%lu/%lu 檔案已修正", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu 個檔案已驗證無誤\n%lu/%lu 個檔案沒有 CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu 個檔案已驗證無誤", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "從 %s 注入資料?\n在下方指定偏移量。", + "FAILED_INJECTING_PATH": "從 %s 注入失敗", + "MOUNT_CXI_NDS_TO_DRIVE": "將 CXI/NDS 掛載為磁碟區", + "MOUNT_IMAGE_TO_DRIVE": "將映像掛載為磁碟區", + "RESTORE_SYSNAND_SAFE": "還原 SysNAND (安全)", + "UPDATE_EMBEDDED_BACKUP": "更新內嵌備份", + "SHOW_TITLE_INFO": "顯示軟體資訊", + "DECRYPT_FILE": "解密檔案 (...)", + "DECRYPT_FILE_OUT": "解密檔案 (%s)", + "ENCRYPT_FILE": "加密檔案 (...)", + "ENCRYPT_FILE_OUT": "加密檔案 (%s)", + "BUILD_CIA_FROM_FILE": "以檔案建立 CIA", + "BUILD_CIA_STANDARD": "建立 CIA (標準)", + "BUILD_CIA_LEGIT": "建立 CIA (legit)", + "DUMP_CXI_NDS_FILE": "導出 CXI/NDS 檔案", + "INSTALL_GAME_IMAGE": "安裝遊戲映像", + "INSTALL_TICKET": "安裝 ticket", + "DUMP_TICKET_FILE": "導出 ticket 檔案", + "UNINSTALL_TITLE": "解除安裝軟體", + "VERIFY_FILE": "驗證檔案", + "TRANSFER_IMAGE_TO_CTRNAND": "將映像傳輸至 CTRNAND", + "INJECT_TO_H_AND_S": "注入至安全使用須知", + "TRIM_FILE": "縮小檔案", + "RENAME_FILE": "重新命名檔案", + "BUILD_XORPADS_SD": "建立 XORpad (輸出至 SD)", + "BUILD_XORPADS_INPLACE": "建立 XORpads (目前位置)", + "EXTRACT_X": "提取 %s", + "INIT_X": "初始化 %s", + "INSTALL_X": "安裝 %s", + "INSTALL_FIRM": "安裝 FIRM", + "BOOT_FIRM": "啟動 FIRM", + "SET_AS_ACTIVE_FONT": "設為目前字型", + "SET_AS_ACTIVE_LANGUAGE": "設為目前語言", + "DUMP_BA_VC_SAVE": "導出 GBA VC 存檔", + "INJECT_GBA_VC_SAVE": "注入 GBA VC 存檔", + "SET_AS_DEFAULT": "設為預設值", + "MOUNTING_IMAGE_FAILED": "掛載映像:失敗", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\n已掛載為磁碟區 %s\n查看該路徑?", + "DECRYPT_TO_OUT": "解密至 %s", + "DECRYPT_INPLACE": "解密並替換原檔案", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "嘗試解密所有選中的 %lu 個檔案?", + "TRYING_TO_DECRYPT_N_FILES": "嘗試解密 %lu 個檔案中……", + "DECRYPTION_FAILED_CONTINUE": "解密失敗\n \n要繼續嗎?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 個檔案解密成功\n%lu/%lu 個為非加密檔案\n%lu/%lu 個屬於不同類型", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu 個檔案已解密完成", + "N_FILES_WRITTEN_TO_OUT": "%lu 個檔案已寫入至 %s", + "FILE_NOT_ENCRYPTED": "並非已加密檔案", + "DECRYPTION_SUCCESS": "解密成功", + "DECRYPTION_FAILED": "解密失敗", + "PATH_DECRYPTED_TO_OUT": "%s\n已解密並儲存至 %s", + "ENCRYPT_TO_OUT": "加密至 %s", + "ENCRYPT_INPLACE": "加密並替換原檔案", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "嘗試加密所有選中的 %lu 個檔案?", + "TRYING_TO_ENCRYPT_N_FILES": "嘗試加密 %lu 個檔案中……", + "ENCRYPTION_FAILED_CONTINUE": "加密失敗\n \n要繼續嗎?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 個檔案加密成功\n%lu/%lu 個屬於不同類型", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu 個檔案已加密完成", + "ENCRYPTION_SUCCESS": "加密成功", + "ENCRYPTION_FAILED": "加密失敗", + "PATH_ENCRYPTED_TO_OUT": "%s\n已加密並儲存至 %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "嘗試處理所有選中的 %lu 個檔案?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\n建立 %s 失敗\n \n要繼續嗎?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 個 %s 建立成功\n%lu/%lu 個屬於不同類型", + "N_OF_N_TYPES_BUILT": "%lu/%lu 個 %s 建立成功", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu 個檔案轉換失敗。\n建議進行驗證。", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s 已建立並儲存至 %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s 建立失敗", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "檔案轉換失敗。\n \n要立即驗證嗎?", + "VERIFICATION_SUCCESS": "驗證無誤", + "VERIFICATION_FAILED": "驗證失敗", + "CONTENT_IS_MISSING": "內容遺失", + "INSTALL_TO_SYSNAND": "安裝至 SysNAND", + "INSTALL_TO_EMUNAND": "安裝至 EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "嘗試安裝所有選中的 %lu 個檔案?", + "TRYING_TO_INSTALL_N_FILES": "嘗試安裝 %lu 個檔案中……", + "INSTALL_FAILED_CONTINUE": "安裝失敗\n \n要繼續嗎?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 個檔案安裝成功\n%lu/%lu 個屬於不同類型", + "N_OF_N_FILES_INSTALLED": "%lu/%lu 個檔案已安裝成功", + "INSTALL_SUCCESS": "安裝成功", + "INSTALL_FAILED": "安裝失敗", + "FILE_FAILED_INSTALL_VERIFY_NOW": "檔案安裝失敗。\n \n要立刻驗證嗎?", + "KEEP_TICKET_AND_SAVEGAME": "保留 ticket 和存檔", + "UNINSTALL_EVERYTHING": "解除安裝所有內容", + "ABORT_UNINSTALL": "中止解除安裝", + "UNINSTALL_N_SELECTED_TITLES": "解除安裝所有選中的 %lu 個軟體?", + "UNINSTALL_SELECTED_TITLE": "解除安裝選中的軟體?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu 個軟體已成功解除安裝", + "UNINSTALLING_PLEASE_WAIT": "解除安裝中,請稍候……", + "UNINSTALL_FAILED": "解除安裝失敗!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "嘗試驗證所有選中的 %lu 個檔案?", + "VERIFICATION_FAILED_CONTINUE": "驗證失敗\n \n要繼續嗎?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 個檔案已驗證無誤\n%lu/%lu 個屬於不同類型", + "VERIFYING_FILE_PLEASE_WAIT": "正在驗證檔案中,請稍候……", + "NAND_VALIDATION_SUCCESS": "NAND 驗證成功", + "NAND_VALIDATION_FAILED": "NAND 驗證失敗", + "DUMP_FOR_N_SELECTED_FILES": "導出所有選中的 %lu 個檔案?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "已導出 %lu/%lu 個 legit ticket。\n \n嘗試導出所有 ticket?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu 個 ticket 已導出至 %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nticket 已導出至 %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\n未找到 legit ticket。\n \n仍要繼續導出?", + "DUMP_TICKET_FAILED": "導出 ticket 失敗!", + "BUILDING_X": "建立 %s 中……", + "BUILDING_X_SYSNAND": "建立 %s 中 (SysNAND)……", + "BUILDING_X_EMUNAND": "建立 %s 中 (EmuNAND)……", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu 個檔案完成處理\n%lu/%lu 個屬於不同類型", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu 個檔案完成處理", + "BUILD_DATABASE_SUCCESS": "資料庫建立成功。", + "BUILD_DATABASE_FAILED": "資料庫建立失敗。", + "TRY_TO_TRIM_N_SELECTED_FILES": "縮小所有選中的 %lu 個檔案?", + "TRIMMING_FAILED_CONTINUE": "縮小失敗\n \n要繼續嗎?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu 個檔案已縮小\n%lu/%lu 個為不同類型\n已儲存 %s", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu 個檔案已縮小\n已儲存 %s", + "FILE_CANT_BE_TRIMMED": "檔案無法縮小。", + "FILE_ALREADY_TRIMMED": "檔案已縮小過。", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\n目前大小: %s\n縮小號後的大小: %s\n差異: %s\n \n要縮小此檔案嗎?", + "TRIMMING_FAILED": "縮小失敗。", + "PATH_TRIMMED_BY_X": "%s\n已縮小 %s。", + "TRY_TO_RENAME_N_SELECTED_FILES": "嘗試重新命名所有選中的 %lu 個檔案?", + "N_OF_N_RENAMED": "%lu/%lu 個檔案已重新命名", + "COULD_NOT_RENAME_TO_GOOD_NAME": "無法重新命名為易讀名稱", + "SYSNAND_H_AND_S_INJECT": "注入 SysNAND 安全使用須知", + "EMUNAND_H_AND_S_INJECT": "注入 EmuNAND 安全使用須知", + "H_AND_S_INJECT_SUCCESS": "成功注入安全使用須知", + "H_AND_S_INJECT_FAILURE": "注入安全使用須知失敗", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "嘗試提取所有選中的 %lu 個檔案?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu 個檔案已成功提取\n%lu/%lu 個屬於不同類型", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu 個檔案已成功提取", + "EXTRACTING_DOT_CODE": "提取 .code 中,請稍候……", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s 已提取至 %s", + "DOT_CODE_EXTRACT_FAILED": ".code 提取失敗", + "TRANSFER_TO_SYSNAND": "傳輸至 SysNAND", + "TRANSFER_TO_EMUNAND": "傳輸至 EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND 傳輸成功", + "CTRNAND_TRANSFER_FAILED": "CTRNAND 傳輸失敗", + "NO_VALID_DESTINATION_FOUND": "無效的目標", + "NAND_RESTORE_SUCCESS": "NAND 還原成功", + "NAND_RESTORE_FAILED": "NAND 還原失敗", + "REBUILD_NCSD_SUCCESS": "重建 NCSD 成功", + "REBUILD_NCSD_FAILED": "重建 NCSD 失敗", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen 成功 %c 輸出位置: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen 失敗 %c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "更新內嵌備份中……", + "BACKUP_UPDATE_NOT_REQUIRED": "無需更新備份", + "BACKUP_UPDATE_COMPLETED": "已完成備份更新", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Install to FIRM0", + "INSTALL_TO_FIRM1": "Install to FIRM1", + "INSTALL_TO_BOTH": "Install to both", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Switch EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "還原安全使用須知", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "還原安全使用須知 (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "還原安全使用須知 (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Set RTC date&time:", + "NEW_RTC_DATE_TIME_IS_TIME": "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen calibration success!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen calibration failed!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC date&time seems to be\nwrong. Set it now?", + "RESUME_GODMODE9": "Resume GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Select payload...", + "SELECT_SCRIPT": "Select script...", + "SELECT_LUA_SCRIPT": "Select Lua script...", + "POWEROFF_SYSTEM": "Poweroff system", + "REBOOT_SYSTEM": "Reboot system", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader payloads menu.\nSelect payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Out of memory.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Open title manager", + "SEARCH_FOR_FILES": "Search for files...", + "FIX_CMACS_FOR_DRIVE": "Fix CMACs for drive", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "找到 %lu 個結果。", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "刪除 %lu 個項目?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "刪除 %lu/%lu 個項目失敗" +} diff --git a/resources/lua-doc.md b/resources/lua-doc.md new file mode 100644 index 000000000..62eb91f86 --- /dev/null +++ b/resources/lua-doc.md @@ -0,0 +1,1120 @@ +# GodMode9 Lua documentation + +GodMode9 includes a Lua 5.4.7 implementation. + +## Running scripts + +There are four ways to run Lua scripts: + +* Select it in the file browser and choose "`Execute Lua script`" +* Place it in `0:/gm9/luascripts`, then open the HOME menu, choose "`Lua scripts...`", then choose the script +* Place it in `data/luascripts`, then build GodMode9 from source + * This takes precedence over `0:/gm9/luascripts` +* Place it at `data/autorun.lua`, then build GodMode9 from source with `SCRIPT_RUNNER=1` to automatically run it at launch + +## Packages + +Lua scripts can load custom modules. The default search path (defined as `package.path`) is: + +``` +0:/gm9/luapackages/?.lua;0:/gm9/luapackages/?/init.lua;V:/luapackages/?.lua;V:/luapackages/?/init.lua +``` + +For example, when a script calls `require("foobar")`, the package searcher will look for the module in this order: + +* `0:/gm9/luapackages/foobar.lua` +* `0:/gm9/luapackages/foobar/init.lua` +* `V:/luapackages/foobar.lua` +* `V:/luapackages/foobar/init.lua` + +## Comparison with GM9Script + +These tables are provided to assist with converting from GM9Script to Lua. + +### Commands + +GM9 | Lua | Notes +-- | -- | -- +goto | http://lua-users.org/wiki/GotoStatement |   +labelsel | ui.ask_selection |   +for | fs.find_all | Recursive searching does not work exactly the same, it will search for the filename in all directories +keychk | ui.check_key |   +echo | ui.echo |   +qr | ui.show_qr |   +ask | ui.ask |   +input | ui.ask_input |   +filesel | fs.ask_select_file |   +dirsel | fs.ask_select_dir |   +set | local var = value | More details on variables and scoping: https://www.lua.org/pil/4.2.html +strsplit | string.find and string.sub |   +strrep | string.gsub | https://www.lua.org/manual/5.4/manual.html#pdf-string.gsub +allow | fs.allow |   +cp | fs.copy |   +mv | fs.move |   +inject | fs.write_file |   +fill | fs.fill_file |   +fdummy | fs.make_dummy_file |   +rm | fs.remove |   +mkdir | fs.mkdir |   +mount | fs.img_mount |   +umount | fs.img_umount |   +find | fs.find |   +findnot | fs.find_not |   +fget | fs.read_file |   +fset | fs.write_file |   +sha | fs.hash_file OR fs.verify_with_sha_file | hash_file simply returns a hash, verify_with_sha_file compares it with a corresponding .sha file +shaget | fs.hash_file |   +dumptxt | fs.write_file | Use "end" for offset to append data +fixcmac | fs.fix_cmacs |   +verify | fs.verify |   +decrypt | title.decrypt |   +encrypt | title.encrypt |   +buildcia | title.build_cia |   +install | title.install |   +extrcode | title.extract_code |   +cmprcode | title.compress_code |   +sdump | fs.key_dump |   +applyips | target.apply_ips |   +applybps | target.apply_bps |   +applybpm | target.apply_bpm |   +textview | fs.show_file_text_viewer | fs.show_text_viewer can be used to show text from a variable +cartdump | fs.cart_dump |   +isdir | fs.is_dir |   +exist | fs.exists |   +boot | sys.boot |   +switchsd | fs.sd_switch |   +nextemu | sys.next_emu |   +reboot | sys.reboot |   +poweroff | sys.power_off |   +bkpt | bkpt |   + +### PREVIEW_MODE variable + +Unlike the `PREVIEW_MODE` GM9Script variable, this has been split into multiple functions. + +Setting | Lua +-- | -- +“quick" and “full" | (There is no alternative to view a Lua script as it’s running.) +“off" | ui.clear +text | ui.show_text +png file | ui.show_png +game icon | ui.show_game_info + +### Other constants + +GM9 | Lua | Notes +-- | -- | -- +DATESTAMP | util.get_datestamp() | Formatted like “241202", equivalent to os.date("%y%m%d") +TIMESTAMP | util.get_timestamp() | Formatted like “010828", equivalent to os.date("%H%M%S") +SYSID0 | sys.sys_id0 |   +EMUID0 | sys.emu_id0 |   +EMUBASE | sys.emu_base |   +SERIAL | sys.serial |   +REGION | sys.region |   +SDSIZE | fs.stat_fs("0:/").total | int instead of string (use ui.format_bytes to format it) +SDFREE | fs.stat_fs("0:/").free | int instead of string (use ui.format_bytes to format it) +NANDSIZE | NANDSIZE | int instead of string (use ui.format_bytes to format it) +GM9OUT | GM9OUT |   +CURRDIR | CURRDIR | nil instead of “(null)" if it can’t be found +ONTYPE | CONSOLE_TYPE | “O3DS" or “N3DS" +RDTYPE | IS_DEVKIT | boolean instead of a string +HAX | HAX |   +GM9VER | GM9VER |   + +## Comparisons with standard Lua + +These original Lua 5.4 modules are fully available: +* [Basic functions](https://www.lua.org/manual/5.4/manual.html#6.1) + * `print` will replace the top screen with an output log. Currently it does not implement some features such as line wrapping. + * dofile and loadfile don't work yet. +* [coroutine](https://www.lua.org/manual/5.4/manual.html#6.2) +* [debug](https://www.lua.org/manual/5.4/manual.html#6.10) +* [math](https://www.lua.org/manual/5.4/manual.html#6.7) +* [string](https://www.lua.org/manual/5.4/manual.html#6.4) +* [table](https://www.lua.org/manual/5.4/manual.html#6.6) +* [utf8](https://www.lua.org/manual/5.4/manual.html#6.5) + +These modules are partially available: +* [os](https://www.lua.org/manual/5.4/manual.html#6.9) + * Only `os.clock`, `os.time`, `os.date`, `os.difftime`, and `os.remove` +* [io](https://www.lua.org/manual/5.4/manual.html#6.8) + * Only `io.open`; for open files, all but `file:setvbuf` and `file:lines` + * This is a custom compatibility module that uses `fs` functions. If there are differences compared to the original `io` implementation, please report them as issues. + +These modules work differently: +* [package](https://www.lua.org/manual/5.4/manual.html#6.3) + * `package.cpath` and `package.loadlib` are nonfunctional due to GM9 having no ability to load dynamic libraries. + +## Third-party libraries + +rxi's [json.lua](https://github.com/rxi/json.lua) is pre-included. To use it, first load it: + +```lua +local json = require("json") +``` + +--- + +## API reference + +### Constants + +#### GM9VER +The version such as `"v2.1.1-159-gff2cb913"`, the same string that is shown on the main screen. + +#### SCRIPT +Path to the executed script, such as `"0:/gm9/luascripts/myscript.lua"`. + +#### CURRDIR +Directory of the executed script, such as `"0:/gm9/luascripts"`. + +#### GM9OUT +The value `"0:/gm9/out"`. + +#### HAX +> [!WARNING] +> This needs checking if it's accurate. +One of three values: +* "ntrboot" if started from an ntrboot cart +* "sighax" if booted directly from a FIRM partition +* Empty string otherwise + +#### NANDSIZE +Total size of SysNAND in bytes. + +#### CONSOLE_TYPE +The string `"O3DS"` or `"N3DS"`. + +#### IS_DEVKIT +`true` if the console is a developer unit. + +--- + +### `ui` module + +> [!NOTE] +> This assumes the default build is used, where the bottom screen is the main screen. If GodMode9 is compiled with `SWITCH_SCREENS=1`, then every instance where something appears on the bottom screen will actually be on the top screen and vice versa. + +#### ui.echo + +* `void ui.echo(string text)` + +Display text on the bottom screen and wait for the user to press A. + +* **Arguments** + * `text` - Text to show the user + +#### ui.ask + +* `bool ui.ask(string text)` + +Prompt the user with a yes/no question. + +* **Arguments** + * `text` - Text to ask the user +* **Returns:** `true` if the user accepts + +#### ui.ask_hex + +* `int ui.ask_hex(string text, int initial, int n_digits)` + +Ask the user to input a hex number. + +* **Arguments** + * `text` - Text to ask the user + * `initial` - Starting value + * `n_digits` - Amount of hex digits allowed +* **Returns:** the number the user entered, or `nil` if canceled + +#### ui.ask_number + +* `int ui.ask_number(string text, int initial)` + +Ask the user to input a number. + +* **Arguments** + * `text` - Text to ask the user + * `initial` - Starting value +* **Returns:** the number the user entered, or `nil` if canceled + +#### ui.ask_text + +* `string ui.ask_text(string prompt, string initial, int max_length)` + +Ask the user to input text. + +* **Arguments** + * `prompt` - Text to ask the user + * `initial` - Starting value + * `max_length` - Maximum length of the string +* **Returns:** the text the user entered, or `nil` if canceled + +#### ui.ask_selection + +* `int ui.ask_selection(string prompt, table options)` + +Ask the user to choose an option from a list. A maximum of 256 options are allowed. + +* **Arguments** + * `prompt` - Text to ask the user + * `options` - Table of options +* **Returns:** index of selected option, or `nil` if canceled + +#### ui.clear + +* `void ui.clear()` + +Clears the top screen. + +#### ui.show_png + +* `void ui.show_png(string path)` + +Displays a PNG file on the top screen. + +The image must not be larger than 400 pixels horizontal or 240 pixels vertical. If `SWITCH_SCREENS=1` is used, it must not be larger than 320 pixels horizontal. + +* **Arguments** + * `path` - Path to PNG file +* **Throws** + * `"Could not read (file)"` - file does not exist or there was another read error + * `"Invalid PNG file"` - file is not a valid PNG + * `"PNG too large"` - too large horizontal or vertical, or an out-of-memory error + +#### ui.show_text + +* `void ui.show_text(string text)` + +Displays text on the top screen. + +* **Arguments** + * `text` - Text to show the user + +#### ui.show_game_info + +* `void ui.show_game_info(string path)` + +Shows game file info. Accepts any files that include an SMDH, a DS game file, or GBA file. + +* **Arguments** + * `path` - Path to game file (CIA, CCI/".3ds", SMDH, TMD, TIE (DSiWare export), Ticket, NDS, GBA) +* **Throws** + * `"ShowGameFileIcon failed on "` - failed to get game info from path + +#### ui.show_qr + +* `void ui.show_qr(string text, string data)` + +Displays a QR code on the top screen, and a prompt on the bottom screen, and waits for the user to press A. + +* **Arguments** + * `text` - Text to show the user + * `data` - Data to encode into the QR code +* **Throws** + * `"could not allocate memory"` - out-of-memory error when attempting to generate the QR code + +#### ui.show_text_viewer + +* `void ui.show_text_viewer(string text)` + +Display a scrollable text viewer. + +* **Arguments** + * `text` - Text to display +* **Throws** + * `"text validation failed"` - given string contains invalid characters + * `"failed to run MemTextViewer"` - internal memory viewer error + +#### ui.show_file_text_viewer + +* `void ui.show_file_text_viewer(string path)` + +Display a scrollable text viewer from a text file. + +* **Arguments** + * `path` - Path to text file +* **Throws** + * `"could not allocate memory"` - out-of-memory error when attempting to create the text buffer + * `"text validation failed"` - text file contains invalid characters + * `"failed to run MemTextViewer"` - internal memory viewer error + +#### ui.format_bytes + +* `string ui.format_bytes(int bytes)` + +Format a number with `Byte`, `kB`, `MB`, or `GB`. + +> [!NOTE] +> This is affected by localization and may return different text if the language is not English. + +* **Arguments** + * `bytes` - Size to format +* **Returns:** formatted string + +#### ui.check_key + +* `bool ui.check_key(string key)` + +Checks if the user is holding down a key. + +* **Arguments** + * `key` - A button string: `"A"`, `"B"`, `"SELECT"`, `"START"`, `"RIGHT"`, `"LEFT"`, `"UP"`, `"DOWN"`, `"R"`, `"L"`, `"X"`, `"Y"` +* **Returns:** `true` if currently held, `false` if not + +--- + +### `fs` module + +#### fs.move + +* `void fs.move(string src, string dst[, table opts {bool no_cancel, bool silent, bool overwrite, bool skip_all}])` + +Moves or renames a file or directory. + +* **Arguments** + * `src` - Item to move + * `dst` - Destination name + * `opts` (optional) - Option flags + * `no_cancel` - Don’t allow user to cancel + * `silent` - Don’t show progress + * `overwrite` - Overwrite files + * `skip_all` - Skip existing files +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"destination already exists on -> and {overwrite=true} was not used"` - attempted to move an item over an existing one without using `overwrite` + * `"PathMoveCopy failed on -> "` - error when moving, or user canceled + +#### fs.remove + +* `void fs.remove(string path[, table opts {bool recursive}])` + +Delete a file or directory. + +* **Arguments** + * `path` - Path to delete + * `opts` (optional) - Option flags + * `recursive` - Remove directories recursively +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"requested directory remove without {recursive=true} on "` - attempted to delete a directory without using `recursive` + * `"PathDelete failed on %s"` - error when deleting + +#### fs.copy + +* `void fs.copy(string src, string dst[, table opts {bool calc_sha, bool sha1, bool no_cancel, bool silent, bool overwrite, bool skip_all, bool append, bool recursive}])` + +Copy a file or directory. + +* **Arguments** + * `src` - Item to copy + * `dst` - Destination name + * `opts` (optional) - Option flags + * `calc_sha` - Write `.sha` files containing a SHA-256 (default) or SHA-1 hash + * `sha1` - Use SHA-1 + * `no_cancel` - Don’t allow user to cancel + * `silent` - Don’t show progress + * `overwrite` - Overwrite files + * `skip_all` - Skip existing files + * `append` - Append to the end of existing files instead of overwriting + * `recursive` - Copy directories recursively +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"requested directory copy without {recursive=true} on -> "` - attempted to copy a directory without using `recursive` + * `"destination already exists on -> and {overwrite=true} was not used"` - attempted to copy an item over an existing one without using `overwrite` + * `"PathMoveCopy failed on -> "` - error when copying, or user canceled + +#### fs.mkdir + +* `void fs.mkdir(string path)` + +Create a directory. This creates intermediate directories as required, so `fs.mkdir("a/b/c")` would create `a`, then `b`, then `c`. + +* **Arguments** + * `path` - Directory to create +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"could not mkdir ()"` - error when creating directories + +#### fs.stat + +* `table fs.stat(string path)` + +Get information about a file or directory. The result is a stat table with these keys: + +* **Arguments** + * `path` - Directory to stat +* **Returns:** A stat table with keys: + * `name` (string) + * `type` (string) - `"dir"` or `"file"` + * `size` (number) + * `read_only` (bool) +* **Throws** + * `"could not stat (##)"` - error when attempting to stat item, with FatFs error number + +#### fs.list_dir + +* `table fs.list_dir(string path)` + +Get the contents of a directory. The result is a list of stat tables with these keys: +* `name` (string) +* `type` (string) - `"dir"` or `"file"` +* `size` (number) +* `read_only` (bool) + +* **Arguments** + * `path` - Directory to list +* **Returns:** A list of stat tables, each with keys: + * `name` (string) + * `type` (string) - `"dir"` or `"file"` + * `size` (number) + * `read_only` (bool) +* **Throws** + * `"could not opendir (##)"` - error when attempting to open directory, with FatFs error number + * `"could not readdir (##)"` - error when attempting to read directory, with FatFs error number + +#### fs.stat_fs + +* `table fs.stat_fs(string path)` + +Get information about a filesystem. + +> [!NOTE] +> This function can take several seconds before it returns an answer. + +* **Arguments** + * `path` - Filesystem to stat +* **Returns:** A stat table with keys: + * `free` (number) + * `total` (number) + * `used` (number) + +#### fs.dir_info + +* `table fs.dir_info(string path)` + +Get information about a directory. + +> [!NOTE] +> This function can take several seconds before it returns an answer. + +* **Arguments** + * `path` - Directory to check +* **Returns:** An info table with keys: + * `size` (number) + * `dirs` (number) + * `files` (number) +* **Throws** + * `"error when running DirInfo"` - error when scanning directory + +#### fs.ask_select_file + +* `string fs.ask_select_file(string prompt, string path[, bool opts {bool include_dirs, bool explorer}])` + +Prompt the user to select a file based on a pattern. Accepts a wildcard pattern like `"0:/gm9/in/*_ctrtransfer_n3ds.bin"`. + +* **Arguments** + * `prompt` - Text to ask the user + * `path` - Wildcard pattern to search for + * `opts` (optional) - Option flags + * `include_dirs` - Include directories in selection + * `explorer` - Use file explorer, including navigating subdirectories +* **Returns:** path selected, or `nil` if user canceled +* **Throws** + * `"forbidden drive"` - attempted search on `Z:` + * `"invalid path"` - could not find `/` in path + +#### fs.ask_select_dir + +* `string fs.ask_select_dir(string prompt, string path[, bool opts {bool explorer}])` + +Prompt the user to select a directory. + +* **Arguments** + * `prompt` - Text to ask the user + * `path` - Directory to search + * `opts` (optional) - Option flags + * `explorer` - Use file explorer, including navigating subdirectories +* **Returns:** path selected, or `nil` if user canceled +* **Throws** + * `"forbidden drive"` - attempted search on `Z:` + +#### fs.find + +* `string fs.find(string pattern[, bool opts {bool first}])` + +Searches for a file based on a wildcard pattern. Returns the last result, unless `first` is specified, or `nil` if nothing was found. + +Pattern can use `?` for search values, for example `00017?02` will match `00017002`, `00017102`, etc. Wildcards are also accepted. + +* **Arguments** + * `pattern` - Pattern to search for + * `opts` (optional) - Option flags + * `first` - Return first result instead of last +* **Returns:** found file, or `nil` if nothing is found +* **Throws** + * `"failed to find (##)"` - error when attempting to find path, with FatFs error number + +#### fs.find_not + +* `string fs.find(string pattern)` + +Searches for a free filename based on a pattern. + +Pattern can use `?` for search values, for example `nand_??.bin` will check to see if `nand_00.bin` exists. If it doesn't, it returns this string. Otherwise, it checks if `nand_01.bin` exists and keeps going until an unused filename can be found. + +* **Arguments** + * `pattern` - Pattern to search for +* **Returns:** found file +* **Throws** + * `"failed to find (##)"` - error when attempting to find path, with FatFs error number + +#### fs.find_all + +* `table fs.find_all(string dir, string pattern[, table opts {bool recursive}])` + +Search for all files that match a pattern. +* **Arguments** + * `dir` - Directory to search + * `pattern` - Filename pattern + * `opts` (optional) - Option flags + * `recursive` - Remove directories recursively +* **Returns:** table of found files +* **Throws** + * `"could not open directory"` - failed to open directory + +#### fs.allow + +* `bool fs.allow(string path[, table flags {bool ask_all}])` + +Check for and request permission to write to a sensitive path. + +* **Arguments** + * `path` - Path to request permission for + * `opts` (optional) - Option flags + * `ask_all` - Request to write to all files in directory +* **Returns:** `true` if granted, `false` if user declines + +#### fs.img_mount + +* `void fs.img_mount(string path)` + +Mount an image file. Can be anything mountable through the file browser. + +* **Arguments** + * `path` - Path to image file +* **Throws** + * `"failed to mount "` - not a valid image file + +#### fs.img_umount + +* `void fs.img_umount()` + +Unmount the currently mounted image file. + +#### fs.get_img_mount + +* `string fs.get_img_mount()` + +Get the currently mounted image file. + +* **Returns:** path to file, or `nil` if none is mounted + +#### fs.hash_file + +* `string fs.hash_file(string path, int offset, int size[, table opts {bool sha1}])` + +Calculate the hash for a file. Uses SHA-256 unless `sha1` is specified. To hash an entire file, `size` should be `0`. + +> [!TIP] +> * Use `fs.verify_with_sha_file` to compare with a corresponding `.sha` file. +> * Use `util.bytes_to_hex` to convert the result to printable hex characters. + +> [!NOTE] +> Using an offset that is not `0`, with a size of `0` (to hash to end of file), is currently undefined behavior. In the future this should work properly. + +* **Arguments** + * `path` - File to hash + * `offset` - Data offset + * `size` - Amount of data to hash, or `0` to hash to end of file + * `opts` (optional) - Option flags + * `sha1` - Use SHA-1 +* **Returns:** SHA-256 or SHA-1 hash as byte string +* **Throws** + * `"failed to stat "` - could not stat file to get size + * `"FileGetSha failed on "` - could not read file or user canceled + +#### fs.hash_data + +* `string fs.hash_data(string data[, table opts {bool sha1}])` + +Calculate the hash for some data. Uses SHA-256 unless `sha1` is specified. + +> [!TIP] +> * Use `util.bytes_to_hex` to convert the result to printable hex characters. + +* **Arguments** + * `data` - Data to hash + * `opts` (optional) - Option flags + * `sha1` - Use SHA-1 +* **Returns:** SHA-256 or SHA-1 hash as byte string + +#### fs.verify + +* `bool fs.verify(string path)` + +Verify the integrity of a file. + +> [!NOTE] +> This is for files that have their own hashes built-in. For verifying against a corresponding `.sha` file, use `fs.verify_with_sha_file`. + +* **Arguments** + * `path` - File to verify +* **Returns:** `true` if successful, `false` if failed or not verifiable + +#### fs.verify_with_sha_file + +* `bool fs.verify_with_sha_file(string path)` + +Calculate the hash of a file and compare it with a corresponding `.sha` file. + +> [!IMPORTANT] +> This currently assumes SHA-256. In the future this may automatically use SHA-1 when appropriate, based on the `.sha` file size. + +* **Argumens** + * `path` - File to hash +* **Returns:** `true` if successful, `false` if failed, `nil` if `.sha` file could not be read +* **Throws** + * `"failed to stat "` - could not stat file to get size + * `"FileGetSha failed on "` - could not read file or user canceled + +#### fs.exists + +* `bool fs.exists(string path)` + +Check if an item exists. + +* **Arguments** + * `path` - Path to file or directory +* **Returns:** `true` if exists, `false` otherwise + +#### fs.is_dir + +* `bool fs.is_dir(string path)` + +Check if an item exists, and is a directory. + +* **Arguments** + * `path` - Path to directory +* **Returns:** `true` if exists and is a directory, `false` otherwise + +#### fs.is_file + +* `bool fs.is_file(string path)` + +Check if an item exists, and is a file. + +* **Arguments** + * `path` - Path to file +* **Returns:** `true` if exists and is a file, `false` otherwise + +#### fs.sd_is_mounted + +* `bool fs.sd_is_mounted()` + +Check if the SD card is mounted. + +* **Returns:** `true` if SD card is mounted + +#### fs.sd_switch + +* `void fs.sd_switch([string message])` + +Prompt the user to remove and insert an SD card. + +* **Arguments** + * `message` (optional) - Text to prompt the user, defaults to `"Please switch the SD card now."` +* **Throws** + * `"user canceled"` - user canceled the switch + +#### fs.fix_cmacs + +* `void fs.fix_cmacs(string path)` + +Fix CMACs for a directory. + +* **Arguments** + * `path` - Path to recursively fix CMACs for +* **Throws** + * `fixcmac failed` - user denied permission, or fixing failed + +#### fs.read_file + +* `string fs.read_file(string path, int offset, int/string size)` + +Read data from a file. + +* **Arguments** + * `path` - File to read + * `offset` - Data offset + * `size` - Amount of data to read +* **Returns:** string of data +* **Throws** + * `"could not allocate memory to read file"` - out-of-memory error when attempting to create the data buffer + * `"could not read (##)"` - error when attempting to read file, with FatFs error number + +#### fs.write_file + +* `int fs.write_file(string path, int offset, string data)` + +Write data to a file. + +* **Arguments** + * `path` - File to write + * `offset` - Offset to write to, or the string `"end"` to write at the end of file + * `data` - Data to write +* **Returns:** amount of bytes written +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"error writing (##)"` - error when attempting to write file, with FatFs error number + +#### fs.fill_file + +* `void fs.fill_file(string path, int offset, int size, int byte)` + +Fill a file with a specified byte. + +* **Arguments** + * `path` - File to write + * `offset` - Offset to write to + * `size` - Amount of data to write + * `byte` - Number between `0x00` and `0xFF` (`0` and `255`) indicating the byte to write + * `opts` (optional) - Option flags + * `no_cancel` - Don’t allow user to cancel +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"byte is not between 0x00 and 0xFF (got: ##)"` - byte value is not a single byte + * `"FileSetByte failed on "` - writing failed or user canceled + +#### fs.make_dummy_file + +* `void fs.make_dummy_file(string path, int size)` + +Create a dummy file. + +> [!NOTE] +> The file will contain data from the unused parts of the filesystem. If you need to ensure it's clean, use `fs.fill_file`. + +* **Arguments** + * `path` - File to create + * `size` - File size to set +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"FileCreateDummy failed on "` - dummy creation failed + +#### fs.truncate + +* `void fs.truncate(string path, int size)` + +Truncate a file to a specific size. + +> [!IMPORTANT] +> Does not work for virtual filesystems. + +* **Arguments** + * `path` - File to create + * `size` - File size to set +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"failed to open (note: this only works on FAT filesystems, not virtual)"` - opening file failed, or a virtual filesystem was used + * `"failed to seek on "` - seeking file failed + * `"failed to truncate on "` - truncating file failed + +#### fs.key_dump + +* `void fs.key_dump(string file[, table opts {bool overwrite}])` + +Dumps title keys or seeds. Taken from both SysNAND and EmuNAND. The resulting file is saved to `0:/gm9/out`. + +* **Arguments** + * `file` - One of three supported filenames: `seeddb.bin`, `encTitleKeys.bin`, `decTitleKeys.bin` + * `opts` (optional) - Option flags + * `overwrite` - Overwrite files +* **Throws** + * `"building failed"` - building failed or file already exists and `overwrite` was not used + +#### fs.cart_dump + +* `void fs.cart_dump(string path, int size[, table opts {bool encrypted}])` + +Dump the raw data from the inserted game card. No modifications are made to the data. This means for example, Card2 games will not have the save area cleared. + +* **Arguments** + * `path` - File to write data to + * `size` - Amount of data to read + * `opts` (optional) - Option flags + * `encrypted` - Dump game encrypted, only for DS/DSi games? +* **Throws** + * `"out of memory"` - out-of-memory error when attempting to create the data buffer + * `"cart init fail"` - card is not inserted or some other failure when attempting to initialize + * `"cart dump failed or canceled"` - cart read failed or used canceled + +--- + +### `title` module + +#### title.decrypt, title.encrypt + +* `void title.decrypt(string path)` +* `void title.decrypt(string path)` + +Decrypt or encrypt a title or key database, done in-place. + +* **Arguments** + * `path` - Path to title or key database +* **Throws** + * `"CryptAesKeyDb failed on "` - could not crypt key database + * `"CryptGameFile failed on "` - could not crypt title + +#### title.install + +* `void title.install(string path[, table opts {bool to_emunand}])` + +Install a title. + +* **Arguments** + * `path` - File to install + * `opts` (optional) - Option flags + * `to_emunand` - Install to EmuNAND +* **Throws** + * `"InstallGameFile failed on "` - install failed or user canceled + +#### title.build_cia + +* `void title.build_cia(string path[, table opts {bool legit}])` + +Build title as a CIA. Resulting file is put in `0:/gm9/out`. + +* **Arguments** + * `path` - File to build as CIA + * `opts` (optional) - Option flags + * `legit` - Build as legit CIA if possible +* **Throws** + * `"BuildCiaFromGameFile failed on "` - build failed or user canceled + +#### title.extract_code + +* `void title.extract_code(string src, string dst)` + +Extracts the `.code` from a title and decompresses it. + +* **Arguments** + * `src` - File containing `.code` + * `dst` - Destination to write decompressed `.code` +* **Throws** + * `"writing not allowed: "` - user denied permission + * `" does not have code"` - invalid file type + * `"failed to extract code from "` - extraction failed + +#### title.compress_code + +* `void title.compress_code(string src, string dst)` + +Compress a `.code` file. + +* **Arguments** + * `src` - Extracted `.code`, like from `title.extract_code` + * `dst` - Destination to write compressed `.code` +* **Throws** + * `"writing not allowed: "` - user denied permission + * `"failed to compress code from "` - compression failed + +#### title.apply_ips, title.apply_bps, title.apply_bpm + +* `void title.apply_ips(string patch, string src, string target)` +* `void title.apply_bps(string patch, string src, string target)` +* `void title.apply_bpm(string patch, string src, string target)` + +Apply an IPS, BPS, or BPM patch. + +* **Arguments** + * `patch` - IPS, BPS, or BPM patch file + * `src` - File to patch + * `target` - Destination to write patched file to +* **Throws** + * `"ApplyIPSPatch failed"` - failed to apply IPS patch + * `"ApplyBPSPatch failed"` - failed to apply BPS patch + * `"ApplyBPMPatch failed"` - failed to apply BPM patch + +--- + +### `sys` module + +#### sys.boot + +* `void sys.boot(string path)` + +Boot a FIRM file. + +* **Arguments** + * `path` - FIRM file +* **Throws** + * `"out of memory"` - out-of-memory error when attempting to create the data buffer + * `"not a bootable firm"` - file cannot be booted + +#### sys.reboot + +* `void sys.reboot()` + +Reboots the console. + +#### sys.power_off + +* `void sys.power_off()` + +Powers off the console. + +#### sys.region + +* `string sys.region` + +System region, based on SysNAND's `SecureInfo_[AB]` file. Not affected by `SecureInfo_C`. + +Possible values: `"JPN"`, `"USA"`, `"EUR"`, `"AUS"`, `"CHN"`, `"KOR"`, `"TWN"`, `nil` (if it does not exist, or the region byte is invalid) + +#### sys.serial + +* `string sys.serial` + +Serial number, based on SysNAND's `SecureInfo_[AB]` file. Not affected by `SecureInfo_C`. + +Can be `nil` if the file does not exist. + +#### sys.secureinfo_letter + +* `string sys.secureinfo_letter` + +The letter at the end of the console's `SecureInfo_[AB]` file. + +Possible values: `"A"`, `"B"`, `nil` (if it does not exist) + +#### sys.sys_id0 + +* `string sys.sys_id0` + +ID0 of SysNAND as a printable hex string. + +Can be `nil` if the file does not exist. + +#### sys.emu_id0 + +* `string sys.emu_id0` + +ID0 of EmuNAND as a printable hex string. + +Can be `nil` if the file does not exist. + +#### sys.emu_base + +* `int sys.emu_base` + +Current EmuNAND base. + +#### sys.refresh_info + +* `void sys.refresh_info()` + +Refresh the following variables: + +* `sys.region` +* `sys.serial` +* `sys.secureinfo_letter` +* `sys.sys_id0` +* `sys.emu_id0` +* `sys.emu_base` + +This function is automatically called at the beginning of Lua's execution, but errors are caught to prevent a premature exit. This could leave some of the variables at `nil`. + +* **Throws** + * `"could not read SecureInfo"` - `SecureInfo_[AB]` is missing + * `"SecureInfo region byte is invalid"` - `SecureInfo_[AB]` is not between 0 and 6 inclusive + +#### sys.next_emu + +* `void sys.next_emu()` + +Switch to the next available EmuNAND. + +This will automatically call `sys.refresh_info`. + +#### sys.check_embedded_backup + +* `bool sys.check_embedded_backup()` + +Check if `essential.exefs` is embedded into SysNAND, and prompts the user if it isn't. This is the same as the check that is done at boot for GodMode9, but this can be called in a build compiled with `SCRIPT_RUNNER=1` for autorun scripts that require `essential.exefs` to exist. + +* **Returns:** `true` if it exists or was created, `false` if user declines, `nil` if console fails genuine NCSD check (modified partition table) + +#### sys.check_raw_rtc + +* `bool sys.check_raw_rtc()` + +Check if the Raw RTC is set correctly, and prompts the user if it isn't. This is the same as the check that is done at boot for GodMode9, but this can be called in a build compiled with `SCRIPT_RUNNER=1` for autorun scripts that require `essential.exefs` to exist. + +* **Returns:** `true` if set, `false` if user declines + +--- + +### `util` module + +#### util.bytes_to_hex + +* `string util.bytes_to_hex(string data)` + +Convert a byte string to printable hex characters. + +Example: `"test\xaa\xbb\xcc\xdd"` -> `"74657374aabbccdd"` + +* **Arguments** + * `data` - Data to convert +* **Returns:** Hex characters + +#### util.hex_to_bytes + +* `string util.hex_to_bytes(string hexstring)` + +Convert hex characters to a byte string. + +Example: `"74657374aabbccdd"` -> `"test\xaa\xbb\xcc\xdd"` + +* **Arguments** + * `hexstring` - Hex characters to convert +* **Returns:** Byte string +* **Throws** + * `"bad argument #1 to 'char' (number expected, got nil)"` - invalid hex characters + +#### util.get_datestamp + +* `string util.get_datestamp()` + +Returns a date stamp formatted like "241202" for 2024 December 02. Equivalent to `os.date("%y%m%d")`. + +* **Returns:** Date stamp + +#### util.get_timestamp + +* `string util.get_timestamp()` + +Returns a date stamp formatted like "010828" for 01:08:28. Equivalent to `os.date("%H%M%S")`. + +* **Returns:** Time stamp + +#### util.running_as_module + +* `bool util.running_as_module()` + +Determines if the currently executing script was directly run, or was imported by another script. Useful for scripts that want to be usable directly, while also importable. + +> [!NOTE] +> This is not well tested. + +* **Returns:** `true` if the current script was imported as a module diff --git a/resources/sample/HelloScript.lua b/resources/sample/HelloScript.lua new file mode 100644 index 000000000..e8626e754 --- /dev/null +++ b/resources/sample/HelloScript.lua @@ -0,0 +1,172 @@ +--[[ + GodMode9 "Hello Script" + Tutorial script - read / run this to learn how it works + last changed: 2025/03/16 + author: ihaveahax + based on HelloScript.gm9 by d0k3 +]] + +-- This script intends to show off the features of Lua within GodMode9. +-- While I hope it works enough to show the syntax, it is not a complete Lua tutorial. + +-- For a comparison between Lua and GM9Script, look inside lua-doc.md, inside the release archive, and in "resources" in the repository. + +-- Comments begin with a '--'. Multiline comments begin with '--[[' and then end with ']]'. + +-- This is an example function, the echo function from the ui module. +-- It is simular to the "echo" command from GM9Script. +ui.echo("'Hello Script'\nby d0k3 and ihaveahax\n \nThis is a sample script to\nshowcase Lua scripting.") -- comments work anywhere + +-- QR codes +-- The 'ui.show_qr' function will display text on the bottom screen, and a QR code on the top screen. +ui.show_qr("Scan for cool stuff!", "https://github.com/d0k3/GodMode9") + +-- The basic 'print' function is also available. +-- This is useful for debugging. It replaces the top screen with an output log. +print("I used print just now!") +print("I'm on the top screen! (unless you used SWITCH_SCREENS)") +ui.echo("Check the top screen!") + +-- Asking the user +-- The 'ui.ask' function will ask the user to answer a prompt with yes or no. +-- It returns a boolean. +local answer = ui.ask("Continue running this script?") +if not answer then + print("Stopping now!") + -- Stop executing a script if you return at the top level. + return +end + +print("Continuing execution!") + +-- Let's first make sure there's nothing mounted. +-- The tests coming up will write to the ramdrive, +-- but it might be potentially taken over by IMGNAND. +print("Unmounting") +fs.img_umount() + +-- Most commands that interact with files accept options. +-- This is a table that's the final argument. Each option accepts a boolean. +-- All the options that functions can take is in the documentation, but these are the most common: +-- no_cancel - Don't allow the user to cancel +-- silent - Don't show progress +-- overwrite - Overwrite files +-- skip_all - Skip existing files +print("Copying M:/otp.mem to 9:/otp_copied_by_lua.mem!") +fs.copy("M:/otp.mem", "9:/otp_copied_by_lua.mem", {overwrite=true}) + +-- Constants +-- These variables are set by GodMode9 when executing a Lua script. +-- GM9VER - the GodMode9 version number +-- SCRIPT - the executed script, such as "0:/gm9/luascripts/HelloScript.lua" +-- CURRDIR - the directory of the executed script, such as "0:/gm9/luascripts" +-- GM9OUT - the standard output path "0:/gm9/out" +-- HAX - the hax the system is currently running from, which can be "ntrboot", "sighax", or an empty string +-- NANDSIZE - total size of SysNAND in bytes +-- CONSOLE_TYPE - the string "O3DS" or "N3DS" +-- IS_DEVKIT - true if the console is a developer unit +-- +-- Some that were environmental variables are now part of the sys or util modules. +-- sys.sys_id0 - id0 belonging to SysNAND +-- sys.emu_id0 - id0 belonging to EmuNAND (nil if not available) +-- sys.serial - serial number +-- sys.region - region of the SysNAND ("JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN", nil (if it does not exist, or the region byte is invalid) +-- util.get_timestamp() - current time in hhmmss format, equivalent to os.date("%y%m%d") +-- util.get_datestamp() - current date in YYMMDD format, equivalent to os.date("%H%M%S") +-- +-- Let's now print a bunch of these out using string concatenation! +local retail_or_devkit = "retail" +if IS_DEVKIT then + retail_or_devkit = "devkit" +end +ui.echo("Your GodMode9 version is "..GM9VER.. + "\nYour region is "..sys.region.. + "\nYour serial number is "..sys.serial.. + "\nYour std out path is "..GM9OUT.. + "\nCurrent dir is "..CURRDIR.. + "\nCurrent hax is "..HAX.. + "\nYour system is a "..retail_or_devkit.. + "\nCurrent timestamp is: "..util.get_timestamp().. + "\nYour sys / emu id0 is:\n"..sys.sys_id0.."\n"..tostring(sys.emu_id0)) -- emu_id0 could be nil! + +-- Functions can raise errors. If these are not handled, the script stops executing. +-- Uncomment this below to see that in action: +--nonexistant() +-- If you attempt this, the error would be like "attempt to call a nil value (global 'nonexistant')". +-- However you can catch errors and handle them gracefully by using Lua's pcall. +-- Here's an example function that will fail, but it won't stop the script. +-- This would be the same as doing fs.copy("0:/otp.mem", "M:/cantdothis.mem") +local success, result = pcall(fs.copy, "M:/otp.mem", "V:/cantdothis.mem") +if not success then + print("fs.copy failed:") + print(result) + ui.echo("That was close!\nThis fs.copy failed (on purpose).".. + "\n \nYou could now check the error\nin the result variable.") +end + +-- There are a few ways to ask for input. +-- 'ui.ask_text' shows a keyboard. You can specify initial text and the maximum length. +local my_text = ui.ask_text("Gimmie some text up to 16 characters!", "GodMode9!!!", 16) + +-- 'ui.ask_number' will ask for a number. +local my_number = ui.ask_number("I want a number now!", 123) + +-- 'ui.ask_hex' will ask for a hexadecimal number. You can set a maximum number of hex digits. +local my_hex = ui.ask_hex("Now a hex number.", 0x8badf00d, 8) + +-- 'ui.ask_selection' will ask the user to pick from a selection. +-- It returns the index of the selected option, or nil if nothing. +local selections = { + "64", + "Melee", + "Brawl", + "for Nintendo 3DS", + "for Wii U", + "Ultimate" +} +local sel_number = ui.ask_selection("Pick your favorite Smash", selections) +local selection +if sel_number then + selection = selections[sel_number] +else + selection = "(None of them)" +end + +-- Now let's print them all. +ui.echo("You've put in: ".. + "\nSome text: "..my_text.. + "\nA number: "..my_number.. + "\nA hex number: "..my_hex.. + "\nA selection: "..selection) + +-- Now let's play with hashes. +-- 'fs.hash_file' will return a SHA256 hash as a bytestring. +local nand_hdr_sha = fs.hash_file("S:/nand_hdr.bin", 0, 0) +-- Write it out to a sha file. We're doing this in the ramdrive for testing. +fs.write_file("9:/nand_hdr.bin.sha", 0, nand_hdr_sha) +-- Let's copy over nand_hdr.bin so we can use a convenience function to verify it. +fs.copy("S:/nand_hdr.bin", "9:/nand_hdr.bin", {no_cancel=true, overwrite=true}) +-- And now we can use 'fs.verify_with_sha_file'! +-- This will check the .sha file next to the file we want. +local is_valid = fs.verify_with_sha_file("9:/nand_hdr.bin") +print("Is 9:/nand_hdr.bin valid?", is_valid) + +-- 'fs.copy' is also capable of generating a hash on copy. +-- This will create 9:/nand_cid.mem.sha. +fs.copy("M:/nand_cid.mem", "9:/nand_cid.mem", {no_cancel=true, calc_sha=true, overwrite=true}) + +-- Files in certain formats can be verified with 'fs.verify'. +-- This will use the hashes within FIRM1 to check its validity. +local firm1_is_valid = fs.verify("S:/firm1.bin") +print("Is FIRM1 valid?", firm1_is_valid) + +ui.echo("Check the top screen!") + +-- There are loads more functions! Every feature of GM9Script has an equivalent feature within Lua. +-- Check the comprehensive documentation of every GM9 Lua function in lua-doc.md +-- For standard Lua 5.4 functions, check the reference manual: https://www.lua.org/manual/5.4/ + +local do_reboot = ui.ask("Congratulatins! You have finished the script!\n \nDo you want to reboot now?") +if do_reboot then + sys.reboot() +end diff --git a/utils/transcp.py b/utils/transcp.py new file mode 100755 index 000000000..3b4cb2552 --- /dev/null +++ b/utils/transcp.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser, FileType +import json + +# Special keys +LANGUAGE_NAME = "GM9_LANGUAGE" +VERSION = "GM9_TRANS_VER" + +parser = ArgumentParser(description="Creates the language.inl file from source.json") +parser.add_argument("source", type=FileType("r"), help="source.json") +parser.add_argument("inl", type=FileType("w"), help="language.inl") +args = parser.parse_args() + +# Load the JSON and handle the meta values +source = json.load(args.source) +version = source[VERSION] +del source[VERSION] +del source[LANGUAGE_NAME] + +# Create the header file +args.inl.write("#define TRANSLATION_VER %d\n\n" % version) +for key in source: + # Escape \r, \n, and quotes + val = source[key].replace("\r", "\\r").replace("\n", "\\n").replace('"', '\\"') + args.inl.write('STRING(%s, "%s")\n' % (key, val)) diff --git a/utils/transriff.py b/utils/transriff.py new file mode 100755 index 000000000..fb13641e7 --- /dev/null +++ b/utils/transriff.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 + +""" Create a TRF translation for GodMode9 from a translation JSON. """ + +import argparse +import json +import math +import pathlib +import struct +import sys + + +# Special keys +LANGUAGE_NAME = "GM9_LANGUAGE" +VERSION = "GM9_TRANS_VER" + + +def ceil_to_multiple(num: int, base: int) -> int: + """ + Return the ceiling of num which is a multiple of base. + + Args: + num: Number whose ceiling to return. + base: Value which num will become a multiple of. + + Returns: + Num rounded to the next multiple of base. + """ + return base * math.ceil(num / base) + + +def get_language(data: dict) -> bytes: + """ + Get language name from JSON data. + + Args: + data: JSON translation data. + + Returns: + The translation's language name. + + Raises: + ValueError: If no language name exists. + """ + try: + return data[LANGUAGE_NAME].encode("utf-8") + except KeyError as exception: + raise ValueError("missing language name") from exception + +def get_version(data: dict) -> int: + """ + Get translation version from JSON data. + + Args: + data: JSON translation data. + + Returns: + The translation's version. + + Raises: + ValueError: If no version exists. + """ + try: + return data[VERSION] + except KeyError as exception: + raise ValueError("missing verison number") from exception + + +def load_translations(data: dict) -> dict[str, bytearray]: + """ + Load translations from JSON data. + + Args: + data: JSON translation data. + + Returns: + The loaded strings. + """ + return { + key: bytearray(value, "utf-8") + b"\0" + for key, value in data.items() + if key not in (LANGUAGE_NAME, VERSION) + } + + +def strings_to_trf(mapping: dict[str, bytearray], version: int, language: str) -> bytearray: + """ + Create a TRF file from translated strings. + + Args: + mapping: Mapping between labels and translated strings. + version: Translation version. + language: Translation language. + + Returns: + The translation strings as TRF data. + """ + # File header. + trfdata = bytearray(b"RIFF\0\0\0\0") + + # Metadata section. + trfdata += ( + b"META" + + struct.pack(" None: + """ + Entrypoint of transriff. + + Args: + source: JSON to convert from. + dest: TRF file to write. + """ + data = json.loads(source.read_text()) + + try: + language = get_language(data) + version = get_version(data) + except ValueError as exception: + sys.exit(f"Fatal: {exception}.") + mapping = load_translations(data) + + trf_file = strings_to_trf(mapping, version, language) + + dest.write_bytes(trf_file) + print(f"Info: {dest.as_posix()} created with {len(mapping)} strings.") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Create a TRF translation for GodMode9 from a translation JSON." + ) + + parser.add_argument( + "source", + type=pathlib.Path, + help="JSON to convert from" + ) + parser.add_argument( + "dest", + type=pathlib.Path, + help="TRF file to write" + ) + + args = parser.parse_args() + + main(args.source, args.dest)