Przeglądaj źródła

Revert "remove: 继续移除多余的库"

This reverts commit fa1c43b48f0f50682cae1793c86b3a59a2861aca.
Wendal Chen 1 rok temu
rodzic
commit
9e749e82e7
44 zmienionych plików z 8016 dodań i 0 usunięć
  1. 180 0
      components/device/spi_slave/binding/luat_lib_spislave.c
  2. 16 0
      components/device/spi_slave/include/luat_spi_slave.h
  3. 141 0
      components/device/wlanraw/binding/luat_lib_wlanraw.c
  4. 22 0
      components/device/wlanraw/include/luat_wlan_raw.h
  5. 21 0
      components/nes/LICENSE
  6. 64 0
      components/nes/README.md
  7. 64 0
      components/nes/README_zh.md
  8. 68 0
      components/nes/inc/nes.h
  9. 42 0
      components/nes/inc/nes_apu.h
  10. 114 0
      components/nes/inc/nes_cpu.h
  11. 68 0
      components/nes/inc/nes_mapper.h
  12. 184 0
      components/nes/inc/nes_ppu.h
  13. 123 0
      components/nes/inc/nes_rom.h
  14. 131 0
      components/nes/luat_lib_nes.c
  15. 83 0
      components/nes/port/nes_conf.h
  16. 96 0
      components/nes/port/nes_port.c
  17. 71 0
      components/nes/port/nes_port.h
  18. 386 0
      components/nes/src/nes.c
  19. 36 0
      components/nes/src/nes_apu.c
  20. 1384 0
      components/nes/src/nes_cpu.c
  21. 46 0
      components/nes/src/nes_mapper.c
  22. 44 0
      components/nes/src/nes_mapper/nes_mapper0.c
  23. 54 0
      components/nes/src/nes_mapper/nes_mapper2.c
  24. 202 0
      components/nes/src/nes_ppu.c
  25. 168 0
      components/nes/src/nes_rom.c
  26. 327 0
      components/network/posix/luat_network_posix.c
  27. 20 0
      components/network/posix/luat_network_posix.h
  28. 51 0
      components/network/zlink/include/luat_zlink.h
  29. 0 0
      components/network/zlink/src/luat_zlink.c
  30. 156 0
      components/nr_micro_shell/README.md
  31. 168 0
      components/nr_micro_shell/ansi.c
  32. 57 0
      components/nr_micro_shell/ansi.h
  33. 133 0
      components/nr_micro_shell/ansi_def.h
  34. 284 0
      components/nr_micro_shell/ansi_port.c
  35. 90 0
      components/nr_micro_shell/ansi_port.h
  36. 371 0
      components/nr_micro_shell/nr_micro_shell.c
  37. 154 0
      components/nr_micro_shell/nr_micro_shell.h
  38. 156 0
      components/nr_micro_shell/nr_micro_shell_config.h
  39. 119 0
      components/onewire/binding/luat_lib_onewire.c
  40. 44 0
      components/onewire/include/luat_onewire.h
  41. 421 0
      components/onewire/src/luat_onewire.c
  42. 39 0
      components/rostr/luat_rostr.c
  43. 63 0
      components/rostr/luat_rostr.h
  44. 1555 0
      components/rostr/luat_rostr_data.c

+ 180 - 0
components/device/spi_slave/binding/luat_lib_spislave.c

@@ -0,0 +1,180 @@
+/*
+@module spislave
+@summary SPI从机
+@version 1.0
+@date    2024.3.27
+@demo spislave
+@tag LUAT_USE_SPI_SLAVE
+@usage
+-- 请查阅demo
+-- 当前仅XT804系列支持, 例如 Air101/Air103/Air601
+ */
+#include "luat_base.h"
+#include "rotable2.h"
+#include "luat_zbuff.h"
+#include "luat_msgbus.h"
+#include "luat_timer.h"
+#include "luat_spi_slave.h"
+
+#define LUAT_LOG_TAG "spislave"
+#include "luat_log.h"
+
+// 存放回调函数
+static int lua_cb_ref;
+
+/*
+初始化SPI从机
+@api spislave.setup(id, opts)
+@int 从机SPI的编号,注意与SPI主机的编号的差异,这个与具体设备相关
+@table opts 扩展配置参数,当前无参数
+@return boolean true表示成功,其他失败
+@usage
+-- 当前仅XT804系列支持, 例如 Air101/Air103/Air601/Air690
+-- Air101为例, 初始化SPI从机, 编号为2, SPI模式
+spislave.setup(2)
+-- Air101为例, 初始化SPI从机, 编号为3, SDIO模式
+spislavve.setup(3)
+*/
+static int l_spi_slave_setup(lua_State *L) {
+    luat_spi_slave_conf_t conf = {
+        .id = luaL_checkinteger(L, 1)
+    };
+    int ret = luat_spi_slave_open(&conf);
+    if (ret) {
+        lua_pushboolean(L, 0);
+        lua_pushinteger(L, ret);
+        return 2;
+    }
+    lua_pushboolean(L, 1);
+    return 1;
+}
+
+/*
+是否可写
+@api spislave.ready(id)
+@int 从机SPI的编号
+@return boolean true表示可写,其他不可写
+*/
+static int l_spi_slave_ready(lua_State *L) {
+    luat_spi_slave_conf_t conf = {
+        .id = luaL_checkinteger(L, 1)
+    };
+    int ret = luat_spi_slave_writable(&conf);
+    if (ret) {
+        lua_pushboolean(L, 1);
+        return 1;
+    }
+    return 0;
+}
+
+/*
+注册事件回调函数
+@api spislave.on(id, cb)
+@int 从机SPI的编号
+@function 回调函数
+*/
+static int l_spi_slave_on(lua_State *L) {
+    if (lua_cb_ref) {
+        luaL_unref(L, LUA_REGISTRYINDEX, lua_cb_ref);
+        lua_cb_ref = 0;
+    }
+    if (lua_isfunction(L, 2)) {
+        lua_pushvalue(L, 2);
+        lua_cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    }
+    return 0;
+}
+
+/*
+读取数据
+@api spislave.read(id, ptr, buff, len)
+@int 从机SPI的编号
+@userdata 用户数据指针, 从回调函数得到
+@int zbuff缓冲对象
+@int 读取长度,从回调函数得到
+@return int 读取到字节数,通常与期望读取的长度相同
+@return int 错误码, 仅当出错时返回
+*/
+static int l_spi_slave_read(lua_State *L) {
+    luat_spi_slave_conf_t conf = {
+        .id = luaL_checkinteger(L, 1)
+    };
+    void* ptr = lua_touserdata(L, 2);
+    luat_zbuff_t* zbuf = (luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE);
+    int len = luaL_checkinteger(L, 4);
+    int ret = luat_spi_slave_read(&conf, ptr, zbuf->addr, len);
+    if (ret >= 0 ){
+        lua_pushinteger(L, ret);
+        return 1;
+    }
+    lua_pushinteger(L, 0);
+    lua_pushinteger(L, ret);
+    return 2;
+}
+/*
+写入数据
+@api spislave.write(id, ptr, buff, len)
+@int 从机SPI的编号
+@userdata 用户数据指针, 当前传nil
+@int zbuff缓冲对象
+@int 写入长度,注意不能超过硬件限制,通常是1500字节
+@return boolean true表示成功,其他失败
+@return int 错误码, 仅当出错时返回
+*/
+static int l_spi_slave_write(lua_State *L) {
+    luat_spi_slave_conf_t conf = {
+        .id = luaL_checkinteger(L, 1)
+    };
+    luat_zbuff_t* zbuf = (luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE);
+    int len = luaL_checkinteger(L, 4);
+    int ret = luat_spi_slave_write(&conf, zbuf->addr, len);
+    if (ret == 0 ){
+        lua_pushboolean(L, 1);
+        return 1;
+    }
+    lua_pushboolean(L, 0);
+    lua_pushinteger(L, ret);
+    return 2;
+}
+
+static const rotable_Reg_t reg_spi_slave[] = {
+    { "setup",              ROREG_FUNC(l_spi_slave_setup)},
+    { "ready",              ROREG_FUNC(l_spi_slave_ready)},
+    { "read",               ROREG_FUNC(l_spi_slave_read)},
+    { "write",              ROREG_FUNC(l_spi_slave_write)},
+    { "on",                 ROREG_FUNC(l_spi_slave_on)},
+    { NULL,                 ROREG_INT(0)}
+};
+
+LUAMOD_API int luaopen_spislave(lua_State *L)
+{
+    luat_newlib2(L, reg_spi_slave);
+    return 1;
+}
+
+static int l_spi_slave_event_handler(lua_State *L, void* ptr) {
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    if (!lua_cb_ref) {
+        return 0; // 没设置回调函数, 直接退出
+    }
+    lua_rawgeti(L, LUA_REGISTRYINDEX, lua_cb_ref);
+    if (!lua_isfunction(L, -1)) {
+        return 0; // 没设置回调函数, 直接退出
+    }
+    lua_pushinteger(L, msg->arg1);
+    lua_pushlightuserdata(L, msg->ptr);
+    lua_pushinteger(L, msg->arg2);
+    lua_call(L, 3, 0);
+    return 0;
+}
+
+int l_spi_slave_event(int id, int event, void* buff, size_t max_size) {
+    rtos_msg_t msg = {
+        .handler = l_spi_slave_event_handler,
+        .arg1 = id | event,
+        .arg2 = max_size,
+        .ptr = buff,
+    };
+    luat_msgbus_put(&msg, 0);
+    return 0;
+}

+ 16 - 0
components/device/spi_slave/include/luat_spi_slave.h

@@ -0,0 +1,16 @@
+#ifndef LUAT_SPI_SLAVE_H
+#define LUAT_SPI_SLAVE_H
+
+typedef struct luat_spi_slave_conf {
+    uint8_t id;
+}luat_spi_slave_conf_t;
+
+int luat_spi_slave_open(luat_spi_slave_conf_t *conf);
+int luat_spi_slave_close(luat_spi_slave_conf_t *conf);
+int luat_spi_slave_read(luat_spi_slave_conf_t *conf, uint8_t* src, uint8_t* buf, size_t len);
+int luat_spi_slave_write(luat_spi_slave_conf_t *conf, uint8_t* buf, size_t len);
+
+int l_spi_slave_event(int id, int event, void* buff, size_t max_size);
+int luat_spi_slave_writable(luat_spi_slave_conf_t *conf);
+
+#endif

+ 141 - 0
components/device/wlanraw/binding/luat_lib_wlanraw.c

@@ -0,0 +1,141 @@
+/*
+@module wlanraw
+@summary WLAN数据RAW传输
+@version 1.0
+@date    2024.4.11
+@tag LUAT_USE_WLAN_RAW
+@usage
+-- 请查阅 https://github.com/wendal/xt804-spinet
+ */
+#include "luat_base.h"
+#include "rotable2.h"
+#include "luat_zbuff.h"
+#include "luat_msgbus.h"
+#include "luat_timer.h"
+#include "luat_wlan_raw.h"
+#include "luat_zbuff.h"
+#include "luat_mem.h"
+
+#define LUAT_LOG_TAG "wlan.raw"
+#include "luat_log.h"
+
+// 存放回调函数
+static int lua_cb_ref;
+#define RAW_BUFF_COUNT 8
+#define RAW_BUFF_SIZE  1600
+
+static luat_wlan_raw_data_t datas[RAW_BUFF_COUNT];
+
+/*
+初始化WLAN的RAW层
+@api wlanraw.setup(opts, cb)
+@table opts 配置参数
+@function 回调函数,形式function(buff, size)
+@return boolean true表示成功,其他失败
+@usage
+-- 当前仅XT804系列支持, 例如 Air101/Air103/Air601/Air690
+wlanraw.setup({
+    buffsize = 1600, -- 缓冲区大小, 默认1600字节
+    buffcount = 10, -- 缓冲区数量, 默认8
+}, cb)
+*/
+static int l_wlan_raw_setup(lua_State *L) {
+    if (datas[0].buff) {
+        return 0;
+    }
+    size_t len = RAW_BUFF_SIZE;
+    size_t count = RAW_BUFF_COUNT;
+    lua_newtable(L);
+    for (size_t i = 0; i < count; i++)
+    {
+        luat_zbuff_t *buff = (luat_zbuff_t *)lua_newuserdata(L, sizeof(luat_zbuff_t));
+        luaL_setmetatable(L, LUAT_ZBUFF_TYPE);
+        lua_pushvalue(L, -1);
+        memset(buff, 0, sizeof(luat_zbuff_t));
+        buff->type = LUAT_HEAP_PSRAM;
+        buff->addr = (uint8_t *)luat_heap_opt_malloc(buff->type, len);
+        buff->len = len;
+        datas[i].zbuff_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+        datas[i].zbuff_used = &buff->used;
+        datas[i].buff = buff->addr;
+        lua_seti(L, -2, i + 1);
+        // LLOGD("zbuff_ref 数组索引%d lua索引%d", i, datas[i].zbuff_ref);
+    }
+    lua_pushvalue(L, 2);
+    lua_cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    luat_wlan_raw_conf_t conf = {0};
+    luat_wlan_raw_setup(&conf);
+    lua_pushboolean(L, 1);
+    lua_pushvalue(L, 3);
+    return 1;
+}
+
+static int l_wlan_raw_write(lua_State *L) {
+    int id = luaL_checkinteger(L, 1);
+    luat_zbuff_t * buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
+    int offset = luaL_optinteger(L, 3, 0);
+    int len = luaL_optinteger(L, 4, buff->used - offset);
+    int ret = luat_wlan_raw_write(id, buff->addr + offset, len);
+    lua_pushboolean(L, ret == 0);
+    lua_pushinteger(L, ret);
+    return 2;
+}
+
+static const rotable_Reg_t reg_wlan_raw[] = {
+    { "setup",              ROREG_FUNC(l_wlan_raw_setup)},
+    { "write",              ROREG_FUNC(l_wlan_raw_write)},
+    { NULL,                 ROREG_INT(0)}
+};
+
+LUAMOD_API int luaopen_wlan_raw(lua_State *L)
+{
+    luat_newlib2(L, reg_wlan_raw);
+    return 1;
+}
+
+static int l_wlan_raw_event_handler(lua_State *L, void* ptr) {
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    if (!lua_cb_ref) {
+        return 0; // 没设置回调函数, 直接退出
+    }
+    lua_rawgeti(L, LUA_REGISTRYINDEX, lua_cb_ref);
+    if (!lua_isfunction(L, -1)) {
+        return 0; // 没设置回调函数, 直接退出
+    }
+    lua_pushinteger(L, msg->arg1);
+    // LLOGD("取出zbuff lua索引%d", msg->arg2);
+    lua_rawgeti(L, LUA_REGISTRYINDEX, msg->arg2);
+    lua_call(L, 2, 0);
+    return 0;
+}
+
+int l_wlan_raw_event(int tp, void* buff, size_t len) {
+    rtos_msg_t msg = {
+        .handler = l_wlan_raw_event_handler,
+        .arg1 = tp,
+        .arg2 = 0,
+        .ptr = NULL,
+    };
+    if (len > RAW_BUFF_SIZE) {
+        LLOGE("类型 %d 数据长度%d 超过缓冲区大小%d", tp, len, RAW_BUFF_SIZE);
+        return -2;
+    }
+    if (!lua_cb_ref) {
+        LLOGW("未初始化, 忽略数据 %d %p %d", tp, buff, len);
+        return -3;
+    }
+    for (size_t i = 0; i < RAW_BUFF_COUNT; i++)
+    {
+        if ((*datas[i].zbuff_used) == 0) {
+            // LLOGD("使用zbuff传输 数组索引%d 写入长度%d", i, len);
+            memcpy(datas[i].buff, buff, len);
+            // datas[i].used = 1;
+            *(datas[i].zbuff_used) = len;
+            msg.arg2 = datas[i].zbuff_ref;
+            luat_msgbus_put(&msg, 0);
+            return 0;
+        }
+    }
+    LLOGE("没有可用的zbuff");
+    return -1;
+}

+ 22 - 0
components/device/wlanraw/include/luat_wlan_raw.h

@@ -0,0 +1,22 @@
+#ifndef LUAT_WLAN_RAW_H
+#define LUAT_WLAN_RAW_H
+
+typedef struct luat_wlan_raw_conf {
+    int id;
+}luat_wlan_raw_conf_t;
+
+typedef struct luat_wlan_raw_data {
+    int zbuff_ref;
+    size_t* zbuff_used;
+    uint8_t *buff;
+    // int used;
+}luat_wlan_raw_data_t;
+
+int luat_wlan_raw_setup(luat_wlan_raw_conf_t *conf);
+int luat_wlan_raw_close(luat_wlan_raw_conf_t *conf);
+// int luat_wlan_raw_read(luat_wlan_raw_conf_t *conf, uint8_t* src, uint8_t* buf, size_t len);
+int luat_wlan_raw_write(int id, uint8_t* buf, size_t len);
+
+int l_wlan_raw_event(int tp, void* buff, size_t max_size);
+
+#endif

+ 21 - 0
components/nes/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Dozingfiretruck
+
+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.

+ 64 - 0
components/nes/README.md

@@ -0,0 +1,64 @@
+**English** | [中文](./README_zh.md) 
+
+![github license](https://img.shields.io/github/license/Dozingfiretruck/nes)![linux](https://github.com/Dozingfiretruck/nes/actions/workflows/action.yml/badge.svg?branch=master)
+
+
+
+# nes
+
+#### Introduction
+The nes simulator implemented in c , requires c11
+
+**attention:**
+
+**This repository is only for the nes simulator and does not provide the game !!!**
+
+Support:
+
+- [x] CUP
+
+- [x] PPU
+
+- [ ] APU
+
+mapper  support:0,2
+
+#### Software Architecture
+The example is based on SDL2 for image and sound output, without special dependencies, and you can port to any hardware by yourself
+
+
+#### Compile Tutorial
+
+​	clone repository,install[xmake](https://github.com/xmake-io/xmake)  ,execute `xmake` directly to compile
+
+#### Instructions
+
+​	on linux enter  `./nes xxx.nes` load the game to run
+​	on windows enter `.\nes.exe xxx.nes` load the game to run
+
+
+
+Key mapping::
+
+​                                      up                                                    A            B
+
+​                           left  down  right	  select      start        
+
+P1:
+
+​                                      W                                                     J            K
+
+​                            A	    S	    D		      V             B        
+
+P2:
+
+​                                       ↑                                                      5            6
+
+​                             ←	  ↓	    →		    1             2        
+
+#### Literature reference
+
+https://www.nesdev.org/
+
+
+

+ 64 - 0
components/nes/README_zh.md

@@ -0,0 +1,64 @@
+[**English**](./README.md)  | **中文**
+
+![github license](https://img.shields.io/github/license/Dozingfiretruck/nes)![linux](https://github.com/Dozingfiretruck/nes/actions/workflows/action.yml/badge.svg?branch=master)
+
+
+
+# nes
+
+#### 介绍
+c语言实现的nes模拟器,要求c11
+
+**注意:**
+
+**本仓库仅为nes模拟器,不提供游戏本体!!!**
+
+支持情况:
+
+- [x] CUP
+
+- [x] PPU
+
+- [ ] APU
+
+mapper 支持:0,2
+
+#### 软件架构
+示例基于SDL2进行图像声音输出,没有特殊依赖,您可自行移植至任意硬件
+
+
+#### 编译教程
+
+​	克隆本仓库,安装[xmake](https://github.com/xmake-io/xmake)  ,直接执行 xmake 编译即可 
+
+#### 使用说明
+
+​	linux下输入 `./nes xxx.nes` 加载要运行的游戏
+​	windows下输入 `.\nes.exe xxx.nes` 加载要运行的游戏
+
+
+
+按键映射:
+
+​                                      上                                                    A            B
+
+​                           左	   下	    右		 选择        开始        
+
+P1:
+
+​                                      W                                                     J            K
+
+​                            A	    S	    D		      V             B        
+
+P2:
+
+​                                       ↑                                                      5            6
+
+​                             ←	  ↓	    →		    1             2        
+
+#### 文献参考
+
+https://www.nesdev.org/
+
+
+

+ 68 - 0
components/nes/inc/nes.h

@@ -0,0 +1,68 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_
+#define _NES_
+
+#include "nes_port.h"
+#include "nes_rom.h"
+#include "nes_cpu.h"
+#include "nes_ppu.h"
+#include "nes_apu.h"
+#include "nes_mapper.h"
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#define NES_NAME                "NES"
+#define NES_WIDTH               256
+#define NES_HEIGHT              240
+
+#define NES_OK                  0 
+#define NES_ERROR               -1
+
+typedef struct nes{
+    uint8_t nes_quit;
+    nes_rom_info_t nes_rom;
+    nes_cpu_t nes_cpu;
+    nes_ppu_t nes_ppu;
+    nes_mapper_t nes_mapper;
+    nes_color_t nes_draw_data[NES_DRAW_SIZE];
+} nes_t;
+
+
+int nes_init(nes_t *nes);
+int nes_deinit(nes_t *nes);
+
+int nes_initex(nes_t* nes);
+int nes_deinitex(nes_t* nes);
+
+void nes_run(nes_t* nes);
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_

+ 42 - 0
components/nes/inc/nes_apu.h

@@ -0,0 +1,42 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_APU_
+#define _NES_APU_
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+struct nes;
+typedef struct nes nes_t;
+
+uint8_t nes_read_apu_register(nes_t *nes,uint16_t address);
+void nes_write_apu_register(nes_t* nes,uint16_t address,uint8_t data);
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_APU_

+ 114 - 0
components/nes/inc/nes_cpu.h

@@ -0,0 +1,114 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_CPU_
+#define _NES_CPU_
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+// https://www.nesdev.org/wiki/Controller_reading
+#define NES_CPU_RAM_SIZE        0x800   /*  2KB */
+
+struct nes;
+typedef struct nes nes_t;
+
+#define NES_VERCTOR_NMI         0xFFFA  /*  NMI vector (NMI=not maskable interupts) */
+#define NES_VERCTOR_RESET       0xFFFC  /*  Reset vector */
+#define NES_VERCTOR_IRQBRK      0xFFFE  /*  IRQ vector */
+
+/*
+Bit No. 15      14      13      12      11      10      9       8
+        A1      B1      Select1 Start1  Up1     Down1   Left1   Right1 
+Bit No. 7       6       5       4       3       2       1       0
+        A2      B2      Select2 Start2  Up2     Down2   Left2   Right2 
+*/
+typedef struct nes_joypad{
+    uint8_t offset1;
+    uint8_t offset2;
+    uint8_t mask;
+    union {
+        struct {
+            uint8_t R2:1;   
+            uint8_t L2:1;    
+            uint8_t D2:1;    
+            uint8_t U2:1;  
+            uint8_t ST2:1; 
+            uint8_t SE2:1;
+            uint8_t B2:1;    
+            uint8_t A2:1;
+            uint8_t R1:1;   
+            uint8_t L1:1;    
+            uint8_t D1:1;    
+            uint8_t U1:1;  
+            uint8_t ST1:1; 
+            uint8_t SE1:1;
+            uint8_t B1:1;    
+            uint8_t A1:1;  
+        };
+        uint16_t joypad;
+    };
+} nes_joypad_t;
+
+// https://www.nesdev.org/wiki/CPU_registers
+typedef struct nes_cpu{
+    /*  CPU registers */
+    uint8_t A;                          /*  Accumulator */
+    uint8_t X;                          /*  Indexes X */
+    uint8_t Y;                          /*  Indexes Y */
+    uint16_t PC;                        /*  Program Counter */
+    uint8_t SP;                         /*  Stack Pointer */
+    union {
+        struct {
+            uint8_t C:1;                /*  carry flag (1 on unsigned overflow) */
+            uint8_t Z:1;                /*  zero flag (1 when all bits of a result are 0) */
+            uint8_t I:1;                /*  IRQ flag (when 1, no interupts will occur (exceptions are IRQs forced by BRK and NMIs)) */
+            uint8_t D:1;                /*  decimal flag (1 when CPU in BCD mode) */
+            uint8_t B:1;                /*  break flag (1 when interupt was caused by a BRK) */
+            uint8_t U:1;                /*  unused (always 1) */
+            uint8_t V:1;                /*  overflow flag (1 on signed overflow) */
+            uint8_t N:1;                /*  negative flag (1 when result is negative) */
+        };
+        uint8_t P;                      /*  Status Register */
+    };
+    uint32_t cycles;  
+    uint8_t opcode;     
+    uint8_t cpu_ram[NES_CPU_RAM_SIZE];
+    uint8_t* prg_banks[4];              /*  4 bank ( 8Kb * 4 ) = 32KB  */
+    nes_joypad_t joypad;
+} nes_cpu_t;
+
+void nes_cpu_init(nes_t *nes);
+void nes_cpu_reset(nes_t* nes);
+
+void nes_nmi(nes_t* nes);
+void nes_opcode(nes_t* nes,uint16_t ticks);
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_CPU_

+ 68 - 0
components/nes/inc/nes_mapper.h

@@ -0,0 +1,68 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_MAPPER_
+#define _NES_MAPPER_
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+struct nes;
+typedef struct nes nes_t;
+
+typedef struct {
+    /* Initialize Mapper */
+    void (*mapper_init)(nes_t* nes);
+    /* Write to Mapper */
+    void (*mapper_write)(nes_t* nes,uint16_t write_addr, uint8_t data );
+    /* Write to SRAM */
+    void (*mapper_sram)( uint16_t write_addr, uint8_t data );
+    /* Write to Apu */
+    void (*mapper_apu)( uint16_t write_addr, uint8_t data );
+    /* Read from Apu */
+    uint8_t (*mapper_read_apu)( uint16_t write_addr );
+    /* Callback at VSync */
+    void (*mapper_vsync)(void);
+    /* Callback at HSync */
+    void (*mapper_hsync)(void);
+    /* Callback at PPU read/write */
+    void (*mapper_ppu)( uint16_t write_addr );
+    /* Callback at Rendering Screen 1:BG, 0:Sprite */
+    void (*mapper_render_screen)( uint8_t mode );
+} nes_mapper_t;
+
+/* mapper */
+int nes_load_mapper(nes_t* nes);
+void nes_load_prgrom_8k(nes_t* nes,int des, int src);
+void nes_load_chrrom_1k(nes_t* nes,int des, int src);
+int nes_mapper0_init(nes_t* nes);
+int nes_mapper1_init(nes_t* nes);
+int nes_mapper2_init(nes_t* nes);
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_MAPPER_

+ 184 - 0
components/nes/inc/nes_ppu.h

@@ -0,0 +1,184 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_PPU_
+#define _NES_PPU_
+
+#include "nes_conf.h"
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#define NES_PPU_VRAM_SIZE       0x1000  /*  4KB */
+
+struct nes;
+typedef struct nes nes_t;
+
+// https://www.nesdev.org/wiki/PPU_OAM
+typedef struct{
+    uint8_t	y;		                    /*  Y position of top of sprite */
+    union {
+        struct {
+            uint8_t pattern_8x16:1;     /*  Bank ($0000 or $1000) of tiles */
+            uint8_t tile_index_8x16 :7; /*  Tile number of top of sprite (0 to 254; bottom half gets the next tile) */
+        };
+        uint8_t	tile_index_number;	    /*  Tile index number */
+    };
+    union {
+        struct {
+            uint8_t sprite_palette:2;   /*  Palette (4 to 7) of sprite */
+            uint8_t :3;                 /*  nimplemented (read 0) */
+            uint8_t priority :1;        /*  Priority (0: in front of background; 1: behind background) */
+            uint8_t flip_h :1;          /*  Flip sprite horizontally */
+            uint8_t flip_v :1;          /*  Flip sprite vertically */
+        };
+        uint8_t	attributes;	            /*  Attributes */
+    };
+    uint8_t	x;		                    /*  X position of left side of sprite. */
+} sprite_info_t;
+
+// https://www.nesdev.org/wiki/PPU_registers
+typedef struct nes_ppu{
+    union {
+        struct {
+            uint8_t ppu_vram0[NES_PPU_VRAM_SIZE / 4];
+            uint8_t ppu_vram1[NES_PPU_VRAM_SIZE / 4];
+            uint8_t ppu_vram2[NES_PPU_VRAM_SIZE / 4];
+            uint8_t ppu_vram3[NES_PPU_VRAM_SIZE / 4];
+        };
+        uint8_t ppu_vram[NES_PPU_VRAM_SIZE];
+    };
+    union {
+        struct {
+            uint8_t CTRL_N:2;           /*  Base nametable address (0 = $2000; 1 = $2400; 2 = $2800; 3 = $2C00) */
+            uint8_t CTRL_I:1;           /*  VRAM address increment per CPU read/write of PPUDATA (0: add 1, going across; 1: add 32, going down) */
+            uint8_t CTRL_S:1;           /*  Sprite pattern table address for 8x8 sprites (0: $0000; 1: $1000; ignored in 8x16 mode) */
+            uint8_t CTRL_B:1;           /*  Background pattern table address (0: $0000; 1: $1000) */
+            uint8_t CTRL_H:1;           /*  Sprite size (0: 8x8 pixels; 1: 8x16 pixels – see PPU OAM#Byte 1) */
+            uint8_t CTRL_P:1;           /*  (0: read backdrop from EXT pins; 1: output color on EXT pins) */
+            uint8_t CTRL_V:1;           /*  Generate an NMI at the start of the vertical blanking interval (0: off; 1: on) */
+        };
+        uint8_t ppu_ctrl;
+    };
+    union {
+        struct {
+            uint8_t MASK_Gr:1;          /*  Greyscale (0: normal color, 1: produce a greyscale display) */
+            uint8_t MASK_m:1;           /*  1: Show background in leftmost 8 pixels of screen, 0: Hide */
+            uint8_t MASK_M:1;           /*  1: Show sprites in leftmost 8 pixels of screen, 0: Hide */
+            uint8_t MASK_b:1;           /*  1: Show background */
+            uint8_t MASK_s:1;           /*  1: Show sprites */
+            uint8_t MASK_R:1;           /*  Emphasize red (green on PAL/Dendy) */
+            uint8_t MASK_G:1;           /*  Emphasize green (red on PAL/Dendy) */
+            uint8_t MASK_B:1;           /*  Emphasize blue */
+        };
+        uint8_t ppu_mask;
+    };
+    union {
+        struct {
+            uint8_t  :4;    
+            uint8_t STATUS_F:1;         /*  VRAM write flag: 0 = write valid, 1 = write ignored */
+            uint8_t STATUS_O:1;         /*  Sprite overflow. The intent was for this flag to be set
+                                            whenever more than eight sprites appear on a scanline, but a
+                                            hardware bug causes the actual behavior to be more complicated
+                                            and generate false positives as well as false negatives; see
+                                            PPU sprite evaluation. This flag is set during sprite
+                                            evaluation and cleared at dot 1 (the second dot) of the
+                                            pre-render line. */
+            uint8_t STATUS_S:1;         /*  Sprite 0 Hit.  Set when a nonzero pixel of sprite 0 overlaps
+                                            a nonzero background pixel; cleared at dot 1 of the pre-render
+                                            line.  Used for raster timing. */
+            uint8_t STATUS_V:1;         /*  Vertical blank has started (0: not in vblank; 1: in vblank).
+                                            Set at dot 1 of line 241 (the line *after* the post-render
+                                            line); cleared after reading $2002 and at dot 1 of the
+                                            pre-render line. */
+        };
+        uint8_t ppu_status;
+    };
+    union {
+        struct {
+            uint8_t* pattern_table[8];
+            uint8_t* name_table[4];
+        };
+        uint8_t* chr_banks[16];         /*  16k chr_banks,without background_palette and sprite_palette
+                                            0 - 3 pattern_table_0 4k
+                                            4 - 7 pattern_table_1 4k
+                                            8     name_table_0    1k
+                                            9     name_table_1    1k
+                                            10    name_table_2    1k
+                                            11    name_table_3    1k
+                                            12-15 mirrors */
+    };
+    union {
+		struct{ // Scroll
+			uint16_t coarse_x  : 5;     
+			uint16_t coarse_y  : 5;     
+			uint16_t nametable : 2;     
+			uint16_t fine_y    : 3;     
+			uint16_t           : 1;     
+		}v;
+        uint16_t v_reg;                 /*  Current VRAM address (15 bits) */
+    };
+    union {
+		struct{ // Scroll
+			uint16_t coarse_x  : 5;
+			uint16_t coarse_y  : 5;
+			uint16_t nametable : 2;
+			uint16_t fine_y    : 3;
+			uint16_t           : 1;
+		}t;
+        uint16_t t_reg;                 /*  Temporary VRAM address (15 bits); can also be thought of as the address of the top left onscreen tile. */
+    };
+    struct {
+        uint8_t x:3;                    /*  Fine X scroll (3 bits) */
+        uint8_t w:1;                    /*  First or second write toggle (1 bit) */
+        uint8_t :4;// 可利用做xxx标志位
+    };
+    uint8_t oam_addr;                   /*  OAM read/write address */
+    union {
+        sprite_info_t sprite_info[0x100 / 4];
+        uint8_t oam_data[0x100];        /*  OAM data read/write 
+                                            The OAM (Object Attribute Memory) is internal memory inside the PPU that contains a display list of up to 64 sprites, 
+                                            where each sprite's information occupies 4 bytes.*/
+    };
+    uint8_t buffer;                     /*  PPU internal buffer */
+    uint8_t palette_indexes[0x20];      /*  $3F00-$3F1F Palette RAM indexes */
+    union {
+        struct {
+            nes_color_t background_palette[0x10];
+            nes_color_t sprite_palette[0x10];
+        };
+        nes_color_t palette[0x20];
+    };
+} nes_ppu_t;
+
+void nes_ppu_init(nes_t *nes);
+uint8_t nes_read_ppu_register(nes_t *nes,uint16_t address);
+void nes_write_ppu_register(nes_t *nes,uint16_t address, uint8_t data);
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_PPU_

+ 123 - 0
components/nes/inc/nes_rom.h

@@ -0,0 +1,123 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_ROM_
+#define _NES_ROM_
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+struct nes;
+typedef struct nes nes_t;
+
+/* NES 2.0: https://wiki.nesdev.org/w/index.php/NES_2.0 */
+#define TRAINER_SIZE            (0x200)
+#define PRG_ROM_UNIT_SIZE       (0x4000)
+#define CHR_ROM_UNIT_SIZE       (0x2000)
+typedef struct {
+    uint8_t identification[4];          /*  0-3   Identification String. Must be "NES<EOF>". */
+    uint8_t prg_rom_size_l;             /*  4     PRG-ROM size LSB */
+    uint8_t chr_rom_size_l;             /*  5     CHR-ROM size LSB */
+    struct {
+        uint8_t mirroring:1;            /*  D0    Hard-wired nametable mirroring type        0: Horizontal or mapper-controlled 1: Vertical */
+        uint8_t save:1;                 /*  D1    "Battery" and other non-volatile memory    0: Not present 1: Present */
+        uint8_t trainer:1;              /*  D2    512-byte Trainer                           0: Not present 1: Present between Header and PRG-ROM data */
+        uint8_t four_screen:1;          /*  D3    Hard-wired four-screen mode                0: No 1: Yes */
+        uint8_t mapper_number_l:4;      /*  D4-7  Mapper Number D0..D3 */
+    };
+    struct {
+        uint8_t console_type:2;         /*  D0-1  Console type   0: Nintendo Entertainment System/Family Computer 1: Nintendo Vs. System 2: Nintendo Playchoice 10 3: Extended Console Type */
+        uint8_t identifier2:2;          /*  D2-3  NES 2.0 identifier */
+        uint8_t mapper_number_m:4;      /*  D4-7  Mapper Number D4..D7 */
+    }; 
+    struct {
+        uint8_t mapper_number_h:4;      /*  D0-3  Mapper number D8..D11 */
+        uint8_t submapper:4;            /*  D4-7  Submapper number */
+    };                                  /*  Mapper MSB/Submapper */
+    struct {
+        uint8_t prg_rom_size_m:4;       /*  D0-3  PRG-ROM size MSB */
+        uint8_t chr_rom_size_m:4;       /*  D4-7  CHR-ROM size MSB */
+    };                                  /*  PRG-ROM/CHR-ROM size MSB */
+    struct {
+        uint8_t prg_ram_size_m:4;       /*  D0-3  PRG-RAM (volatile) shift count */
+        uint8_t eeprom_size_m:4;        /*  D4-7  PRG-NVRAM/EEPROM (non-volatile) shift count */
+    };                                  /*  PRG-RAM/EEPROM size
+                                            If the shift count is zero, there is no PRG-(NV)RAM.
+                                            If the shift count is non-zero, the actual size is
+                                            "64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7. */
+    struct {
+        uint8_t chr_ram_size_m:4;       /*  D0-3  CHR-RAM size (volatile) shift count */
+        uint8_t chr_nvram_size_m:4;     /*  D4-7  CHR-NVRAM size (non-volatile) shift count */
+    };                                  /*  CHR-RAM size
+                                            If the shift count is zero, there is no CHR-(NV)RAM.
+                                            If the shift count is non-zero, the actual size is
+                                            "64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7. */
+    struct {
+        uint8_t timing_mode :2;         /*  D0-1    CPU/PPU timing mode 
+                                                    0: RP2C02 ("NTSC NES")
+                                                    1: RP2C07 ("Licensed PAL NES")
+                                                    2: Multiple-region
+                                                    3: UMC 6527P ("Dendy") */
+        uint8_t :6;
+    };                                  /*  CPU/PPU Timing */
+    struct {
+        uint8_t ppu_type:4;             /*  D0-3  Vs. PPU Type */
+        uint8_t hardware_type:4;        /*  D4-7  Vs. Hardware Type */
+    };                                  /*  When Byte 7 AND 3 =1: Vs. System Type
+                                            When Byte 7 AND 3 =3: Extended Console Type */
+    struct {
+        uint8_t miscellaneous_number:2; /*  D0-1  Number of miscellaneous ROMs present */
+        uint8_t :6;
+    };                                  /*  Miscellaneous ROMs */
+    struct {
+        uint8_t expansion_device:6;     /*  D0-5  Default Expansion Device */
+        uint8_t :2;
+    };                                  /*  Default Expansion Device */
+} nes_header_info_t;
+
+typedef struct nes_rom_info{
+    uint16_t prg_rom_size;
+    uint16_t chr_rom_size;
+    uint8_t* prg_rom;
+    uint8_t* chr_rom;
+    uint8_t* sram;
+    uint16_t mapper_number;             /*  Mapper Number */
+    uint8_t  mirroring_type;            /*  0: Horizontal or mapper-controlled 1: Vertical */
+    uint8_t  four_screen;               /*  0: No 1: Yes */
+    uint8_t  save_ram;                  /*  0: Not present 1: Present */
+} nes_rom_info_t;
+
+#if (NES_USE_FS == 1)
+nes_t* nes_load_file(const char* file_path);
+#endif
+
+nes_t* nes_load_rom(const uint8_t* nes_rom);
+int nes_rom_free(nes_t* nes);
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_ROM_

+ 131 - 0
components/nes/luat_lib_nes.c

@@ -0,0 +1,131 @@
+
+/*
+@module  nes
+@summary nes模拟器
+@version 1.0
+@date    2023.4.10
+@tag     LUAT_USE_NES
+*/
+
+#include "luat_base.h"
+#include "luat_rtos.h"
+#include "luat_lcd.h"
+#include "luat_mem.h"
+#include "luat_rtos.h"
+
+#include "nes.h"
+#include "nes_port.h"
+
+#define LUAT_LOG_TAG "nes"
+#include "luat_log.h"
+
+enum {
+    Up = 1,
+    Down,
+    Left,
+    Right,
+    A,
+    B,
+    Start,
+    Select
+};
+
+static luat_rtos_queue_t nes_thread;
+static nes_t* nes = NULL;
+
+void nes_task(void *param){
+    nes_run(nes);
+}
+
+/*
+nes模拟器初始化
+@api nes.init(file_path)
+@string file_path 文件路径
+@return bool 成功返回true,否则返回false
+@usage
+nes.init("/luadb/super_mario.nes")
+*/
+static int l_nes_init(lua_State *L) {
+    size_t nes_rom_len;
+    const char* nes_rom = luaL_checklstring(L, 1, &nes_rom_len);
+    nes = nes_load_file(nes_rom);
+    if (!nes){
+        return 0;
+    }
+    if (luat_rtos_task_create(&nes_thread, 4*1024, 50, "nes", nes_task, nes, 0)){
+        return 0;
+    }
+    lua_pushboolean(L, 1);
+    return 1;
+}
+/*
+nes模拟器初始化
+@api nes.key(key,val)
+@number key 按键
+@number val 状态 1按下 0抬起
+@return bool 成功返回true,否则返回false
+@usage
+nes.init("/luadb/super_mario.nes")
+*/
+static int l_nes_key(lua_State *L) {
+    int key = luaL_checkinteger(L, 1);
+    int val = luaL_checkinteger(L, 2);
+    switch (key){
+        case Up:
+            nes->nes_cpu.joypad.U1 = val;
+            break;
+        case Down:
+            nes->nes_cpu.joypad.D1 = val;
+            break;
+        case Left:
+            nes->nes_cpu.joypad.L1 = val;
+            break;
+        case Right:
+            nes->nes_cpu.joypad.R1 = val;
+            break;
+        case A:
+            nes->nes_cpu.joypad.A1 = val;
+            break;
+        case B:
+            nes->nes_cpu.joypad.B1 = val;
+            break;
+        case Start:
+            nes->nes_cpu.joypad.ST1 = val;
+            break;
+        case Select:
+            nes->nes_cpu.joypad.SE1 = val;
+            break;
+        default:
+            break;
+    }
+    return 0;
+}
+
+#include "rotable2.h"
+static const rotable_Reg_t reg_nes[] =
+{
+    {"init",    ROREG_FUNC(l_nes_init)  },
+    {"key",     ROREG_FUNC(l_nes_key)   },
+
+    //@const Up 按键上
+    { "Up",     ROREG_INT(Up)           },
+    //@const Down 按键下
+    { "Down",   ROREG_INT(Down)         },
+    //@const Left 按键左
+    { "Left",   ROREG_INT(Left)         },
+    //@const Right 按键右
+    { "Right",  ROREG_INT(Right)        },
+    //@const A 按键A
+    { "A",      ROREG_INT(A)            },
+    //@const B 按键B
+    { "B",      ROREG_INT(B)            },
+    //@const Start 按键开始
+    { "Start",  ROREG_INT(Start)        },
+    //@const Select 按键选择
+    { "Select", ROREG_INT(Select)       },
+	{ NULL,     ROREG_INT(0)}
+};
+LUAMOD_API int luaopen_nes( lua_State *L ) {
+    luat_newlib2(L, reg_nes);
+    return 1;
+}

+ 83 - 0
components/nes/port/nes_conf.h

@@ -0,0 +1,83 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_CONF_
+#define _NES_CONF_
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#define NES_FRAME_SKIP          2
+
+#define NES_USE_SRAM            0
+#define NES_COLOR_DEPTH         16
+#define NES_COLOR_SWAP          1
+#define NES_RAM_LACK            1
+
+#define NES_USE_FS              1
+
+#ifndef NES_USE_FS
+#define NES_USE_FS              0
+#endif
+
+#ifndef NES_FRAME_SKIP
+#define NES_FRAME_SKIP          0
+#endif
+
+#ifndef NES_RAM_LACK
+#define NES_RAM_LACK            0
+#endif
+
+#if (NES_RAM_LACK == 1)
+#define NES_DRAW_SIZE         (NES_WIDTH * NES_HEIGHT / 2) 
+#else
+#define NES_DRAW_SIZE         (NES_WIDTH * NES_HEIGHT)
+#endif
+
+#ifndef NES_COLOR_SWAP
+#define NES_COLOR_SWAP         0
+#endif
+
+/* Color depth:
+ * - 16: RGB565
+ * - 32: ARGB8888
+ */
+#ifndef NES_COLOR_DEPTH
+#define NES_COLOR_DEPTH         32
+#endif
+
+#if (NES_COLOR_DEPTH == 32)
+#define nes_color_t uint32_t
+#elif (NES_COLOR_DEPTH == 16)
+#define nes_color_t uint16_t
+#else
+#error "no supprt color depth"
+#endif
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_CONF_

+ 96 - 0
components/nes/port/nes_port.c

@@ -0,0 +1,96 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "nes.h"
+
+#include "luat_base.h"
+#include "luat_mem.h"
+#include "luat_timer.h"
+#include "luat_fs.h"
+#include "luat_lcd.h"
+
+/* memory */
+void *nes_malloc(int num){
+    return luat_heap_malloc(num);
+}
+
+void nes_free(void *address){
+    luat_heap_free(address);
+}
+
+void *nes_memcpy(void *str1, const void *str2, size_t n){
+    return memcpy(str1, str2, n);
+}
+
+void *nes_memset(void *str, int c, size_t n){
+    return memset(str,c,n);
+}
+
+int nes_memcmp(const void *str1, const void *str2, size_t n){
+    return memcmp(str1,str2,n);
+}
+
+#if (NES_USE_FS == 1)
+/* io */
+FILE *nes_fopen( const char * filename, const char * mode ){
+    return luat_fs_fopen(filename,mode);
+}
+
+size_t nes_fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file){
+    return luat_fs_fread(ptr, size_of_elements, number_of_elements,a_file);
+}
+
+int nes_fseek(FILE *stream, long int offset, int whence){
+    return luat_fs_fseek(stream,offset,whence);
+}
+
+int nes_fclose( FILE *fp ){
+    return luat_fs_fclose(fp);
+}
+#endif
+
+/* wait */
+void nes_wait(uint32_t ms){
+    luat_timer_mdelay(ms);
+}
+
+static luat_lcd_conf_t* nes_lcd_conf;
+
+int nes_initex(nes_t *nes){
+    nes_lcd_conf = luat_lcd_get_default();
+    return 0;
+}
+
+int nes_deinitex(nes_t *nes){
+    return 0;
+}
+
+int nes_draw(size_t x1, size_t y1, size_t x2, size_t y2, nes_color_t* color_data){
+    return luat_lcd_draw(nes_lcd_conf, x1, y1, x2, y2, color_data);
+}
+
+void nes_frame(void){
+    luat_timer_us_delay(10);
+}
+

+ 71 - 0
components/nes/port/nes_port.h

@@ -0,0 +1,71 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * 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.
+ */
+
+#ifndef _NES_PORT_
+#define _NES_PORT_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "nes_conf.h"
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* log */
+#ifdef __DEBUG__
+#define nes_printf(...)  printf(__VA_ARGS__)
+#else
+#define nes_printf(...)
+#endif
+
+/* memory */
+void *nes_malloc(int num);
+void nes_free(void *address);
+void *nes_memcpy(void *str1, const void *str2, size_t n);
+void *nes_memset(void *str, int c, size_t n);
+int nes_memcmp(const void *str1, const void *str2, size_t n);
+
+#if (NES_USE_FS == 1)
+/* io */
+FILE *nes_fopen( const char * filename, const char * mode );
+size_t nes_fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
+int nes_fseek(FILE *stream, long int offset, int whence);
+int nes_fclose( FILE *fp );
+#endif
+
+void nes_wait(uint32_t ms);
+
+void nes_frame(void);
+
+int nes_draw(size_t x1, size_t y1, size_t x2, size_t y2, nes_color_t* color_data);
+
+
+#ifdef __cplusplus          
+    }
+#endif
+
+#endif// _NES_PORT_

+ 386 - 0
components/nes/src/nes.c

@@ -0,0 +1,386 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+#define NES_PPU_CPU_CLOCKS		113
+
+int nes_init(nes_t *nes){
+    nes_initex(nes);
+    nes_cpu_init(nes);
+    nes_ppu_init(nes);
+    return 0;
+}
+
+int nes_deinit(nes_t *nes){
+    nes->nes_quit = 1;
+    nes_deinitex(nes);
+    return 0;
+}
+
+extern nes_color_t nes_palette[];
+
+static inline void nes_palette_generate(nes_t* nes){
+    for (size_t i = 0; i < 32; i++) {
+        nes->nes_ppu.palette[i] = nes_palette[nes->nes_ppu.palette_indexes[i]];
+    }
+    for (size_t i = 1; i < 8; i++){
+        nes->nes_ppu.palette[4 * i] = nes->nes_ppu.palette[0];
+    }
+}
+
+static void nes_render_background_line(nes_t* nes,uint16_t scanline,nes_color_t* draw_data){
+    uint8_t p = 0;
+    int8_t m = 7 - nes->nes_ppu.x;
+    const uint8_t dx = (const uint8_t)nes->nes_ppu.v.coarse_x;
+    const uint8_t dy = (const uint8_t)nes->nes_ppu.v.fine_y;
+    const uint8_t tile_y = (const uint8_t)nes->nes_ppu.v.coarse_y;
+    uint8_t nametable_id = (uint8_t)nes->nes_ppu.v.nametable;
+    for (uint8_t tile_x = dx; tile_x < 32; tile_x++){
+        uint32_t pattern_id = nes->nes_ppu.name_table[nametable_id][tile_x + (tile_y << 5)];
+        const uint8_t* bit0_p = nes->nes_ppu.pattern_table[nes->nes_ppu.CTRL_B ? 4 : 0] + pattern_id * 16;
+        const uint8_t* bit1_p = bit0_p + 8;
+        const uint8_t bit0 = bit0_p[dy];
+        const uint8_t bit1 = bit1_p[dy];
+        uint8_t attribute = nes->nes_ppu.name_table[nametable_id][960 + ((tile_y >> 2) << 3) + (tile_x >> 2)];
+        // 1:D4-D5/D6-D7 0:D0-D1/D2-D3
+        // 1:D2-D3/D6-D7 0:D0-D1/D4-D5
+        const uint8_t high_bit = ((attribute >> (((tile_y & 2) << 1) | (tile_x & 2))) & 3) << 2;
+        for (; m >= 0; m--){
+            uint8_t low_bit = ((bit0 >> m) & 0x01) | ((bit1 >> m)<<1 & 0x02);
+            uint8_t palette_index = (high_bit & 0x0c) | low_bit;
+            draw_data[p++] = nes->nes_ppu.background_palette[palette_index];
+        }
+        m = 7;
+    }
+    nametable_id ^= nes->nes_rom.mirroring_type ? 1:2;
+    for (uint8_t tile_x = 0; tile_x <= dx; tile_x++){
+        uint32_t pattern_id = nes->nes_ppu.name_table[nametable_id][tile_x + (tile_y << 5)];
+        const uint8_t* bit0_p = nes->nes_ppu.pattern_table[nes->nes_ppu.CTRL_B ? 4 : 0] + pattern_id * 16;
+        const uint8_t* bit1_p = bit0_p + 8;
+        const uint8_t bit0 = bit0_p[dy];
+        const uint8_t bit1 = bit1_p[dy];
+        uint8_t attribute = nes->nes_ppu.name_table[nametable_id][960 + ((tile_y >> 2) << 3) + (tile_x >> 2)];
+        // 1:D4-D5/D6-D7 0:D0-D1/D2-D3
+        // 1:D2-D3/D6-D7 0:D0-D1/D4-D5
+        const uint8_t high_bit = ((attribute >> (((tile_y & 2) << 1) | (tile_x & 2))) & 3) << 2;
+        uint8_t skew = 0;
+        if (tile_x == dx){
+            if (nes->nes_ppu.x){
+                skew = 8 - nes->nes_ppu.x;
+            }else
+                break;
+        }
+        for (; m >= skew; m--){
+            uint8_t low_bit = ((bit0 >> m) & 0x01) | ((bit1 >> m)<<1 & 0x02);
+            uint8_t palette_index = (high_bit & 0x0c) | low_bit;
+            draw_data[p++] = nes->nes_ppu.background_palette[palette_index];
+        }
+        m = 7;
+    }
+}
+
+static void nes_render_sprite_line(nes_t* nes,uint16_t scanline,nes_color_t* draw_data){
+    nes_color_t background_color = nes->nes_ppu.background_palette[0];
+    uint8_t sprite_number = 0;
+    uint8_t sprite_size = nes->nes_ppu.CTRL_H?16:8;
+    
+    for (uint8_t i = 63; i > 0 ; i--){
+        if (nes->nes_ppu.sprite_info[i].y >= 0xEF)
+            continue;
+        uint8_t sprite_y = (uint8_t)(nes->nes_ppu.sprite_info[i].y + 1);
+        if (scanline < sprite_y || scanline >= sprite_y + sprite_size)
+            continue;
+        sprite_number ++;
+        if(sprite_number > 8 ){
+            nes->nes_ppu.STATUS_O = 1;
+            goto sprite0;
+        }
+
+        const uint8_t* sprite_bit0_p = nes->nes_ppu.pattern_table[nes->nes_ppu.CTRL_H?((nes->nes_ppu.sprite_info[i].pattern_8x16)?4:0):(nes->nes_ppu.CTRL_S?4:0)] \
+                                        + (nes->nes_ppu.CTRL_H?(nes->nes_ppu.sprite_info[i].tile_index_8x16 << 1 ):(nes->nes_ppu.sprite_info[i].tile_index_number)) * 16;
+        const uint8_t* sprite_bit1_p = sprite_bit0_p + 8;
+
+        uint8_t dy = scanline - sprite_y;
+
+        if (nes->nes_ppu.CTRL_H){
+            if (nes->nes_ppu.sprite_info[i].flip_v){
+                if (dy < 8){
+                    sprite_bit0_p +=16;
+                    sprite_bit1_p +=16;
+                    dy = sprite_size - dy - 1 -8;
+                }else{
+                    dy = sprite_size - dy - 1;
+                }
+            }else{
+                if (dy > 7){
+                    sprite_bit0_p +=16;
+                    sprite_bit1_p +=16;
+                    dy-=8;
+                }
+            }
+        }else{
+            if (nes->nes_ppu.sprite_info[i].flip_v){
+                dy = sprite_size - dy - 1;
+            }
+        }
+
+        const uint8_t sprite_bit0 = sprite_bit0_p[dy];
+        const uint8_t sprite_bit1 = sprite_bit1_p[dy];
+
+        uint8_t p = nes->nes_ppu.sprite_info[i].x;
+        if (nes->nes_ppu.sprite_info[i].flip_h){
+            for (int8_t m = 0; m <= 7; m++){
+                uint8_t low_bit = ((sprite_bit0 >> m) & 0x01) | ((sprite_bit1 >> m)<<1 & 0x02);
+                uint8_t palette_index = (nes->nes_ppu.sprite_info[i].sprite_palette << 2) | low_bit;
+                if (palette_index%4 != 0){
+                    if (nes->nes_ppu.sprite_info[i].priority){
+                        if (draw_data[p] == background_color){
+                            draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                        }
+                    }else{
+                        draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                    }
+                }
+                if (p == 255)
+                    break;
+                p++;
+            }
+        }else{
+            for (int8_t m = 7; m >= 0; m--){
+                uint8_t low_bit = ((sprite_bit0 >> m) & 0x01) | ((sprite_bit1 >> m)<<1 & 0x02);
+                uint8_t palette_index = (nes->nes_ppu.sprite_info[i].sprite_palette << 2) | low_bit;
+                if (palette_index%4 != 0){
+                    if (nes->nes_ppu.sprite_info[i].priority){
+                        if (draw_data[p] == background_color){
+                            draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                        }
+                    }else{
+                        draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                    }
+                }
+                if (p == 255)
+                    break;
+                p++;
+            }
+        }
+    }
+sprite0:
+    // sprite 0
+    if (nes->nes_ppu.sprite_info[0].y >= 0xEF)
+        return;
+    uint8_t sprite_y = (uint8_t)(nes->nes_ppu.sprite_info[0].y + 1);
+    if (scanline < sprite_y || scanline >= sprite_y + sprite_size)
+        return;
+    sprite_number ++;
+    if(sprite_number > 8 ){
+        nes->nes_ppu.STATUS_O = 1;
+    }
+
+    const uint8_t* sprite_bit0_p = nes->nes_ppu.pattern_table[nes->nes_ppu.CTRL_H?((nes->nes_ppu.sprite_info[0].pattern_8x16)?4:0):(nes->nes_ppu.CTRL_S?4:0)] \
+                                    + (nes->nes_ppu.CTRL_H?(nes->nes_ppu.sprite_info[0].tile_index_8x16 << 1 ):(nes->nes_ppu.sprite_info[0].tile_index_number)) * 16;
+    const uint8_t* sprite_bit1_p = sprite_bit0_p + 8;
+
+    uint8_t dy = scanline - sprite_y;
+
+    if (nes->nes_ppu.CTRL_H){
+        if (nes->nes_ppu.sprite_info[0].flip_v){
+            if (dy < 8){
+                sprite_bit0_p +=16;
+                sprite_bit1_p +=16;
+                dy = sprite_size - dy - 1 -8;
+            }else{
+                dy = sprite_size - dy - 1;
+            }
+        }else{
+            if (dy > 7){
+                sprite_bit0_p +=16;
+                sprite_bit1_p +=16;
+                dy-=8;
+            }
+        }
+    }else{
+        if (nes->nes_ppu.sprite_info[0].flip_v){
+            dy = sprite_size - dy - 1;
+        }
+    }
+    
+    const uint8_t sprite_bit0 = sprite_bit0_p[dy];
+    const uint8_t sprite_bit1 = sprite_bit1_p[dy];
+
+    const uint8_t sprite_date = sprite_bit0 | sprite_bit1;
+    if (sprite_date && nes->nes_ppu.MASK_b && nes->nes_ppu.STATUS_S == 0){
+        uint8_t nametable_id = (uint8_t)nes->nes_ppu.v.nametable;
+        const uint8_t tile_x = (nes->nes_ppu.sprite_info[0].x) >> 3;
+        const uint8_t tile_y = scanline >> 3;
+        uint32_t pattern_id = nes->nes_ppu.name_table[nametable_id][tile_x + (tile_y << 5)];
+        const uint8_t* bit0_p = nes->nes_ppu.pattern_table[nes->nes_ppu.CTRL_B ? 4 : 0] + pattern_id * 16;
+        const uint8_t* bit1_p = bit0_p + 8;
+        uint8_t background_date = bit0_p[dy] | bit1_p[dy]<<1;
+        if (sprite_date == background_date){
+            nes->nes_ppu.STATUS_S = 1;
+        }
+    }
+    if (nes->nes_ppu.STATUS_O == 1){
+        return;
+    }
+    
+    uint8_t p = nes->nes_ppu.sprite_info[0].x;
+    if (nes->nes_ppu.sprite_info[0].flip_h){
+        for (int8_t m = 0; m <= 7; m++){
+            uint8_t low_bit = ((sprite_bit0 >> m) & 0x01) | ((sprite_bit1 >> m)<<1 & 0x02);
+            uint8_t palette_index = (nes->nes_ppu.sprite_info[0].sprite_palette << 2) | low_bit;
+            if (palette_index%4 != 0){
+                if (nes->nes_ppu.sprite_info[0].priority){
+                    if (draw_data[p] == background_color){
+                        draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                    }
+                }else{
+                    draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                }
+            }
+            if (p == 255)
+                break;
+            p++;
+        }
+    }else{
+        for (int8_t m = 7; m >= 0; m--){
+            uint8_t low_bit = ((sprite_bit0 >> m) & 0x01) | ((sprite_bit1 >> m)<<1 & 0x02);
+            uint8_t palette_index = (nes->nes_ppu.sprite_info[0].sprite_palette << 2) | low_bit;
+            if (palette_index%4 != 0){
+                if (nes->nes_ppu.sprite_info[0].priority){
+                    if (draw_data[p] == background_color){
+                        draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                    }
+                }else{
+                    draw_data[p] = nes->nes_ppu.sprite_palette[palette_index];
+                }
+            }
+            if (p == 255)
+                break;
+            p++;
+        }
+    }
+}
+
+
+void nes_run(nes_t* nes){
+    // nes_printf("mapper:%03d\n",nes->nes_rom.mapper_number);
+    // nes_printf("prg_rom_size:%d*16kb\n",nes->nes_rom.prg_rom_size);
+    // nes_printf("chr_rom_size:%d*8kb\n",nes->nes_rom.chr_rom_size);
+    nes_cpu_reset(nes);
+    // nes->nes_cpu.PC = 0xC000;
+    // printf("nes->nes_cpu.PC %02X",nes->nes_cpu.PC);
+    uint64_t frame_cnt = 0;
+    uint16_t scanline = 0;
+
+    while (!nes->nes_quit){
+        frame_cnt++;
+        nes_palette_generate(nes);
+
+        if (nes->nes_ppu.MASK_b == 0){
+#if (NES_RAM_LACK == 1)
+            for (size_t i = 0; i < NES_HEIGHT * NES_WIDTH / 2; i++){
+                nes->nes_draw_data[i] = nes->nes_ppu.background_palette[0];
+            }
+#else
+            for (size_t i = 0; i < NES_HEIGHT * NES_WIDTH; i++){
+                nes->nes_draw_data[i] = nes->nes_ppu.background_palette[0];
+            }
+#endif
+        }
+        
+        for(scanline = 0; scanline < NES_HEIGHT; scanline++) { // 0-239 Visible frame
+            if (nes->nes_ppu.MASK_b){
+#if (NES_RAM_LACK == 1)
+                nes_render_background_line(nes,scanline,nes->nes_draw_data + scanline%(NES_HEIGHT/2) * NES_WIDTH);
+#else
+                nes_render_background_line(nes,scanline,nes->nes_draw_data + scanline * NES_WIDTH);
+#endif
+            }
+            if (nes->nes_ppu.MASK_s){
+#if (NES_RAM_LACK == 1)
+                nes_render_sprite_line(nes,scanline,nes->nes_draw_data + scanline%(NES_HEIGHT/2) * NES_WIDTH);
+#else
+                nes_render_sprite_line(nes,scanline,nes->nes_draw_data + scanline * NES_WIDTH);
+#endif
+            }
+            nes_opcode(nes,NES_PPU_CPU_CLOCKS);
+            if (nes->nes_ppu.MASK_b){
+                if ((nes->nes_ppu.v.fine_y) < 7) {
+                    nes->nes_ppu.v.fine_y++;
+                }else {
+                    nes->nes_ppu.v.fine_y = 0;
+                    uint8_t y = (uint8_t)(nes->nes_ppu.v.coarse_y);
+                    if (y == 29) {
+                        y = 0;
+                        nes->nes_ppu.v_reg ^= 0x0800;
+                    }else if (y == 31) {
+                        y = 0;
+                    }else {
+                        y++;
+                    }
+                    nes->nes_ppu.v.coarse_y = y;
+                }
+                // v: ....A.. ...BCDEF <- t: ....A.. ...BCDEF
+                nes->nes_ppu.v_reg = (nes->nes_ppu.v_reg & (uint16_t)0xFBE0) | (nes->nes_ppu.t_reg & (uint16_t)0x041F);
+            }
+            
+#if (NES_RAM_LACK == 1)
+            if((frame_cnt % (NES_FRAME_SKIP+1))==0){
+                if (scanline == NES_HEIGHT/2-1){
+                    nes_draw(0, 0, NES_WIDTH-1, NES_HEIGHT/2-1, nes->nes_draw_data);
+                }else if(scanline == NES_HEIGHT-1){
+                    nes_draw(0, NES_HEIGHT/2, NES_WIDTH-1, NES_HEIGHT-1, nes->nes_draw_data);
+                }
+            }
+#endif
+        }
+#if (NES_RAM_LACK == 0)
+        if((frame_cnt % (NES_FRAME_SKIP+1))==0){
+            nes_draw(0, 0, NES_WIDTH-1, NES_HEIGHT-1, nes->nes_draw_data);
+        }
+#endif
+        nes_opcode(nes,NES_PPU_CPU_CLOCKS); //240 Post-render line
+
+        nes->nes_ppu.STATUS_V = 1;// Set VBlank flag
+        if (nes->nes_ppu.CTRL_V) {
+            nes_nmi(nes);
+        }
+        for(; scanline < 261; scanline++){ // 241-260行 垂直空白行 x20
+            nes_opcode(nes,NES_PPU_CPU_CLOCKS);
+        }
+
+        nes->nes_ppu.ppu_status &= 0x10; // Clear:VBlank,Sprite 0,Overflow
+        nes_opcode(nes,NES_PPU_CPU_CLOCKS); // 261 Pre-render line
+        //do more
+        if (nes->nes_ppu.MASK_b){
+            // v: GHIA.BC DEF..... <- t: GHIA.BC DEF.....
+            nes->nes_ppu.v_reg = (nes->nes_ppu.v_reg & (uint16_t)0x841F) | (nes->nes_ppu.t_reg & (uint16_t)0x7BE0);
+        }
+        // nes_frame();
+    }
+}
+

+ 36 - 0
components/nes/src/nes_apu.c

@@ -0,0 +1,36 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+uint8_t nes_read_apu_register(nes_t *nes,uint16_t address){
+    uint8_t data = 0;
+    nes_printf("nes_read apu %04X %02X\n",address,data);
+    return data;
+}
+
+void nes_write_apu_register(nes_t* nes,uint16_t address,uint8_t data){
+    nes_printf("nes_write apu %04X %02X\n",address,data);
+}

+ 1384 - 0
components/nes/src/nes_cpu.c

@@ -0,0 +1,1384 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+typedef struct {
+    void (*instruction)(nes_t* nes);      //instructions 
+    uint16_t (*addressing_mode)(nes_t* nes);  //addressing_mode
+    uint8_t	ticks;
+} nes_opcode_t;
+
+static nes_opcode_t nes_opcode_table[256];
+
+static inline uint8_t nes_read_joypad(nes_t* nes,uint16_t address){
+    uint8_t state = 0;
+    if (address == 0x4016){
+        state = (nes->nes_cpu.joypad.joypad & (0x8000 >> (nes->nes_cpu.joypad.offset1 & nes->nes_cpu.joypad.mask))) ? 1 : 0;
+        nes->nes_cpu.joypad.offset1++;
+    }else if(address == 0x4017){
+        state = (nes->nes_cpu.joypad.joypad & (0x80 >> (nes->nes_cpu.joypad.offset2 & nes->nes_cpu.joypad.mask))) ? 1 : 0;
+        nes->nes_cpu.joypad.offset2++;
+    }
+    // nes_printf("nes_read joypad %04X %d %02X %d\n",address,nes->nes_cpu.joypad.mask,nes->nes_cpu.joypad.joypad,state);
+    return state;
+}
+
+static inline void nes_write_joypad(nes_t* nes,uint8_t data){
+    nes->nes_cpu.joypad.mask = (data & 1)?0x00:0x07;
+    if (data & 1)
+        nes->nes_cpu.joypad.offset1 = nes->nes_cpu.joypad.offset2 = 0;
+    // nes_printf("nes_write joypad %04X %02X %d\n",address,data,nes->nes_cpu.joypad.mask);
+}
+
+static uint8_t nes_read_cpu(nes_t* nes,uint16_t address){
+    switch (address >> 13){
+        case 0://$0000-$1FFF 2KB internal RAM + Mirrors of $0000-$07FF
+            return nes->nes_cpu.cpu_ram[address & (uint16_t)0x07ff];
+        case 1://$2000-$3FFF NES PPU registers + Mirrors of $2000-2007 (repeats every 8 bytes)
+            return nes_read_ppu_register(nes,address);
+        case 2://$4000-$5FFF NES APU and I/O registers
+            if (address == 0x4016 || address == 0x4017)
+                return nes_read_joypad(nes, address);
+            else if (address < 0x4016){
+                return nes_read_apu_register(nes, address);
+            }else {
+                nes_printf("nes_read address %04X not sPport\n",address);
+            }
+            return 0;
+        case 3://$6000-$7FFF SRAM
+#if (NES_USE_SRAM == 1)
+            return nes->nes_rom.sram[address & (uint16_t)0x1fff];
+#endif
+            return 0;
+        case 4: case 5: case 6: case 7:
+            return nes->nes_cpu.prg_banks[(address >> 13)-4][address & (uint16_t)0x1fff];
+        default :
+            nes_printf("nes_read_cpu error %04X\n",address);
+            return -1;
+    }
+    return 0;
+}
+
+static inline const uint8_t* nes_get_dma_address(nes_t* nes,uint8_t data) {
+    switch (data >> 5)
+    {
+    default:
+    case 1:
+        // PPU寄存器
+        nes_printf("PPU REG!");
+    case 2:
+        // 扩展区
+        nes_printf("TODO");
+    case 0:
+        // 系统内存
+        return nes->nes_cpu.cpu_ram + ((uint16_t)(data & 0x07) << 8);
+    // case 3:
+    //     // 存档 SRAM区
+    //     return famicom->save_ram + ((uint16_t)(data & 0x1f) << 8);
+    case 4: case 5: case 6: case 7:
+        // 高一位为1, [$8000, $10000) 程序PRG-ROM区
+        return nes->nes_cpu.prg_banks[(data >> 4) & 0x3] + ((uint16_t)(data & 0x0f) << 8);
+    }
+}
+
+static void nes_write_cpu(nes_t* nes,uint16_t address, uint8_t data){
+    switch (address >> 13){
+        case 0://$0000-$1FFF 2KB internal RAM + Mirrors of $0000-$07FF
+            nes->nes_cpu.cpu_ram[address & (uint16_t)0x07ff] = data;
+            return;
+        case 1://$2000-$3FFF NES PPU registers + Mirrors of $2000-2007 (repeats every 8 bytes)
+            nes_write_ppu_register(nes,address, data);
+            return;
+        case 2://$4000-$5FFF NES APU and I/O registers
+            if (address == 0x4016 || address == 0x4017)
+                nes_write_joypad(nes,data);
+            else if (address == 0x4014){
+                // nes_printf("nes_write DMA %04X %02X\n",address,data);
+                if (nes->nes_ppu.oam_addr) {
+                    uint8_t* dst = nes->nes_ppu.oam_data;
+                    const uint8_t len = nes->nes_ppu.oam_addr;
+                    const uint8_t* src = nes_get_dma_address(nes,data);
+                    memcpy(dst, src + len, len);
+                    memcpy(dst + len, src, 256 - len);
+                } else {
+                    memcpy(nes->nes_ppu.oam_data, nes_get_dma_address(nes,data), 256);
+                }
+                nes->nes_cpu.cycles += 513;
+                nes->nes_cpu.cycles += nes->nes_cpu.cycles & 1;
+            }else if (address < 0x4016){
+                nes_write_apu_register(nes, address,data);
+            }else {
+                nes_printf("nes_write address %04X not sPport\n",address);
+            }
+            return;
+        case 3://$6000-$7FFF SRAM
+#if (NES_USE_SRAM == 1)
+            nes->nes_rom.sram[address & (uint16_t)0x1fff] = data;
+#endif
+            return;
+        case 4: case 5: case 6: case 7:
+            nes->nes_mapper.mapper_write(nes, address, data);
+            // nes->nes_cpu.prg_banks[(address >> 13)-4][address & (uint16_t)0x1fff] = data;
+            return;
+        default :
+            nes_printf("nes_write_ppu_register error %04X %02X\n",address,data);
+            return;
+    }
+}
+
+#define NES_PUSH(nes,a)     nes_write_cpu(nes,0x100 + nes->nes_cpu.SP--,(a))
+#define NES_PUSHW(nes,a)    NES_PUSH(nes, (a) >> 8 ); NES_PUSH(nes, (a) & 0xff)
+
+#define NES_POP(nes)        nes_read_cpu(nes, 0x100 + ++(nes->nes_cpu.SP))
+
+#define NES_CHECK_N(x)      nes->nes_cpu.N = ((uint8_t)(x) & 0x80)>>7
+#define NES_CHECK_Z(x)      nes->nes_cpu.Z = ((uint8_t)(x) == 0)
+
+
+/* Adressing modes */
+
+//#Immediate
+static uint16_t nes_imm(nes_t* nes){
+    return nes->nes_cpu.PC++;
+}
+
+static uint16_t nes_rel(nes_t* nes){
+    const uint8_t data = nes_read_cpu(nes,nes->nes_cpu.PC++);
+    const uint16_t address = nes->nes_cpu.PC + (int8_t)data;
+    return address;
+}
+
+//ABS
+static uint16_t nes_abs(nes_t* nes){
+    uint16_t address = nes_read_cpu(nes,nes->nes_cpu.PC)|(uint16_t)nes_read_cpu(nes,nes->nes_cpu.PC + 1) << 8;
+    nes->nes_cpu.PC += 2;
+    return address;
+}
+
+//ABX
+static uint16_t nes_abx(nes_t* nes){
+    uint16_t address = nes_read_cpu(nes,nes->nes_cpu.PC)|(uint16_t)nes_read_cpu(nes,nes->nes_cpu.PC + 1) << 8;
+    nes->nes_cpu.PC += 2;
+    if (nes_opcode_table[nes->nes_cpu.opcode].ticks==4){
+        if ((address>>8) != ((address+nes->nes_cpu.X)>>8))nes->nes_cpu.cycles++;
+    }
+    return address + nes->nes_cpu.X;
+}
+
+//ABY
+static uint16_t nes_aby(nes_t* nes){
+    uint16_t address = nes_read_cpu(nes,nes->nes_cpu.PC)|(uint16_t)nes_read_cpu(nes,nes->nes_cpu.PC + 1) << 8;
+    nes->nes_cpu.PC += 2;
+    if (nes_opcode_table[nes->nes_cpu.opcode].ticks==4){
+        if ((address>>8) != ((address+nes->nes_cpu.Y)>>8))nes->nes_cpu.cycles++;
+    }
+    return address + nes->nes_cpu.Y;
+}
+
+static uint16_t nes_zp(nes_t* nes){
+    return (uint16_t)nes_read_cpu(nes,nes->nes_cpu.PC++);
+}
+
+static uint16_t nes_zpx(nes_t* nes){
+    uint16_t address = (uint16_t)nes_read_cpu(nes,nes->nes_cpu.PC++) + nes->nes_cpu.X;
+    return address & 0xFF;
+}
+
+static uint16_t nes_zpy(nes_t* nes){
+    uint16_t address = nes_read_cpu(nes,nes->nes_cpu.PC++) + nes->nes_cpu.Y;
+    return address & 0xFF;
+}
+
+static uint16_t nes_izx(nes_t* nes){
+    uint8_t address = nes_read_cpu(nes,nes->nes_cpu.PC++);
+    address += nes->nes_cpu.X;
+    return nes_read_cpu(nes,address)|(uint16_t)nes_read_cpu(nes,(uint8_t)(address + 1)) << 8;
+}
+
+static uint16_t nes_izy(nes_t* nes){
+    uint8_t value = nes_read_cpu(nes,nes->nes_cpu.PC++);
+    uint16_t address = nes_read_cpu(nes,value)|(uint16_t)nes_read_cpu(nes,(uint8_t)(value + 1)) << 8;
+    if (nes_opcode_table[nes->nes_cpu.opcode].ticks==5){
+        if ((address>>8) != ((address+nes->nes_cpu.Y)>>8))nes->nes_cpu.cycles++;
+    }
+    return address + nes->nes_cpu.Y;
+}
+
+static uint16_t nes_ind(nes_t* nes){
+    uint16_t value1 = nes_read_cpu(nes,nes->nes_cpu.PC)|(uint16_t)nes_read_cpu(nes,(nes->nes_cpu.PC + 1)) << 8;
+    // 6502 BUG
+    const uint16_t value2 = (value1 & (uint16_t)0xFF00)| ((value1 + 1) & (uint16_t)0x00FF);
+
+    uint16_t address = nes_read_cpu(nes,value1)|(uint16_t)nes_read_cpu(nes,value2) << 8;
+    nes->nes_cpu.PC+=2;
+    return address;
+}
+
+
+/* Logical and arithmetic commands: */
+
+/* 
+    and accumulator A<--A&M NZ
+    A := A & {adr}
+    N  V  U  B  D  I  Z  C
+    *                 *
+*/
+static void nes_and(nes_t* nes){
+    nes->nes_cpu.A &= nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+/* 
+    or accumulator A<--A|M NZ
+    A :=A or {adr}
+    N  V  U  B  D  I  Z  C
+    *                 *
+*/
+static void nes_ora(nes_t* nes){
+    nes->nes_cpu.A |= nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+/* 
+    exclusive-or accumulator A<--A^M NZ
+    A := A exor {adr}
+    N  V  U  B  D  I  Z  C
+    *                 *
+*/
+static void nes_eor(nes_t* nes){
+    nes->nes_cpu.A ^= nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// A:=A+{adr}
+// N  V  U  B  D  I  Z  C
+// *  *              *  *
+static void nes_adc(nes_t* nes){
+    const uint8_t src = nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    const uint16_t result16 = nes->nes_cpu.A + src + nes->nes_cpu.C;
+    if (result16 >> 8)nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    const uint8_t result8 = (uint8_t)result16;
+    if (!((nes->nes_cpu.A ^ src) & 0x80) && ((nes->nes_cpu.A ^ result8) & 0x80)) nes->nes_cpu.V = 1;
+    else nes->nes_cpu.V = 0;
+    nes->nes_cpu.A = result8;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// A:=A-{adr}
+
+// EB
+// SBC (SBC) [SBC]
+// The same as the legal opcode $E9 (SBC #byte)
+// Status flags: N,V,Z,C
+
+// N  V  U  B  D  I  Z  C
+// *  *              *  *
+static void nes_sbc(nes_t* nes){
+    const uint8_t src = nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    const uint16_t result16 = nes->nes_cpu.A - src - !nes->nes_cpu.C;
+    if (!(result16 >> 8))nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    const uint8_t result8 = (uint8_t)result16;
+    if (((nes->nes_cpu.A ^ src) & 0x80) && ((nes->nes_cpu.A ^ result8) & 0x80)) nes->nes_cpu.V = 1;
+    else nes->nes_cpu.V = 0;
+    nes->nes_cpu.A = result8;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// A-{adr}
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_cmp(nes_t* nes){
+    const uint16_t value = (uint16_t)nes->nes_cpu.A - (uint16_t)nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    if (!(value & 0x8000))nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    NES_CHECK_N((uint8_t)value);
+    NES_CHECK_Z((uint8_t)value);
+}
+
+// X-{adr}
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_cpx(nes_t* nes){
+    const uint16_t value = (uint16_t)nes->nes_cpu.X - (uint16_t)nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    if (!(value & 0x8000))nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    NES_CHECK_N((uint8_t)value);
+    NES_CHECK_Z((uint8_t)value);
+}
+
+// Y-{adr}
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_cpy(nes_t* nes){
+    const uint16_t value = (uint16_t)nes->nes_cpu.Y - (uint16_t)nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    if (!(value & 0x8000))nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    NES_CHECK_N((uint8_t)value);
+    NES_CHECK_Z((uint8_t)value);
+}
+
+// {adr}:={adr}-1
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_dec(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t data = nes_read_cpu(nes,address);
+    data--;
+    nes_write_cpu(nes,address, data);
+    NES_CHECK_N(data);
+    NES_CHECK_Z(data);
+}
+
+// X:=X-1
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_dex(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    NES_CHECK_N(--nes->nes_cpu.X);
+    NES_CHECK_Z(nes->nes_cpu.X);
+}
+
+// Y:=Y-1
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_dey(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    NES_CHECK_N(--nes->nes_cpu.Y);
+    NES_CHECK_Z(nes->nes_cpu.Y);
+}
+
+// {adr}:={adr}+1
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_inc(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t data = nes_read_cpu(nes,address);
+    nes_write_cpu(nes,address,++data);
+    NES_CHECK_N(data);
+    NES_CHECK_Z(data);
+}
+
+// X:=X+1
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_inx(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    NES_CHECK_N(++nes->nes_cpu.X);
+    NES_CHECK_Z(nes->nes_cpu.X);
+}
+
+// Y:=Y+1
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_iny(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    NES_CHECK_N(++nes->nes_cpu.Y);
+    NES_CHECK_Z(nes->nes_cpu.Y);
+}
+
+// {adr}:={adr}*2
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_asl(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode){
+        uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+        uint8_t value = nes_read_cpu(nes,address);
+        if (value & 0x80)nes->nes_cpu.C = 1;
+        else nes->nes_cpu.C = 0;
+        value <<= 1;
+        nes_write_cpu(nes,address,value);
+        NES_CHECK_N(value);
+        NES_CHECK_Z(value);
+    }else{
+        if (nes->nes_cpu.A&0x80)nes->nes_cpu.C = 1;
+        else nes->nes_cpu.C = 0;
+        nes->nes_cpu.A <<= 1;
+        NES_CHECK_N(nes->nes_cpu.A);
+        NES_CHECK_Z(nes->nes_cpu.A);
+    }
+}
+
+// {adr}:={adr}*2+C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_rol(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode){
+        uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+        uint8_t saveflags=nes->nes_cpu.C;
+        uint8_t value = nes_read_cpu(nes,address);
+        nes->nes_cpu.P= (nes->nes_cpu.P & 0xfe) | ((value>>7) & 0x01);
+        value <<= 1;
+        value |= saveflags;
+        nes_write_cpu(nes,address,value);
+        NES_CHECK_N(value);
+        NES_CHECK_Z(value);
+    }else{
+        uint8_t saveflags=nes->nes_cpu.C;
+        nes->nes_cpu.P= (nes->nes_cpu.P & 0xfe) | ((nes->nes_cpu.A>>7) & 0x01);
+        nes->nes_cpu.A <<= 1;
+        nes->nes_cpu.A |= saveflags;
+        NES_CHECK_N(nes->nes_cpu.A);
+        NES_CHECK_Z(nes->nes_cpu.A);
+    }
+}
+
+// {adr}:={adr}/2
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_lsr(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode){
+        uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+        uint8_t value = nes_read_cpu(nes,address);
+        if (value & 1)nes->nes_cpu.C = 1;
+        else nes->nes_cpu.C = 0;
+        value >>= 1;
+        nes_write_cpu(nes,address,value);
+        NES_CHECK_N(value);
+        NES_CHECK_Z(value);
+    }else{
+        if (nes->nes_cpu.A & 1)nes->nes_cpu.C = 1;
+        else nes->nes_cpu.C = 0;
+        nes->nes_cpu.A >>= 1;
+        NES_CHECK_N(nes->nes_cpu.A);
+        NES_CHECK_Z(nes->nes_cpu.A);
+    }
+}
+
+// {adr}:={adr}/2+C*128
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_ror(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) {
+        uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+        uint8_t saveflags=nes->nes_cpu.C;
+        uint8_t value = nes_read_cpu(nes,address);
+        nes->nes_cpu.P= (nes->nes_cpu.P & 0xfe) | (value & 0x01);
+        value >>= 1;
+        if (saveflags) value |= 0x80;
+        nes_write_cpu(nes,address,value);
+        NES_CHECK_N(value);
+        NES_CHECK_Z(value);  
+    }else{
+        uint8_t saveflags=nes->nes_cpu.C;
+        nes->nes_cpu.P= (nes->nes_cpu.P & 0xfe) | (nes->nes_cpu.A & 0x01);
+        nes->nes_cpu.A >>= 1;
+        if (saveflags) nes->nes_cpu.A |= 0x80;
+        NES_CHECK_N(nes->nes_cpu.A);
+        NES_CHECK_Z(nes->nes_cpu.A);
+    }
+}
+
+/* Move commands: */
+
+// A:={adr}
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_lda(nes_t* nes){
+    nes->nes_cpu.A = nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// {adr}:=A
+static void nes_sta(nes_t* nes){
+    nes_write_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes),nes->nes_cpu.A);
+}
+
+// X:={adr}
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_ldx(nes_t* nes){
+    nes->nes_cpu.X = nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    NES_CHECK_N(nes->nes_cpu.X);
+    NES_CHECK_Z(nes->nes_cpu.X);
+}
+
+// {adr}:=X
+static void nes_stx(nes_t* nes){
+    nes_write_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes),nes->nes_cpu.X);
+}
+
+// Y:={adr}
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_ldy(nes_t* nes){
+    nes->nes_cpu.Y = nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    NES_CHECK_N(nes->nes_cpu.Y);
+    NES_CHECK_Z(nes->nes_cpu.Y);
+}
+
+// {adr}:=Y
+static void nes_sty(nes_t* nes){
+    nes_write_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes),nes->nes_cpu.Y);
+}
+
+// X:=A
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_tax(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.X=nes->nes_cpu.A;
+    NES_CHECK_N(nes->nes_cpu.X);
+    NES_CHECK_Z(nes->nes_cpu.X);
+}
+
+// A:=X
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_txa(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.A=nes->nes_cpu.X;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// Y:=A
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_tay(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.Y=nes->nes_cpu.A;
+    NES_CHECK_N(nes->nes_cpu.Y);
+    NES_CHECK_Z(nes->nes_cpu.Y);
+}
+
+// A:=Y
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_tya(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.A=nes->nes_cpu.Y;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// X:=S
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_tsx(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.X=nes->nes_cpu.SP;
+    NES_CHECK_N(nes->nes_cpu.X);
+    NES_CHECK_Z(nes->nes_cpu.X);
+}
+
+// S:=X
+static void nes_txs(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.SP=nes->nes_cpu.X;
+}
+
+// A:=+(S)
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_pla(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.A = NES_POP(nes);
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// (S)-:=A
+static void nes_pha(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    NES_PUSH(nes,nes->nes_cpu.A);
+}
+
+// P:=+(S)
+// N  V  U  B  D  I  Z  C
+// *  *        *  *  *  *
+static void nes_plp(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.P = NES_POP(nes);
+    // nes->nes_cpu.B=0;
+}
+
+// (S)-:=P
+static void nes_php(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    NES_PUSH(nes,nes->nes_cpu.P);
+}
+
+// Jump/Flag commands:
+static inline void nes_branch(nes_t* nes) {
+    const uint16_t pc_old = nes->nes_cpu.PC;
+    nes->nes_cpu.PC = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.cycles++;
+    nes->nes_cpu.cycles += (nes->nes_cpu.PC ^ pc_old) >> 8 & 1;
+}
+
+// branch on N=0
+static void nes_bpl(nes_t* nes){
+    if (nes->nes_cpu.N==0){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// branch on N=1
+static void nes_bmi(nes_t* nes){
+    if (nes->nes_cpu.N){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// branch on V=0
+static void nes_bvc(nes_t* nes){
+    if (nes->nes_cpu.V==0){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// branch on V=1
+static void nes_bvs(nes_t* nes){
+    if (nes->nes_cpu.V){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// branch on C=0
+static void nes_bcc(nes_t* nes){
+    if (nes->nes_cpu.C==0){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// branch on C=1
+static void nes_bcs(nes_t* nes){
+    if (nes->nes_cpu.C){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// branch on Z=0
+static void nes_bne(nes_t* nes){
+    if (nes->nes_cpu.Z==0){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// branch on Z=1
+static void nes_beq(nes_t* nes){
+    if (nes->nes_cpu.Z){
+        nes_branch(nes);
+    } else nes->nes_cpu.PC++;
+}
+
+// (S)-:=PC,P PC:=($FFFE)
+// N  V  U  B  D  I  Z  C
+//          1     1
+static void nes_brk(nes_t* nes){
+    nes->nes_cpu.PC ++;
+    if (nes->nes_cpu.I==0){
+        NES_PUSHW(nes,nes->nes_cpu.PC-1);
+        NES_PUSH(nes,nes->nes_cpu.P);
+        // nes->nes_cpu.B = 1;
+        nes->nes_cpu.I = 1;
+        nes->nes_cpu.PC = nes_read_cpu(nes,NES_VERCTOR_IRQBRK)|(uint16_t)nes_read_cpu(nes,NES_VERCTOR_IRQBRK + 1) << 8;
+    }
+}
+
+// P,PC:=+(S)
+// N  V  U  B  D  I  Z  C
+// *  *        *  *  *  *
+static void nes_rti(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.P = NES_POP(nes);
+    nes->nes_cpu.U = 1;
+    nes->nes_cpu.B = 0;
+    nes->nes_cpu.PC = (uint16_t)NES_POP(nes);
+    nes->nes_cpu.PC |= (uint16_t)NES_POP(nes) << 8;
+}
+
+// (S)-:=PC PC:={adr}
+static void nes_jsr(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    NES_PUSHW(nes,nes->nes_cpu.PC-1);
+    nes->nes_cpu.PC = address;
+}
+
+// PC:=+(S)
+static void nes_rts(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.PC = (uint16_t)NES_POP(nes);
+    nes->nes_cpu.PC |= (uint16_t)NES_POP(nes) << 8;
+    nes->nes_cpu.PC++;
+}
+
+// PC:={adr}
+static void nes_jmp(nes_t* nes){
+    nes->nes_cpu.PC=nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// N:=b7 V:=b6 Z:=A&{adr}
+// N  V  U  B  D  I  Z  C
+// *  *              *  
+static void nes_bit(nes_t* nes){
+    const uint8_t value = nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    NES_CHECK_Z(value & nes->nes_cpu.A);
+    if (value & (uint8_t)(1 << 6)) nes->nes_cpu.V = 1;
+    else nes->nes_cpu.V = 0;
+    NES_CHECK_N(value);
+}
+
+// C:=0
+// N  V  U  B  D  I  Z  C
+//                      0
+static void nes_clc(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.C=0;
+}
+
+// C:=1
+// N  V  U  B  D  I  Z  C
+//                      1
+static void nes_sec(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.C=1;
+}
+
+// D:=0
+// N  V  U  B  D  I  Z  C
+//             0         
+static void nes_cld(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.D=0;
+}
+
+// D:=1
+// N  V  U  B  D  I  Z  C
+//             1         
+static void nes_sed(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.D=1;
+}
+
+// I:=0
+// N  V  U  B  D  I  Z  C
+//                0      
+static void nes_cli(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.I=0;
+}
+
+// I:=1
+// N  V  U  B  D  I  Z  C
+//                1      
+static void nes_sei(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.I=1;
+}
+
+// V:=0
+// N  V  U  B  D  I  Z  C
+//    0                  
+static void nes_clv(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    nes->nes_cpu.V=0;
+}
+
+// DOP (NOP) [SKB] TOP (NOP) [SKW]
+// No operation . The argument has no signifi-cance. Status
+// flags: -
+static void nes_nop(nes_t* nes){
+    if (nes_opcode_table[nes->nes_cpu.opcode].addressing_mode) nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+
+// Illegal opcodes:
+
+// {adr}:={adr}*2 A:=A or {adr}	
+// SLO (SLO) [ASO]
+// Shift left one bit in memory, then OR accumulator with memory. =
+// Status flags: N,Z,C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_slo(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t data = nes_read_cpu(nes,address);
+    if (data & 0x80)nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    data <<= 1;
+    nes_write_cpu(nes,address,data);
+
+    nes->nes_cpu.A |= data;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// {adr}:={adr}rol A:=A and {adr}
+// RLA (RLA) [RLA]
+// Rotate one bit left in memory, then AND accumulator with memory. Status
+// flags: N,Z,C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_rla(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t saveflags=nes->nes_cpu.C;
+    uint8_t value = nes_read_cpu(nes,address);
+    nes->nes_cpu.P= (nes->nes_cpu.P & 0xfe) | ((value>>7) & 0x01);
+    value <<= 1;
+    value |= saveflags;
+    nes_write_cpu(nes,address,value);
+
+    nes->nes_cpu.A &= value;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// {adr}:={adr}/2 A:=A exor {adr}
+// SRE (SRE) [LSE]
+// Shift right one bit in memory, then EOR accumulator with memory. Status
+// flags: N,Z,C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_sre(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t data = nes_read_cpu(nes,address);
+    if (data & 1)nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    data >>= 1;
+    nes_write_cpu(nes,address,data);
+
+    nes->nes_cpu.A ^= data;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// {adr}:={adr}ror A:=A adc {adr}
+// RRA (RRA) [RRA]
+// Rotate one bit right in memory, then add memory to accumulator (with
+// carry).
+// Status flags: N,V,Z,C
+// N  V  U  B  D  I  Z  C
+// *  *              *  *
+static void nes_rra(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t saveflags=nes->nes_cpu.C;
+    uint8_t value = nes_read_cpu(nes,address);
+    nes->nes_cpu.P= (nes->nes_cpu.P & 0xfe) | (value & 0x01);
+    value >>= 1;
+    if (saveflags) value |= 0x80;
+    nes_write_cpu(nes,address,value);
+
+    const uint16_t result16 = nes->nes_cpu.A + value + nes->nes_cpu.C;
+    if (result16 >> 8)nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    const uint8_t result8 = (uint8_t)result16;
+    if (!((nes->nes_cpu.A ^ value) & 0x80) && ((nes->nes_cpu.A ^ result8) & 0x80)) nes->nes_cpu.V = 1;
+    else nes->nes_cpu.V = 0;
+    nes->nes_cpu.A = result8;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// {adr}:=A&X
+// AAX (SAX) [AXS]
+// AND X register with accumulator and store result in memory. Status
+// flags: N,Z
+
+static void nes_sax(nes_t* nes){
+    nes_write_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes),nes->nes_cpu.A & nes->nes_cpu.X);
+}
+
+// A,X:={adr}
+
+// AB
+// ATX (LXA) [OAL]
+// AND byte with accumulator, then transfer accumulator to X register.
+// Status flags: N,Z
+
+// A7
+// LAX (LAX) [LAX]
+// Load accumulator and X register with memory.
+// Status flags: N,Z
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_lax(nes_t* nes){
+    nes->nes_cpu.A = nes_read_cpu(nes,nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes));
+    nes->nes_cpu.X = nes->nes_cpu.A;
+    NES_CHECK_N(nes->nes_cpu.A);
+    NES_CHECK_Z(nes->nes_cpu.A);
+}
+
+// {adr}:={adr}-1 A-{adr}
+// DCP (DCP) [DCM]
+// Subtract 1 from memory (without borrow).
+// Status flags: C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_dcp(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t data = nes_read_cpu(nes,address);
+    data--;
+    nes_write_cpu(nes,address,data);
+    const uint16_t result16 = (uint16_t)nes->nes_cpu.A - (uint16_t)data;
+
+    if (!(result16 & (uint16_t)0x8000))nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+
+    NES_CHECK_N((uint8_t)result16);
+    NES_CHECK_Z((uint8_t)result16);
+}
+
+// {adr}:={adr}+1 A:=A-{adr}
+// ISC (ISB) [INS]
+// Increase memory by one, then subtract memory from accu-mulator (with
+// borrow). Status flags: N,V,Z,C
+// N  V  U  B  D  I  Z  C
+// *  *              *  *
+static void nes_isc(nes_t* nes){
+    uint16_t address = nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+    uint8_t data = nes_read_cpu(nes,address);
+    data++;
+    nes_write_cpu(nes,address,data);
+
+    const uint16_t result16 = nes->nes_cpu.A - data - !nes->nes_cpu.C;
+    if (!(result16 >> 8))nes->nes_cpu.C = 1;
+    else nes->nes_cpu.C = 0;
+    const uint8_t result8 = (uint8_t)result16;
+    if (((nes->nes_cpu.A ^ data) & 0x80) && ((nes->nes_cpu.A ^ result8) & 0x80)) nes->nes_cpu.V = 1;
+    else nes->nes_cpu.V = 0;
+    nes->nes_cpu.A = result8;
+    NES_CHECK_Z(nes->nes_cpu.A);
+    NES_CHECK_N(nes->nes_cpu.A);
+}
+
+// A:=A&#{imm}
+// AAC (ANC) [ANC]
+// AND byte with accumulator. If result is negative then carry is set.
+// Status flags: N,Z,C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_anc(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// A:=(A&#{imm})/2
+// ASR (ASR) [ALR]
+// AND byte with accumulator, then shift right one bit in accumu-lator.
+// Status flags: N,Z,C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_alr(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// A:=(A&#{imm})/2
+// ARR (ARR) [ARR]
+// AND byte with accumulator, then rotate one bit right in accu-mulator and
+// check bit 5 and 6:
+// If both bits are 1: set C, clear V.
+// If both bits are 0: clear C and V.
+// If only bit 5 is 1: set V, clear C.
+// If only bit 6 is 1: set C and V.
+// Status flags: N,V,Z,C
+// alr
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+// arr
+// N  V  U  B  D  I  Z  C
+// *  *              *  *
+static void nes_arr(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// A:=X&#{imm}
+// XAA (ANE) [XAA]
+// Exact operation unknown. Read the referenced documents for more
+// information and observations.
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_xaa(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// X:=A&X-#{imm}
+// AXS (SBX) [SAX]
+// AND X register with accumulator and store result in X regis-ter, then
+// subtract byte from X register (without borrow).
+// Status flags: N,Z,C
+// N  V  U  B  D  I  Z  C
+// *                 *  *
+static void nes_axs(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+
+// {adr}:=A&X&H
+// AXA (SHA) [AXA]
+// AND X register with accumulator then AND result with 7 and store in
+// memory. Status flags: -
+static void nes_ahx(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// {adr}:=Y&H
+// SYA (SHY) [SAY]
+// AND Y register with the high byte of the target address of the argument
+// + 1. Store the result in memory.
+// M =3D Y AND HIGH(arg) + 1
+// Status flags: -
+static void nes_shy(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// {adr}:=X&H
+// SXA (SHX) [XAS]
+// AND X register with the high byte of the target address of the argument
+// + 1. Store the result in memory.
+// M =3D X AND HIGH(arg) + 1
+// Status flags: -
+static void nes_shx(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// S:=A&X {adr}:=S&H
+// XAS (SHS) [TAS]
+// AND X register with accumulator and store result in stack pointer, then
+// AND stack pointer with the high byte of the target address of the
+// argument + 1. Store result in memory.
+// S =3D X AND A, M =3D S AND HIGH(arg) + 1
+// Status flags: -
+static void nes_tas(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// A,X,S:={adr}&S
+// LAR (LAE) [LAS]
+// AND memory with stack pointer, transfer result to accu-mulator, X
+// register and stack pointer.
+// Status flags: N,Z
+// N  V  U  B  D  I  Z  C
+// *                 *  
+static void nes_las(nes_t* nes){
+    nes_opcode_table[nes->nes_cpu.opcode].addressing_mode(nes);
+}
+
+// KIL (JAM) [HLT]
+// Stop program counter (processor lock P).
+// Status flags: -
+
+void nes_nmi(nes_t* nes){
+    NES_PUSHW(nes,nes->nes_cpu.PC);
+    NES_PUSH(nes,nes->nes_cpu.P);
+    nes->nes_cpu.I = 1;
+    nes->nes_cpu.PC = nes_read_cpu(nes,NES_VERCTOR_NMI)|(uint16_t)nes_read_cpu(nes,NES_VERCTOR_NMI + 1) << 8;
+    nes->nes_cpu.cycles += 7;
+}
+
+void nes_cpu_reset(nes_t* nes){
+    nes->nes_cpu.A = nes->nes_cpu.X = nes->nes_cpu.Y = nes->nes_cpu.P = 0;
+    nes->nes_cpu.U = 1;
+    // nes->nes_cpu.B = 1;
+    
+    nes->nes_cpu.P = 0x34;
+
+    nes->nes_cpu.SP = 0xFD;
+    nes->nes_cpu.PC = nes_read_cpu(nes,NES_VERCTOR_RESET)|(uint16_t)nes_read_cpu(nes,NES_VERCTOR_RESET + 1) << 8;
+    nes->nes_cpu.cycles = 7;
+}
+
+void nes_cpu_init(nes_t* nes){
+
+}
+
+static nes_opcode_t nes_opcode_table[] = {
+    {nes_brk,	NULL,	    7   },      // 0x00     BRK             7
+    {nes_ora,   nes_izx,    6   },      // 0x01     ORA     izx     6
+    {NULL,	    NULL,	    0   },      // 0x02     KIL
+    {nes_slo,	nes_izx,	8   },      // 0x03     SLO     izx     8
+    {nes_nop,	nes_zp,	    3   },      // 0x04     NOP     zp      3
+    {nes_ora,	nes_zp,	    3   },      // 0x05     ORA     zp      3
+    {nes_asl,	nes_zp,	    5   },      // 0x06     ASL     zp      5
+    {nes_slo,	nes_zp,	    5   },      // 0x07     SLO     zp      5
+    {nes_php,	NULL,	    3   },      // 0x08     PHP             3
+    {nes_ora,	nes_imm,	2   },      // 0x09     ORA     imm     2
+    {nes_asl,	NULL,	    2   },      // 0x0A     ASL             2
+    {nes_anc,	nes_imm,	2   },      // 0x0B     ANC     imm     2
+    {nes_nop,	nes_abs,	4   },      // 0x0C     NOP     abs     4
+    {nes_ora,	nes_abs,	4   },      // 0x0D     ORA     abs     4
+    {nes_asl,	nes_abs,	6   },      // 0x0E     ASL     abs     6
+    {nes_slo,	nes_abs,	6   },      // 0x0F     SLO     abs     6
+    {nes_bpl,	nes_rel,	2   },      // 0x10     BPL     rel     2*
+    {nes_ora,   nes_izy,    5   },      // 0x11     ORA     izy     5*
+    {NULL,      NULL,	    0   },      // 0x12     KIL
+    {nes_slo,	nes_izy,	8   },      // 0x13     SLO     izy     8
+    {nes_nop,	nes_zpx,	4   },      // 0x14     NOP     zpx     4
+    {nes_ora,	nes_zpx,	4   },      // 0x15     ORA     zpx     4
+    {nes_asl,	nes_zpx,	6   },      // 0x16     ASL     zpx     6
+    {nes_slo,	nes_zpx,	6   },      // 0x17     SLO     zpx     6
+    {nes_clc,	NULL,	    2   },      // 0x18     CLC             2
+    {nes_ora,	nes_aby,	4   },      // 0x19     ORA     aby     4*
+    {nes_nop,	NULL,	    2   },      // 0x1A     NOP             2
+    {nes_slo,	nes_aby,	7   },      // 0x1B     SLO     aby     7
+    {nes_nop,	nes_abx,	4   },      // 0x1C     NOP     abx     4*
+    {nes_ora,	nes_abx,	4   },      // 0x1D     ORA     abx     4*
+    {nes_asl,	nes_abx,	7   },      // 0x1E     ASL     abx     7
+    {nes_slo,	nes_abx,	7   },      // 0x1F     SLO     abx     7
+    {nes_jsr,	nes_abs,	6   },      // 0x20     JSR     abs     6
+    {nes_and,   nes_izx,    6   },      // 0x21     AND     izx     6
+    {NULL,      NULL,	    0   },      // 0x22     KIL
+    {nes_rla,	nes_izx,	8   },      // 0x23     RLA     izx     8
+    {nes_bit,	nes_zp,	    3   },      // 0x24     BIT     zp      3
+    {nes_and,	nes_zp,     3   },      // 0x25     AND     zp      3
+    {nes_rol,	nes_zp,     5   },      // 0x26     ROL     zp      5
+    {nes_rla,	nes_zp,     5   },      // 0x27     RLA     zp      5
+    {nes_plp,	NULL,	    4   },      // 0x28     PLP             4
+    {nes_and,	nes_imm,	2   },      // 0x29     AND     imm     2
+    {nes_rol,	NULL,	    2   },      // 0x2A     ROL             2
+    {nes_anc,	nes_imm,	2   },      // 0x2B     ANC     imm     2
+    {nes_bit,	nes_abs,	4   },      // 0x2C     BIT     abs     4
+    {nes_and,	nes_abs,	4   },      // 0x2D     AND     abs     4
+    {nes_rol,	nes_abs,	6   },      // 0x2E     ROL     abs     6
+    {nes_rla,	nes_abs,	6   },      // 0x2F     RLA     abs     6
+    {nes_bmi,	nes_rel,	2   },      // 0x30     BMI     rel     2*
+    {nes_and,   nes_izy,    5   },      // 0x31     AND     izy     5*
+    {NULL,      NULL,	    0   },      // 0x32     KIL
+    {nes_rla,	nes_izy,	8   },      // 0x33     RLA     izy     8
+    {nes_nop,	nes_zpx,	4   },      // 0x34     NOP     zpx     4
+    {nes_and,	nes_zpx,    4   },      // 0x35     AND     zpx     4
+    {nes_rol,	nes_zpx,    6   },      // 0x36     ROL     zpx     6
+    {nes_rla,	nes_zpx,    6   },      // 0x37     RLA     zpx     6
+    {nes_sec,	NULL,	    2   },      // 0x38     SEC             2
+    {nes_and,	nes_aby,	4   },      // 0x39     AND     aby     4*
+    {nes_nop,	NULL,	    2   },      // 0x3A     NOP             2
+    {nes_rla,	nes_aby,	7   },      // 0x3B     RLA     aby     7
+    {nes_nop,	nes_abx,	4   },      // 0x3C     NOP     abx     4*
+    {nes_and,	nes_abx,	4   },      // 0x3D     AND     abx     4*
+    {nes_rol,	nes_abx,	7   },      // 0x3E     ROL     abx     7
+    {nes_rla,	nes_abx,	7   },      // 0x3F     RLA     abx     7
+    {nes_rti,	NULL,	    6   },      // 0x40     RTI             6
+    {nes_eor,   nes_izx,    6   },      // 0x41     EOR     izx     6
+    {NULL,      NULL,	    0   },      // 0x42     KIL
+    {nes_sre,	nes_izx,	8   },      // 0x43     SRE     izx     8
+    {nes_nop,	nes_zp,	    3   },      // 0x44     NOP     zp      3
+    {nes_eor,	nes_zp,     3   },      // 0x45     EOR     zp      3
+    {nes_lsr,	nes_zp,     5   },      // 0x46     LSR     zp      5
+    {nes_sre,	nes_zp,     5   },      // 0x47     SRE     zp      5
+    {nes_pha,	NULL,	    3   },      // 0x48     PHA             3
+    {nes_eor,	nes_imm,	2   },      // 0x49     EOR     imm     2
+    {nes_lsr,	NULL,	    2   },      // 0x4A     LSR             2
+    {nes_alr,	nes_imm,	2   },      // 0x4B     ALR     imm     2
+    {nes_jmp,	nes_abs,	3   },      // 0x4C     JMP     abs     3
+    {nes_eor,	nes_abs,	4   },      // 0x4D     EOR     abs     4
+    {nes_lsr,	nes_abs,	6   },      // 0x4E     LSR     abs     6
+    {nes_sre,	nes_abs,	6   },      // 0x4F     SRE     abs     6
+    {nes_bvc,	nes_rel,	2   },      // 0x50     BVC     rel     2*
+    {nes_eor,   nes_izy,    5   },      // 0x51     EOR     izy     5*
+    {NULL,      NULL,	    0   },      // 0x52     KIL
+    {nes_sre,	nes_izy,	8   },      // 0x53     SRE     izy     8
+    {nes_nop,	nes_zpx,	4   },      // 0x54     NOP     zpx     4
+    {nes_eor,	nes_zpx,    4   },      // 0x55     EOR     zpx     4
+    {nes_lsr,	nes_zpx,    6   },      // 0x56     LSR     zpx     6
+    {nes_sre,	nes_zpx,    6   },      // 0x57     SRE     zpx     6
+    {nes_cli,	NULL,	    2   },      // 0x58     CLI             2
+    {nes_eor,	nes_aby,	4   },      // 0x59     EOR     aby     4*
+    {nes_nop,	NULL,	    2   },      // 0x5A     NOP             2
+    {nes_sre,	nes_aby,	7   },      // 0x5B     SRE     aby     7
+    {nes_nop,	nes_abx,	4   },      // 0x5C     NOP     abx     4*
+    {nes_eor,	nes_abx,	4   },      // 0x5D     EOR     abx     4*
+    {nes_lsr,	nes_abx,	7   },      // 0x5E     LSR     abx     7
+    {nes_sre,	nes_abx,	7   },      // 0x5F     SRE     abx     7
+    {nes_rts,	NULL,   	6   },      // 0x60     RTS             6
+    {nes_adc,   nes_izx,    6   },      // 0x61     ADC     izx     6
+    {NULL,      NULL,	    0   },      // 0x62     KIL
+    {nes_rra,	nes_izx,	8   },      // 0x63     RRA     izx     8
+    {nes_nop,	nes_zp,	    3   },      // 0x64     NOP     zp      3
+    {nes_adc,	nes_zp,     3   },      // 0x65     ADC     zp      3
+    {nes_ror,	nes_zp,     5   },      // 0x66     ROR     zp      5
+    {nes_rra,	nes_zp,     5   },      // 0x67     RRA     zp      5
+    {nes_pla,	NULL,	    4   },      // 0x68     PLA             4
+    {nes_adc,	nes_imm,	2   },      // 0x69     ADC     imm     2
+    {nes_ror,	NULL,	    2   },      // 0x6A     ROR             2
+    {nes_arr,	nes_imm,	2   },      // 0x6B     ARR     imm     2
+    {nes_jmp,	nes_ind,	5   },      // 0x6C     JMP     ind     5
+    {nes_adc,	nes_abs,	4   },      // 0x6D     ADC     abs     4
+    {nes_ror,	nes_abs,	6   },      // 0x6E     ROR     abs     6
+    {nes_rra,	nes_abs,	6   },      // 0x6F     RRA     abs     6
+    {nes_bvs,	nes_rel,   	2   },      // 0x70     BVS     rel     2*
+    {nes_adc,   nes_izy,    5   },      // 0x71     ADC     izy     5*
+    {NULL,      NULL,	    0   },      // 0x72     KIL
+    {nes_rra,	nes_izy,	8   },      // 0x73     RRA     izy     8
+    {nes_nop,	nes_zpx,	4   },      // 0x74     NOP     zpx     4
+    {nes_adc,	nes_zpx,    4   },      // 0x75     ADC     zpx     4
+    {nes_ror,	nes_zpx,    6   },      // 0x76     ROR     zpx     6
+    {nes_rra,	nes_zpx,    6   },      // 0x77     RRA     zpx     6
+    {nes_sei,	NULL,	    2   },      // 0x78     SEI             2
+    {nes_adc,	nes_aby,	4   },      // 0x79     ADC     aby     4*
+    {nes_nop,	NULL,	    2   },      // 0x7A     NOP             2
+    {nes_rra,	nes_aby,	7   },      // 0x7B     RRA     aby     7
+    {nes_nop,	nes_abx,	4   },      // 0x7C     NOP     abx     4*
+    {nes_adc,	nes_abx,	4   },      // 0x7D     ADC     abx     4*
+    {nes_ror,	nes_abx,	7   },      // 0x7E     ROR     abx     7
+    {nes_rra,	nes_abx,	7   },      // 0x7F     RRA     abx     7
+    {nes_nop,	nes_imm,   	2   },      // 0x80     NOP     imm     2
+    {nes_sta,   nes_izx,    6   },      // 0x81     STA     izx     6
+    {nes_nop,   nes_imm,	2   },      // 0x82     NOP     imm     2
+    {nes_sax,	nes_izx,	6   },      // 0x83     SAX     izx     6
+    {nes_sty,	nes_zp,	    3   },      // 0x84     STY     zp      3
+    {nes_sta,	nes_zp,     3   },      // 0x85     STA     zp      3
+    {nes_stx,	nes_zp,     3   },      // 0x86     STX     zp      3
+    {nes_sax,	nes_zp,     3   },      // 0x87     SAX     zp      3
+    {nes_dey,	NULL,	    2   },      // 0x88     DEY             2
+    {nes_nop,	nes_imm,	2   },      // 0x89     NOP     imm     2
+    {nes_txa,	NULL,	    2   },      // 0x8A     TXA             2
+    {nes_xaa,	nes_imm,	2   },      // 0x8B     XAA     imm     2
+    {nes_sty,	nes_abs,	4   },      // 0x8C     STY     abs     4
+    {nes_sta,	nes_abs,	4   },      // 0x8D     STA     abs     4
+    {nes_stx,	nes_abs,	4   },      // 0x8E     STX     abs     4
+    {nes_sax,	nes_abs,	4   },      // 0x8F     SAX     abs     4
+    {nes_bcc,	nes_rel,   	2   },      // 0x90     BCC     rel     2*
+    {nes_sta,   nes_izy,    6   },      // 0x91     STA     izy     6
+    {NULL,      NULL,	    0   },      // 0x92     KIL
+    {nes_ahx,	nes_izy,	6   },      // 0x93     AHX     izy     6
+    {nes_sty,	nes_zpx,	4   },      // 0x94     STY     zpx     4
+    {nes_sta,	nes_zpx,    4   },      // 0x95     STA     zpx     4
+    {nes_stx,	nes_zpy,    4   },      // 0x96     STX     zpy     4
+    {nes_sax,	nes_zpy,    4   },      // 0x97     SAX     zpy     4
+    {nes_tya,	NULL,	    2   },      // 0x98     TYA             2
+    {nes_sta,	nes_aby,	5   },      // 0x99     STA     aby     5
+    {nes_txs,	NULL,	    2   },      // 0x9A     TXS             2
+    {nes_tas,	nes_aby,	5   },      // 0x9B     TAS     aby     5
+    {nes_shy,	nes_abx,	5   },      // 0x9C     SHY     abx     5
+    {nes_sta,	nes_abx,	5   },      // 0x9D     STA     abx     5
+    {nes_shx,	nes_aby,	5   },      // 0x9E     SHX     aby     5
+    {nes_ahx,	nes_aby,	5   },      // 0x9F     AHX     aby     5
+    {nes_ldy,	nes_imm,   	2   },      // 0xA0     LDY     imm     2
+    {nes_lda,   nes_izx,    6   },      // 0xA1     LDA     izx     6
+    {nes_ldx,   nes_imm,	2   },      // 0xA2     LDX     imm     2
+    {nes_lax,	nes_izx,	6   },      // 0xA3     LAX     izx     6
+    {nes_ldy,	nes_zp,	    3   },      // 0xA4     LDY     zp      3
+    {nes_lda,	nes_zp,     3   },      // 0xA5     LDA     zp      3
+    {nes_ldx,	nes_zp,     3   },      // 0xA6     LDX     zp      3
+    {nes_lax,	nes_zp,     3   },      // 0xA7     LAX     zp      3
+    {nes_tay,	NULL,	    2   },      // 0xA8     TAY             2
+    {nes_lda,	nes_imm,	2   },      // 0xA9     LDA     imm     2
+    {nes_tax,	NULL,	    2   },      // 0xAA     TAX             2
+    {nes_lax,	nes_imm,	2   },      // 0xAB     LAX     imm     2
+    {nes_ldy,	nes_abs,	4   },      // 0xAC     LDY     abs     4
+    {nes_lda,	nes_abs,	4   },      // 0xAD     LDA     abs     4
+    {nes_ldx,	nes_abs,	4   },      // 0xAE     LDX     abs     4
+    {nes_lax,	nes_abs,	4   },      // 0xAF     LAX     abs     4
+    {nes_bcs,	nes_rel,   	2   },      // 0xB0     BCS     rel     2*
+    {nes_lda,   nes_izy,    5   },      // 0xB1     LDA     izy     5*
+    {NULL,      NULL,	    0   },      // 0xB2     KIL
+    {nes_lax,	nes_izy,	5   },      // 0xB3     LAX     izy     5*
+    {nes_ldy,	nes_zpx,	4   },      // 0xB4     LDY     zpx     4
+    {nes_lda,	nes_zpx,    4   },      // 0xB5     LDA     zpx     4
+    {nes_ldx,	nes_zpy,    4   },      // 0xB6     LDX     zpy     4
+    {nes_lax,	nes_zpy,    4   },      // 0xB7     LAX     zpy     4
+    {nes_clv,	NULL,	    2   },      // 0xB8     CLV             2
+    {nes_lda,	nes_aby,	4   },      // 0xB9     LDA     aby     4*
+    {nes_tsx,	NULL,	    2   },      // 0xBA     TSX             2
+    {nes_las,	nes_aby,	4   },      // 0xBB     LAS     aby     4*
+    {nes_ldy,	nes_abx,	4   },      // 0xBC     LDY     abx     4*
+    {nes_lda,	nes_abx,	4   },      // 0xBD     LDA     abx     4*
+    {nes_ldx,	nes_aby,	4   },      // 0xBE     LDX     aby     4*
+    {nes_lax,	nes_aby,	4   },      // 0xBF     LAX     aby     4*
+    {nes_cpy,	nes_imm,   	2   },      // 0xC0     CPY     imm     2
+    {nes_cmp,   nes_izx,    6   },      // 0xC1     CMP     izx     6
+    {nes_nop,   nes_imm,	2   },      // 0xC2     NOP     imm     2
+    {nes_dcp,	nes_izx,	8   },      // 0xC3     DCP     izx     8
+    {nes_cpy,	nes_zp,  	3   },      // 0xC4     CPY     zp      3
+    {nes_cmp,	nes_zp,     3   },      // 0xC5     CMP     zp      3
+    {nes_dec,	nes_zp,     5   },      // 0xC6     DEC     zp      5
+    {nes_dcp,	nes_zp,     5   },      // 0xC7     DCP     zp      5
+    {nes_iny,	NULL,	    2   },      // 0xC8     INY             2
+    {nes_cmp,	nes_imm,	2   },      // 0xC9     CMP     imm     2
+    {nes_dex,	NULL,	    2   },      // 0xCA     DEX             2
+    {nes_axs,	nes_imm,	2   },      // 0xCB     AXS     imm     2
+    {nes_cpy,	nes_abs,	4   },      // 0xCC     CPY     abs     4
+    {nes_cmp,	nes_abs,	4   },      // 0xCD     CMP     abs     4
+    {nes_dec,	nes_abs,	6   },      // 0xCE     DEC     abs     6
+    {nes_dcp,	nes_abs,	6   },      // 0xCF     DCP     abs     6
+    {nes_bne,	nes_rel,   	2   },      // 0xD0     BNE     rel     2*
+    {nes_cmp,   nes_izy,    5   },      // 0xD1     CMP     izy     5*
+    {NULL,      NULL,	    0   },      // 0xD2     KIL
+    {nes_dcp,	nes_izy,	8   },      // 0xD3     DCP     izy     8
+    {nes_nop,	nes_zpx,  	4   },      // 0xD4     NOP     zpx     4
+    {nes_cmp,	nes_zpx,    4   },      // 0xD5     CMP     zpx     4
+    {nes_dec,	nes_zpx,    6   },      // 0xD6     DEC     zpx     6
+    {nes_dcp,	nes_zpx,    6   },      // 0xD7     DCP     zpx     6
+    {nes_cld,	NULL,	    2   },      // 0xD8     CLD             2
+    {nes_cmp,	nes_aby,	4   },      // 0xD9     CMP     aby     4*
+    {nes_nop,	NULL,	    2   },      // 0xDA     NOP             2
+    {nes_dcp,	nes_aby,	7   },      // 0xDB     DCP     aby     7
+    {nes_nop,	nes_abx,	4   },      // 0xDC     NOP     abx     4*
+    {nes_cmp,	nes_abx,	4   },      // 0xDD     CMP     abx     4*
+    {nes_dec,	nes_abx,	7   },      // 0xDE     DEC     abx     7
+    {nes_dcp,	nes_abx,	7   },      // 0xDF     DCP     abx     7
+    {nes_cpx,	nes_imm,   	2   },      // 0xE0     CPX     imm     2
+    {nes_sbc,   nes_izx,    6   },      // 0xE1     SBC     izx     6
+    {nes_nop,   nes_imm,	2   },      // 0xE2     NOP     imm     2
+    {nes_isc,	nes_izx,	8   },      // 0xE3     ISC     izx     8
+    {nes_cpx,	nes_zp,  	3   },      // 0xE4     CPX     zp      3
+    {nes_sbc,	nes_zp,     3   },      // 0xE5     SBC     zp      3
+    {nes_inc,	nes_zp,     5   },      // 0xE6     INC     zp      5
+    {nes_isc,	nes_zp,     5   },      // 0xE7     ISC     zp      5
+    {nes_inx,	NULL,	    2   },      // 0xE8     INX             2
+    {nes_sbc,	nes_imm,	2   },      // 0xE9     SBC     imm     2
+    {nes_nop,	NULL,	    2   },      // 0xEA     NOP             2
+    {nes_sbc,	nes_imm,	2   },      // 0xEB     SBC     imm     2
+    {nes_cpx,	nes_abs,	4   },      // 0xEC     CPX     abs     4
+    {nes_sbc,	nes_abs,	4   },      // 0xED     SBC     abs     4
+    {nes_inc,	nes_abs,	6   },      // 0xEE     INC     abs     6
+    {nes_isc,	nes_abs,	6   },      // 0xEF     ISC     abs     6
+    {nes_beq,	nes_rel,   	2   },      // 0xF0     BEQ     rel     2*
+    {nes_sbc,   nes_izy,    5   },      // 0xF1     SBC     izy     5*
+    {NULL,      NULL,	    0   },      // 0xF2     KIL
+    {nes_isc,	nes_izy,	8   },      // 0xF3     ISC     izy     8
+    {nes_nop,	nes_zpx,  	4   },      // 0xF4     NOP     zpx     4
+    {nes_sbc,	nes_zpx,    4   },      // 0xF5     SBC     zpx     4
+    {nes_inc,	nes_zpx,    6   },      // 0xF6     INC     zpx     6
+    {nes_isc,	nes_zpx,    6   },      // 0xF7     ISC     zpx     6
+    {nes_sed,	NULL,	    2   },      // 0xF8     SED             2
+    {nes_sbc,	nes_aby,	4   },      // 0xF9     SBC     aby     4*
+    {nes_nop,	NULL,	    2   },      // 0xFA     NOP             2
+    {nes_isc,	nes_aby,	7   },      // 0xFB     ISC     aby     7
+    {nes_nop,	nes_abx,	4   },      // 0xFC     NOP     abx     4*
+    {nes_sbc,	nes_abx,	4   },      // 0xFD     SBC     abx     4*
+    {nes_inc,	nes_abx,	7   },      // 0xFE     INC     abx     7
+    {nes_isc,	nes_abx,	7   },      // 0xFF     ISC     abx     7
+};
+
+
+void nes_opcode(nes_t* nes,uint16_t ticks){
+    while (ticks > nes->nes_cpu.cycles){
+        nes->nes_cpu.opcode = nes_read_cpu(nes,nes->nes_cpu.PC++);
+        nes_opcode_table[nes->nes_cpu.opcode].instruction(nes);
+        nes->nes_cpu.cycles += nes_opcode_table[nes->nes_cpu.opcode].ticks;
+    }
+    nes->nes_cpu.cycles -= ticks;
+}
+
+

+ 46 - 0
components/nes/src/nes_mapper.c

@@ -0,0 +1,46 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+void nes_load_prgrom_8k(nes_t* nes,int des, int src) {
+    nes->nes_cpu.prg_banks[des] = nes->nes_rom.prg_rom + 8 * 1024 * src;
+}
+
+void nes_load_chrrom_1k(nes_t* nes,int des, int src) {
+    nes->nes_ppu.pattern_table[des] = nes->nes_rom.chr_rom + 1024 * src;
+}
+
+int nes_load_mapper(nes_t* nes){
+    switch (nes->nes_rom.mapper_number){
+        case 0 :
+            return nes_mapper0_init(nes);
+        case 2 :
+            return nes_mapper2_init(nes);
+        default :
+            nes_printf("mapper:%03d is unsupported\n",nes->nes_rom.mapper_number);
+            return NES_ERROR;
+    }
+}

+ 44 - 0
components/nes/src/nes_mapper/nes_mapper0.c

@@ -0,0 +1,44 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+static void nes_mapper_init(nes_t* nes){
+    const int mirror = nes->nes_rom.prg_rom_size & 2;
+    nes_load_prgrom_8k(nes,0, 0);
+    nes_load_prgrom_8k(nes,1, 1);
+    nes_load_prgrom_8k(nes,2, mirror+0);
+    nes_load_prgrom_8k(nes,3, mirror+1);
+
+    for (int i = 0; i < 8; i++){
+        nes_load_chrrom_1k(nes,i,i);
+    }
+}
+
+int nes_mapper0_init(nes_t* nes){
+    nes->nes_mapper.mapper_init = nes_mapper_init;
+    return 0;
+}
+

+ 54 - 0
components/nes/src/nes_mapper/nes_mapper2.c

@@ -0,0 +1,54 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+
+static void nes_mapper_init(nes_t* nes){
+    const int mirror = nes->nes_rom.prg_rom_size * 2;
+    nes_load_prgrom_8k(nes,0, 0);
+    nes_load_prgrom_8k(nes,1, 1);
+    nes_load_prgrom_8k(nes,2, mirror-2);
+    nes_load_prgrom_8k(nes,3, mirror-1);
+
+    for (int i = 0; i < 8; i++){
+        nes_load_chrrom_1k(nes,i,i);
+    }
+}
+
+static void nes_mapper_write(nes_t* nes, uint16_t address, uint8_t date) {
+    const int bank = (date % nes->nes_rom.prg_rom_size) * 2;
+    nes_load_prgrom_8k(nes, 0, bank + 0);
+    nes_load_prgrom_8k(nes, 1, bank + 1);
+}
+
+
+
+int nes_mapper2_init(nes_t* nes){
+    nes->nes_mapper.mapper_init = nes_mapper_init;
+    nes->nes_mapper.mapper_write = nes_mapper_write;
+    return 0;
+}
+

+ 202 - 0
components/nes/src/nes_ppu.c

@@ -0,0 +1,202 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+//https://www.nesdev.org/pal.txt
+#if (NES_COLOR_DEPTH == 32)
+// ARGB8888
+nes_color_t nes_palette[]={
+    0xFF757575, 0xFF271B8F, 0xFF0000AB, 0xFF47009F, 0xFF8F0077, 0xFFB0013, 0xFFA70000, 0xFF7F0B00,0xFF432F00, 0xFF004700, 0xFF005100, 0xFF003F17, 0xFF1B3F5F, 0xFF000000, 0xFF000000, 0xFF000000,
+    0xFFBCBCBC, 0xFF0073EF, 0xFF233BEF, 0xFF8300F3, 0xFFBF00BF, 0xFF7005B, 0xFFDB2B00, 0xFFCB4F0F,0xFF8B7300, 0xFF009700, 0xFF00AB00, 0xFF00933B, 0xFF00838B, 0xFF000000, 0xFF000000, 0xFF000000,
+    0xFFFFFFFF, 0xFF3FBFFF, 0xFF5F97FF, 0xFFA78BFD, 0xFFF77BFF, 0xFFF77B7, 0xFFFF7763, 0xFFFF9B3B,0xFFF3BF3F, 0xFF83D313, 0xFF4FDF4B, 0xFF58F898, 0xFF00EBDB, 0xFF000000, 0xFF000000, 0xFF000000,
+    0xFFFFFFFF, 0xFFABE7FF, 0xFFC7D7FF, 0xFFD7CBFF, 0xFFFFC7FF, 0xFFFC7DB, 0xFFFFBFB3, 0xFFFFDBAB,0xFFFFE7A3, 0xFFE3FFA3, 0xFFABF3BF, 0xFFB3FFCF, 0xFF9FFFF3, 0xFF000000, 0xFF000000, 0xFF000000,
+};
+#elif (NES_COLOR_DEPTH == 16)
+#if (NES_COLOR_SWAP == 0)
+// RGB565
+nes_color_t nes_palette[]={
+    0x73AE, 0x20D1, 0x0015, 0x4013, 0x880E, 0x0802, 0xA000, 0x7840,0x4160, 0x0220, 0x0280, 0x01E2, 0x19EB, 0x0000, 0x0000, 0x0000,
+    0xBDF7, 0x039D, 0x21DD, 0x801E, 0xB817, 0x000B, 0xD940, 0xCA61,0x8B80, 0x04A0, 0x0540, 0x0487, 0x0411, 0x0000, 0x0000, 0x0000,
+    0xFFFF, 0x3DFF, 0x5CBF, 0xA45F, 0xF3DF, 0x0BB6, 0xFBAC, 0xFCC7,0xF5E7, 0x8682, 0x4EE9, 0x5FD3, 0x075B, 0x0000, 0x0000, 0x0000,
+    0xFFFF, 0xAF3F, 0xC6BF, 0xD65F, 0xFE3F, 0x0E3B, 0xFDF6, 0xFED5,0xFF34, 0xE7F4, 0xAF97, 0xB7F9, 0x9FFE, 0x0000, 0x0000, 0x0000,
+};
+#else
+// RGB565_SWAP
+nes_color_t nes_palette[]={
+    0xAE73, 0xD120, 0x1500, 0x1340, 0x0E88, 0x0208, 0x00A0, 0x4078,0x6041, 0x2002, 0x8002, 0xE201, 0xEB19, 0x0000, 0x0000, 0x0000,
+    0xF7BD, 0x9D03, 0xDD21, 0x1E80, 0x17B8, 0x0B00, 0x40D9, 0x61CA,0x808B, 0xA004, 0x4005, 0x8704, 0x1104, 0x0000, 0x0000, 0x0000,
+    0xFFFF, 0xFF3D, 0xBF5C, 0x5FA4, 0xDFF3, 0xB60B, 0xACFB, 0xC7FC,0xE7F5, 0x8286, 0xE94E, 0xD35F, 0x5B07, 0x0000, 0x0000, 0x0000,
+    0xFFFF, 0x3FAF, 0xBFC6, 0x5FD6, 0x3FFE, 0x3B0E, 0xF6FD, 0xD5FE,0x34FF, 0xF4E7, 0x97AF, 0xF9B7, 0xFE9F, 0x0000, 0x0000, 0x0000,
+};
+#endif
+#endif
+
+static inline uint8_t nes_read_ppu_memory(nes_t* nes){
+    const uint16_t address = nes->nes_ppu.v_reg & (uint16_t)0x3FFF;
+    const uint16_t index = address >> 10;
+    const uint16_t offset = address & (uint16_t)0x3FF;
+    if (address < (uint16_t)0x3F00) {
+        uint8_t data = nes->nes_ppu.buffer;
+        nes->nes_ppu.buffer = nes->nes_ppu.chr_banks[index][offset];
+        return data;
+    } else {
+        nes->nes_ppu.buffer = nes->nes_ppu.chr_banks[index][offset];
+        return nes->nes_ppu.palette_indexes[address & (uint16_t)0x1f];
+    }
+}
+
+static inline void nes_write_ppu_memory(nes_t* nes,uint8_t data){
+    const uint16_t address = nes->nes_ppu.v_reg & (uint16_t)0x3FFF;
+    if (address < (uint16_t)0x3F00) {
+        const uint16_t index = address >> 10;
+        const uint16_t offset = address & (uint16_t)0x3FF;
+        nes->nes_ppu.chr_banks[index][offset] = data;
+    } else {
+        if (address & (uint16_t)0x03) {
+            nes->nes_ppu.palette_indexes[address & (uint16_t)0x1f] = data;
+        } else {
+            const uint16_t offset = address & (uint16_t)0x0f;
+            nes->nes_ppu.palette_indexes[offset] = data;
+            nes->nes_ppu.palette_indexes[offset | (uint16_t)0x10] = data;
+        }
+    }
+}
+
+// https://www.nesdev.org/wiki/PPU_registers
+uint8_t nes_read_ppu_register(nes_t* nes,uint16_t address){
+    uint8_t data = 0;
+    switch (address & (uint16_t)0x07){
+        case 2://Status ($2002) < read
+            // w:                  <- 0
+            data = nes->nes_ppu.ppu_status;
+            nes->nes_ppu.STATUS_V = 0;
+            nes->nes_ppu.w = 0;
+            break;
+        case 4://OAM data ($2004) <> read/write
+            data = nes->nes_ppu.oam_data[nes->nes_ppu.oam_addr];
+            break;
+        case 7://Data ($2007) <> read/write
+            data = nes_read_ppu_memory(nes);
+            nes->nes_ppu.v_reg += (uint16_t)((nes->nes_ppu.CTRL_I) ? 32 : 1);
+            break;
+        default :
+            nes_printf("nes_read_ppu_register error %04X\n",address);
+            return -1;
+    }
+    // nes_printf("nes_read_ppu_register %04X %02X\n",address,data);
+    return data;
+}
+
+void nes_write_ppu_register(nes_t* nes,uint16_t address, uint8_t data){
+    // nes_printf("nes_write_ppu_register %04X %02X\n",address,data);
+    switch (address & (uint16_t)0x07){
+        case 0://Controller ($2000) > write
+            // t: ...GH.. ........ <- d: ......GH
+            //    <used elsewhere> <- d: ABCDEF..
+            nes->nes_ppu.ppu_ctrl = data;
+            nes->nes_ppu.t.nametable = (data & 0x03);
+            break;
+        case 1://Mask ($2001) > write
+            nes->nes_ppu.ppu_mask = data;
+            break;
+        case 3://OAM address ($2003) > write
+            nes->nes_ppu.oam_addr = data;
+            break;
+        case 4://OAM data ($2004) <> read/write
+            nes->nes_ppu.oam_data[nes->nes_ppu.oam_addr++] = data;
+            break;
+        case 5://Scroll ($2005) >> write x2
+            if (nes->nes_ppu.w) {   // w is 1
+                // t: FGH..AB CDE..... <- d: ABCDEFGH
+                // w:                  <- 0
+                nes->nes_ppu.t.fine_y = (data & 0x07);
+                nes->nes_ppu.t.coarse_y = (data & 0xF8)>>3;
+                nes->nes_ppu.w = 0;
+            } else {                // w is 0
+                // t: ....... ...ABCDE <- d: ABCDE...
+                // x:              FGH <- d: .....FGH
+                // w:                  <- 1
+                nes->nes_ppu.t.coarse_x = (data & 0xF8)>>3;
+                nes->nes_ppu.x = (data & 0x07);
+                nes->nes_ppu.w = 1;
+            }
+            break;
+        case 6://Address ($2006) >> write x2
+            if (nes->nes_ppu.w) {   // w is 1
+                // t: ....... ABCDEFGH <- d: ABCDEFGH
+                // v: <...all bits...> <- t: <...all bits...>
+                // w:                  <- 0
+                nes->nes_ppu.t_reg = (nes->nes_ppu.t_reg & (uint16_t)0xFF00) | (uint16_t)data;
+                nes->nes_ppu.v_reg = nes->nes_ppu.t_reg;
+                nes->nes_ppu.w = 0;
+            } else {                // w is 0
+                // t: .CDEFGH ........ <- d: ..CDEFGH
+                //        <unused>     <- d: AB......
+                // t: Z...... ........ <- 0 (bit Z is cleared)
+                // w:                  <- 1
+                nes->nes_ppu.t_reg = (nes->nes_ppu.t_reg & (uint16_t)0xFF) | (((uint16_t)data & 0x3F) << 8);
+                nes->nes_ppu.w = 1;
+            }
+            break;
+        case 7://Data ($2007) <> read/write
+            nes_write_ppu_memory(nes,data);
+            nes->nes_ppu.v_reg += (uint16_t)((nes->nes_ppu.CTRL_I) ? 32 : 1);
+            break;
+        default :
+            nes_printf("nes_write_ppu_register error %04X %02X\n",address,data);
+            return;
+    }
+}
+
+void nes_ppu_init(nes_t *nes){
+    // four_screen
+    if (nes->nes_rom.four_screen) { 
+        nes->nes_ppu.name_table[0] = nes->nes_ppu.ppu_vram0;
+        nes->nes_ppu.name_table[1] = nes->nes_ppu.ppu_vram1;
+        nes->nes_ppu.name_table[2] = nes->nes_ppu.ppu_vram2;
+        nes->nes_ppu.name_table[3] = nes->nes_ppu.ppu_vram3;
+    }
+    // Vertical
+    else if (nes->nes_rom.mirroring_type) {
+        nes->nes_ppu.name_table[0] = nes->nes_ppu.ppu_vram0;
+        nes->nes_ppu.name_table[1] = nes->nes_ppu.ppu_vram1;
+        nes->nes_ppu.name_table[2] = nes->nes_ppu.ppu_vram0;
+        nes->nes_ppu.name_table[3] = nes->nes_ppu.ppu_vram1;
+    }
+    // Horizontal or mapper-controlled
+    else {
+        nes->nes_ppu.name_table[0] = nes->nes_ppu.ppu_vram0;
+        nes->nes_ppu.name_table[1] = nes->nes_ppu.ppu_vram0;
+        nes->nes_ppu.name_table[2] = nes->nes_ppu.ppu_vram1;
+        nes->nes_ppu.name_table[3] = nes->nes_ppu.ppu_vram1;
+    }
+    // mirrors
+    nes->nes_ppu.chr_banks[12] = nes->nes_ppu.name_table[0];
+    nes->nes_ppu.chr_banks[13] = nes->nes_ppu.name_table[1];
+    nes->nes_ppu.chr_banks[14] = nes->nes_ppu.name_table[2];
+    nes->nes_ppu.chr_banks[15] = nes->nes_ppu.name_table[3];
+}
+

+ 168 - 0
components/nes/src/nes_rom.c

@@ -0,0 +1,168 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Dozingfiretruck
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "nes.h"
+
+#if (NES_USE_SRAM == 1)
+    #define SRAM_SIZE           (0x2000)
+#endif
+
+#if (NES_USE_FS == 1)
+nes_t* nes_load_file(const char* file_path ){
+    nes_header_info_t nes_header_info = {0};
+    nes_t* nes = NULL;
+
+    FILE* nes_file = nes_fopen(file_path, "rb");
+    if (!nes_file){
+        goto error;
+    } 
+    nes = (nes_t *)nes_malloc(sizeof(nes_t));
+    if (nes == NULL) {
+        goto error;
+    }
+    memset(nes, 0, sizeof(nes_t));
+
+#if (NES_USE_SRAM == 1)
+    nes->nes_rom.sram = (uint8_t*)nes_malloc(SRAM_SIZE);
+#endif
+    if (nes_fread(&nes_header_info, sizeof(nes_header_info), 1, nes_file)) {
+        if ( nes_memcmp( nes_header_info.identification, "NES\x1a", 4 )){
+            goto error;
+        }
+        if (nes_header_info.trainer){
+#if (NES_USE_SRAM == 1)
+            if (nes_fread(nes->nes_rom.sram, TRAINER_SIZE, 1, nes_file)==0){
+                goto error;
+            }
+#else
+            nes_fseek(nes_file, TRAINER_SIZE, SEEK_CUR);
+#endif
+        }
+        nes->nes_rom.prg_rom_size = ((nes_header_info.prg_rom_size_m << 8) & 0xF00) | nes_header_info.prg_rom_size_l;
+        nes->nes_rom.chr_rom_size = ((nes_header_info.prg_rom_size_m << 8) & 0xF00) | nes_header_info.chr_rom_size_l;
+        nes->nes_rom.mapper_number = ((nes_header_info.mapper_number_h << 8) & 0xF00) | ((nes_header_info.mapper_number_m << 4) & 0xF0) | (nes_header_info.mapper_number_l & 0x0F);
+        nes->nes_rom.mirroring_type = (nes_header_info.mirroring);
+        nes->nes_rom.four_screen = (nes_header_info.four_screen);
+        nes->nes_rom.save_ram = (nes_header_info.save);
+
+        nes->nes_rom.prg_rom = (uint8_t*)nes_malloc(PRG_ROM_UNIT_SIZE * nes->nes_rom.prg_rom_size);
+        if (nes->nes_rom.prg_rom == NULL) {
+            goto error;
+        }
+        if (nes_fread(nes->nes_rom.prg_rom, PRG_ROM_UNIT_SIZE, nes->nes_rom.prg_rom_size, nes_file)==0){
+            goto error;
+        }
+        nes->nes_rom.chr_rom = (uint8_t*)nes_malloc(CHR_ROM_UNIT_SIZE * (nes->nes_rom.chr_rom_size ? nes->nes_rom.chr_rom_size : 1));
+        if (nes->nes_rom.chr_rom == NULL) {
+            goto error;
+        }
+        if (nes->nes_rom.chr_rom_size){
+            if (nes_fread(nes->nes_rom.chr_rom, CHR_ROM_UNIT_SIZE, (nes->nes_rom.chr_rom_size), nes_file)==0){
+                goto error;
+            }
+        }
+    }else{
+        goto error;
+    }
+    nes_fclose(nes_file);
+    nes_init(nes);
+    nes_load_mapper(nes);
+    nes->nes_mapper.mapper_init(nes);
+    return nes;
+error:
+    if (nes_file){
+        nes_fclose(nes_file);
+    }
+    if (nes){
+        nes_rom_free(nes);
+    }
+    return NULL;
+}
+#endif
+
+// release
+int nes_rom_free(nes_t* nes){
+    if (nes->nes_rom.prg_rom){
+        nes_free(nes->nes_rom.prg_rom);
+    }
+    if (nes->nes_rom.chr_rom){
+        nes_free(nes->nes_rom.chr_rom);
+    }
+    if (nes->nes_rom.sram){
+        nes_free(nes->nes_rom.sram);
+    }
+    if (nes){
+        nes_free(nes);
+    }
+    return NES_OK;
+}
+
+nes_t* nes_load_rom(const uint8_t* nes_rom){
+    nes_t* nes = (nes_t *)nes_malloc(sizeof(nes_t));
+    if (nes == NULL) {
+        goto error;
+    }
+    memset(nes, 0, sizeof(nes_t));
+
+    nes_header_info_t* nes_header_info = (nes_header_info_t*)nes_rom;
+
+#if (NES_USE_SRAM == 1)
+    nes->nes_rom.sram = (uint8_t*)nes_malloc(SRAM_SIZE);
+#endif
+        if ( nes_memcmp( nes_header_info->identification, "NES\x1a", 4 )){
+            goto error;
+        }
+        uint8_t* nes_bin = nes_rom + sizeof(nes_header_info_t);
+        if (nes_header_info->trainer){
+#if (NES_USE_SRAM == 1)
+#else
+#endif
+            nes_bin += TRAINER_SIZE;
+        }
+        nes->nes_rom.prg_rom_size = ((nes_header_info->prg_rom_size_m << 8) & 0xF00) | nes_header_info->prg_rom_size_l;
+        nes->nes_rom.chr_rom_size = ((nes_header_info->prg_rom_size_m << 8) & 0xF00) | nes_header_info->chr_rom_size_l;
+        nes->nes_rom.mapper_number = ((nes_header_info->mapper_number_h << 8) & 0xF00) | ((nes_header_info->mapper_number_m << 4) & 0xF0) | (nes_header_info->mapper_number_l & 0x0F);
+        nes->nes_rom.mirroring_type = (nes_header_info->mirroring);
+        nes->nes_rom.four_screen = (nes_header_info->four_screen);
+        nes->nes_rom.save_ram = (nes_header_info->save);
+
+        nes->nes_rom.prg_rom = nes_bin;
+        nes_bin += PRG_ROM_UNIT_SIZE * nes->nes_rom.prg_rom_size;
+
+        if (nes->nes_rom.chr_rom_size){
+            nes->nes_rom.chr_rom = nes_bin;
+        }
+    nes_init(nes);
+    nes_load_mapper(nes);
+    nes->nes_mapper.mapper_init(nes);
+    return nes;
+error:
+    if (nes){
+        nes_rom_free(nes);
+    }
+    return NULL;
+}
+
+

+ 327 - 0
components/network/posix/luat_network_posix.c

@@ -0,0 +1,327 @@
+#include "luat_base.h"
+#include "luat_network_adapter.h"
+#include "luat_mem.h"
+#include "luat_msgbus.h"
+#include "luat_crypto.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/select.h>
+
+#define LUAT_LOG_TAG "network"
+#include "luat_log.h"
+
+#include "luat_network_posix.h"
+
+CBFuncEx_t posix_network_cb;
+void * posix_network_param;
+uint8_t posix_network_ready;
+
+static luat_rtos_mutex_t* master_lock;
+
+static void posix_send_event(int id, int p1, int p2, int p3) {
+    luat_network_cb_param_t params = {0};
+    params.tag = 0;
+    params.param = posix_network_param;
+    // 触发一下回调
+    // if (ready) {
+    OS_EVENT event = {
+        .ID = id,
+        .Param1 = p1,
+        .Param2 = p2,
+        .Param3 = p3
+    };
+    LLOGD("posix event %d %d %d %d", id, p1, p2, p3);
+    posix_network_cb(&event, &params);
+}
+
+void posix_network_client_thread_entry(posix_socket_t *ps) {
+
+    luat_network_cb_param_t params = {0};
+    params.tag = 0;
+    params.param = posix_network_param;
+    // 触发一下回调
+    // if (ready) {
+    OS_EVENT event = {0};
+
+    struct sockaddr_in sockaddr = {0};
+    sockaddr.sin_family = AF_INET;
+    sockaddr.sin_port = htons(ps->remote_port);
+    sockaddr.sin_addr.s_addr = ps->remote_ip.ipv4;
+    luat_rtos_task_sleep(50);
+
+    LLOGD("ready to connect %d", ps->socket_id);
+    int ret = connect(ps->socket_id, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+
+    LLOGD("connect ret %d", ret);
+    if (ret) {
+        // 失败了
+        LLOGD("connect FAIL ret %d", ret);
+        posix_send_event(EV_NW_SOCKET_ERROR, ps->socket_id, 0, 0);
+        luat_heap_free(ps);
+        return;
+    }
+    // 发送系统消息, 通知连接成功
+    posix_send_event(EV_NW_SOCKET_CONNECT_OK, ps->socket_id, 0, 0);
+    LLOGD("wait data now");
+
+    fd_set readfds;
+    fd_set writefds;
+    fd_set errorfds;
+    int maxsock;
+    struct timeval tv;
+    maxsock = ps->socket_id;
+    // timeout setting
+    tv.tv_sec = 0;
+    tv.tv_usec = 3000; //暂时3ms吧
+    while (1) {
+        // initialize file descriptor set
+        FD_ZERO(&readfds);
+        // FD_ZERO(&writefds);
+        FD_ZERO(&errorfds);
+        FD_SET(ps->socket_id, &readfds);
+        // FD_SET(ps->socket_id, &writefds);
+        FD_SET(ps->socket_id, &errorfds);
+
+        if (master_lock)
+            if (luat_rtos_mutex_lock(master_lock, 100))
+                continue;
+        ret = select(maxsock + 1, &readfds, NULL, &errorfds, &tv);
+        if (master_lock)
+            luat_rtos_mutex_unlock(master_lock);
+
+        if (ret < 0) {
+            LLOGE("select ret %d", ret);
+            break;
+        } else if (ret == 0) {
+            //printf("select timeout\n");
+            continue;
+        }
+
+        if (FD_ISSET(maxsock, &readfds)) {
+            // 发消息,可读了
+        }
+        // if (FD_ISSET(maxsock, &writefds)) {
+        //     // 发消息,发送完成了??
+        // }
+        if (FD_ISSET(maxsock, &errorfds)) {
+            // 发消息,出错了
+            break;
+        }
+    }
+
+    luat_heap_free(ps);
+    LLOGI("socket thread exit");
+}
+
+void posix_network_set_ready(uint8_t ready) {
+    LLOGD("CALL posix_network_set_ready");
+    posix_network_ready = ready;
+    luat_network_cb_param_t params = {0};
+    params.tag = 0;
+    params.param = posix_network_param;
+    // 触发一下回调
+    // if (ready) {
+        OS_EVENT event = {
+            .ID = EV_NW_STATE,
+            .Param1 = 0,
+            .Param2 = ready,
+            .Param3 = 0
+        };
+        posix_network_cb(&event, &params);
+    // }
+}
+
+//检查网络是否准备好,返回非0准备好,user_data是注册时的user_data,传入给底层api
+uint8_t (posix_check_ready)(void *user_data) {
+    LLOGD("CALL posix_check_ready %d", posix_network_ready);
+    return posix_network_ready;
+};
+
+//创建一个socket,并设置成非阻塞模式,user_data传入对应适配器, tag作为socket的合法依据,给check_socket_vaild比对用
+//成功返回socketid,失败 < 0
+int (posix_create_socket)(uint8_t is_tcp, uint64_t *tag, void *param, uint8_t is_ipv6, void *user_data) {
+    // TODO 支持IPV6
+    int s = socket(AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, is_tcp ? IPPROTO_TCP : IPPROTO_UDP);
+    LLOGD("CALL posix_create_socket %d %d", s, is_tcp);
+    return s;
+}
+
+//作为client绑定一个port,并连接remote_ip和remote_port对应的server
+//成功返回0,失败 < 0
+int (posix_socket_connect)(int socket_id, uint64_t tag, uint16_t local_port, luat_ip_addr_t *remote_ip, uint16_t remote_port, void *user_data) {
+    LLOGD("CALL posix_socket_connect %d", socket_id);
+    posix_socket_t *ps = luat_heap_malloc(sizeof(posix_socket_t));
+    if (ps == NULL) {
+        LLOGE("out of memory when malloc posix_socket_t");
+        return -1;
+    }
+    ps->socket_id = socket_id;
+    ps->tag = tag;
+    ps->local_port = local_port;
+    memcpy(&ps->remote_ip, remote_ip, sizeof(luat_ip_addr_t));
+    ps->remote_port = remote_port;
+    ps->user_data = user_data;
+
+    int ret = network_posix_client_thread_start(ps);
+    LLOGD("socket thread start %d", ret);
+
+    if (ret) {
+        luat_heap_free(ps);
+    }
+    return ret;
+}
+//作为server绑定一个port,开始监听
+//成功返回0,失败 < 0
+int (posix_socket_listen)(int socket_id, uint64_t tag, uint16_t local_port, void *user_data) {
+    // 尚未支持
+    return -1;
+}
+//作为server接受一个client
+//成功返回0,失败 < 0
+int (posix_socket_accept)(int socket_id, uint64_t tag, luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data) {
+    // 尚未支持
+    return -1;
+}
+
+//主动断开一个tcp连接,需要走完整个tcp流程,用户需要接收到close ok回调才能确认彻底断开
+//成功返回0,失败 < 0
+int (posix_socket_disconnect)(int socket_id, uint64_t tag, void *user_data) {
+    return close(socket_id);
+}
+
+//释放掉socket的控制权,除了tag异常外,必须立刻生效
+//成功返回0,失败 < 0
+int (posix_socket_close)(int socket_id, uint64_t tag, void *user_data) {
+    return close(socket_id);
+}
+
+//强行释放掉socket的控制权,必须立刻生效
+//成功返回0,失败 < 0
+int (posix_socket_force_close)(int socket_id, void *user_data) {
+    return close(socket_id);
+}
+
+//tcp时,不需要remote_ip和remote_port,如果buf为NULL,则返回当前缓存区的数据量,当返回值小于len时说明已经读完了
+//udp时,只返回1个block数据,需要多次读直到没有数据为止
+//成功返回实际读取的值,失败 < 0
+int (posix_socket_receive)(int socket_id, uint64_t tag, uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data) {
+    
+    struct timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = 1000; //暂时1ms吧
+    setsockopt(socket_id, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+
+    if (master_lock)
+        if (luat_rtos_mutex_lock(master_lock, 100))
+            return -1;
+    int ret = recv(socket_id, buf, len, flags);
+    if (master_lock)
+        luat_rtos_mutex_unlock(master_lock);
+    return ret;
+}
+
+//tcp时,不需要remote_ip和remote_port
+//成功返回>0的len,缓冲区满了=0,失败 < 0,如果发送了len=0的空包,也是返回0,注意判断
+int (posix_socket_send)(int socket_id, uint64_t tag, const uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t remote_port, void *user_data) {
+    
+    struct timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = 1000; //暂时1ms吧
+    setsockopt(socket_id, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+
+    if (master_lock)
+        if (luat_rtos_mutex_lock(master_lock, 100))
+            return -1;
+    int ret = send(socket_id, buf, len, flags);
+    if (master_lock)
+        luat_rtos_mutex_unlock(master_lock);
+    return ret;
+}
+
+//检查socket合法性,成功返回0,失败 < 0
+int (posix_socket_check)(int socket_id, uint64_t tag, void *user_data) {
+    // TODO 通过select errorfds?
+    LLOGD("CALL posix_socket_check %d %lld", socket_id, tag);
+    return 0;
+}
+
+//保留有效的socket,将无效的socket关闭
+void (posix_socket_clean)(int *vaild_socket_list, uint32_t num, void *user_data) {
+    
+}
+
+int (posix_getsockopt)(int socket_id, uint64_t tag, int level, int optname, void *optval, uint32_t *optlen, void *user_data) {
+    return getsockopt(socket_id, level, optname, optval, optlen);
+}
+
+int (posix_setsockopt)(int socket_id, uint64_t tag, int level, int optname, const void *optval, uint32_t optlen, void *user_data) {
+    return setsockopt(socket_id, level, optname, optval, optlen);
+}
+
+//非posix的socket,用这个根据实际硬件设置参数
+int (posix_user_cmd)(int socket_id, uint64_t tag, uint32_t cmd, uint32_t value, void *user_data) {
+    return 0; // 没有这些东西
+}
+
+
+int (posix_dns)(const char *domain_name, uint32_t len, void *param,  void *user_data) {
+    LLOGD("CALL posix_dns %.*s", len, domain_name);
+    return -1; // 暂不支持DNS
+}
+
+int (posix_set_dns_server)(uint8_t server_index, luat_ip_addr_t *ip, void *user_data) {
+    return 0; // 暂不支持设置DNS
+}
+
+#ifdef LUAT_USE_LWIP
+int (posix_set_mac)(uint8_t *mac, void *user_data);
+int (posix_set_static_ip)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, luat_ip_addr_t *ipv6, void *user_data);
+#endif
+int (posix_get_local_ip_info)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, void *user_data) {
+    ip->ipv4 = 0;
+    submask->ipv4 = 0;
+    gateway->ipv4 = 0;
+    return 0;
+}
+
+//所有网络消息都是通过cb_fun回调
+//cb_fun回调时第一个参数为OS_EVENT,包含了socket的必要信息,第二个是luat_network_cb_param_t,其中的param是这里传入的param(就是适配器序号)
+//OS_EVENT ID为EV_NW_XXX,param1是socket id param2是各自参数 param3是create_soceket传入的socket_param(就是network_ctrl *)
+//dns结果是特别的,ID为EV_NW_SOCKET_DNS_RESULT,param1是获取到的IP数据量,0就是失败了,param2是ip组,动态分配的, param3是dns传入的param(就是network_ctrl *)
+void (posix_socket_set_callback)(CBFuncEx_t cb_fun, void *param, void *user_data) {
+    LLOGD("call posix_socket_set_callback %p %p", cb_fun, param);
+    if (master_lock == NULL)
+        luat_rtos_mutex_create(master_lock);
+    posix_network_cb = cb_fun;
+    posix_network_param = param;
+}
+
+
+network_adapter_info network_posix = {
+    .check_ready = posix_check_ready,
+    .create_soceket = posix_create_socket,
+    .socket_connect  = posix_socket_connect,
+    .socket_accept = posix_socket_accept,
+    .socket_disconnect  = posix_socket_disconnect,
+    .socket_close = posix_socket_close,
+    .socket_force_close = posix_socket_force_close,
+    .socket_receive = posix_socket_receive,
+    .socket_send = posix_socket_send,
+    .socket_clean = posix_socket_clean,
+    .getsockopt = posix_getsockopt,
+    .setsockopt = posix_setsockopt,
+    .user_cmd  = posix_user_cmd,
+    .dns = posix_dns,
+    .set_dns_server = posix_set_dns_server,
+    .get_local_ip_info = posix_get_local_ip_info,
+    .socket_set_callback = posix_socket_set_callback,
+    .name = "posix",
+    .max_socket_num = 4,
+    .no_accept = 1, // 暂时不支持接收
+    .is_posix = 1,
+};

+ 20 - 0
components/network/posix/luat_network_posix.h

@@ -0,0 +1,20 @@
+#ifndef LUAT_NETWORK_POSIX_H
+#define LUAT_NETWORK_POSIX_H
+
+#include "luat_base.h"
+#include "luat_network_adapter.h"
+
+typedef struct posix_socket
+{
+    int socket_id;
+    uint64_t tag;
+    uint16_t local_port;
+    luat_ip_addr_t remote_ip;
+    uint16_t remote_port;
+    void *user_data;
+}posix_socket_t;
+
+int network_posix_client_thread_start(posix_socket_t* ps);
+void posix_network_client_thread_entry(posix_socket_t* args);
+
+#endif

+ 51 - 0
components/network/zlink/include/luat_zlink.h

@@ -0,0 +1,51 @@
+#ifndef LUAT_ZLINK_H
+#define LUAT_ZLINK_H
+
+typedef void 	(*luat_zlink_output)(void *arg, const void *data, size_t len);
+
+int luat_pcap_init(luat_zlink_output output, void *arg);
+int luat_pcap_write(const void *data, size_t len);
+int luat_pcap_push(const void *data, size_t len);
+
+typedef struct luat_zlink_pkg
+{
+    uint8_t magic[4]; // ZINK
+    uint8_t pkgid[4];   // 包id, 自增
+    uint8_t flags[2];   // 标志位, 预留,当前为0
+    uint8_t len[2];    // 仅计算len之后的数据
+    uint8_t cmd0;    // 命令分类
+    uint8_t cmd1;    // 具体命令
+    uint8_t data[0];
+}luat_zlink_pkg_t;
+
+enum {
+    // 基础指令
+    LUAT_ZLINK_CMD_NONE = 0, // 空指令
+    LUAT_ZLINK_CMD_VERSION, // 查询协议版本号
+    LUAT_ZLINK_CMD_PING,    // 心跳包
+    LUAT_ZLINK_CMD_PONG,    // 心跳包应答
+    LUAT_ZLINK_CMD_REBOOT,  // 重启模块
+
+    LUAT_ZLINK_CMD_MSG = 64,     // 日志输出, 用于调试
+
+    // WLAN命令
+    // WLAN 基础命令
+    LUAT_ZLINK_CMD_WLAN_INIT = (1 << 8) + 1,
+    LUAT_ZLINK_CMD_WLAN_STATUS,
+    // WLAN设置命令
+    LUAT_ZLINK_CMD_WLAN_SSID = (1 << 8) + 16,
+    LUAT_ZLINK_CMD_WLAN_PASSWORD,
+    LUAT_ZLINK_CMD_WLAN_MAC,
+
+    // WLAN控制命令
+    LUAT_ZLINK_CMD_WLAN_CONNECT = (1 << 8) + 32,
+    LUAT_ZLINK_CMD_WLAN_DISCONNECT,
+    LUAT_ZLINK_CMD_WLAN_SCAN,
+
+
+    // MAC包收发指令, 只有发送和收到(ACK),应该不需要其他的吧
+    LUAT_ZLINK_CMD_MACPKG_SEND = (2 << 8) + 1,
+    LUAT_ZLINK_CMD_MACPKG_ACK,
+};
+
+#endif

+ 0 - 0
components/network/zlink/src/luat_zlink.c


+ 156 - 0
components/nr_micro_shell/README.md

@@ -0,0 +1,156 @@
+* # nr_micro_shell
+
+  ## 介绍
+
+  在进行调试和维护时,常常需要与单片机进行交互,获取、设置某些参数或执行某些操作,**nr_micro_shell**正是为满足这一需求,针对资源较少的MCU编写的基本命令行工具。虽然RT_Thread组件中已经提供了强大的**finsh**命令行交互工具,但对于ROM、RAM资源较少的单片机,**finsh**还是略显的庞大,在这些平台上,若仍想保留基本的命令行交互功能,**nr_micro_shell**是一个不错的选择。
+
+  **nr_micro_shell**具有以下优点
+
+  1.占用资源少,使用简单,灵活方便。使用过程只涉及两个shell_init()和shell()两个函数,无论是使用RTOS还是裸机都可以方便的应用该工具,不需要额外的编码工作。
+
+  2.交互体验好。完全类似于linux shell命令行,当串口终端支持ANSI(如Hypertrm终端)时,其不仅支持基本的命令行交互,还提供Tab键命令补全,查询历史命令,方向键移动光标修改功能。
+
+  3.扩展性好。**nr_micro_shell**为用户提供自定义命令的标准函数原型,只需要按照命令编写命令函数,并注册命令函数,即可使用命令。
+
+  ## 移植:
+
+  参考AIR101
+
+  ## 配置:
+
+  所有配置工作都可以在 **_nr_micro_shell_config.h_** 中完成。有关详细信息,请参见文件中的注释。
+
+  ## 用法:
+
+  - 确保所有文件都已添加到项目中。
+
+  - 确保 **_nr_micro_shell_config.h_** 中的宏函数"shell_printf(),ansi_show_char()"可以在项目中正常使用。
+
+  - 使用示例如下
+
+  ```c
+  #include "nr_micro_shell.h"
+  
+  int main(void)
+  {
+      /* 初始化 */
+      shell_init();
+  
+      while(1)
+      {
+          if(USART GET A CHAR 'c')
+          {
+              /* nr_micro_shell接收字符 */
+              shell(c);
+          }
+      }
+  }
+  ```
+
+  建议直接使用硬件输入前,建议使用如下代码(确保可以正常打印信息),验证nr_micro_shell是否可以正常运行
+
+  ```c
+  #include "nr_micro_shell.h"
+  
+  int main(void)
+  {
+      unsigned int i = 0;
+      //匹配好结束符配置 NR_SHELL_END_OF_LINE 0
+      char test_line[] = "test 1 2 3\n"
+      /* 初始化 */
+      shell_init();
+      
+      /* 初步测试代码 */
+      for(i = 0; i < sizeof(test_line)-1; i++)
+      {
+          shell(test_line[i]);
+      }
+  
+      /* 正式工作代码 */
+      while(1)
+      {
+          if(USART GET A CHAR 'c')
+          {
+              /* nr_micro_shell接收字符 */
+              shell(c);
+          }
+      }
+  }
+  ```
+
+  ## 添加自己的命令
+
+  **STEP1**:
+
+  您需要在**nr_micro_shell_commands.c***中实现一个命令函数。命令函数的原型如下
+
+  ```c
+  void your_command_funtion(char argc, char *argv)
+  {
+      .....
+  }
+  ```
+
+  **argc**是参数的数目。**argv**存储每个参数的起始地址和内容。如果输入字符串是
+
+  ```c
+  test -a 1
+  ```
+
+  则**argc**为3,**argv**的内容为
+
+  ```c
+  -------------------------------------------------------------
+  0x03|0x08|0x0b|'t'|'e'|'s'|'t'|'\0'|'-'|'a'|'\0'|'1'|'\0'|
+  -------------------------------------------------------------
+  ```
+
+  如果想知道第一个或第二个参数的内容,应该使用
+
+  ```c
+  /* "-a" */
+  printf(argv[argv[1]])
+  /* "1" */
+  printf(argv[argv[2]])
+  ```
+
+  **STEP2**:
+  在使用命令前需要注册命令,共有两种方法注册命令
+
+  1.当配置文件中NR_SHELL_USING_EXPORT_CMD未被定义,在**static_cmd[]**表中写入
+
+  ```c
+  const static_cmd_st static_cmd[] =
+  {
+     .....
+     {"your_command_name",your_command_funtion},
+     .....
+     {"\0",NULL}
+  };
+  ```
+
+  **_注意:不要删除{"\0",NULL}!_**
+
+  2.当配置文件中NR_SHELL_USING_EXPORT_CMD被定义,且NR_SHELL_CMD_EXPORT()支持使用的编译器时,可以使用以下方式注册命令
+
+  ```c
+  NR_SHELL_CMD_EXPORT(your_command_name,your_command_funtion);
+  ```
+
+  ## 注意事项
+
+  根据你的使用习惯使用NR_SHELL_USING_EXPORT_CMD选择命令注册方式。
+
+  使用注册表注册命令时,确保您的工程中存在注册表
+
+  ```c
+  const static_cmd_st static_cmd[] ={   .....   {"\0",NULL}};
+  ```
+
+  使用NR_SHELL_CMD_EXPORT()时确保,NR_SHELL_CMD_EXPORT()支持使用的编译器,否则会报错。
+
+  nr_micro_shell 不支持ESC键等控制键(控制符)。
+
+  ## 原地址连接
+
+  - 主页: <https://gitee.com/nrush/nr_micro_shell>

+ 168 - 0
components/nr_micro_shell/ansi.c

@@ -0,0 +1,168 @@
+/**
+ * @file      ansi.c
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      28 Oct 2019
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/* Includes ------------------------------------------------------------------ */
+#include "ansi.h"
+#include <stdio.h>
+
+ansi_st nr_ansi;
+
+const char nr_ansi_in_cmd[] = {'m', 'I', 'A', 'B', 'C', 'D', 'X', 'K', 'M', 'P', 'J', '@', 'L', 'l', 'h', 'n', 'H', 's', 'u', '~','\0'};
+void (*const nr_ansi_in_cmd_fun[])(ansi_st *) =
+    {
+        nr_ansi_in_m_function,
+        nr_ansi_in_I_function,
+        nr_ansi_in_A_function,
+        nr_ansi_in_B_function,
+        nr_ansi_in_C_function,
+        nr_ansi_in_D_function,
+        nr_ansi_in_X_function,
+        nr_ansi_in_K_function,
+        nr_ansi_in_M_function,
+        nr_ansi_in_P_function,
+        nr_ansi_in_J_function,
+        nr_ansi_in_at_function,
+        nr_ansi_in_L_function,
+        nr_ansi_in_l_function,
+        nr_ansi_in_h_function,
+        nr_ansi_in_n_function,
+        nr_ansi_in_H_function,
+        nr_ansi_in_s_function,
+        nr_ansi_in_u_function,
+		nr_ansi_in___function,
+	};
+
+const char nr_ansi_in_special_symbol[] = {'\b', '\n', '\r', '\t', '\0'};
+void (*const nr_ansi_in_special_symbol_fun[])(ansi_st *) =
+    {
+        nr_ansi_in_bsb_function,
+        nr_ansi_in_bsn_function,
+        nr_ansi_in_bsr_function,
+        nr_ansi_in_bst_function};
+
+int ansi_search_char(char x, const char *buf)
+{
+    int i = 0;
+    for (i = 0; (buf[i] != x) && (buf[i] != '\0'); i++)
+        ;
+    if (buf[i] != '\0')
+    {
+        return i;
+    }
+    else
+    {
+        return -1;
+    }
+}
+
+enum
+{
+    ANSI_NO_CTRL_CHAR,
+	ANSI_MAYBE_CTRL_CHAR,
+    ANSI_WAIT_CTRL_CHAR_END,
+};
+
+void ansi_init(ansi_st *ansi)
+{
+    ansi->counter = 0;
+    ansi->p = -1;
+
+    ansi->current_line[ansi->counter] = '\0';
+
+    ansi->cmd_num = 0;
+    ansi->combine_state = ANSI_NO_CTRL_CHAR;
+}
+
+void ansi_clear_current_line(ansi_st *ansi)
+{
+    ansi->counter = 0;
+    ansi->p = -1;
+
+    ansi->current_line[ansi->counter] = '\0';
+}
+
+char ansi_get_char(char x, ansi_st *ansi)
+{
+    int cmd_id = -1;
+
+    if (ansi->combine_state == ANSI_NO_CTRL_CHAR)
+    {
+        cmd_id = ansi_search_char(x, nr_ansi_in_special_symbol);
+        if (cmd_id >= 0)
+        {
+            if (nr_ansi_in_special_symbol_fun[cmd_id] != NULL)
+            {
+                nr_ansi_in_special_symbol_fun[cmd_id](ansi);
+            }
+        }
+        else if (x == '\033')
+        {
+            ansi->combine_state = ANSI_WAIT_CTRL_CHAR_END;
+            ansi->combine_buf[ansi->cmd_num] = x;
+			ansi->cmd_num++;
+        }
+        else
+        {
+			nr_ansi_common_char_slover(ansi,x);
+        }
+    }
+    else if (ansi->combine_state == ANSI_WAIT_CTRL_CHAR_END)
+    {
+        ansi->combine_buf[ansi->cmd_num] = x;
+
+        if (('a' <= x && 'z' >= x) || ('A' <= x && 'Z' >= x) || x== '~')
+        {
+            cmd_id = ansi_search_char(x, nr_ansi_in_cmd);
+            nr_ansi_in_cmd_fun[cmd_id](ansi);
+
+            ansi->cmd_num = 0;
+            ansi->combine_state = ANSI_NO_CTRL_CHAR;
+        }
+        else if (ansi->cmd_num > 18)
+        {
+            ansi->cmd_num = 0;
+            ansi->combine_state = ANSI_NO_CTRL_CHAR;
+        }
+        else
+        {
+            ansi->cmd_num++;
+        }
+    }
+    else
+    {
+        ansi->combine_state = ANSI_NO_CTRL_CHAR;
+    }
+
+    return x;
+}
+
+/******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 57 - 0
components/nr_micro_shell/ansi.h

@@ -0,0 +1,57 @@
+/**
+ * @file      ansi.h
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      28 Oct 2019
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __ansi_h
+#define __ansi_h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ansi_port.h"
+#include "stdio.h"
+
+    char ansi_get_char(char x, ansi_st *ansi);
+    void ansi_init(ansi_st *ansi);
+    void ansi_clear_current_line(ansi_st *ansi);
+
+    extern ansi_st nr_ansi;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 133 - 0
components/nr_micro_shell/ansi_def.h

@@ -0,0 +1,133 @@
+/**
+ * @file      ansi_def.h
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      11 June 2020
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ * 
+ * Change Logs:
+ * Date             Author              Notes
+ * 2020-6-11        Ji Youzhou          first version
+ * 
+ */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __ansi_def_h
+#define __ansi_def_h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "nr_micro_shell_config.h"
+
+#define NR_ANSI_CTRL_MAX_LEN 20
+#define NR_ANSI_MAX_EX_DATA_NUM 1
+
+    enum
+    {
+        ANSI_ENABLE_SHOW,
+        ANSI_DISABLE_SHOW
+    };
+
+    typedef struct nr_ansi_struct
+    {
+        short p;
+        unsigned int counter;
+        char current_line[NR_ANSI_LINE_SIZE];
+
+        char combine_buf[NR_ANSI_CTRL_MAX_LEN];
+        char cmd_num;
+        char combine_state;
+    } ansi_st;
+
+    typedef void (*ansi_fun_t)(ansi_st *);
+
+#define NR_ANSI_SET_TEXT(cmd) ((const char *)"\033["##cmd##"m") /** the form of set text font */
+
+/** set the color of background */
+#define NR_ANSI_BBLACK "40"
+#define NR_ANSI_BRED "41"
+#define NR_ANSI_BGREEN "42"
+#define NR_ANSI_BGRAY "43"
+#define NR_ANSI_BBLUE "44"
+#define NR_ANSI_BPURPLE "45"
+#define NR_ANSI_BAQUAM "46"
+#define NR_ANSI_BWHITE "47"
+
+/** set the color of character */
+#define NR_ANSI_FBLACK "30"
+#define NR_ANSI_FRED "31"
+#define NR_ANSI_FGREEN "32"
+#define NR_ANSI_FGRAY "33"
+#define NR_ANSI_FBLUE "34"
+#define NR_ANSI_FPURPLE "35"
+#define NR_ANSI_FAQUAM "36"
+#define NR_ANSI_FWHITE "37"
+
+/** special effect */
+#define NR_ANSI_NORMAL "0"
+#define NR_ANSI_BRIGHT "1"
+#define NR_ANSI_UNDERLINE "4"
+#define NR_ANSI_FLASH "5"
+#define NR_ANSI_INVERSE "7"
+#define NR_ANSI_INVISABLE "8"
+
+/****************************************************/
+
+/** clear code */
+#define NR_ANSI_CLEAR_RIGHT "\033[K"
+#define NR_ANSI_CLEAR_LEFT "\033[1K"
+#define NR_ANSI_CLEAR_WHOLE "\033[2K"
+
+#define NR_ANSI_CLEAR_SCREEN "\033[2J"
+
+#define NR_ANSI_HIDE_COURSER "\033[?25l"
+#define NR_ANSI_SHOW_COURSER "\033[?25h"
+
+#define NR_ANSI_SET_FONT(cmd) ((const char *)"\033["#cmd"I")
+#define NR_ANSI_CLR_R_NCHAR(cmd) ((const char *)"\033["#cmd"X")
+#define NR_ANSI_CLR_R_MV_L_NCHAR(cmd) ((const char *)"\033["#cmd"P")
+
+/** move course code */
+#define NR_ANSI_MV_L_N(n) ((const char *)"\033["#n"D")
+#define NR_ANSI_MV_R_N(n) ((const char *)"\033["#n"C")
+
+#define NR_ANSI_NORMAL "0"
+#define NR_ANSI_SONG "1"
+#define NR_ANSI_HEI "2"
+#define NR_ANSI_KAI "3"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 284 - 0
components/nr_micro_shell/ansi_port.c

@@ -0,0 +1,284 @@
+/**
+ * @file      ansi_port.c
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      28 Oct 2019
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "ansi_port.h"
+#include "ansi.h"
+#include <stdio.h>
+#include "nr_micro_shell.h"
+#include <string.h>
+
+// show string
+void ansi_show_str(char *str, unsigned int len)
+{
+    unsigned int i;
+    for (i = 0; i < len; i++)
+    {
+        ansi_show_char(str[i]);
+    }
+}
+
+void nr_ansi_common_char_slover(ansi_st *ansi,char x)
+{
+	unsigned int i;
+	
+	if (ansi->counter < NR_ANSI_LINE_SIZE - 2)
+    {
+        if (ansi->p < ansi->counter)
+        {
+            for (i = ansi->counter; i > ansi->p; i--)
+            {
+                ansi->current_line[i] = ansi->current_line[i - 1];
+            }
+        }
+
+        ansi->p++;
+        ansi->counter++;
+
+        ansi->current_line[ansi->p] = x;
+
+        ansi->current_line[ansi->counter] = '\0';
+		if(ansi->p+1 < ansi->counter)
+		{
+			shell_printf("\033[1@");
+		}
+
+        #ifndef NR_MICRO_SHELL_SIMULATOR	
+        ansi_show_char(x);
+        #endif	
+    }
+    else
+    {
+        ansi->counter = NR_ANSI_LINE_SIZE - 3;
+        if (ansi->p >= ansi->counter)
+        {
+            ansi->p = ansi->counter - 1;
+        }
+        ansi->current_line[ansi->counter] = '\0';
+    }
+}
+
+void nr_ansi_ctrl_common_slover(ansi_st *ansi)
+{
+    unsigned int i;
+    for (i = 0; i < ansi->cmd_num; i++)
+    {
+        ansi_show_char((*(ansi->combine_buf + i)));
+    }
+}
+
+// line break '\r' processing
+void nr_ansi_in_enter(ansi_st *ansi)
+{
+#if NR_SHELL_END_OF_LINE == 1
+	ansi->p = -1;
+    ansi->counter = 0;
+
+    nr_shell.cmd_his.index = nr_shell.cmd_his.len;
+    ansi_show_char('\r');
+    ansi_show_char('\n');
+#else
+    ansi_show_char('\r');
+#endif
+}
+
+// line break '\n' processing
+void nr_ansi_in_newline(ansi_st *ansi)
+{
+	ansi->p = -1;
+    ansi->counter = 0;
+
+    nr_shell.cmd_his.index = nr_shell.cmd_his.len;
+#ifndef NR_MICRO_SHELL_SIMULATOR	
+#if NR_SHELL_END_OF_LINE != 1
+    ansi_show_char('\r');
+    ansi_show_char('\n');
+#else
+    ansi_show_char('\n');
+#endif
+#endif
+}
+
+// Backspace '\b' processing
+void nr_ansi_in_backspace(ansi_st *ansi)
+{
+    unsigned int i;
+
+    if (ansi->p >= 0)
+    {
+        for (i = ansi->p; i < ansi->counter; i++)
+        {
+            ansi->current_line[i] = ansi->current_line[i + 1];
+        }
+
+        ansi->p--;
+        ansi->counter--;
+
+        ansi_show_char('\b');
+#if NR_SHLL_FULL_ANSI == 1
+        shell_printf(NR_ANSI_CLR_R_MV_L_NCHAR(1));
+#endif
+    }
+}
+
+// up key processing
+void nr_ansi_in_up(ansi_st *ansi)
+{
+    if (nr_shell.cmd_his.index > 0)
+    {
+#if NR_SHLL_FULL_ANSI == 1
+        shell_printf("\033[%dD", ansi->p + 1);
+        shell_printf(NR_ANSI_CLEAR_RIGHT);
+#else
+        shell_printf("\r\n");
+        shell_printf(nr_shell.user_name);
+#endif
+
+        shell_his_copy_queue_item(&nr_shell.cmd_his, nr_shell.cmd_his.index, ansi->current_line);
+        ansi->counter = strlen(ansi->current_line);
+        ansi->p = ansi->counter - 1;
+
+        ansi_show_str(ansi->current_line, ansi->counter);
+		
+		nr_shell.cmd_his.index--;
+        nr_shell.cmd_his.index = (nr_shell.cmd_his.index == 0) ? nr_shell.cmd_his.len : nr_shell.cmd_his.index;
+    }
+}
+
+// down key processing
+void nr_ansi_in_down(ansi_st *ansi)
+{
+    if (nr_shell.cmd_his.index > 0)
+    {
+#if NR_SHLL_FULL_ANSI == 1
+        shell_printf("\033[%dD", ansi->p + 1);
+        shell_printf(NR_ANSI_CLEAR_RIGHT);
+#else
+        shell_printf("\r\n");
+        shell_printf(nr_shell.user_name);
+#endif
+
+        shell_his_copy_queue_item(&nr_shell.cmd_his, nr_shell.cmd_his.index, ansi->current_line);
+        ansi->counter = strlen(ansi->current_line);
+        ansi->p = ansi->counter - 1;
+
+        ansi_show_str(ansi->current_line, ansi->counter);
+		
+		nr_shell.cmd_his.index++;
+        nr_shell.cmd_his.index = (nr_shell.cmd_his.index > nr_shell.cmd_his.len) ? 1 : nr_shell.cmd_his.index;
+    }
+}
+
+// left key <- processing
+void nr_ansi_in_left(ansi_st *ansi)
+{
+    if (ansi->p > -1)
+    {
+        ansi->p--;
+#if NR_SHLL_FULL_ANSI == 1
+        shell_printf("\033[1D");
+#endif
+    }
+}
+
+// right key <- processing
+void nr_ansi_in_right(ansi_st *ansi)
+{
+    if (ansi->p < (int)(ansi->counter - 1))
+    {
+        ansi->p++;
+#if NR_SHLL_FULL_ANSI == 1
+        shell_printf("\033[1C");
+#endif
+    }
+}
+
+// tab key processing
+void nr_ansi_in_tab(ansi_st *ansi)
+{
+    unsigned char i;
+    char *cmd;
+    cmd = shell_cmd_complete(&nr_shell, ansi->current_line);
+    if (cmd != NULL)
+    {
+
+        if (ansi->counter == 0)
+        {
+            shell_printf("\r\n");
+            for (i = 0; nr_shell.static_cmd[i].fp != NULL; i++)
+            {
+                shell_printf("%s",nr_shell.static_cmd[i].cmd);
+                shell_printf("\r\n");
+            }
+
+            shell_printf("%s",nr_shell.user_name);
+        }
+        else
+        {
+#if NR_SHLL_FULL_ANSI == 1
+            shell_printf("\033[%dD", ansi->p + 1);
+            shell_printf(NR_ANSI_CLEAR_RIGHT);
+#else
+            shell_printf("\r\n");
+            shell_printf("%s",nr_shell.user_name);
+#endif
+            ansi->counter = strlen(cmd);
+            ansi->p = ansi->counter - 1;
+            strcpy(ansi->current_line, cmd);
+
+            ansi_show_str(ansi->current_line, ansi->counter);
+        }
+    }
+}
+
+/*ansi delete*/
+void nr_ansi_in__(ansi_st *ansi)
+{
+	unsigned int i;
+	if(ansi->combine_buf[2] == '3')
+	{
+		for(i = ansi->p+1;i<ansi->counter;i++)
+		{
+			ansi->current_line[i] = ansi->current_line[i+1];
+		}
+		if((short)ansi->counter > ansi->p)
+		{
+			ansi->counter--;
+#if NR_SHLL_FULL_ANSI == 1
+			ansi_show_str("\033[1P",4);
+#endif
+		}
+		
+	}
+}
+
+/******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 90 - 0
components/nr_micro_shell/ansi_port.h

@@ -0,0 +1,90 @@
+/**
+ * @file      ansi_port.h
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      28 Oct 2019
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __ansi_port_h
+#define __ansi_port_h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /* Includes ------------------------------------------------------------------*/
+#include "ansi_def.h"
+
+    void nr_ansi_ctrl_common_slover(ansi_st *ansi);
+    void nr_ansi_in_newline(ansi_st *ansi);
+    void nr_ansi_in_backspace(ansi_st *ansi);
+    void nr_ansi_in_up(ansi_st *ansi);
+    void nr_ansi_in_down(ansi_st *ansi);
+    void nr_ansi_in_left(ansi_st *ansi);
+    void nr_ansi_in_right(ansi_st *ansi);
+    void nr_ansi_in_tab(ansi_st *ansi);
+    void nr_ansi_in_enter(ansi_st *ansi);
+    void nr_ansi_in__(ansi_st *ansi);
+    void nr_ansi_common_char_slover(ansi_st *ansi, char x);
+
+/** special characters functions \b,\n,\r,\t*/
+#define nr_ansi_in_bsb_function nr_ansi_in_backspace
+#define nr_ansi_in_bsn_function nr_ansi_in_newline
+#define nr_ansi_in_bsr_function nr_ansi_in_enter
+#define nr_ansi_in_bst_function nr_ansi_in_tab
+
+/** control characters functions */
+#define nr_ansi_in_m_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_I_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_A_function nr_ansi_in_up
+#define nr_ansi_in_B_function nr_ansi_in_down
+#define nr_ansi_in_C_function nr_ansi_in_right
+#define nr_ansi_in_D_function nr_ansi_in_left
+#define nr_ansi_in_X_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_K_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_M_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_P_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_J_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_at_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_L_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_l_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_h_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_n_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_H_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_s_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in_u_function nr_ansi_ctrl_common_slover
+#define nr_ansi_in___function nr_ansi_in__
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 371 - 0
components/nr_micro_shell/nr_micro_shell.c

@@ -0,0 +1,371 @@
+/**
+ * @file      nr_micro_shell.c
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      28 Oct 2019
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "nr_micro_shell.h"
+#include <string.h>
+#include <ctype.h>
+
+
+NR_SHELL_CMD_EXPORT_START(0,NULL);
+NR_SHELL_CMD_EXPORT_END(n,NULL);
+
+shell_st nr_shell =
+    {
+        .user_name = NR_SHELL_USER_NAME,
+        .static_cmd = nr_cmd_start_add,
+};
+
+static char *nr_shell_strtok(char *string_org, const char *demial)
+{
+	static unsigned char *last;
+	unsigned char *str;
+	const unsigned char *ctrl = (const unsigned char *)demial;
+	unsigned char map[32];
+	int count;
+
+	for (count = 0; count < 32; count++)
+	{
+		map[count] = 0;
+	}
+	do
+	{
+		map[*ctrl >> 3] |= (1 << (*ctrl & 7));
+	} while (*ctrl++);
+	if (string_org)
+	{
+		str = (unsigned char *)string_org;
+	}
+	else
+	{
+		str = last;
+	}
+	while ((map[*str >> 3] & (1 << (*str & 7))) && *str)
+	{
+		str++;
+	}
+	string_org = (char *)str;
+	for (; *str; str++)
+	{
+		if (map[*str >> 3] & (1 << (*str & 7)))
+		{
+			*str++ = '\0';
+			break;
+		}
+	}
+	last = str;
+	if (string_org == (char *)str)
+	{
+		return NULL;
+	}
+	else
+	{
+		return string_org;
+	}
+}
+
+void _shell_init(shell_st *shell)
+{
+
+#ifdef NR_SHELL_SHOW_LOG
+	shell_printf(" _   _ ____    __  __ _                  ____  _          _ _ \r\n");
+	shell_printf("| \\ | |  _ \\  |  \\/  (_) ___ _ __ ___   / ___|| |__   ___| | |\r\n");
+	shell_printf("|  \\| | |_) | | |\\/| | |/ __| '__/ _ \\  \\___ \\| '_ \\ / _ \\ | |\r\n");
+	shell_printf("| |\\  |  _ <  | |  | | | (__| | | (_) |  ___) | | | |  __/ | |\r\n");
+	shell_printf("|_| \\_|_| \\_\\ |_|  |_|_|\\___|_|  \\___/  |____/|_| |_|\\___|_|_|\r\n");
+	shell_printf("                                                              \r\n");
+#endif
+
+	shell_printf("%s",shell->user_name);
+	shell_his_queue_init(&shell->cmd_his);
+	shell_his_queue_add_cmd(&shell->cmd_his, "ls cmd");
+	shell->cmd_his.index = 1;
+}
+
+shell_fun_t shell_search_cmd(shell_st *shell, char *str)
+{
+	unsigned int i = 0;
+	while (shell->static_cmd[i].fp != NULL)
+	{
+		if (!strcmp(str, shell->static_cmd[i].cmd))
+		{
+			return shell->static_cmd[i].fp;
+		}
+		i++;
+	}
+
+	return NULL;
+}
+
+void shell_parser(shell_st *shell, char *str)
+{
+	char argc = 0;
+	char argv[NR_SHELL_CMD_LINE_MAX_LENGTH + NR_SHELL_CMD_PARAS_MAX_NUM];
+	char *token = str;
+	shell_fun_t fp;
+	char index = NR_SHELL_CMD_PARAS_MAX_NUM;
+
+	if (shell_his_queue_search_cmd(&shell->cmd_his, str) == 0 && str[0] != '\0')
+	{
+		shell_his_queue_add_cmd(&shell->cmd_his, str);
+	}
+
+	if (strlen(str) > NR_SHELL_CMD_LINE_MAX_LENGTH)
+	{
+		shell_printf("this command is too long."NR_SHELL_NEXT_LINE);
+		shell_printf("%s",shell->user_name);
+		return;
+	}
+
+	token = nr_shell_strtok(token, " ");
+	fp = shell_search_cmd(shell, str);
+
+	if (fp == NULL)
+	{
+		if (isalpha(str[0]))
+		{
+			shell_printf("no command named: %s"NR_SHELL_NEXT_LINE, token);
+		}
+	}
+	else
+	{
+		argv[argc] = index;
+		strcpy(argv + index, str);
+		index += strlen(str) + 1;
+		argc++;
+
+		token = nr_shell_strtok(NULL, " ");
+		while (token != NULL)
+		{
+			argv[argc] = index;
+			strcpy(argv + index, token);
+			index += strlen(token) + 1;
+			argc++;
+			token = nr_shell_strtok(NULL, " ");
+		}
+	}
+
+	if (fp != NULL)
+	{
+		fp(argc, argv);
+	}
+
+	shell_printf("%s",shell->user_name);
+}
+
+char *shell_cmd_complete(shell_st *shell, char *str)
+{
+	char *temp = NULL;
+	unsigned char i;
+	char *best_matched = NULL;
+	unsigned char min_position = 255;
+
+	for (i = 0; shell->static_cmd[i].cmd[0] != '\0'; i++)
+	{
+		temp = NULL;
+		temp = strstr(shell->static_cmd[i].cmd, str);
+		if (temp != NULL && ((unsigned long)temp - (unsigned long)(&shell->static_cmd[i]) < min_position))
+		{
+			min_position = (unsigned long)temp - (unsigned long)(&shell->static_cmd[i]);
+			best_matched = (char *)&shell->static_cmd[i];
+			if (min_position == 0)
+			{
+				break;
+			}
+		}
+	}
+
+	return best_matched;
+}
+
+void shell_his_queue_init(shell_his_queue_st *queue)
+{
+	queue->fp = 0;
+	queue->rp = 0;
+	queue->len = 0;
+
+	queue->store_front = 0;
+	queue->store_rear = 0;
+	queue->store_num = 0;
+}
+
+void shell_his_queue_add_cmd(shell_his_queue_st *queue, char *str)
+{
+	unsigned short int str_len;
+	unsigned short int i;
+
+	str_len = strlen(str);
+
+	if (str_len > NR_SHELL_CMD_HISTORY_BUF_LENGTH)
+	{
+		return;
+	}
+
+	while (str_len > (NR_SHELL_CMD_HISTORY_BUF_LENGTH - queue->store_num) || queue->len == NR_SHELL_MAX_CMD_HISTORY_NUM)
+	{
+
+		queue->fp++;
+		queue->fp = (queue->fp > NR_SHELL_MAX_CMD_HISTORY_NUM) ? 0 : queue->fp;
+		queue->len--;
+
+		if (queue->store_front <= queue->queue[queue->fp])
+		{
+			queue->store_num -= queue->queue[queue->fp] - queue->store_front;
+		}
+		else
+		{
+			queue->store_num -= queue->queue[queue->fp] + NR_SHELL_CMD_HISTORY_BUF_LENGTH - queue->store_front + 1;
+		}
+
+		queue->store_front = queue->queue[queue->fp];
+	}
+
+	queue->queue[queue->rp] = queue->store_rear;
+	queue->rp++;
+	queue->rp = (queue->rp > NR_SHELL_MAX_CMD_HISTORY_NUM) ? 0 : queue->rp;
+	queue->len++;
+
+	for (i = 0; i < str_len; i++)
+	{
+		queue->buf[queue->store_rear] = str[i];
+		queue->store_rear++;
+		queue->store_rear = (queue->store_rear > NR_SHELL_CMD_HISTORY_BUF_LENGTH) ? 0 : queue->store_rear;
+		queue->store_num++;
+	}
+	queue->queue[queue->rp] = queue->store_rear;
+}
+
+unsigned short int shell_his_queue_search_cmd(shell_his_queue_st *queue, char *str)
+{
+	unsigned short int str_len;
+	unsigned short int i, j;
+	unsigned short int index_temp = queue->fp;
+	unsigned short int start;
+	unsigned short int end;
+	unsigned short int cmd_len;
+	unsigned short int matched_id = 0;
+	unsigned short int buf_index;
+
+	if (queue->len == 0)
+	{
+		return matched_id;
+	}
+	else
+	{
+		str_len = strlen(str);
+		for (i = 0; i < queue->len; i++)
+		{
+			start = queue->queue[index_temp];
+			index_temp++;
+			index_temp = (index_temp > NR_SHELL_MAX_CMD_HISTORY_NUM) ? 0 : index_temp;
+			end = queue->queue[index_temp];
+
+			if (start <= end)
+			{
+				cmd_len = end - start;
+			}
+			else
+			{
+				cmd_len = NR_SHELL_CMD_HISTORY_BUF_LENGTH + 1 - start + end;
+			}
+
+			if (cmd_len == str_len)
+			{
+				matched_id = i + 1;
+				buf_index = start;
+				for (j = 0; j < str_len; j++)
+				{
+					if (queue->buf[buf_index] != str[j])
+					{
+						matched_id = 0;
+						break;
+					}
+
+					buf_index++;
+					buf_index = (buf_index > NR_SHELL_CMD_HISTORY_BUF_LENGTH) ? 0 : buf_index;
+				}
+
+				if (matched_id != 0)
+				{
+					return matched_id;
+				}
+			}
+		}
+
+		return 0;
+	}
+}
+
+void shell_his_copy_queue_item(shell_his_queue_st *queue, unsigned short i, char *str_buf)
+{
+	unsigned short index_temp;
+	unsigned short start;
+	unsigned short end;
+	unsigned short j;
+
+	if (i <= queue->len)
+	{
+		index_temp = queue->fp + i - 1;
+		index_temp = (index_temp > NR_SHELL_MAX_CMD_HISTORY_NUM) ? (index_temp - NR_SHELL_MAX_CMD_HISTORY_NUM - 1) : index_temp;
+
+		start = queue->queue[index_temp];
+		index_temp++;
+		index_temp = (index_temp > NR_SHELL_MAX_CMD_HISTORY_NUM) ? 0 : index_temp;
+		end = queue->queue[index_temp];
+
+		if (start < end)
+		{
+			for (j = start; j < end; j++)
+			{
+				str_buf[j - start] = queue->buf[j];
+			}
+
+			str_buf[j - start] = '\0';
+		}
+		else
+		{
+			for (j = start; j < NR_SHELL_CMD_HISTORY_BUF_LENGTH + 1; j++)
+			{
+				str_buf[j - start] = queue->buf[j];
+			}
+
+			for (j = 0; j < end; j++)
+			{
+				str_buf[j + NR_SHELL_CMD_HISTORY_BUF_LENGTH + 1 - start] = queue->buf[j];
+			}
+
+			str_buf[j + NR_SHELL_CMD_HISTORY_BUF_LENGTH + 1 - start] = '\0';
+		}
+	}
+}
+
+/******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 154 - 0
components/nr_micro_shell/nr_micro_shell.h

@@ -0,0 +1,154 @@
+/**
+ * @file      nr_micro_shell.h
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      28 Oct 2019
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __nr_micro_shell_h
+#define __nr_micro_shell_h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /* Includes ------------------------------------------------------------------*/
+#include "stdio.h"
+#include "nr_micro_shell_config.h"
+#include "ansi.h"
+
+#ifndef shell_printf
+#define shell_printf(fmt, args...) printf(fmt, ##args);
+#endif
+
+    typedef void (*shell_fun_t)(char, char *);
+
+    typedef struct static_cmd_function_struct
+    {
+        char cmd[NR_SHELL_CMD_NAME_MAX_LENGTH];
+        void (*fp)(char argc, char *argv);
+        char *description;
+    } static_cmd_st;
+
+    typedef struct shell_history_queue_struct
+    {
+        unsigned short int fp;
+        unsigned short int rp;
+
+        unsigned short int len;
+        unsigned short int index;
+
+        unsigned short int store_front;
+        unsigned short int store_rear;
+        unsigned short int store_num;
+
+        char queue[NR_SHELL_MAX_CMD_HISTORY_NUM + 1];
+        char buf[NR_SHELL_CMD_HISTORY_BUF_LENGTH + 1];
+
+    } shell_his_queue_st;
+
+    typedef struct nr_shell
+    {
+        char user_name[NR_SHELL_USER_NAME_MAX_LENGTH];
+        const static_cmd_st *static_cmd;
+        shell_his_queue_st cmd_his;
+    } shell_st;
+
+    void _shell_init(shell_st *shell);
+    void shell_parser(shell_st *shell, char *str);
+    char *shell_cmd_complete(shell_st *shell, char *str);
+    void shell_his_queue_init(shell_his_queue_st *queue);
+    void shell_his_queue_add_cmd(shell_his_queue_st *queue, char *str);
+    unsigned short int shell_his_queue_search_cmd(shell_his_queue_st *queue, char *str);
+    void shell_his_copy_queue_item(shell_his_queue_st *queue, unsigned short i, char *str_buf);
+
+    extern shell_st nr_shell;
+
+#define shell_init()            \
+    {                           \
+        ansi_init(&nr_ansi);    \
+        _shell_init(&nr_shell); \
+    }
+
+#if NR_SHELL_END_OF_LINE == 1
+#define NR_SHELL_END_CHAR '\r'
+#else
+#define NR_SHELL_END_CHAR '\n'
+#endif
+	
+#if NR_SHELL_END_OF_LINE == 0
+#define NR_SHELL_NEXT_LINE "\n"
+#endif
+
+#if NR_SHELL_END_OF_LINE == 1
+#define NR_SHELL_NEXT_LINE "\r\n"
+#endif
+	
+#if NR_SHELL_END_OF_LINE == 2
+#define NR_SHELL_NEXT_LINE "\r\n"
+#endif
+
+#define shell(c)                                             \
+    {                                                        \
+        if (ansi_get_char(c, &nr_ansi) == NR_SHELL_END_CHAR) \
+        {                                                    \
+            shell_parser(&nr_shell, nr_ansi.current_line);   \
+            ansi_clear_current_line(&nr_ansi);               \
+        }                                                    \
+    }
+
+#ifdef USING_RT_THREAD
+    int rt_nr_shell_system_init(void);
+#endif
+
+#define NR_USED __attribute__((used))
+#define NR_SECTION(x) __attribute__((section(".rodata.nr_shell_cmd" x)))
+#define NR_SHELL_CMD_EXPORT_START(cmd, func) \
+    NR_USED const static_cmd_st _nr_cmd_start_ NR_SECTION("0.end") = {#cmd, NULL}
+#define NR_SHELL_CMD_EXPORT(cmd, func) \
+    NR_USED const static_cmd_st _nr_cmd_##cmd NR_SECTION("1") = {#cmd, func}
+#define NR_SHELL_CMD_EXPORT_END(cmd, func) \
+    NR_USED const static_cmd_st _nr_cmd_end_ NR_SECTION("1.end") = {#cmd, NULL}
+
+    
+#ifdef NR_SHELL_USING_EXPORT_CMD
+	extern const static_cmd_st _nr_cmd_start_;
+#define nr_cmd_start_add (&_nr_cmd_start_+1)
+#else
+	extern const static_cmd_st static_cmd[];
+#define nr_cmd_start_add (&static_cmd[0])
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 156 - 0
components/nr_micro_shell/nr_micro_shell_config.h

@@ -0,0 +1,156 @@
+/**
+ * @file      nr_micro_shell_config.h
+ * @author    Ji Youzhou
+ * @version   V0.1
+ * @date      28 Oct 2019
+ * @brief     [brief]
+ * *****************************************************************************
+ * @attention
+ * 
+ * MIT License
+ * 
+ * Copyright (C) 2019 Ji Youzhou. or its affiliates.  All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __nr_micro_shell_config_h
+#define __nr_micro_shell_config_h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define NR_MICRO_SHELL_SIMULATOR
+
+    /* Includes ------------------------------------------------------------------*/
+#ifndef NR_MICRO_SHELL_SIMULATOR
+#include <rtconfig.h>
+#include <rtthread.h>
+#endif
+
+
+#ifdef PKG_USING_NR_MICRO_SHELL
+
+/* use nr_micro_shell in rt_thread. */
+#define USING_RT_THREAD
+
+/* ANSI command line buffer size. */
+#define NR_ANSI_LINE_SIZE RT_NR_SHELL_LINE_SIZE
+
+/* Maximum user name length. */
+#define NR_SHELL_USER_NAME_MAX_LENGTH RT_NR_SHELL_USER_NAME_MAX_LENGTH
+
+/* Maximum command name length. */
+#define NR_SHELL_CMD_NAME_MAX_LENGTH RT_NR_SHELL_CMD_NAME_MAX_LENGTH
+
+/* Command line buffer size. */
+#define NR_SHELL_CMD_LINE_MAX_LENGTH NR_ANSI_LINE_SIZE
+
+/* The maximum number of parameters in the command. */
+#define NR_SHELL_CMD_PARAS_MAX_NUM RT_NR_SHELL_CMD_PARAS_MAX_NUM
+
+/* Command stores the most history commands (the maximum number here refers to the maximum number of commands that can be stored. When the history command line cache is full, it will automatically release the earliest command record) */
+#define NR_SHELL_MAX_CMD_HISTORY_NUM RT_NR_SHELL_MAX_CMD_HISTORY_NUM
+
+/* History command cache length */
+#define NR_SHELL_CMD_HISTORY_BUF_LENGTH RT_NR_SHELL_CMD_HISTORY_BUF_LENGTH
+
+#define NR_SHELL_USER_NAME RT_NR_SHELL_USER_NAME
+
+/*
+The end of line.
+0: \n
+1: \r
+2: \r\n
+*/
+#define NR_SHELL_END_OF_LINE RT_NR_SHELL_END_OF_LINE
+
+/* Weather the terminal support all ANSI codes. */
+#define NR_SHLL_FULL_ANSI 1
+
+/* Show logo or not. */
+#ifdef RT_NR_SHELL_SHOW_LOG
+#define NR_SHELL_SHOW_LOG
+#endif
+
+/* Use NR_SHELL_CMD_EXPORT() or not */
+#define NR_SHELL_USING_EXPORT_CMD
+
+/* If you use RTOS, you may need to do some special processing for printf(). */
+#define shell_printf(fmt, args...) rt_kprintf(fmt, ##args)
+#define ansi_show_char(x) rt_kprintf("%c", x)
+
+#endif
+
+#ifndef PKG_USING_NR_MICRO_SHELL
+/* ANSI command line buffer size. */
+#define NR_ANSI_LINE_SIZE 100
+
+/* Maximum user name length. */
+#define NR_SHELL_USER_NAME_MAX_LENGTH 30
+
+/* Maximum command name length. */
+#define NR_SHELL_CMD_NAME_MAX_LENGTH 10
+
+/* Command line buffer size. */
+#define NR_SHELL_CMD_LINE_MAX_LENGTH NR_ANSI_LINE_SIZE
+
+/* The maximum number of parameters in the command. */
+#define NR_SHELL_CMD_PARAS_MAX_NUM 10
+
+/* Command stores the most history commands (the maximum number here refers to the maximum number of commands that can be stored. When the history command line cache is full, it will automatically release the earliest command record) */
+#define NR_SHELL_MAX_CMD_HISTORY_NUM 3
+
+/* History command cache length */
+#define NR_SHELL_CMD_HISTORY_BUF_LENGTH 253
+
+/* The user's name. */
+#define NR_SHELL_USER_NAME "luatos@root:"
+
+/*
+0: \n
+1: \r
+2: \r\n
+*/
+#define NR_SHELL_END_OF_LINE 0
+
+/* Weather the terminal support all ANSI codes. */
+#define NR_SHLL_FULL_ANSI 1
+
+/* Show logo or not. */
+// #define NR_SHELL_SHOW_LOG
+
+// /* Use NR_SHELL_CMD_EXPORT() or not */
+// #define NR_SHELL_USING_EXPORT_CMD
+
+/* If you use RTOS, you may need to do some special processing for printf(). */
+#define shell_printf(fmt, args...) printf(fmt, ##args);
+#define ansi_show_char(x) putchar(x)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+    /******************* (C) COPYRIGHT 2019 Ji Youzhou *****END OF FILE*****************/

+ 119 - 0
components/onewire/binding/luat_lib_onewire.c

@@ -0,0 +1,119 @@
+/*
+@module  onewire
+@summary 单总线协议驱动
+@version 1.0
+@date    2023.11.16
+@author  wendal
+@tag     LUAT_USE_ONEWIRE
+@demo    onewire
+@usage
+-- 本代码库尚处于开发阶段
+*/
+
+#include "luat_base.h"
+#include "luat_mem.h"
+#include "luat_onewire.h"
+
+#define LUAT_LOG_TAG "onewire"
+#include "luat_log.h"
+
+static int l_onewire_open(lua_State *L)
+{
+    return 0;
+}
+
+static int l_onewire_close(lua_State *L)
+{
+    return 0;
+}
+
+
+/*
+读取DS18B20
+@api onewire.ds18b20(mode, pin, check)
+@int GPIO模式对应GPIO编号, HW模式根据实际硬件来确定
+@boolean 是否检查数据的CRC值,可选
+@int 模式, 只能是 onewire.GPIO 或者 onewire.HW,可选
+@return number 成功返回温度值,否则返回nil.单位 0.1摄氏度
+@usage
+
+-- GPIO模式,接 GPIO 9
+local temp = onewire.ds18b20(9, true, onewire.GPIO)
+if temp then
+    log.info("读取到的温度值", temp)
+else
+    log.info("读取失败")
+end
+
+*/
+static int l_onewire_ds18b20(lua_State *L)
+{
+    luat_onewire_ctx_t ctx = {0};
+    int ret = 0;
+    ctx.id = luaL_checkinteger(L, 1);
+    int check_crc = lua_toboolean(L, 2);
+    ctx.mode = luaL_optinteger(L, 3, LUAT_ONEWIRE_MODE_GPIO);
+    int32_t val = 0;
+    ret = luat_onewire_ds18b20(&ctx, check_crc, &val);
+    if (ret) {
+        return 0;
+    }
+    lua_pushinteger(L, val);
+    return 1;
+}
+
+/*
+读取DHT11
+@api onewire.dht1x(mode, pin, check)
+@int GPIO模式对应GPIO编号, HW模式根据实际硬件来确定
+@boolean 是否检查数据的CRC值,可选
+@int 模式, 只能是 onewire.GPIO 或者 onewire.HW,可选
+@return number 成功返回温度值,否则返回nil.单位 0.01摄氏度
+@return number 成功返回相对湿度,否则返回nil.单位 0.01%
+@usage
+
+-- GPIO模式,接 GPIO 9
+local temp = onewire.dht1x(onewire.GPIO, 9, true)
+if temp then
+    log.info("读取到的温度值", temp)
+else
+    log.info("读取失败")
+end
+
+*/
+static int l_onewire_dht1x(lua_State *L)
+{
+    luat_onewire_ctx_t ctx = {0};
+    int ret = 0;
+    ctx.id = luaL_checkinteger(L, 1);
+    int check_crc = lua_toboolean(L, 2);
+    ctx.mode = luaL_optinteger(L, 3, LUAT_ONEWIRE_MODE_GPIO);
+    int32_t temp = 0;
+    int32_t hm = 0;
+    ret = luat_onewire_dht(&ctx, &temp, &hm, check_crc);
+    if (ret) {
+        return 0;
+    }
+    lua_pushinteger(L, temp);
+    lua_pushinteger(L, hm);
+    return 2;
+}
+
+#include "rotable2.h"
+static const rotable_Reg_t reg_onewire[] =
+    {
+        {"ds18b20", ROREG_FUNC(l_onewire_ds18b20)},
+        {"dht1x", ROREG_FUNC(l_onewire_dht1x)},
+        {"open", ROREG_FUNC(l_onewire_open)},
+        {"close", ROREG_FUNC(l_onewire_close)},
+
+        {"GPIO", ROREG_INT(1)},
+        {"HW", ROREG_INT(2)},
+        {NULL, ROREG_INT(0)}
+    };
+
+LUAMOD_API int luaopen_onewire(lua_State *L)
+{
+    luat_newlib2(L, reg_onewire);
+    return 1;
+}

+ 44 - 0
components/onewire/include/luat_onewire.h

@@ -0,0 +1,44 @@
+#ifndef LUAT_ONEWIRE_H
+#define LUAT_ONEWIRE_H
+
+#define LUAT_ONEWIRE_MODE_GPIO 1
+#define LUAT_ONEWIRE_MODE_HW   2
+
+typedef struct luat_onewire_ctx
+{
+    int32_t id;
+    int32_t mode;
+    void* userdata;
+}luat_onewire_ctx_t;
+
+
+int luat_onewire_setup(luat_onewire_ctx_t* ctx);
+int luat_onewire_read(luat_onewire_ctx_t* ctx, char* buff, size_t len);
+int luat_onewire_write(luat_onewire_ctx_t* ctx, const char* buff, size_t len);
+int luat_onewire_close(luat_onewire_ctx_t* ctx);
+
+int luat_onewire_setup_gpio(luat_onewire_ctx_t* ctx);
+int luat_onewire_read_gpio(luat_onewire_ctx_t* ctx, char* buff, size_t len);
+int luat_onewire_write_gpio(luat_onewire_ctx_t* ctx, const char* buff, size_t len);
+int luat_onewire_close_gpio(luat_onewire_ctx_t* ctx);
+
+typedef int (*onewire_setup)(luat_onewire_ctx_t* ctx);
+typedef int (*onewire_read)(luat_onewire_ctx_t* ctx, char* buff, size_t len);
+typedef int (*onewire_write)(luat_onewire_ctx_t* ctx, const char* buff, size_t len);
+typedef int (*onewire_close)(luat_onewire_ctx_t* ctx);
+
+typedef struct luat_onewire_opt {
+    int32_t mode;
+    onewire_setup setup;
+    onewire_read read;
+    onewire_write write;
+    onewire_close close;
+}luat_onewire_opt_t;
+
+int luat_onewire_set_hw_opt(const luat_onewire_opt_t* ctx);
+
+int luat_onewire_ds18b20(luat_onewire_ctx_t* ctx, int check_crc, int32_t *re);
+
+int luat_onewire_dht(luat_onewire_ctx_t* ctx, int32_t* temp, int32_t* hm, int check_crc);
+
+#endif

+ 421 - 0
components/onewire/src/luat_onewire.c

@@ -0,0 +1,421 @@
+#include "luat_base.h"
+#include "luat_onewire.h"
+#include "luat_gpio.h"
+#include "luat_rtos.h"
+#include "luat_timer.h"
+
+#define LUAT_LOG_TAG "onewire"
+#include "luat_log.h"
+
+#define CONNECT_FAILED -1
+#define CONNECT_SUCCESS 0
+
+static luat_onewire_opt_t* opt_hw;
+static const luat_onewire_opt_t opt_gpio = {
+    .mode = LUAT_ONEWIRE_MODE_GPIO,
+    .setup = luat_onewire_setup_gpio,
+    .read = luat_onewire_read_gpio,
+    .write = luat_onewire_write_gpio,
+    .close = luat_onewire_close_gpio
+};
+
+int luat_onewire_set_hw_opt(const luat_onewire_opt_t* opt) {
+    opt_hw = (luat_onewire_opt_t*)opt;
+    return 0;
+}
+
+static const luat_onewire_opt_t* get_opt(luat_onewire_ctx_t* ctx) {
+    const luat_onewire_opt_t* opt = &opt_gpio;
+    if (ctx->mode != LUAT_ONEWIRE_MODE_GPIO) {
+        if (opt_hw == NULL) {
+            LLOGE("当前硬件未支持硬件模式驱动Onewire");
+            return NULL;
+        }
+        opt = opt_hw; 
+    }
+    return opt;
+}
+
+int luat_onewire_setup(luat_onewire_ctx_t* ctx) {
+    const luat_onewire_opt_t* opt = get_opt(ctx);
+    if (opt == NULL)
+        return -1;
+    return opt->setup(ctx);
+}
+
+int luat_onewire_read(luat_onewire_ctx_t* ctx, char* buff, size_t len){
+    const luat_onewire_opt_t* opt = get_opt(ctx);
+    if (opt == NULL)
+        return -1;
+    return opt->read(ctx, buff, len);
+}
+
+int luat_onewire_write(luat_onewire_ctx_t* ctx, const char* buff, size_t len){
+    const luat_onewire_opt_t* opt = get_opt(ctx);
+    if (opt == NULL)
+        return -1;
+    return opt->write(ctx, buff, len);
+}
+
+int luat_onewire_close(luat_onewire_ctx_t* ctx){
+    const luat_onewire_opt_t* opt = get_opt(ctx);
+    if (opt == NULL)
+        return -1;
+    return opt->close(ctx);
+}
+
+// TODO GPIO默认实现, 可以从lib_sensor迁移过来
+int luat_onewire_setup_gpio(luat_onewire_ctx_t* ctx) {
+    luat_gpio_mode(ctx->id, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
+    return 0;
+}
+
+int ds18b20_reset_gpio(luat_onewire_ctx_t* ctx) {
+    int pin = ctx->id;
+    luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
+    luat_gpio_set(pin, Luat_GPIO_LOW);
+    luat_timer_us_delay(550); /* 480us - 960us */
+    luat_gpio_set(pin, Luat_GPIO_HIGH);
+    luat_timer_us_delay(40); /* 15us - 60us*/
+    return 0;
+}
+
+int ds18b20_connect_gpio(luat_onewire_ctx_t* ctx) {
+    uint8_t retry = 0;
+    int pin = ctx->id;
+    luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
+
+    while (luat_gpio_get(pin) && retry < 200)
+    {
+        retry++;
+        luat_timer_us_delay(1);
+    };
+
+    if (retry >= 200)
+        return -1;
+    else
+        retry = 0;
+
+    while (!luat_gpio_get(pin) && retry < 240)
+    {
+        retry++;
+        luat_timer_us_delay(1);
+    };
+
+    if (retry >= 240)
+        return -1;
+
+    return 0;
+}
+
+static uint8_t w1_read_bit(int pin){
+  uint8_t data;
+  luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
+  luat_gpio_set(pin, Luat_GPIO_LOW);
+  luat_timer_us_delay(2);
+//   luat_gpio_set(pin, Luat_GPIO_HIGH);
+  luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
+  data = (uint8_t)luat_gpio_get(pin);
+  luat_timer_us_delay(60);
+  return data;
+}
+
+static uint8_t w1_read_byte(int pin)
+{
+  uint8_t i, j, dat;
+  dat = 0;
+  luat_timer_us_delay(90);
+  for (i = 1; i <= 8; i++)
+  {
+    j = w1_read_bit(pin);
+    dat = (j << 7) | (dat >> 1);
+  }
+
+  return dat;
+}
+
+int luat_onewire_read_gpio(luat_onewire_ctx_t* ctx, char* buff, size_t len) {
+    for (size_t i = 0; i < len; i++)
+    {
+        buff[i] = w1_read_byte(ctx->id);
+    }
+    return len;
+}
+
+static void w1_write_byte(int pin, uint8_t dat)
+{
+  uint8_t j;
+  uint8_t testb;
+  luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
+
+  for (j = 1; j <= 8; j++)
+  {
+    testb = dat & 0x01;
+    dat = dat >> 1;
+
+    if (testb)
+    {
+      luat_gpio_set(pin, Luat_GPIO_LOW);
+      luat_timer_us_delay(2);
+      luat_gpio_set(pin, Luat_GPIO_HIGH);
+      luat_timer_us_delay(60);
+    }
+    else
+    {
+      luat_gpio_set(pin, Luat_GPIO_LOW);
+      luat_timer_us_delay(60);
+      luat_gpio_set(pin, Luat_GPIO_HIGH);
+      luat_timer_us_delay(2);
+    }
+  }
+}
+
+int luat_onewire_write_gpio(luat_onewire_ctx_t* ctx, const char* buff, size_t len) {
+    for (size_t i = 0; i < len; i++)
+    {
+        w1_write_byte(ctx->id, (uint8_t)buff[i]);
+    }
+    
+    return len;
+}
+
+int luat_onewire_close_gpio(luat_onewire_ctx_t* ctx) {
+    luat_gpio_mode(ctx->id, Luat_GPIO_INPUT, Luat_GPIO_DEFAULT, Luat_GPIO_LOW);
+    return 0;
+}
+
+static const uint8_t crc8_maxim[256] = {
+    0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
+    157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
+    35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
+    190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
+    70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
+    219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
+    101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
+    248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
+    140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
+    17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
+    175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
+    50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
+    202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
+    87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
+    233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
+    116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
+
+
+int luat_onewire_ds18b20(luat_onewire_ctx_t* ctx, int check_crc, int32_t *re) {
+
+    // 初始化单总线
+    luat_os_entry_cri();
+    int ret = luat_onewire_setup(ctx);
+    if (ret)
+    {
+        LLOGW("setup失败 mode %d id %d ret %d", ctx->mode, ctx->id, ret);
+        goto exit;
+    }
+    // 复位设备
+    ret = ds18b20_reset_gpio(ctx);
+    // if (ret) {
+    //     LLOGW("reset失败 mode %d id %d ret %d", ctx->mode, ctx->id, ret);
+    //     return 0;
+    // }
+    // 建立连接
+    ret = ds18b20_connect_gpio(ctx);
+    if (ret)
+    {
+        LLOGW("connect失败 mode %d id %d ret %d", ctx->mode, ctx->id, ret);
+        goto exit;
+    }
+    // 写入2字节的数据
+    char wdata[] = {0xCC, 0x44}; /* skip rom */ /* convert */
+    luat_onewire_write(ctx, wdata, 2);
+
+    // 再次复位
+    ds18b20_reset_gpio(ctx);
+    // 再次建立连接
+    ret = ds18b20_connect_gpio(ctx);
+    if (ret)
+    {
+        LLOGW("connect失败2 mode %d id %d ret %d", ctx->mode, ctx->id, ret);
+        goto exit;
+    }
+
+    wdata[1] = 0xBE;
+    luat_onewire_write(ctx, wdata, 2);
+
+    uint8_t data[9] = {0};
+    // 校验模式读9个字节, 否则读2个字节
+    ret = luat_onewire_read(ctx, (char*)data, check_crc ? 9 : 2);
+    luat_onewire_close(ctx); // 后续不需要读取的
+    if (ret != 9)
+    {
+        LLOGW("read失败2 mode %d id %d ret %d", ctx->mode, ctx->id, ret);
+        goto exit;
+    }
+
+    if (check_crc)
+    {
+        uint8_t crc = 0;
+        for (size_t i = 0; i < 8; i++){
+            crc = crc8_maxim[crc ^ data[i]];
+        }
+        if (crc != data[8]) {
+            LLOGD("crc %02X %02X", crc, data[8]);
+            goto exit;
+        }
+    }
+
+    uint8_t TL, TH;
+    int32_t tem;
+    int32_t val;
+
+    TL = data[0];
+    TH = data[1];
+
+    // LLOGD("读出的数据");
+    // LLOGDUMP(data, 9);
+
+    if (TH > 7)
+    {
+        TH = ~TH;
+        TL = ~TL;
+        tem = TH;
+        tem <<= 8;
+        tem += TL;
+        tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
+        val = -tem;
+    }
+    else
+    {
+        tem = TH;
+        tem <<= 8;
+        tem += TL;
+        tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
+        val = tem;
+    }
+    luat_onewire_close(ctx); // 清理并关闭
+    luat_os_exit_cri();
+    *re = val;
+    return 0;
+exit:
+    luat_onewire_close(ctx); // 清理并关闭
+    luat_os_exit_cri();
+    return -1;
+}
+
+
+//------------------------------------------------------------------
+// DHT系列
+
+
+//总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒
+static void dht_reset(int pin)
+{
+  luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
+  luat_gpio_set(pin, Luat_GPIO_HIGH);
+  luat_timer_mdelay(100);
+  luat_gpio_set(pin, Luat_GPIO_LOW);
+  luat_timer_mdelay(20);
+  luat_gpio_set(pin, Luat_GPIO_HIGH);
+}
+
+
+//主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号
+static uint8_t dht_connect(int pin)
+{
+  luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
+  luat_timer_us_delay(10);
+  uint8_t retry = 0;
+  while (luat_gpio_get(pin) && retry < 100)
+  {
+    retry++;
+    luat_timer_us_delay(1);
+  };
+  if (retry >= 100)
+    return CONNECT_FAILED;
+
+  retry = 0;
+  while (!luat_gpio_get(pin) && retry < 100)
+  {
+    retry++;
+    luat_timer_us_delay(1);
+  };
+  if (retry >= 100)
+    return CONNECT_FAILED;
+
+  //相应完后等变低
+  while (luat_gpio_get(pin) && retry < 200)
+  {
+    retry++;
+    luat_timer_us_delay(1);
+  };
+  return CONNECT_SUCCESS;
+}
+
+//总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短决定了数据位是0还是1
+static uint8_t dht_read_bit(int pin)
+{
+  uint8_t retry=0,d=0;
+  while (!luat_gpio_get(pin) && retry < 200)
+  {
+    retry++;
+    luat_timer_us_delay(1);
+  };
+  luat_timer_us_delay(30);
+  d = luat_gpio_get(pin);
+  retry=0;
+  while (luat_gpio_get(pin) && retry < 200)
+  {
+    retry++;
+    luat_timer_us_delay(1);
+  };
+  return d;
+}
+
+static uint8_t dht_read_byte(int pin)
+{
+  uint8_t i, dat;
+  dat = 0;
+  for (i = 0; i < 8; i++)//MSB
+  {
+    dat<<=1;
+    dat+=dht_read_bit(pin);
+  }
+  return dat;
+}
+
+
+
+int luat_onewire_dht(luat_onewire_ctx_t* ctx, int32_t* temp, int32_t* hm, int check_crc) {
+    uint8_t buff[5];
+    dht_reset(ctx->id);
+    luat_os_entry_cri();
+    if(dht_connect(ctx->id))//没连上
+    {
+        luat_os_exit_cri();
+        return -1;
+    }
+  
+    for (size_t i = 0; i < 5; i++)
+    {
+        buff[i] = dht_read_byte(ctx->id);
+    }
+    
+    luat_os_exit_cri();
+
+    // LLOGD("读出的数据 %02X%02X%02X%02X%02X", buff[0], buff[1], buff[2], buff[3], buff[4]);
+
+    if (check_crc) {
+        uint8_t check_r = 0;
+        check_r = buff[0]+buff[1]+buff[2]+buff[3];
+        if (check_r != buff[4]) {
+            // LLOGD("crc校验不成功");
+            return -2;
+        }
+        // LLOGD("crc校验成功");
+    }
+    *temp = buff[0]*100+buff[1];
+    *hm = buff[2]*100+buff[3];
+    return 0;
+}
+

+ 39 - 0
components/rostr/luat_rostr.c

@@ -0,0 +1,39 @@
+#include "luat_base.h"
+
+#include "luat_rostr.h"
+#include "lstring.h"
+#include "lgc.h"
+
+#define LUAT_LOG_TAG "rostr"
+#include "luat_log.h"
+
+extern const luat_rostr_short_t rostr_shr_len0;
+extern const luat_rostr_short_t rostr_shr_len1[];
+extern const luat_rostr_short44_t rostr_shr_datas[];
+
+GCObject* luat_rostr_get_gc(const char *val_str, size_t len) {
+    if (len == 0) {
+        // LLOGD("返回空字符串的rostr指针");
+        return (GCObject*)&rostr_shr_len0;
+    }
+    if (len == 1) {
+        const uint8_t* tmp = (const uint8_t*)val_str;
+        return (GCObject*)&rostr_shr_len1[tmp[0]];
+    }
+    const luat_rostr_short44_t* ptr = rostr_shr_datas;
+    while (ptr->str.shrlen) {
+        if (ptr->str.shrlen == len && strncmp(val_str, ptr->data, len) == 0) {
+            // LLOGD("返回rostr指针 %p %s", ptr, ptr->data);
+            return (GCObject*)ptr;
+        }
+        ptr++;
+    }
+    return NULL;
+}
+TString* luat_rostr_get(const char *val_str, size_t len) {
+    GCObject* gc = luat_rostr_get_gc(val_str, len);
+    if (gc == NULL) {
+        return NULL;
+    }
+    return gco2ts(gc);
+}

+ 63 - 0
components/rostr/luat_rostr.h

@@ -0,0 +1,63 @@
+#ifndef LUAT_ROTSTR_H
+#define LUAT_ROTSTR_H
+
+#include "luat_base.h"
+#include "lstring.h"
+
+typedef struct luat_rostr
+{
+    // 标准头部, 12字节
+    char magic[4];   // 魔数,固定为"ROST"
+    uint8_t version; // 版本信息,从version 1开始, 1字节
+    uint8_t revert[3];// 预留空间
+
+    // 以下是版本1的定义
+    // 首先是短字符串的信息
+    uint32_t short_str_count; // 短字符串的总数量
+    uint32_t short_str_len;   // 短字符串的总长度
+    // 然后是长字符串的信息, 当前均为0, 后续再考虑
+    uint32_t long_str_count;  // 长字符串的总数量
+    uint32_t long_str_len;    // 长字符串的总长度
+    
+    //  每种长度的短字符串的字符串数量, 每个元素为uint16_t
+    uint16_t short_str_len_count[40];
+    
+    // 后续是具体数据, 需要通过运算得到具体的区域,然后遍历里面的字符串
+}luat_rostr_t;
+
+typedef struct luat_rostr_short {
+    TString str;
+    char data[4]; // 注意, 实际长度为str.len + 1, 末尾必须是\0
+    // 后面是字符串数据, 需要对其到4字节
+    // 例如 存储 "abcd" 4个字符, 那么实际长度为 16字节(TString头部) + 4字节(实际数据) + 1字节(\0) = 24字节(21字节对齐到4字节)
+}luat_rostr_short_t;
+
+typedef struct luat_rostr_short8 {
+    TString str;
+    char data[8];
+}luat_rostr_short8_t;
+typedef struct luat_rostr_short12 {
+    TString str;
+    char data[12];
+}luat_rostr_short12_t;
+typedef struct luat_rostr_short16 {
+    TString str;
+    char data[16];
+}luat_rostr_short16_t;
+typedef struct luat_rostr_short20 {
+    TString str;
+    char data[20];
+}luat_rostr_short20_t;
+typedef struct luat_rostr_short24 {
+    TString str;
+    char data[24];
+}luat_rostr_short24_t;
+typedef struct luat_rostr_short44 {
+    TString str;
+    char data[44];
+}luat_rostr_short44_t;
+
+TString* luat_rostr_get(const char *val_str, size_t len);
+GCObject* luat_rostr_get_gc(const char *val_str, size_t len);
+
+#endif

+ 1555 - 0
components/rostr/luat_rostr_data.c

@@ -0,0 +1,1555 @@
+#include "luat_base.h"
+#include "luat_rostr.h"
+#include "lstate.h"
+
+// 本文件用于存放静态字符串
+
+// 首先是几个特殊字符串
+
+// 字符串长度为0的字符串
+const luat_rostr_short_t rostr_shr_len0 = {
+    .str = {
+        .tt = LUA_TSHRSTR,
+        .hash = G_SEED_FIXED,
+        .marked = (1 << BLACKBIT)
+    }
+};
+
+// 长度为1的字符串
+const luat_rostr_short_t rostr_shr_len1[256] = {
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018759}, .data="\x00"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601875A}, .data="\x01"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601875B}, .data="\x02"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018744}, .data="\x03"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018745}, .data="\x04"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018746}, .data="\x05"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018747}, .data="\x06"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018740}, .data="\x07"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018741}, .data="\x08"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018742}, .data="\x09"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018743}, .data="\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601874C}, .data="\x0B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601874D}, .data="\x0C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601874E}, .data="\x0D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601874F}, .data="\x0E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018748}, .data="\x0F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018749}, .data="\x10"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601874A}, .data="\x11"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601874B}, .data="\x12"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B4}, .data="\x13"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B5}, .data="\x14"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B6}, .data="\x15"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B7}, .data="\x16"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B0}, .data="\x17"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B1}, .data="\x18"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B2}, .data="\x19"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B3}, .data="\x1A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186BC}, .data="\x1B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186BD}, .data="\x1C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186BE}, .data="\x1D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186BF}, .data="\x1E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B8}, .data="\x1F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B9}, .data=" "},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186BA}, .data="!"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186BB}, .data="\""},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A4}, .data="#"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A5}, .data="$"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A6}, .data="\x25"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A7}, .data="&"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A0}, .data="'"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A1}, .data="("},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A2}, .data=")"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A3}, .data="*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AC}, .data="+"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AD}, .data=","},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AE}, .data="-"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AF}, .data="."},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A8}, .data="/"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A9}, .data="0"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AA}, .data="1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AB}, .data="2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018694}, .data="3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018695}, .data="4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018696}, .data="5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018697}, .data="6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018690}, .data="7"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018691}, .data="8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018692}, .data="9"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018693}, .data=":"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869C}, .data=";"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869D}, .data="<"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869E}, .data="="},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869F}, .data=">"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018698}, .data="?"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018699}, .data="@"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869A}, .data="A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869B}, .data="B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018684}, .data="C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018685}, .data="D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018686}, .data="E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018687}, .data="F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018680}, .data="G"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018681}, .data="H"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018682}, .data="I"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018683}, .data="J"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601868C}, .data="K"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601868D}, .data="L"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601868E}, .data="M"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601868F}, .data="N"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018688}, .data="O"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018689}, .data="P"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601868A}, .data="Q"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601868B}, .data="R"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F4}, .data="S"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F5}, .data="T"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F6}, .data="U"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F7}, .data="V"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F0}, .data="W"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F1}, .data="X"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F2}, .data="Y"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F3}, .data="Z"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FC}, .data="["},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FD}, .data="\x5C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FE}, .data="]"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FF}, .data="^"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F8}, .data="_"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186F9}, .data="`"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FA}, .data="a"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FB}, .data="b"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E4}, .data="c"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E5}, .data="d"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E6}, .data="e"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E7}, .data="f"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E0}, .data="g"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E1}, .data="h"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E2}, .data="i"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E3}, .data="j"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EC}, .data="k"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186ED}, .data="l"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EE}, .data="m"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EF}, .data="n"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E8}, .data="o"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E9}, .data="p"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EA}, .data="q"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EB}, .data="r"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D4}, .data="s"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D5}, .data="t"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D6}, .data="u"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D7}, .data="v"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D0}, .data="w"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D1}, .data="x"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D2}, .data="y"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D3}, .data="z"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186DC}, .data="{"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186DD}, .data="|"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186DE}, .data="}"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186DF}, .data="~"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D8}, .data="\x7F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D9}, .data="\x80"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186DA}, .data="\x81"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186DB}, .data="\x82"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C4}, .data="\x83"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C5}, .data="\x84"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C6}, .data="\x85"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C7}, .data="\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C0}, .data="\x87"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C1}, .data="\x88"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C2}, .data="\x89"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C3}, .data="\x8A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186CC}, .data="\x8B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186CD}, .data="\x8C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186CE}, .data="\x8D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186CF}, .data="\x8E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C8}, .data="\x8F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186C9}, .data="\x90"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186CA}, .data="\x91"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186CB}, .data="\x92"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018634}, .data="\x93"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018635}, .data="\x94"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018636}, .data="\x95"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018637}, .data="\x96"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018630}, .data="\x97"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018631}, .data="\x98"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018632}, .data="\x99"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018633}, .data="\x9A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601863C}, .data="\x9B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601863D}, .data="\x9C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601863E}, .data="\x9D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601863F}, .data="\x9E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018638}, .data="\x9F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018639}, .data="\xA0"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601863A}, .data="\xA1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601863B}, .data="\xA2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018624}, .data="\xA3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018625}, .data="\xA4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018626}, .data="\xA5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018627}, .data="\xA6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018620}, .data="\xA7"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018621}, .data="\xA8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018622}, .data="\xA9"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018623}, .data="\xAA"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601862C}, .data="\xAB"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601862D}, .data="\xAC"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601862E}, .data="\xAD"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601862F}, .data="\xAE"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018628}, .data="\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018629}, .data="\xB0"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601862A}, .data="\xB1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601862B}, .data="\xB2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018614}, .data="\xB3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018615}, .data="\xB4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018616}, .data="\xB5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018617}, .data="\xB6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018610}, .data="\xB7"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018611}, .data="\xB8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018612}, .data="\xB9"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018613}, .data="\xBA"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601861C}, .data="\xBB"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601861D}, .data="\xBC"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601861E}, .data="\xBD"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601861F}, .data="\xBE"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018618}, .data="\xBF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018619}, .data="\xC0"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601861A}, .data="\xC1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601861B}, .data="\xC2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018604}, .data="\xC3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018605}, .data="\xC4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018606}, .data="\xC5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018607}, .data="\xC6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018600}, .data="\xC7"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018601}, .data="\xC8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018602}, .data="\xC9"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018603}, .data="\xCA"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601860C}, .data="\xCB"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601860D}, .data="\xCC"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601860E}, .data="\xCD"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601860F}, .data="\xCE"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018608}, .data="\xCF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018609}, .data="\xD0"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601860A}, .data="\xD1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601860B}, .data="\xD2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018674}, .data="\xD3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018675}, .data="\xD4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018676}, .data="\xD5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018677}, .data="\xD6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018670}, .data="\xD7"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018671}, .data="\xD8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018672}, .data="\xD9"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018673}, .data="\xDA"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601867C}, .data="\xDB"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601867D}, .data="\xDC"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601867E}, .data="\xDD"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601867F}, .data="\xDE"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018678}, .data="\xDF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018679}, .data="\xE0"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601867A}, .data="\xE1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601867B}, .data="\xE2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018664}, .data="\xE3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018665}, .data="\xE4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018666}, .data="\xE5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018667}, .data="\xE6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018660}, .data="\xE7"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018661}, .data="\xE8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018662}, .data="\xE9"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018663}, .data="\xEA"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601866C}, .data="\xEB"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601866D}, .data="\xEC"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601866E}, .data="\xED"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601866F}, .data="\xEE"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018668}, .data="\xEF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018669}, .data="\xF0"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601866A}, .data="\xF1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601866B}, .data="\xF2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018654}, .data="\xF3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018655}, .data="\xF4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018656}, .data="\xF5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018657}, .data="\xF6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018650}, .data="\xF7"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018651}, .data="\xF8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018652}, .data="\xF9"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018653}, .data="\xFA"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601865C}, .data="\xFB"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601865D}, .data="\xFC"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601865E}, .data="\xFD"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601865F}, .data="\xFE"},
+};
+
+const luat_rostr_short44_t rostr_shr_datas[] = {
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x4B18F625}, .data="sys_pub"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2EB3A989}, .data="taskId"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x95F94FCE}, .data="MSG_TIMER"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x3B5D0F6E}, .data="INF_TIMEOUT"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xCA11A544}, .data="receive"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xB51DF576}, .data="exparam"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x99790F9A}, .data="param"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB08B8A}, .data="msg"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x6383F2D3}, .data="safeRun"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA76C98F9}, .data="thread"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF171A8DE}, .data="tmpt"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA74935D0}, .data="remove"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x4C516DC8}, .data="dispatch"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8E83CD2F}, .data="insert"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x5F5969C2}, .data="publish"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x13E1B204}, .data="callback"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xE3AC9CE0}, .data="messageQueue"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x2835CB6C}, .data="subscribers"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x973DD01F}, .data="timerIsActive"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x8D1074FE}, .data="timerLoopStart"},        
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9A5C3262}, .data="_repeat"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0xB9F00535}, .data="timerAdvStart"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09A3B}, .data="fnc"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x9557EFDC}, .data="timerStopAll"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A2F1}, .data="cb"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x30A1A92F}, .data="(for control)"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x7D4E24C5}, .data="(for state)"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x3FC6D73A}, .data="(for generator)"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2C548960}, .data="number"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0C4AD}, .data="val"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x831AE76C}, .data="timerStop"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x0487DEA9}, .data="(for step)"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x289DFD2E}, .data="(for limit)"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xF8A5150C}, .data="(for index)"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BDEE}, .data="t2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BD8F}, .data="t1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xDA90A9A4}, .data="cmpTable"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA782620E}, .data="create"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0FBE4}, .data="fun"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x04E47D43}, .data="waitUntilExt"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xB92313DC}, .data="waitUntilMsg"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xBDA08EFB}, .data="unsubscribe"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x96524FD3}, .data="subscribe"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A4AC}, .data="id"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xB6CE46D1}, .data="waitUntil"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x095915ED}, .data="timer_stop"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97B8A540}, .data="yield"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xD1471911}, .data="message"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0xF64D9C7D}, .data="rtos.timer_start error"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x6DDB7DB4}, .data="timer_start"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xE4151EB2}, .data="timerid"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B69D}, .data="ms"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1704EBE}, .data="wait"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x58588904}, .data="running"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3AB60004}, .data="ismain"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x9A082CAE}, .data="check_task"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2A426F6F}, .data="resume"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x6A711504}, .data="coresume"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EAFDB3E}, .data="reboot"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x9D770907}, .data="timerStart"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x9CC7A6C9}, .data="coroutine.resume"},      
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BB25}, .data="\r\n"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xE56A047A}, .data="traceback"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x8695C695}, .data="traceBack"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB08B7F}, .data="arg"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A54E}, .data="co"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC1201A56}, .data="wrapper"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 23, .hash = 0x5E870D76}, .data="COROUTINE_ERROR_RESTART"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 25, .hash = 0xD211C766}, .data="COROUTINE_ERROR_ROLL_BACK"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16275AF}, .data="para"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x35ECD85A}, .data="taskTimerPool"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x025777DA}, .data="timerPool"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98CE4E9E}, .data="msgId"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xDE6DA56B}, .data="taskTimerId"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xBDBC7689}, .data="MSG_TIMER_ID_MAX"},      
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0xF03E5B45}, .data="TASK_TIMER_ID_MAX"},     
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC6DE511}, .data="2.3.2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x13685FFB}, .data="SCRIPT_LIB_VER"},        
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x6C746148}, .data="@/lua/sys.lua"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1706D93}, .data="stat"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xC206C1AA}, .data="打印"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1697B43}, .data="info"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0FBF8}, .data="run"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x83C893B0}, .data="taskInit"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0DCB5}, .data="sys"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD75143E1}, .data="main.lua"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x9148F7F2}, .data="profiler"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x62F3CAD3}, .data="xxtea"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xE254116D}, .data="onewire"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xAC898D84}, .data="ws2812"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xCF79E424}, .data="sqlite3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x6293D7B6}, .data="fatfs"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3C211843}, .data="ercoap"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x16C24E8C}, .data="errDump"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB3FF03}, .data="WS*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xC8CE7328}, .data="websocket"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x8D8EF8C1}, .data="MQTTCTRL*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF177F4A0}, .data="mqtt"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC8C2DDE}, .data="http2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF178D471}, .data="http"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x08C4BE06}, .data="NWCTRL*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x81402487}, .data="socket"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD06EC1B0}, .data="coremark"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x754EA778}, .data="fastlz"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3E245A70}, .data="ymodem"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1620D11}, .data="data"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x6CE60D60}, .data="rawdata"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98C8B2DE}, .data="hcode"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1661C09}, .data="code"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x96293F3C}, .data="token"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97A08F1D}, .data="msgid"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A53C}, .data="tp"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A2CDC00}, .data="COAP*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x585FEEC7}, .data="libcoap"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD7043B11}, .data="mqttcore"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2BEBB}, .data="fdb"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1774F9E}, .data="fskv"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B694}, .data="fs"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xFCFE81C6}, .data="libgnss"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9631AADD}, .data="gmssl"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAE958913}, .data="bit64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x5CE667F9}, .data="iconv_t"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B29E77C}, .data="iconv"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x27EB37AF}, .data="iotauth"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD56FC9E9}, .data="protobuf"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x989D74A7}, .data="miniz"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2BC59}, .data="rsa"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x380F9090}, .data="crypto"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xDE03977F}, .data="ZBUFF*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97BB4576}, .data="zbuff"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165D44C}, .data="json"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1676580}, .data="pack"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x62818A29}, .data="timer"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB08B04}, .data="log"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D103F}, .data="rtos"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09B63}, .data="rtc"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0DAF0}, .data="mcu"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A59E}, .data="pm"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB02630}, .data="wdt"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0FF35}, .data="pwm"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09968}, .data="adc"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A243333}, .data="ESPI*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1067132}, .data="SPI*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB007B1}, .data="spi"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A6B81C4}, .data="EI2C*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0947D}, .data="i2c"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16966DF}, .data="gpio"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF171A2C4}, .data="uart"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB026E1}, .data="bit"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC771659}, .data="bit32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x961C4434}, .data="debug"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF29A2F77}, .data="utf8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF167B24E}, .data="math"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xDE0064C2}, .data="string"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B69B}, .data="os"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A5733EE}, .data="FILE*"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A540}, .data="io"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE95A2A6A}, .data="unpack"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97A93985}, .data="table"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2FB74447}, .data="__name"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x3D4EB7E2}, .data="rotable"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x115B22A8}, .data="__metatable"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xA71107E0}, .data="__pairs"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x9F0053A5}, .data="coroutine"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x260706B1}, .data="seeall"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x28440103}, .data="module"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA768F75F}, .data="unload"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xE25FB2A7}, .data="require"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xD14B5356}, .data="package"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x7398F586}, .data="Lua 5.3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x2CC14752}, .data="_VERSION"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2606FFC2}, .data="xpcall"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16401FB}, .data="type"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x356E4F73}, .data="tostring"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x23751D25}, .data="tonumber"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xFCD2869A}, .data="setmetatable"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EF49C2A}, .data="select"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8144473D}, .data="rawset"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x814E6A68}, .data="rawget"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x38FC0FEB}, .data="rawlen"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x1C02FEE2}, .data="rawequal"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9886291D}, .data="print"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9977BB19}, .data="pcall"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x7C2E4889}, .data="pairs"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF177836C}, .data="next"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x4BAF8403}, .data="loadstring"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1654257}, .data="load"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x74E6FD1B}, .data="loadfile"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x276E6449}, .data="ipairs"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xFCD2868E}, .data="getmetatable"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x6294D23B}, .data="error"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2A456BF2}, .data="dofile"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0xDBEBCD99}, .data="collectgarbage"},        
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8E83CC41}, .data="assert"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A064}, .data="_G"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x2525B4B4}, .data="_LOADED"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xF59C93E8}, .data="taskCB"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xE628ECDA}, .data="cleanMsg"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x11A5147E}, .data="param4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE7E208DD}, .data="param3"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xFD0D39B5}, .data="param2"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA0057C22}, .data="param1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9F103991}, .data="sendMsg"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD41BDB9E}, .data="finish"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x814E702F}, .data="target"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9CC40010}, .data="waitMsg"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD1507446}, .data="waitTo"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x4DFBCFB8}, .data="taskDel"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A53D}, .data="To"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x3B181560}, .data="msgQueue"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98BC2363}, .data="cbFun"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xCDB58E09}, .data="taskName"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xF1A3DF85}, .data="taskInitEx"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xC31FB6C4}, .data="taskList"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x0B5B0100}, .data="cwaitMt"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x22EB7D3F}, .data="sysplus"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xBF6255DA}, .data="VERSION"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x36A7F719}, .data="PROJECT"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x1632B779}, .data="sys_wait"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x9B1E7F19}, .data="sys_send"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xAA57D437}, .data="no cb fun"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8FDF468A}, .data="sys_cw"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0xC2DB339C}, .data="@/lua/sysplus.lua"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x0953B716}, .data="mem_stat"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x1ED251A6}, .data="IP_READY"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A138761}, .data="1.0.0"},
+
+    // 从irtu搜集的字符串
+#if 0
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0xD5585082}, .data="\x2F\x6C\x75\x61\x2F\x73\x79\x73\x2E\x6C\x75\x61\x3A\x34\x31\x31\x3A\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB39697}, .data="\x34\x31\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x7F1E5E74}, .data="\x2F\x6C\x75\x61\x2F\x73\x79\x73\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x5C88EC0C}, .data="\x61\x73\x73\x65\x72\x74\x69\x6F\x6E\x20\x66\x61\x69\x6C\x65\x64\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x4B9BAF5D}, .data="\x5F\x5F\x74\x6F\x73\x74\x72\x69\x6E\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xDABA54A8}, .data="\x2F\x75\x73\x65\x72\x2E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018682}, .data="\x49"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x4CCEB0D9}, .data="\x30\x2E\x30\x2E\x30\x2E\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x94656A09}, .data="\x4E\x45\x54\x5F\x52\x45\x43\x56\x5F\x57\x41\x49\x54\x5F\x33\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xE664D838}, .data="\x55\x41\x52\x54\x5F\x53\x45\x4E\x54\x5F\x52\x44\x59\x5F\x33\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x10385656}, .data="\x55\x41\x52\x54\x5F\x52\x45\x43\x56\x5F\x57\x41\x49\x54\x5F\x33\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xF2816489}, .data="\x4E\x45\x54\x5F\x52\x45\x43\x56\x5F\x57\x41\x49\x54\x5F\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x3169F403}, .data="\x55\x41\x52\x54\x5F\x53\x45\x4E\x54\x5F\x52\x44\x59\x5F\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xBF55E1C5}, .data="\x55\x41\x52\x54\x5F\x52\x45\x43\x56\x5F\x57\x41\x49\x54\x5F\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xE6564E4D}, .data="\x2F\x6C\x75\x61\x64\x62\x2F\x69\x72\x74\x75\x2E\x63\x66\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x20161758}, .data="\x73\x75\x62\x73\x74\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x7BDC130E}, .data="\x73\x74\x72\x6C\x69\x73\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x8F9059DB}, .data="\x64\x65\x6C\x69\x6D\x69\x74\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A6}, .data="\x25"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF10460F2}, .data="\x28\x2E\x2D\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1709016}, .data="\x25\x78\x25\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD28C3927}, .data="\x5B\x25\x73\x25\x70\x5D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x49732A34}, .data="\x43\x6F\x6E\x74\x65\x6E\x74\x5F\x74\x79\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x814428D5}, .data="\x6F\x66\x66\x73\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9655952B}, .data="\x63\x74\x79\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF291210E}, .data="\x41\x41\x41\x41"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA7657B08}, .data="\x42\x61\x73\x69\x63\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0xA6E9A0C8}, .data="\x41\x75\x74\x68\x6F\x72\x69\x7A\x61\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x6044204C}, .data="\x66\x69\x6C\x65\x53\x69\x7A\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x761320D9}, .data="\x28\x2E\x2D\x3A\x2E\x2D\x29\x40"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x7B05C4CD}, .data="\x75\x73\x65\x72\x20\x68\x65\x61\x64\x65\x72\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x8B4028D4}, .data="\x43\x6F\x6E\x6E\x65\x63\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x2C87ADC7}, .data="\x7A\x68\x2D\x43\x4E\x2C\x7A\x68\x2C\x63\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x12868465}, .data="\x41\x63\x63\x65\x70\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB3F3C5}, .data="\x2A\x2F\x2A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EA2CA35}, .data="\x41\x63\x63\x65\x70\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x9F4E4270}, .data="\x4D\x6F\x7A\x69\x6C\x6C\x61\x2F\x34\x2E\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x821E93C8}, .data="\x55\x73\x65\x72\x2D\x41\x67\x65\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x22079B36}, .data="\x70\x61\x72\x61\x6D\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869E}, .data="\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E4}, .data="\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE0A633CD}, .data="\x25\x25\x25\x30\x32\x58"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186B9}, .data="\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x49BB5B99}, .data="\x28\x5B\x5E\x25\x77\x5F\x25\x2A\x25\x2E\x25\x2D\x20\x5D\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98AC26AA}, .data="\x75\x63\x68\x61\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2BC37}, .data="\x74\x61\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x430DDFA0}, .data="\x5B\x25\x7A\x01\x2D\x7F\xC2\x2D\xF4\x5D\x5B\x80\x2D\xBF\x5D\x2A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3ABEC8BA}, .data="\x6F\x72\x69\x67\x69\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF17B0ADD}, .data="\x74\x61\x62\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x48814F88}, .data="\x73\x79\x73\x2E\x72\x65\x73\x74\x61\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x1ED1093C}, .data="\x73\x79\x73\x2E\x72\x65\x73\x74\x61\x72\x74\x20\x63\x61\x75\x73\x65\x20\x6E\x75\x6C\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x48485DFA}, .data="\x75\x72\x6C\x65\x6E\x63\x6F\x64\x65\x54\x61\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x451A1CCF}, .data="\x75\x72\x6C\x45\x6E\x63\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x17FDC9EA}, .data="\x75\x74\x66\x38\x54\x6F\x54\x61\x62\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0x5DC2E0F7}, .data="\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xF2B9F5D4}, .data="\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6A\x73\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 33, .hash = 0x70F03F20}, .data="\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x78\x2D\x77\x77\x77\x2D\x66\x6F\x72\x6D\x2D\x75\x72\x6C\x65\x6E\x63\x6F\x64\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98CE2BE4}, .data="\x6D\x65\x72\x67\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x394EC742}, .data="\x64\x74\x75\x6C\x69\x62\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC84AE375}, .data="\x61\x64\x61\x70\x74\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x844B7DED}, .data="\x4C\x57\x49\x50\x5F\x47\x50"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x72129AE5}, .data="\x6F\x6E\x65\x4E\x65\x74\x4E\x65\x77"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x0D68B1FC}, .data="\x61\x6C\x69\x79\x75\x6E\x4F\x74\x6F\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x2C1169A1}, .data="\x6F\x6E\x65\x4E\x65\x74\x5F\x6D\x71\x74\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xFEF24F78}, .data="\x74\x63\x70\x54\x61\x73\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD17511BE}, .data="\x66\x6C\x79\x54\x61\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x7049F8D5}, .data="\x68\x65\x61\x64\x73\x74\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xEBB7E813}, .data="\x68\x65\x61\x64\x64\x61\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x1C55FAD2}, .data="\x69\x73\x62\x6F\x64\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA76DD003}, .data="\x69\x73\x68\x65\x61\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2E1E4D25}, .data="\x69\x73\x63\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x96559528}, .data="\x64\x74\x79\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB04D61}, .data="\x77\x61\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x9227016F}, .data="\x6D\x65\x74\x68\x6F\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BBEA}, .data="\x3A\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x7259C128}, .data="\xE5\x8F\x8D\xE5\xBA\x8F\xE5\x88\x97\xE5\x8C\x96\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x615FAA65}, .data="\xE5\xBC\x80\xE5\x90\xAF\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0x1A374838}, .data="\x53\x65\x72\x76\x65\x72\x20\x63\x6F\x6E\x6E\x65\x63\x74\x69\x6F\x6E\x20\x66\x61\x69\x6C\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0xE5EAC844}, .data="\xE5\xAE\x88\xE6\x8A\xA4\xE5\x85\xA8\xE9\x83\xA8\xE7\xBA\xBF\xE7\xA8\x8B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xFDDBAA6F}, .data="\xE5\xAE\x88\xE6\x8A\xA4\xE7\xBA\xBF\xE7\xA8\x8B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x8630AE10}, .data="\x4F\x4E\x45\x4E\x45\x54\x4E\x45\x57"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xBAA211D0}, .data="\x54\x58\x49\x4F\x54\x4E\x45\x57"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1568670}, .data="\x4F\x4D\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1568714}, .data="\x4F\x54\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF178CBBD}, .data="\x73\x6E\x74\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x325D73F1}, .data="\x41\x4C\x49\x59\x55\x4E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x4BC59AD1}, .data="\x4F\x4E\x45\x4E\x45\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16AA991}, .data="\x48\x54\x54\x50"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16DA076}, .data="\x4D\x51\x54\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1566001}, .data="\x44\x54\x55\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB35EE5}, .data="\x54\x43\x50"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xED54E2F8}, .data="\xE8\xBF\x99\xE9\x87\x8C\xE8\xB5\x8B\xE5\x80\xBC\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xE45C2D06}, .data="\x75\x73\x65\x72\x5F\x6E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x3491BA24}, .data="\x63\x6C\x69\x65\x6E\x74\x5F\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x03E19E2D}, .data="\x44\x65\x76\x69\x63\x65\x4E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xFD7FA181}, .data="\x6F\x6E\x65\x4E\x65\x74\x41\x64\x64\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x8C2BFBFA}, .data="\x2F\x63\x75\x73\x74\x6F\x6D\x65\x2F\x75\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0xDC73B4B8}, .data="\x2F\x63\x75\x73\x74\x6F\x6D\x65\x2F\x75\x70\x5F\x72\x65\x70\x6C\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x57E685B5}, .data="\x72\x61\x77\x5F\x6B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x1C6581F2}, .data="\x65\x78\x70\x69\x72\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA6D1ECAE}, .data="\x63\x6F\x6E\x6E\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x8858BB04}, .data="\x74\x78\x5F\x62\x6F\x64\x79\x5F\x6A\x73\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x5567A1F1}, .data="\x74\x78\x5F\x62\x6F\x64\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x0A3D4678}, .data="\x68\x6D\x61\x63\x5F\x73\x68\x61\x31\x5F\x64\x61\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x6351D5E5}, .data="\x50\x72\x6F\x64\x75\x63\x74\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3ED4670A}, .data="\x52\x65\x67\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xA8D85181}, .data="\x68\x65\x61\x64\x65\x72\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 28, .hash = 0xAA914547}, .data="\xE8\x85\xBE\xE8\xAE\xAF\xE4\xBA\x91\xE8\xAE\xBE\xE5\xA4\x87\xE6\xB3\xA8\xE5\x86\x8C\xE5\xA4\xB1\xE8\xB4\xA5\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 28, .hash = 0x2AB084A5}, .data="\xE8\x85\xBE\xE8\xAE\xAF\xE4\xBA\x91\xE6\xB3\xA8\xE5\x86\x8C\xE8\xAE\xBE\xE5\xA4\x87\xE6\x88\x90\xE5\x8A\x9F\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x7A8492D2}, .data="\x74\x65\x73\x74\x48\x74\x74\x70\x2E\x73\x65\x72\x42\x61\x63\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 33, .hash = 0xFD03FE2B}, .data="\xE8\x85\xBE\xE8\xAE\xAF\xE4\xBA\x91\xE6\x96\xB0\xE7\x89\x88\xE8\xBF\x9E\xE6\x8E\xA5\xE6\x96\xB9\xE5\xBC\x8F\xE5\xBC\x80\xE5\x90\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EF9837E}, .data="\x2F\x65\x76\x65\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x9BB69CE8}, .data="\x2F\x63\x6F\x6E\x74\x72\x6F\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 28, .hash = 0x416EC55B}, .data="\x2E\x69\x6F\x74\x63\x6C\x6F\x75\x64\x2E\x74\x65\x6E\x63\x65\x6E\x74\x64\x65\x76\x69\x63\x65\x73\x2E\x63\x6F\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xD9ECC8A3}, .data="\x63\x6C\x69\x65\x6E\x74\x4B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x056FD3A5}, .data="\x2F\x63\x6C\x69\x65\x6E\x74\x2E\x6B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x3CEE2DC0}, .data="\x63\x6C\x69\x65\x6E\x74\x43\x65\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xD992BBDD}, .data="\x2F\x63\x6C\x69\x65\x6E\x74\x2E\x63\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB30914}, .data="\x50\x57\x44"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x27383731}, .data="\x3B\x68\x6D\x61\x63\x73\x68\x61\x32\x35\x36"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x2499A6A1}, .data="\x68\x6D\x61\x63\x5F\x73\x68\x61\x32\x35\x36"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0FB44}, .data="\x70\x73\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x0D64BFB8}, .data="\x65\x6E\x63\x72\x79\x70\x74\x69\x6F\x6E\x54\x79\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x36F9317E}, .data="\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x0BB04500}, .data="\x62\x61\x73\x65\x36\x34\x5F\x64\x65\x63\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF159241A}, .data="\x5A\x45\x52\x4F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x1B635E88}, .data="\x41\x45\x53\x2D\x31\x32\x38\x2D\x43\x42\x43"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0xE13F3D8E}, .data="\x63\x69\x70\x68\x65\x72\x5F\x64\x65\x63\x72\x79\x70\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x83698D98}, .data="\x25\x73\x3B\x31\x32\x30\x31\x30\x31\x32\x36\x3B\x25\x73\x3B\x25\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xFC0B89F3}, .data="\xE6\x9C\x89\xE6\x96\x87\xE4\xBB\xB6\xE5\x95\x8A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 31, .hash = 0xFF6071F7}, .data="\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6A\x73\x6F\x6E\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x55\x54\x46\x2D\x38"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xBA44F2FB}, .data="\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x0319A259}, .data="\x73\x69\x67\x6E\x61\x74\x75\x72\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x5E18B8AB}, .data="\x74\x69\x6D\x65\x73\x74\x61\x6D\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98D29D31}, .data="\x6E\x6F\x6E\x63\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x260155B6}, .data="\x62\x61\x73\x65\x36\x34\x5F\x65\x6E\x63\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xD6151EE8}, .data="\x64\x65\x76\x69\x63\x65\x4E\x41\x4D\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xB058EACA}, .data="\x26\x74\x69\x6D\x65\x73\x74\x61\x6D\x70\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x24EC51D8}, .data="\x26\x70\x72\x6F\x64\x75\x63\x74\x49\x64\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xB53FAF47}, .data="\x26\x6E\x6F\x6E\x63\x65\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x108DF987}, .data="\x64\x65\x76\x69\x63\x65\x4E\x61\x6D\x65\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0x97D827B4}, .data="\xE7\xA1\xAE\xE5\xAE\x9E\xE6\xB2\xA1\xE6\x9C\x89\xE6\x96\x87\xE4\xBB\xB6\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xC70069B6}, .data="\x65\x6E\x72\x6F\x6C\x5F\x65\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x7361B83D}, .data="\x61\x6C\x69\x79\x75\x6E\x4F\x6D\x6F\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x20E01B53}, .data="\x67\x65\x74\x4F\x6E\x65\x53\x65\x63\x72\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 40, .hash = 0x03271A32}, .data="\xE4\xB8\x80\xE5\x9E\x8B\xE4\xB8\x80\xE5\xAF\x86\xE5\x8A\xA8\xE6\x80\x81\xE6\xB3\xA8\xE5\x86\x8C\xE8\xBF\x94\xE5\x9B\x9E\xE4\xB8\x89\xE5\x85\x83\xE7\xBB\x84\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x87F5675F}, .data="\xE9\x98\xBF\xE9\x87\x8C\xE4\xBA\x91\xE6\xB3\xA8\xE5\x86\x8C\xE5\xA4\xB1\xE8\xB4\xA5\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x4BF126BD}, .data="\x49\x6E\x73\x74\x61\x6E\x63\x65\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x70018389}, .data="\x2F\x75\x73\x65\x72\x2F\x75\x70\x64\x61\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC88D10BF}, .data="\x2F\x75\x70\x64\x61\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xDCDF006C}, .data="\x2F\x75\x73\x65\x72\x2F\x67\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF171BE37}, .data="\x2F\x67\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 25, .hash = 0x7937DDD5}, .data="\x2E\x6D\x71\x74\x74\x2E\x69\x6F\x74\x68\x75\x62\x2E\x61\x6C\x69\x79\x75\x6E\x63\x73\x2E\x63\x6F\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0xDBA18A37}, .data="\x2E\x61\x6C\x69\x79\x75\x6E\x63\x73\x2E\x63\x6F\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x171EA208}, .data="\x2E\x69\x6F\x74\x2D\x61\x73\x2D\x6D\x71\x74\x74\x2E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x95DDDE6E}, .data="\x62\x61\x73\x69\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 34, .hash = 0x0B9B76A8}, .data="\x7C\x73\x65\x63\x75\x72\x65\x6D\x6F\x64\x65\x3D\x33\x2C\x73\x69\x67\x6E\x6D\x65\x74\x68\x6F\x64\x3D\x68\x6D\x61\x63\x73\x68\x61\x31\x7C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x5931E502}, .data="\x68\x6D\x61\x63\x5F\x73\x68\x61\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A7}, .data="\x26"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x0E148AD7}, .data="\x63\x6C\x69\x65\x6E\x74\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x1C38B672}, .data="\x61\x6C\x69\x6B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1786399}, .data="\x73\x69\x67\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x1D2C2A16}, .data="\x50\x72\x6F\x64\x75\x63\x74\x53\x65\x63\x72\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xEEBCA2F4}, .data="\x52\x65\x67\x69\x6F\x6E\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 28, .hash = 0x780CD49F}, .data="\xE9\x98\xBF\xE9\x87\x8C\xE4\xBA\x91\xE6\x9F\xA5\xE8\xAF\xA2\xE8\xAF\xB7\xE6\xB1\x82\xE5\xA4\xB1\xE8\xB4\xA5\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x12C9DB81}, .data="\x77\x72\x69\x74\x65\x46\x69\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 34, .hash = 0xA17E2E82}, .data="\x2E\x61\x6C\x69\x79\x75\x6E\x63\x73\x2E\x63\x6F\x6D\x2F\x61\x75\x74\x68\x2F\x72\x65\x67\x69\x73\x74\x65\x72\x2F\x64\x65\x76\x69\x63\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x0C62CA6F}, .data="\x68\x74\x74\x70\x73\x3A\x2F\x2F\x69\x6F\x74\x2D\x61\x75\x74\x68\x2E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16C6E82}, .data="\x50\x4F\x53\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 19, .hash = 0x580B0789}, .data="\x26\x73\x69\x67\x6E\x4D\x65\x74\x68\x6F\x64\x3D\x48\x6D\x61\x63\x4D\x44\x35"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x6853D1A9}, .data="\x26\x73\x69\x67\x6E\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x7E161A0F}, .data="\x26\x72\x61\x6E\x64\x6F\x6D\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xDDFBAA07}, .data="\x26\x64\x65\x76\x69\x63\x65\x4E\x61\x6D\x65\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x0162DEC4}, .data="\x70\x72\x6F\x64\x75\x63\x74\x4B\x65\x79\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x118DA589}, .data="\x68\x6D\x61\x63\x5F\x6D\x64\x35"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x266A6FB0}, .data="\x72\x61\x6E\x64\x6F\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x1F4DF3C8}, .data="\x64\x65\x76\x69\x63\x65\x53\x65\x63\x72\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xEBE21E02}, .data="\x72\x65\x61\x64\x46\x69\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xE27C90E4}, .data="\x6D\x71\x74\x74\x54\x61\x73\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xCBBE241E}, .data="\x75\x73\x65\x72\x6E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xAE8ADCCE}, .data="\x63\x6C\x69\x6E\x65\x6E\x74\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x1D2C2A36}, .data="\x70\x72\x6F\x64\x75\x63\x74\x53\x65\x63\x72\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x6351D5C5}, .data="\x70\x72\x6F\x64\x75\x63\x74\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 26, .hash = 0xFAB6B4F9}, .data="\x2F\x74\x68\x69\x6E\x67\x2F\x70\x72\x6F\x70\x65\x72\x74\x79\x2F\x70\x6F\x73\x74\x2F\x72\x65\x70\x6C\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 20, .hash = 0x61FEA058}, .data="\x2F\x74\x68\x69\x6E\x67\x2F\x70\x72\x6F\x70\x65\x72\x74\x79\x2F\x70\x6F\x73\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC9C8646}, .data="\x24\x73\x79\x73\x2F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x814194EA}, .data="\x6F\x6E\x65\x6E\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xF9345EB1}, .data="\x6C\x69\x73\x74\x54\x6F\x70\x69\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xFB921EB0}, .data="\x70\x75\x62\x5F\x74\x6F\x70\x69\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98FAAE0C}, .data="\x69\x6E\x64\x65\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x9407693E}, .data="\x63\x6F\x6E\x72\x65\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xD6D1E9B7}, .data="\x6D\x65\x73\x73\x61\x67\x65\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9637315B}, .data="\x6D\x71\x74\x74\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF171A27B}, .data="\x63\x65\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x9F4E5DF2}, .data="\x69\x64\x41\x64\x64\x49\x6D\x65\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD49E8B40}, .data="\x63\x6C\x69\x65\x6E\x74\x49\x44"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3AB62BC6}, .data="\x72\x65\x74\x61\x69\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0DFFB}, .data="\x71\x6F\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2A06C}, .data="\x70\x75\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x63B92A3A}, .data="\x63\x6C\x65\x61\x6E\x73\x65\x73\x73\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E146}, .data="\x70\x77\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0EE76}, .data="\x75\x73\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xA5D6F144}, .data="\x6B\x65\x65\x70\x41\x6C\x69\x76\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xDA80F6B3}, .data="\x6D\x71\x74\x74\x5F\x63\x6C\x69\x65\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97A08E2A}, .data="\x70\x6B\x67\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x21D5DF99}, .data="\x70\x61\x79\x6C\x6F\x61\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x95DDA3D3}, .data="\x74\x6F\x70\x69\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x63C09ED0}, .data="\x64\x6F\x77\x6E\x6C\x69\x6E\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1776082}, .data="\x72\x65\x63\x76"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE95A2287}, .data="\x63\x6F\x6E\x61\x63\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98863987}, .data="\x65\x76\x65\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xF137901A}, .data="\xE6\x96\xAD\xE5\xBC\x80\xE8\xBF\x9E\xE6\x8E\xA5\xE4\xBA\x86\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0xF1C55C52}, .data="\xE8\xBF\x9E\xE6\x8E\xA5\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8\xE5\xA4\xB1\xE8\xB4\xA5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x788864B6}, .data="\xE8\xAE\xA2\xE9\x98\x85\xE5\xA4\xB1\xE8\xB4\xA5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 36, .hash = 0x4D9DC138}, .data="\x54\x68\x65\x20\x4D\x51\x54\x54\x53\x65\x72\x76\x65\x72\x20\x63\x6F\x6E\x6E\x65\x63\x74\x69\x6F\x6E\x20\x69\x73\x20\x62\x72\x6F\x6B\x65\x6E\x2E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xFE7E5CCE}, .data="\xE6\x96\xAD\xE5\xBC\x80\xE8\xBF\x9E\xE6\x8E\xA5\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x03A5E305}, .data="\xE7\xAD\x89\xE5\xBE\x85\xE8\xB6\x85\xE6\x97\xB6\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x7CB5925C}, .data="\x70\x72\x54\x6F\x70\x69\x63\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD7B8B224}, .data="\x70\x72\x54\x6F\x70\x69\x63\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC562CD47}, .data="\x70\x72\x54\x6F\x70\x69\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FE}, .data="\x5D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x7E673061}, .data="\x5B\x2B\x4D\x53\x55\x42\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF11B80AB}, .data="\x52\x45\x54\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xD56B4CC8}, .data="\x4D\x45\x53\x53\x41\x47\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0xECAE4570}, .data="\x2E\x2B\x2F\x72\x72\x70\x63\x2F\x72\x65\x71\x75\x65\x73\x74\x2F\x28\x25\x64\x2B\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0xA268F059}, .data="\xE6\x8E\xA5\xE6\x94\xB6\xE5\x88\xB0\xE4\xBA\x86\xE4\xB8\x80\xE6\x9D\xA1\xE6\xB6\x88\xE6\x81\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0x325C6A18}, .data="\x2D\x2D\x2D\x2D\x2D\xE5\x8F\x91\xE5\xB8\x83\xE7\x9A\x84\xE4\xB8\xBB\xE9\xA2\x98\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x5C3F7FA5}, .data="\x64\x69\x73\x63\x6F\x6E\x6E\x65\x63\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB15216}, .data="\x52\x45\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x0191ACFF}, .data="\x6D\x71\x74\x74\xE8\xAE\xA2\xE9\x98\x85\xE6\x88\x90\xE5\x8A\x9F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xA6A728B4}, .data="\x6D\x71\x74\x74\xE8\xBF\x9E\xE6\x8E\xA5\xE6\x88\x90\xE5\x8A\x9F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B4EF08E}, .data="\x72\x65\x61\x64\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xFE0FE116}, .data="\x6D\x71\x74\x74\x5F\x63\x6F\x6E\x61\x63\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x796525C3}, .data="\xE7\xBD\x91\xE7\xBB\x9C\xE5\x88\x9D\xE5\xA7\x8B\xE5\x8C\x96\xE5\xA4\xB1\xE8\xB4\xA5\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2BCA1}, .data="\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x463D1DC2}, .data="\x6D\x65\x6D\x69\x6E\x66\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x8B09E656}, .data="\x6D\x65\x6D\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0xE6797D57}, .data="\x73\x65\x6E\x64\x54\x65\x73\x74\x54\x65\x6C\x65\x6D\x65\x74\x72\x79\x43\x6F\x75\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 27, .hash = 0x0CA2A00A}, .data="\x63\x68\x79\x73\x54\x65\x73\x74\x2E\x73\x65\x6E\x64\x54\x65\x73\x74\x54\x65\x6C\x65\x6D\x65\x74\x72\x79\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF169D074}, .data="\x77\x69\x6C\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xA7EE7357}, .data="\x6B\x65\x65\x70\x61\x6C\x69\x76\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x09FF0948}, .data="\x4B\x45\x45\x50\x41\x4C\x49\x56\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC5A7725E}, .data="\x74\x63\x70\x5F\x73\x73\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x8DF2C2D9}, .data="\x4D\x51\x54\x54\x20\x63\x6C\x69\x65\x6E\x74\x49\x44\x2C\x75\x73\x65\x72\x2C\x70\x77\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x01DED847}, .data="\x4D\x51\x54\x54\x20\x48\x4F\x53\x54\x3A\x50\x4F\x52\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x0D9E0B38}, .data="\x54\x4F\x50\x49\x43\x53"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0x63EAE548}, .data="\xE4\xB8\xBA\xE7\xA9\xBA\xEF\xBC\x8C\xE8\xBF\x9B\xE5\x88\xB0\xE8\xBF\x99\xE9\x87\x8C\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x9D739F54}, .data="\xE4\xB8\xBA\x31\xEF\xBC\x8C\xE8\xBF\x9B\xE5\x88\xB0\xE8\xBF\x99\xE9\x87\x8C\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA7C4EC24}, .data="\x74\x6F\x70\x69\x63\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x03E19E0D}, .data="\x64\x65\x76\x69\x63\x65\x4E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x5DCC2FA0}, .data="\x50\x72\x6F\x64\x75\x63\x74\x4B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC89F616C}, .data="\x61\x64\x64\x49\x6D\x65\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x3176739A}, .data="\xE8\xAE\xA2\xE9\x98\x85\xE6\x88\x96\xE5\x8F\x91\xE5\xB8\x83\xE4\xB8\xBB\xE9\xA2\x98\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x65B84102}, .data="\x24\x7B\x64\x65\x76\x69\x63\x65\x4E\x61\x6D\x65\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0xEFBA01E8}, .data="\x7B\x64\x65\x76\x69\x63\x65\x2D\x6E\x61\x6D\x65\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x203757D7}, .data="\x24\x7B\x79\x6F\x75\x72\x64\x65\x76\x69\x63\x65\x6E\x61\x6D\x65\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x371C7BAC}, .data="\x24\x7B\x64\x65\x76\x69\x63\x65\x6E\x61\x6D\x65\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x8E2CD86C}, .data="\x64\x65\x76\x69\x63\x65\x6E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x5E99580B}, .data="\x24\x7B\x79\x6F\x75\x72\x70\x72\x6F\x64\x75\x63\x74\x6B\x65\x79\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0xFE2D45BE}, .data="\x24\x7B\x70\x72\x6F\x64\x75\x63\x74\x6B\x65\x79\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xBB68C182}, .data="\x70\x72\x6F\x64\x75\x63\x74\x6B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x930121BE}, .data="\x24\x7B\x6D\x65\x73\x73\x61\x67\x65\x69\x64\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xC3AD7181}, .data="\x6D\x65\x73\x73\x61\x67\x65\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97295085}, .data="\x7B\x70\x69\x64\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xA335220C}, .data="\x70\x72\x6F\x64\x75\x63\x74\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF11A6E5D}, .data="\x4B\x45\x59\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1770E8A}, .data="\x4B\x45\x59\x76"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB35041}, .data="\x53\x54\x52"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xE62B980E}, .data="\x6C\x6F\x67\x69\x6E\x4D\x73\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3FCB5329}, .data="\x72\x73\x74\x54\x69\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xE1C497D5}, .data="\x64\x61\x74\x61\x68\x65\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xDAC65737}, .data="\x64\x61\x74\x61\x68\x65\x78\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x116E89D4}, .data="\x6C\x6F\x67\x69\x6E\x5F\x64\x61\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x5D42EF07}, .data="\x73\x75\x62\x4D\x65\x73\x73\x61\x67\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9BB26FF1}, .data="\x74\x78\x5F\x62\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x543EF453}, .data="\x75\x70\x70\x72\x6F\x74\x46\x6E\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x543EFF2F}, .data="\x64\x77\x70\x72\x6F\x74\x46\x6E\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98B93281}, .data="\x6C\x6F\x67\x69\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x611DED1B}, .data="\x69\x6E\x74\x65\x72\x76\x61\x6C\x54\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0F5DF}, .data="\x67\x61\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1651075}, .data="\x70\x69\x6E\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x7CB01100}, .data="\x6F\x75\x74\x70\x75\x74\x53\x6F\x63\x6B\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x94C073FF}, .data="\x6D\x71\x74\x74\x72\x65\x63\x76"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x691D44FA}, .data="\xE5\x85\xB3\xE9\x97\xAD\x74\x63\x70\xE9\x93\xBE\xE6\x8E\xA5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x40C7481A}, .data="\x74\x63\x70\xE8\xBF\x9E\xE6\x8E\xA5\xE5\xA4\xB1\xE8\xB4\xA5\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xAEAD1620}, .data="\x2C\x70\x61\x73\x73\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE3F65C6C}, .data="\x2C\x50\x41\x52\x41\x4D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAD774A25}, .data="\x2C\x44\x41\x54\x41"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x4B49F653}, .data="\x52\x45\x53\x55\x4C\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA7F59C43}, .data="\x72\x65\x73\x69\x7A\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0xBADE80BD}, .data="\xE6\x97\xA0\xE6\x95\xB0\xE6\x8D\xAE\xE5\xBE\x85\xE5\x8F\x91\xE9\x80\x81"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2AEDF}, .data="\x52\x45\x53"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0xCDAFF219}, .data="\x74\x78\xE5\xA4\xB1\xE8\xB4\xA5\x2C\xE9\x80\x80\xE5\x87\xBA\xE5\xBE\xAA\xE7\x8E\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0F4EB}, .data="\x74\x63\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xC712A116}, .data="\x53\x45\x4E\x44\x5F\x45\x52\x52\x4F\x52\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x4AE1B1C1}, .data="\x52\x58\x42\x55\x46\x46\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x134C689C}, .data="\x52\x58\x42\x55\x46\x46\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0xDBF2320A}, .data="\xE6\x95\xB0\xE6\x8D\xAE\xE6\xB5\x81\xE6\xA8\xA1\xE7\x89\x88\xE9\x94\x99\xE8\xAF\xAF\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 25, .hash = 0x90FE51AC}, .data="\xE8\xBF\x9C\xE7\xA8\x8B\xE6\x9F\xA5\xE8\xAF\xA2\xE7\x9A\x84\x41\x50\x49\xE9\x94\x99\xE8\xAF\xAF\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF154C006}, .data="\x2C\x55\x49\x44"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165A689}, .data="\x2C\x63\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x131813FC}, .data="\xE5\xBE\xAA\xE7\x8E\xAF\xE7\xAD\x89\xE5\xBE\x85\xE6\xB6\x88\xE6\x81\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x014DE3A7}, .data="\xE5\x8F\x91\xE9\x80\x81\xE7\x99\xBB\xE5\xBD\x95\xE6\x8A\xA5\xE6\x96\x87"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xC551D6E3}, .data="\x74\x63\x70\xE8\xBF\x9E\xE6\x8E\xA5\xE6\x88\x90\xE5\x8A\x9F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0x2CD84734}, .data="\xE7\xBD\x91\xE7\xBB\x9C\xE5\x88\x9D\xE5\xA7\x8B\xE5\x8C\x96\xE5\xA4\xB1\xE8\xB4\xA5\xEF\xBC\x81"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB358C3}, .data="\x42\x53\x50"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAEA96F37}, .data="\x44\x4E\x41\x4D\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1193901}, .data="\x30\x78\x30\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2C4E64B3}, .data="\x63\x6F\x6E\x76\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x6CE61965}, .data="\x74\x6D\x70\x64\x61\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE58AE08A}, .data="\x74\x6D\x70\x64\x61\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF169C812}, .data="\x25\x30\x32\x58"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A57A}, .data="\x73\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186DD}, .data="\x7C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B67E}, .data="\x30\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x927B3142}, .data="\x73\x65\x63\x6F\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B7D6A99}, .data="\x66\x69\x72\x73\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x6CE37D01}, .data="\x6C\x6E\x67\x64\x61\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x6CEC3A31}, .data="\x6C\x61\x74\x64\x61\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC8FD2D3C}, .data="\x64\x65\x66\x43\x68\x61\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x63EB74AA}, .data="\x64\x61\x74\x61\x6C\x69\x6E\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x34B834E8}, .data="\x49\x50\x5F\x4C\x4F\x53\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x31E33942}, .data="\x64\x65\x76\x5F\x74\x78\x69\x6F\x74\x6E\x65\x77"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xB08117E3}, .data="\x67\x65\x74\x52\x65\x61\x6C\x4C\x6F\x63\x61\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xDEDF719E}, .data="\x67\x65\x74\x4C\x6E\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EE30C0C}, .data="\x67\x65\x74\x4C\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x11E49927}, .data="\x63\x72\x65\x61\x74\x65\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF155C332}, .data="\x66\x75\x6E\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0EE67}, .data="\x65\x72\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0C6C3}, .data="\x75\x72\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x466DC627}, .data="\x44\x54\x55\x5F\x50\x41\x52\x41\x4D\x5F\x52\x45\x41\x44\x59"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x8E456DDB}, .data="\x77\x72\x69\x74\x65\x44\x6F\x6E\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x1DB66E89}, .data="\x70\x61\x72\x69\x74\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2A082}, .data="\x73\x74\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E3}, .data="\x6A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xE1EE2B58}, .data="\x73\x74\x72\x65\x61\x6D\x45\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD4736A57}, .data="\x6C\x65\x6E\x67\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0x095FCDEC}, .data="\xE6\x8E\xA5\xE6\x94\xB6\xE5\x88\xB0\xE7\x9A\x84\xE6\x95\xB0\xE6\x8D\xAE\xE6\x98\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x676A9C29}, .data="\x4E\x45\x54\x5F\x52\x45\x43\x56\x5F\x57\x41\x49\x54\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x417F8893}, .data="\x55\x41\x52\x54\x5F\x53\x45\x4E\x54\x5F\x52\x44\x59\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xA747717E}, .data="\x55\x41\x52\x54\x5F\x52\x45\x43\x56\x5F\x57\x41\x49\x54\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1719202}, .data="\x73\x65\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB316B8}, .data="\x4C\x53\x42"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9EB6E0CF}, .data="\x72\x73\x34\x38\x35\x75\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x8E9EDE6B}, .data="\x44\x45\x46\x41\x55\x4C\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0EEC8}, .data="\x64\x69\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E523}, .data="\x4F\x64\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF158E597}, .data="\x45\x56\x45\x4E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x950E27D3}, .data="\xE4\xB8\xB2\xE5\x8F\xA3\xE7\x9A\x84\xE6\x95\xB0\xE6\x8D\xAE\xE6\x98\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xB55D8C02}, .data="\x73\x74\x72\x65\x61\x6D\x6C\x65\x6E\x67\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xEA91C6CD}, .data="\x73\x65\x6E\x64\x42\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x9E44BF94}, .data="\x73\x74\x61\x72\x74\x54\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xEA8C3A1B}, .data="\x72\x65\x63\x76\x42\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD3DAAC00}, .data="\x73\x61\x6D\x70\x74\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0D604}, .data="\x69\x64\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97AEB341}, .data="\x64\x4E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x96327E5D}, .data="\x69\x73\x53\x73\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x980FD7FC}, .data="\x69\x73\x55\x64\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF17193F9}, .data="\x70\x72\x6F\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xAC07F8EF}, .data="\x53\x45\x4E\x44\x5F\x45\x52\x52\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x04F81290}, .data="\xE7\xBD\x91\xE7\xBB\x9C\xE5\xBC\x82\xE5\xB8\xB8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x9BCB4831}, .data="\x53\x45\x4E\x44\x5F\x4F\x4B\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0C6FE}, .data="\x73\x73\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB35EC1}, .data="\x55\x44\x50"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF125600C}, .data="\x62\x6F\x64\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165450F}, .data="\x68\x65\x61\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97B3DB2A}, .data="\x76\x61\x6C\x75\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x293E23DF}, .data="\x68\x74\x74\x70\x68\x65\x61\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC8D41CA}, .data="\x68\x65\x61\x64\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xF6EBA77B}, .data="\x68\x74\x74\x70\x62\x6F\x64\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 19, .hash = 0x725FEF7E}, .data="\x75\x61\x72\x74\x20\x68\x74\x74\x70\x20\x72\x65\x73\x70\x6F\x6E\x73\x65\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xCAF368C1}, .data="\x28\x2E\x2D\x29\x3A\x28\x2E\x2A\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AC}, .data="\x2B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x815B9E2A}, .data="\x75\x6E\x53\x65\x72\x69\x61\x6C\x69\x7A\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC939DE15}, .data="\x45\x52\x52\x4F\x52\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9D2D918A}, .data="\x73\x65\x6E\x64\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0x2DFC5FDB}, .data="\xE8\xBF\x99\xE4\xB8\xAA\xE9\x87\x8C\xE9\x9D\xA2\xE7\x9A\x84\xE5\x86\x85\xE5\xAE\xB9\xE6\x98\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 28, .hash = 0x5E0A637C}, .data="\xE8\xBF\x9B\xE5\x88\xB0\xE8\xAF\x86\xE5\x88\xAB\xE7\xA0\x81\xE9\x87\x8C\xE9\x9D\xA2\xE6\x9D\xA5\xE6\x9D\xA5\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0xC15B6FF1}, .data="\xE7\x9B\xB4\xE6\x8E\xA5\xE9\x87\x87\xE9\x9B\x86\xE4\xBA\x86\xE4\xB8\x80\xE6\xAC\xA1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD12A0FF0}, .data="\x64\x69\x66\x66\x74\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x893C41C7}, .data="\x67\x65\x74\x54\x69\x6D\x50\x61\x72\x61\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 27, .hash = 0x06C7AFA1}, .data="\xE8\xBF\x9B\xE5\x88\xB0\xE8\xAF\x86\xE5\x88\xAB\xE7\xA0\x81\xE9\x87\x8C\xE9\x9D\xA2\xE6\x9D\xA5\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 29, .hash = 0x7E0D008C}, .data="\x28\x2E\x2D\x29\x2C\x28\x2E\x2D\x29\x2C\x28\x2E\x2D\x29\x2C\x28\x2E\x2D\x29\x2C\x28\x2E\x2D\x29\x2C\x28\x2E\x2B\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF108CC1E}, .data="\x55\x44\x50\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF108CC3C}, .data="\x54\x43\x50\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x4E536F3A}, .data="\x4E\x45\x54\x5F\x4E\x4F\x52\x44\x59\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B3F6A21}, .data="\x73\x70\x6C\x69\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9D3497D1}, .data="\x68\x74\x74\x70\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x1FA1F3AF}, .data="\x75\x73\x65\x72\x61\x70\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9D2A1E79}, .data="\x72\x72\x70\x63\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x28BD2668}, .data="\x63\x6F\x6E\x66\x69\x67\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 27, .hash = 0xEF61D98B}, .data="\x52\x65\x73\x74\x6F\x72\x65\x20\x64\x65\x66\x61\x75\x6C\x74\x20\x70\x61\x72\x61\x6D\x65\x74\x65\x72\x73\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF17537B8}, .data="\x4F\x4B\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB3EE35}, .data="\x2B\x2B\x2B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0xF3BF47F1}, .data="\xE4\xB8\xB2\xE5\x8F\xA3\xE6\xB5\x81\xE9\x87\x8F\xE7\xBB\x9F\xE8\xAE\xA1\xE5\x80\xBC\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xB87D556C}, .data="\x20\x72\x65\x61\x64\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x7231372D}, .data="\x75\x61\x72\x74\x2E\x72\x65\x61\x64\x2D\x2D\x2D\x3E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xEF4EC9B5}, .data="\x73\x69\x6D\x63\x72\x6F\x73\x73\x2C\x65\x72\x72\x6F\x72\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xABD0B299}, .data="\x73\x69\x6D\x63\x72\x6F\x73\x73\x2C\x6F\x6B\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97A099E5}, .data="\x73\x69\x6D\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xDE29E219}, .data="\x66\x6C\x79\x6D\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x3F24A553}, .data="\x72\x72\x70\x63\x2C\x66\x75\x6E\x63\x74\x69\x6F\x6E\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x6C8AEC6C}, .data="\x72\x72\x70\x63\x2C\x66\x75\x6E\x63\x74\x69\x6F\x6E\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x0094E6FE}, .data="\x72\x72\x70\x63\x2C\x75\x70\x63\x6F\x6E\x66\x69\x67\x2C\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x949BA076}, .data="\x55\x50\x44\x41\x54\x45\x5F\x44\x54\x55\x5F\x43\x4E\x46"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x522E9A28}, .data="\x72\x72\x70\x63\x2C\x67\x70\x73\x5F\x63\x6C\x6F\x73\x65\x2C\x6F\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x7436BA0C}, .data="\x72\x72\x70\x63\x2C\x67\x70\x73\x5F\x67\x65\x74\x6D\x73\x67\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xA1C70C28}, .data="\x72\x72\x70\x63\x2C\x67\x70\x73\x5F\x67\x65\x74\x73\x74\x61\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x425B7753}, .data="\x72\x72\x70\x63\x2C\x67\x70\x73\x5F\x77\x61\x6B\x65\x75\x70\x2C\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xBA60111B}, .data="\x72\x72\x70\x63\x2C\x6E\x65\x74\x73\x74\x61\x74\x75\x73\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB02663}, .data="\x67\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x966CC58B}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x70\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x25F519C6}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x74\x69\x6D\x65\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D549B}, .data="\x61\x64\x64\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 38, .hash = 0xA6A69FED}, .data="\xE5\xAE\x9A\xE4\xBD\x8D\xE7\xB1\xBB\xE5\x9E\x8B\x2C\xE5\x9F\xBA\xE7\xAB\x99\xE5\xAE\x9A\xE4\xBD\x8D\xE6\x88\x90\xE5\x8A\x9F\xE8\xBF\x94\xE5\x9B\x9E\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0xB1B951CB}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x72\x65\x61\x6C\x6C\x6F\x63\x61\x74\x69\x6F\x6E\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AD}, .data="\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0xCCD53015}, .data="\x72\x72\x70\x63\x2C\x6C\x6F\x63\x61\x74\x69\x6F\x6E\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x6AAF69C6}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x63\x6F\x72\x65\x76\x65\x72\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x1DCD569F}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x70\x72\x6F\x6A\x65\x63\x74\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x15ED6513}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x69\x63\x63\x69\x64\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x297B8417}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x76\x62\x61\x74\x74\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1663BD1}, .data="\x69\x6D\x73\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x15494269}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x69\x6D\x73\x69\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0xB654FFCB}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x6D\x75\x69\x64\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x6EB08285}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x69\x6D\x65\x69\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0xAC1D0094}, .data="\x52\x65\x6D\x6F\x74\x65\x20\x72\x65\x62\x6F\x6F\x74\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0xABABCCA7}, .data="\x72\x72\x70\x63\x2C\x73\x65\x74\x63\x68\x61\x6E\x6E\x65\x6C\x2C\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x2AAFC13E}, .data="\x77\x45\x42\xE7\x9A\x84\xE5\x80\xBC\x32\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0C627}, .data="\x61\x6C\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x603BB96F}, .data="\x77\x45\x42\xE7\x9A\x84\xE5\x80\xBC"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 25, .hash = 0xC83F8C94}, .data="\xE8\xBF\x9B\xE5\x88\xB0\x73\x65\x74\x63\x68\x61\x6E\x6E\x65\x6C\xE9\x87\x8C\xE9\x9D\xA2\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x6ECBF50D}, .data="\x67\x65\x74\x41\x44\x43"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xF4E21A7C}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x61\x64\x63\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x651A1A9A}, .data="\x65\x72\x72\x6F\x72\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x298A97C9}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x63\x73\x71\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x3EE4F912}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x76\x65\x72\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xD855584A}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x6E\x65\x74\x6D\x6F\x64\x65\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0xC8E671CD}, .data="\x72\x72\x70\x63\x2C\x67\x65\x74\x66\x77\x76\x65\x72\x2C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x463F6157}, .data="\x65\x72\x72\x69\x6E\x66\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB021E9}, .data="\x64\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x7C7D587E}, .data="\x4A\x53\x4F\x4E\x20\x45\x52\x52\x4F\x52"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x8736F037}, .data="\x73\x65\x74\x41\x75\x74\x68\x41\x70\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16714B1}, .data="\x6C\x69\x6E\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x703A6488}, .data="\x28\x2E\x2B\x29\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0F92F}, .data="\x74\x6D\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAE971703}, .data="\x45\x52\x52\x4F\x52"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB3D564}, .data="\x30\x2C\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC6CF59B}, .data="\x30\x2C\x31\x2C\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB33BA8}, .data="\x37\x2C\x38"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xACBDAD14}, .data="\x31\x2C\x32\x2C\x33"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x39B12E5F}, .data="\x50\x41\x53\x53\x57\x4F\x52\x44\x20\x45\x52\x52\x4F\x52"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 35, .hash = 0x707B0CCF}, .data="\x53\x65\x74\x74\x69\x6E\x67\x20\x70\x61\x72\x61\x6D\x65\x74\x65\x72\x73\x20\x68\x61\x76\x65\x20\x62\x65\x65\x6E\x20\x73\x61\x76\x65\x64\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A195}, .data="\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x9A60CC39}, .data="\x77\x72\x69\x74\x69\x6E\x67\x20\x2E\x2E\x2E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x48732232}, .data="\x77\x72\x69\x74\x65\x20\x64\x6F\x6E\x65\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x27098F01}, .data="\x5F\x57\x52\x49\x54\x45\x5F\x44\x4F\x4E\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BC2D}, .data="\x33\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x9A5C07E0}, .data="\x77\x72\x69\x74\x65\x49\x64\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xE9CF73CF}, .data="\x77\x72\x69\x74\x65\x42\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x61DE77C7}, .data="\x53\x45\x4E\x44\x53\x49\x5A\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xAFA5A5BF}, .data="\x20\x77\x72\x69\x74\x69\x6E\x67\x20\x2E\x2E\x2E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x7C43208D}, .data="\x55\x41\x52\x54\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 19, .hash = 0xC0EC10FB}, .data="\x2E\x77\x72\x69\x74\x65\x20\x64\x61\x74\x61\x20\x6C\x65\x6E\x67\x74\x68\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x31004D54}, .data="\x73\x74\x72\xE7\x9A\x84\xE5\xAE\x9E\xE9\x99\x85\xE5\x80\xBC\xE6\x98\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xD91966B7}, .data="\x74\x69\x6D\x65\x63\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xF10D947A}, .data="\x66\x6C\x6F\x77\x43\x6F\x75\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0x1BDF4AD9}, .data="\x75\x61\x72\x74\x32\x2E\x72\x65\x61\x64\x20\x6C\x65\x6E\x67\x74\x68\x20\x63\x6F\x75\x6E\x74\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x8622C7EF}, .data="\x75\x61\x72\x74\x32\x20\x63\x6C\x6F\x73\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0x19DE9377}, .data="\x75\x61\x72\x74\x31\x2E\x72\x65\x61\x64\x20\x6C\x65\x6E\x67\x74\x68\x20\x63\x6F\x75\x6E\x74\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x845A5710}, .data="\x75\x61\x72\x74\x31\x20\x63\x6C\x6F\x73\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A57E}, .data="\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xCCC3A181}, .data="\x67\x65\x74\x44\x61\x74\x61\x6C\x69\x6E\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB089EA}, .data="\x63\x66\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 31, .hash = 0xEA71081A}, .data="\xE8\xBD\xAF\xE4\xBB\xB6\xE6\x81\xA2\xE5\xA4\x8D\xE5\x87\xBA\xE5\x8E\x82\xE9\xBB\x98\xE8\xAE\xA4\xE5\x80\xBC\x3A\x20\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x0C2BAAC4}, .data="\x72\x65\x73\x74\x61\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x423278B6}, .data="\x2F\x62\x64\x69\x6F\x74\x2E\x64\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x42326F3E}, .data="\x2F\x71\x71\x69\x6F\x74\x2E\x64\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xB0E279E5}, .data="\x2F\x61\x6C\x69\x6B\x65\x79\x2E\x63\x6E\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0991D}, .data="\x73\x65\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0FE42}, .data="\x6D\x69\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16FAE54}, .data="\x68\x6F\x75\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB04D74}, .data="\x64\x61\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x967E2CBB}, .data="\x6D\x6F\x6E\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D5829}, .data="\x79\x65\x61\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 29, .hash = 0x9CADA413}, .data="\x25\x30\x34\x64\x2D\x25\x30\x32\x64\x2D\x25\x30\x32\x64\x20\x25\x30\x32\x64\x3A\x25\x30\x32\x64\x3A\x25\x30\x32\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0x2258D536}, .data="\xE7\xBD\x91\xE7\xBB\x9C\xE6\x97\xB6\xE9\x97\xB4\xE5\xB7\xB2\xE5\x90\x8C\xE6\xAD\xA5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B6F1}, .data="\x2A\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165724B}, .data="\x64\x61\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xF3B75210}, .data="\x4E\x54\x50\x5F\x55\x50\x44\x41\x54\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x11031B20}, .data="\x74\x72\x61\x63\x6B\x46\x69\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xF2208504}, .data="\x67\x70\x73\x73\x74\x61\x72\x74\x54\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EBAF844}, .data="\x72\x65\x70\x6F\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xE2ACEA29}, .data="\x69\x6E\x74\x65\x72\x76\x61\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0F428}, .data="\x73\x65\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97A5D60C}, .data="\x67\x75\x61\x72\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2E1E0BFB}, .data="\x70\x77\x6D\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x9368FCF5}, .data="\x47\x50\x53\x5F\x47\x4F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 32, .hash = 0xD0D9EBFE}, .data="\xE8\xBF\x9B\xE5\x88\xB0\xE8\xBF\x99\xE9\x87\x8C\xE6\x9D\xA5\xE4\xBA\x86\x47\x50\x53\x5F\x4D\x53\x47\x5F\x52\x45\x50\x4F\x52\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x3D1293FF}, .data="\x49\x4E\x54\x45\x52\x56\x41\x4C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xB9DE0851}, .data="\x67\x70\x73\xE5\xBC\x80\xE4\xBA\x86\x2B\x2B\x2B\x2B\x2B\x2B\x2B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xA1F5029B}, .data="\x47\x50\x53\x20\xE4\xBB\xBB\xE5\x8A\xA1\xE5\x90\xAF\xE5\x8A\xA8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 29, .hash = 0xB864E9C6}, .data="\x30\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x2D\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x5388EC21}, .data="\x73\x61\x74\x65\x43\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xDA9096E2}, .data="\x67\x67\x61\x54\x61\x62\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD9AB425F}, .data="\x67\x73\x76\x54\x61\x62\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x965A4FB6}, .data="\x73\x70\x65\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FB}, .data="\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186FA}, .data="\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF10FBF00}, .data="\x2E\x25\x64\x2A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x9BA4BE4E}, .data="\x3E\x62\x32\x69\x33\x48\x33\x62\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0xCD175D41}, .data="\x69\x73\x46\x69\x78\x20\x61\x6E\x64\x20\x31\x20\x6F\x72\x20\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09A06}, .data="\x72\x6D\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3B1369A8}, .data="\x67\x65\x74\x52\x6D\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x0ADD6996}, .data="\x73\x61\x74\x65\x6C\x6C\x69\x74\x65\x73\x5F\x74\x72\x61\x63\x6B\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xFE4459DA}, .data="\x41\x5A\x49\x4D\x55\x54\x48"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x27F7F00E}, .data="\x61\x7A\x69\x6D\x75\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D6E63}, .data="\x73\x61\x74\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x1A76FC32}, .data="\x61\x6C\x74\x69\x74\x75\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x46C35C53}, .data="\x67\x65\x74\x47\x67\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xB35E9A43}, .data="\x67\x65\x74\x47\x73\x76"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x85F9DF8C}, .data="\x67\x65\x74\x49\x6E\x74\x4C\x6F\x63\x61\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98F8DCA5}, .data="\x69\x73\x46\x69\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x613F47B2}, .data="\x43\x45\x4C\x4C\x5F\x49\x4E\x46\x4F\x5F\x55\x50\x44\x41\x54\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x316CD4E8}, .data="\x72\x65\x71\x43\x65\x6C\x6C\x49\x6E\x66\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9446CA6B}, .data="\x3E\x62\x37\x66\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2BCBB}, .data="\x73\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0D664}, .data="\x68\x65\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x6281412A}, .data="\x6C\x6F\x77\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x9A45F836}, .data="\x76\x6F\x6C\x74\x56\x61\x6C\x75\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x3E8F4A9B}, .data="\x61\x64\x63\x56\x61\x6C\x75\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E52F}, .data="\x6C\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA7AE51AB}, .data="\x61\x64\x63\x51\x75\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xC2A969C8}, .data="\x70\x6F\x77\x65\x72\x56\x6F\x6C\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x980B8B84}, .data="\x72\x61\x74\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97A0770A}, .data="\x61\x64\x63\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x980B5C0B}, .data="\x63\x68\x67\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x980C4AA5}, .data="\x61\x63\x63\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x980C4841}, .data="\x76\x69\x62\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x980C4736}, .data="\x6C\x65\x64\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D76BF}, .data="\x73\x65\x6E\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1654579}, .data="\x72\x65\x61\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x365C5091}, .data="\x6F\x70\x65\x6E\x46\x6C\x61\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x972F98EF}, .data="\x67\x70\x73\x55\x61\x72\x74\x49\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9811ABDB}, .data="\x73\x6C\x65\x65\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF17AF26B}, .data="\x62\x61\x75\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x61119F54}, .data="\x47\x50\x53\x5F\x4D\x53\x47\x5F\x52\x45\x50\x4F\x52\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E7A4}, .data="\x74\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165826A}, .data="\x62\x69\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2AFFA}, .data="\x47\x50\x53"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x6281412E}, .data="\x70\x6F\x77\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E7A7}, .data="\x75\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x1F63DC19}, .data="\x4E\x45\x54\x5F\x53\x45\x4E\x54\x5F\x52\x44\x59\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x6AA4F43E}, .data="\x66\x72\x6F\x6D\x48\x65\x78\x6E\x65\x77"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xD67161FF}, .data="\x41\x55\x54\x4F\x5F\x53\x41\x4D\x50\x4C\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0DD89}, .data="\x6C\x62\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 28, .hash = 0xB54CBDC3}, .data="\xE5\x9F\xBA\xE7\xAB\x99\xE5\xAE\x9A\xE4\xBD\x8D\xE8\xAF\xB7\xE6\xB1\x82\xE7\x9A\x84\xE7\xBB\x93\xE6\x9E\x9C\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0D4F2}, .data="\x64\x74\x75"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xA6833792}, .data="\x66\x75\x6E\x63\x74\x69\x6F\x6E\x28\x2E\x2B\x29\x65\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x9A7C5239}, .data="\x70\x63\x61\x6C\x6C\x5F\x74\x61\x73\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x70EC345F}, .data="\x43\x48\x5F\x56\x42\x41\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x41A29E12}, .data="\x52\x49\x53\x49\x4E\x47"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x23418F42}, .data="\x56\x55\x41\x52\x54\x5F\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xEF64E380}, .data="\x75\x61\x72\x74\x5F\x49\x4E\x49\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xDC50A7EE}, .data="\x73\x69\x6D\x63\x72\x6F\x73\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD76A8D12}, .data="\x75\x70\x63\x6F\x6E\x66\x69\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x4DB859D0}, .data="\x67\x70\x73\x5F\x63\x6C\x6F\x73\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x577A4817}, .data="\x67\x70\x73\x5F\x67\x65\x74\x6D\x73\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xC1A5E059}, .data="\x67\x70\x73\x5F\x67\x65\x74\x73\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xC38FE4FF}, .data="\x67\x70\x73\x5F\x77\x61\x6B\x65\x75\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x6326C1B8}, .data="\x6E\x65\x74\x73\x74\x61\x74\x75\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2E7C3F79}, .data="\x67\x65\x74\x70\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2E7C3F65}, .data="\x73\x65\x74\x70\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xE48BFF0F}, .data="\x67\x65\x74\x74\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x2BA9FA5A}, .data="\x67\x65\x74\x72\x65\x61\x6C\x6C\x6F\x63\x61\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xDE0629B4}, .data="\x67\x65\x74\x6C\x6F\x63\x61\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x051152A7}, .data="\x67\x65\x74\x63\x6F\x72\x65\x76\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x0516A6BE}, .data="\x67\x65\x74\x70\x72\x6F\x6A\x65\x63\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xFDD77209}, .data="\x67\x65\x74\x69\x63\x63\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xB59DA21E}, .data="\x67\x65\x74\x76\x62\x61\x74\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x02F23EDB}, .data="\x67\x65\x74\x69\x6D\x73\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x999642F5}, .data="\x67\x65\x74\x6D\x75\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC900DF3E}, .data="\x67\x65\x74\x69\x6D\x65\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xC1960F04}, .data="\x73\x65\x74\x63\x68\x61\x6E\x6E\x65\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x47BA2AC0}, .data="\x67\x65\x74\x61\x64\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x33FCF3CF}, .data="\x67\x65\x74\x63\x73\x71"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2C4EFAB3}, .data="\x67\x65\x74\x76\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x30625C94}, .data="\x67\x65\x74\x6E\x65\x74\x6D\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x3AD39B19}, .data="\x67\x65\x74\x66\x77\x76\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16A6F0F}, .data="\x72\x72\x70\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x5FF1F03F}, .data="\x67\x70\x73\x5F\x64\x65\x76"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x8520F9E0}, .data="\x77\x72\x69\x74\x65\x63\x6F\x6E\x66\x69\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x829DB071}, .data="\x72\x65\x61\x64\x63\x6F\x6E\x66\x69\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018692}, .data="\x39"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018691}, .data="\x38"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF167B0DD}, .data="\x61\x75\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869B}, .data="\x42"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869A}, .data="\x41"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1640393}, .data="\x70\x69\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E64E}, .data="\x63\x6D\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE4CDB30A}, .data="\x50\x55\x4C\x4C\x55\x50"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x46C4C050}, .data="\x72\x65\x73\x65\x74\x43\x6F\x6E\x66\x69\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x98A6610F}, .data="\x6E\x65\x74\x72\x65\x61\x64\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xADA7CBA4}, .data="\x70\x69\x6F\x33\x35"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAE8BB2F9}, .data="\x70\x69\x6F\x33\x34"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC855E5E}, .data="\x70\x69\x6F\x33\x33"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC7701C8}, .data="\x70\x69\x6F\x33\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC669D4F}, .data="\x70\x69\x6F\x33\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A13F963}, .data="\x70\x69\x6F\x33\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xACE76631}, .data="\x70\x69\x6F\x32\x39"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xACD45999}, .data="\x70\x69\x6F\x32\x38"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xACC51E82}, .data="\x70\x69\x6F\x32\x37"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xADBB6EBF}, .data="\x70\x69\x6F\x32\x36"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xADAECBAF}, .data="\x70\x69\x6F\x32\x35"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAE883E02}, .data="\x70\x69\x6F\x32\x34"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC898709}, .data="\x70\x69\x6F\x32\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC67E6B6}, .data="\x70\x69\x6F\x32\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A136AA2}, .data="\x70\x69\x6F\x32\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xACC38743}, .data="\x70\x69\x6F\x31\x37"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xADBDE7DE}, .data="\x70\x69\x6F\x31\x36"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF29AA7E4}, .data="\x70\x69\x6F\x39"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF29A201B}, .data="\x70\x69\x6F\x38"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF29DAAB1}, .data="\x70\x69\x6F\x37"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF29D2C76}, .data="\x70\x69\x6F\x36"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF2908237}, .data="\x70\x69\x6F\x35"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF2900CD8}, .data="\x70\x69\x6F\x34"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF11BD5B1}, .data="\x70\x69\x6F\x33"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF10C47CE}, .data="\x70\x69\x6F\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9808EA1C}, .data="\x73\x65\x74\x75\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF11ACD4F}, .data="\x70\x69\x6F\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D039C}, .data="\x70\x69\x6F\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x0345BF6E}, .data="\x52\x45\x4D\x4F\x54\x45\x5F\x43\x4C\x4F\x53\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0xD0E35E68}, .data="\x52\x45\x4D\x4F\x54\x45\x5F\x57\x41\x4B\x45\x55\x50"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98842CC1}, .data="\x61\x6C\x65\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x901D7066}, .data="\x6C\x6F\x63\x61\x74\x65\x4D\x65\x73\x73\x61\x67\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x948CB23E}, .data="\x64\x65\x76\x69\x63\x65\x4D\x65\x73\x73\x61\x67\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x809EB9C2}, .data="\x73\x65\x6E\x73\x4D\x6F\x6E\x69\x74\x6F\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x38F129E8}, .data="\x69\x73\x4F\x70\x65\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09952}, .data="\x76\x63\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0F620}, .data="\x77\x75\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E641}, .data="\x75\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB08AB5}, .data="\x63\x68\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB02627}, .data="\x61\x63\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09949}, .data="\x61\x63\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2BD2F}, .data="\x76\x69\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xDE160752}, .data="\x73\x65\x74\x4C\x6F\x63\x61\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x622A18E1}, .data="\x67\x65\x74\x50\x61\x72\x61\x6D\x56\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B621C4F}, .data="\x76\x62\x61\x74\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1194F1E}, .data="\x61\x64\x63\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF11AC5AD}, .data="\x61\x64\x63\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0EACF}, .data="\x70\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD601869C}, .data="\x3B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xF2604D3C}, .data="\x31\x31\x35\x32\x30\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0DFCC}, .data="\x67\x70\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16604FA}, .data="\x4E\x6F\x6E\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x961E15FD}, .data="\x75\x63\x6F\x6E\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x21836494}, .data="\x73\x6D\x73\x77\x6F\x72\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B53DA1C}, .data="\x64\x65\x6C\x61\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x81441710}, .data="\x70\x72\x65\x73\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF164B602}, .data="\x63\x6F\x6E\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D7637}, .data="\x70\x69\x6E\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF17B0421}, .data="\x63\x6D\x64\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0FE38}, .data="\x61\x70\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8FE70236}, .data="\x64\x77\x70\x72\x6F\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8FE702C1}, .data="\x75\x70\x70\x72\x6F\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0xECF72E4E}, .data="\x70\x72\x6F\x74\x65\x63\x74\x43\x6F\x6E\x74\x65\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x4CF946ED}, .data="\x70\x61\x73\x73\x77\x6F\x72\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x34BD8926}, .data="\x6E\x6F\x72\x6D\x61\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x9228E756}, .data="\x70\x77\x72\x6D\x6F\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xF7936E93}, .data="\x69\x73\x69\x70\x76\x36"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x2E0A10DA}, .data="\x77\x65\x62\x50\x72\x6F\x74\x65\x63\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xF1158C6F}, .data="\x69\x73\x52\x6E\x64\x69\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AA}, .data="\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x978CC335}, .data="\x6E\x6F\x6C\x6F\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x552CCC2B}, .data="\x6E\x65\x74\x52\x65\x61\x64\x54\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x0ED03585}, .data="\x75\x61\x72\x74\x52\x65\x61\x64\x54\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF177109E}, .data="\x66\x6C\x6F\x77"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x4BD5B547}, .data="\x70\x61\x72\x61\x6D\x5F\x76\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB08A5A}, .data="\x72\x65\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x19DB5269}, .data="\x63\x6F\x6E\x76\x65\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97B25B22}, .data="\x70\x6C\x61\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3E796B82}, .data="\x70\x61\x73\x73\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB08AE5}, .data="\x6C\x6E\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB02191}, .data="\x6C\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x46289C78}, .data="\x64\x74\x75\x6C\x69\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xD3402D78}, .data="\x64\x65\x66\x61\x75\x6C\x74\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A09E}, .data="\x50\x43"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2A4D5394}, .data="\x64\x62\x74\x79\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2E1E4DFF}, .data="\x65\x6E\x63\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 20, .hash = 0x0B74A3F0}, .data="\x73\x68\x65\x65\x74\x20\x74\x79\x70\x65\x20\x69\x73\x20\x65\x72\x72\x6F\x72\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 16, .hash = 0x931527B6}, .data="\x64\x62\x3A\x69\x6D\x70\x6F\x72\x74\x20\x65\x72\x72\x6F\x72\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E531}, .data="\x61\x64\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A496}, .data="\x72\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x7CFBDF14}, .data="\x72\x65\x74\x75\x72\x6E\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2A6CF}, .data="\x77\x2B\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF178C336}, .data="\x6F\x70\x65\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB04CF0}, .data="\x6B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF164B708}, .data="\x73\x65\x6C\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0221D}, .data="\x72\x65\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF167658E}, .data="\x62\x61\x63\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x451D808F}, .data="\x49\x72\x72\x65\x67\x75\x6C\x61\x72\x20\x64\x61\x74\x61\x20\x66\x6F\x72\x6D\x61\x74\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2E1E2B5C}, .data="\x64\x65\x63\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B3EE940}, .data="\x73\x68\x65\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD4477C6B}, .data="\x6F\x2E\x70\x61\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x226E7F56}, .data="\x65\x78\x69\x73\x74\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF167B243}, .data="\x70\x61\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1676E77}, .data="\x2E\x62\x61\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x861E400B}, .data="\x28\x5B\x5E\x2F\x5D\x2B\x29\x24"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A8}, .data="\x2F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xDCE544DA}, .data="\x45\x6D\x70\x74\x79\x20\x70\x61\x74\x68\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x98BC6F3F}, .data="\x64\x62\x2E\x6E\x65\x77\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xCC131D9B}, .data="\x6F\x2E\x70\x61\x74\x68\x31\x31\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E8}, .data="\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1663C47}, .data="\x66\x69\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B8D5}, .data="\x7D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BB04}, .data="\x2C\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF101F9C5}, .data="\x5D\x20\x3D\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A398}, .data="\x20\x5B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B8D3}, .data="\x7B\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A4CE}, .data="\x25\x71"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x81D9D449}, .data="\x66\x6F\x72\x6D\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97B3EBDC}, .data="\x77\x72\x69\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EBAFFED}, .data="\x65\x78\x70\x6F\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8EBAFF4F}, .data="\x69\x6D\x70\x6F\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA7AEFE2B}, .data="\x64\x65\x6C\x65\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA7826677}, .data="\x75\x70\x64\x61\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xCAB84019}, .data="\x73\x65\x72\x69\x61\x6C\x69\x7A\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0D267}, .data="\x6E\x65\x77"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x7C31BBAB}, .data="\x73\x65\x72\x69\x61\x6C\x69\x7A\x65\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x41C1D729}, .data="\x64\x62\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x92771416}, .data="\x74\x61\x73\x6B\x43\x6C\x69\x65\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC67F763}, .data="\x31\x32\x34\x31\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x15F5C84D}, .data="\x62\x73\x2E\x6F\x70\x65\x6E\x6C\x75\x61\x74\x2E\x63\x6F\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xA0B347FE}, .data="\x62\x63\x64\x4E\x75\x6D\x54\x6F\x4E\x75\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x7C50B6E5}, .data="\x74\x72\x61\x6E\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2FB68F7E}, .data="\x64\x31\x4E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xB54F2B19}, .data="\x65\x6E\x57\x69\x66\x69\x49\x6E\x66\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xB3B82CAC}, .data="\x65\x6E\x43\x65\x6C\x6C\x49\x6E\x66\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA6DEF886}, .data="\x65\x6E\x4D\x75\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xEB89894B}, .data="\x6E\x75\x6D\x54\x6F\x42\x63\x64\x4E\x75\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x34D6480C}, .data="\x6C\x6F\x63\x54\x79\x70\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x6DECB5DD}, .data="\x72\x65\x61\x64\x5F\x62\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9BB26F8F}, .data="\x72\x78\x5F\x62\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xA81E4FD0}, .data="\x72\x65\x74\x72\x79\x43\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC703A25E}, .data="\x72\x65\x71\x57\x69\x66\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xE4474770}, .data="\x72\x65\x71\x54\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x5DCC2FC0}, .data="\x70\x72\x6F\x64\x75\x63\x74\x4B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x91934A07}, .data="\x72\x65\x71\x41\x64\x64\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 33, .hash = 0x4D94A591}, .data="\xE6\xA0\xB9\xE6\x8D\xAE\xE5\x9F\xBA\xE7\xAB\x99\xE6\x9F\xA5\xE8\xAF\xA2\xE7\xBB\x8F\xE7\xBA\xAC\xE5\xBA\xA6\xE5\xA4\xB1\xE8\xB4\xA5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xAC9D3DD3}, .data="\x6C\x62\x73\x4C\x6F\x63\x2E\x71\x75\x65\x72\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165E7A8}, .data="\x77\x61\x72\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x956A07B5}, .data="\x6C\x62\x73\x4C\x6F\x63\x20\x72\x65\x63\x65\x69\x76\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98AC5288}, .data="\x63\x6C\x65\x61\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98FAF0FA}, .data="\x74\x6F\x48\x65\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x25785B76}, .data="\x72\x65\x71\x53\x74\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x316F39C0}, .data="\x67\x65\x74\x43\x65\x6C\x6C\x49\x6E\x66\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x9A825A2F}, .data="\x62\x41\x62\x41\x41\x41\x41\x41"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x1ED251A6}, .data="\x49\x50\x5F\x52\x45\x41\x44\x59"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0EE97}, .data="\x73\x74\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186A9}, .data="\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165A016}, .data="\x6D\x75\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB02350}, .data="\x63\x6E\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97B0B4E8}, .data="\x74\x57\x69\x66\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xEBE6DBD9}, .data="\x66\x72\x6F\x6D\x48\x65\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF157DDA2}, .data="\x67\x73\x75\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A2DF}, .data="\x41\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x285B3ADD}, .data="\x68\x61\x6E\x64\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x0216221A}, .data="\x63\x6E\x74\x72\x73\x73\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EF}, .data="\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EE}, .data="\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB001BA}, .data="\x3E\x62\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x815E084D}, .data="\x6C\x73\x68\x69\x66\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0EF9E}, .data="\x62\x6F\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1639102}, .data="\x3E\x48\x48\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 19, .hash = 0x81F077E1}, .data="\x72\x73\x73\x69\x2C\x6D\x63\x63\x2C\x6D\x6E\x63\x2C\x6C\x61\x63\x2C\x63\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A402}, .data="\x63\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xDD186688}, .data="\x72\x73\x73\x69\x63\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09A83}, .data="\x6C\x61\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E7B5}, .data="\x63\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09A9B}, .data="\x74\x61\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09A20}, .data="\x6D\x6E\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB09945}, .data="\x6D\x63\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BDE0}, .data="\x76\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BD81}, .data="\x76\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x81C49FE0}, .data="\x63\x6F\x6E\x63\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x815E084B}, .data="\x72\x73\x68\x69\x66\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1658370}, .data="\x62\x61\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165774F}, .data="\x62\x79\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D4}, .data="\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0FFF5}, .data="\x6E\x75\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186ED}, .data="\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x07818211}, .data="\x64\x65\x73\x74\x4C\x65\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x628A874F}, .data="\x69\x6E\x53\x74\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018658}, .data="\xFF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0F42F}, .data="\x72\x65\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16D5BB1}, .data="\x63\x68\x61\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x6E8BA357}, .data="\x6C\x62\x73\x4C\x6F\x63\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAD83ED4D}, .data="\x6E\x65\x74\x43\x42"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x94E1B805}, .data="\x66\x6F\x74\x61\x5F\x74\x61\x73\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x0B58563D}, .data="\x75\x72\x6C\x5F\x70\x6F\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB00771}, .data="\x75\x72\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF171A4E3}, .data="\x68\x6F\x73\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB02614}, .data="\x72\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC134EC71}, .data="\x74\x6C\x73\x5F\x67\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97BB457E}, .data="\x72\x62\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97BB457C}, .data="\x74\x62\x75\x66\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2EFC309E}, .data="\x6E\x43\x61\x63\x68\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x8277EDE8}, .data="\x66\x6F\x74\x61\x44\x6F\x6E\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16604D0}, .data="\x64\x6F\x6E\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x5171B581}, .data="\x72\x63\x76\x43\x68\x75\x6E\x6B\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC5A3FA59}, .data="\x72\x73\x70\x48\x65\x61\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98969F1B}, .data="\x72\x65\x74\x72\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xD9E3E5BC}, .data="\x73\x74\x61\x74\x75\x73\x43\x6F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BDDE}, .data="\x64\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0BDFF}, .data="\x64\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xD090B119}, .data="\x72\x63\x76\x43\x61\x63\x68\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x0589E06C}, .data="\x66\x69\x6C\x65\x6C\x65\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x295CC254}, .data="\x66\x69\x6E\x64\x68\x65\x61\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x96CB6103}, .data="\x74\x6F\x74\x61\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF171A092}, .data="\x70\x6F\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A521}, .data="\x69\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D3}, .data="\x7A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D2}, .data="\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D1}, .data="\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x03F20BED}, .data="\x63\x6C\x69\x65\x6E\x74\x5F\x70\x61\x73\x73\x77\x6F\x72\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x27E75A9F}, .data="\x63\x6C\x69\x65\x6E\x74\x5F\x6B\x65\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xA6495375}, .data="\x63\x6C\x69\x65\x6E\x74\x5F\x63\x65\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xBFBC34CC}, .data="\x73\x65\x72\x76\x65\x72\x5F\x63\x65\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0DF5A}, .data="\x74\x6C\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x0B582CED}, .data="\x6F\x74\x61\x5F\x70\x6F\x72\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xC33A7207}, .data="\x6F\x74\x61\x5F\x75\x72\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0C1C6}, .data="\x6C\x65\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0xECC7D4E3}, .data="\x73\x74\x6F\x72\x67\x65\x5F\x6C\x6F\x63\x61\x74\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x962AD70A}, .data="\x63\x62\x46\x6E\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xE820534B}, .data="\x72\x65\x6C\x65\x61\x73\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0xA370C496}, .data="\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8\xE6\xB2\xA1\xE6\x9C\x89\xE6\x95\xB0\xE6\x8D\xAE"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 21, .hash = 0x1BB38E75}, .data="\xE7\xAD\x89\xE5\xBE\x85\xE6\x96\xB0\xE6\x95\xB0\xE6\x8D\xAE\xE5\x88\xB0\xE6\x9D\xA5"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x14E4DEBF}, .data="\x32\x31\x34\x37\x34\x38\x33\x36\x34\x37"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x66334045}, .data="\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x0E999A39}, .data="\x63\x68\x75\x6E\x6B\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x88225209}, .data="\x54\x72\x61\x6E\x73\x66\x65\x72\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x6281A214}, .data="\x75\x70\x70\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x3D587F39}, .data="\x28\x2E\x2D\x29\x3A\x25\x73\x2A\x28\x2E\x2D\x29\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x63EC211A}, .data="\x67\x6D\x61\x74\x63\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x628A871B}, .data="\x74\x6F\x53\x74\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x2D2F6395}, .data="\x68\x74\x74\x70\xE5\xBA\x94\xE7\xAD\x94\xE4\xB8\x8D\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x46C87339}, .data="\x68\x74\x74\x70\xE6\xB2\xA1\xE6\x9C\x89\xE7\x8A\xB6\xE6\x80\x81\xE8\xBF\x94\xE5\x9B\x9E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x619B19C3}, .data="\x25\x73\x28\x25\x64\x2B\x29\x25\x73\x2E\x2D\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1752FAB}, .data="\x0D\x0A\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1658266}, .data="\x66\x69\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x0524F4B8}, .data="\x46\x4F\x54\x41\xE5\xAE\x8C\xE6\x88\x90"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2F8E2B5C}, .data="\x69\x73\x44\x6F\x6E\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xD77019BE}, .data="\xE4\xB8\x8B\xE8\xBD\xBD\xE5\xAE\x8C\xE6\x88\x90"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xBFDE5D58}, .data="\xE6\x80\xBB\xE5\x85\xB1"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x93F94B23}, .data="\x66\x6F\x74\x61\xE7\xBB\x93\xE6\x9E\x9C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 30, .hash = 0xD879A20C}, .data="\xE6\x94\xB6\xE5\x88\xB0\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8\xE6\x95\xB0\xE6\x8D\xAE\xEF\xBC\x8C\xE9\x95\xBF\xE5\xBA\xA6"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 40, .hash = 0x9480868E}, .data="\xE5\x86\x99\xE5\x85\xA5\xE5\xBC\x82\xE5\xB8\xB8\xEF\xBC\x8C\xE8\xAF\xB7\xE8\x87\xB3\xE5\xB0\x91\xE5\x9C\xA8\x31\xE7\xA7\x92\xE5\x90\x8E\xE9\x87\x8D\xE8\xAF\x95"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165B7EC}, .data="\x75\x73\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x56AE3C66}, .data="\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8\xE6\x96\xAD\xE5\xBC\x80\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B63C}, .data="\x72\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9897CF6E}, .data="\x71\x75\x65\x72\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 36, .hash = 0x54C0F20C}, .data="\x41\x63\x63\x65\x70\x74\x3A\x20\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x0D\x0A\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB3A0CC}, .data="\x2D\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x785479DE}, .data="\x52\x61\x6E\x67\x65\x3A\x20\x62\x79\x74\x65\x73\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD6018693}, .data="\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD1BF9426}, .data="\x48\x6F\x73\x74\x3A\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x968CDB84}, .data="\x20\x48\x54\x54\x50\x2F\x31\x2E\x31\x0D\x0A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A1A6397}, .data="\x47\x45\x54\x20\x2F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF125721F}, .data="\x63\x6F\x70\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0C93C}, .data="\x64\x65\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xB3C411F5}, .data="\x2E\x3A\x28\x25\x64\x2B\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 19, .hash = 0xE629D65C}, .data="\x28\x25\x61\x2D\x29\x3A\x2F\x2F\x28\x25\x53\x2D\x29\x2F\x28\x25\x53\x2B\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD198DC06}, .data="\x63\x6F\x6E\x66\x69\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x7C514290}, .data="\x68\x74\x74\x70\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 33, .hash = 0x765B178D}, .data="\x5F\x47\x2E\x56\x45\x52\x53\x49\x4F\x4E\x20\x6D\x75\x73\x74\x20\x62\x65\x20\x78\x78\x78\x2E\x79\x79\x79\x2E\x7A\x7A\x7A\x21\x21\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2A063}, .data="\x73\x75\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x23252B25}, .data="\x26\x76\x65\x72\x73\x69\x6F\x6E\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x297F6E9D}, .data="\x5F\x4C\x75\x61\x74\x4F\x53\x2D\x53\x6F\x43\x5F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 27, .hash = 0x0C2CBC42}, .data="\x26\x64\x65\x76\x69\x63\x65\x5F\x6B\x65\x79\x3D\x26\x66\x69\x72\x6D\x77\x61\x72\x65\x5F\x6E\x61\x6D\x65\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1607464}, .data="\x69\x6D\x65\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x684F6D20}, .data="\x26\x69\x6D\x65\x69\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AF}, .data="\x2E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xA4C4A417}, .data="\x76\x65\x72\x73\x69\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x1519A8DC}, .data="\x28\x25\x64\x2B\x29\x2E\x28\x25\x64\x2B\x29\x2E\x28\x25\x64\x2B\x29"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x978ACCAB}, .data="\x6D\x61\x74\x63\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 36, .hash = 0xFAA21943}, .data="\x69\x6F\x74\x2E\x6F\x70\x65\x6E\x6C\x75\x61\x74\x2E\x63\x6F\x6D\x20\x6E\x65\x65\x64\x20\x50\x52\x4F\x44\x55\x43\x54\x5F\x4B\x45\x59\x21\x21\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x08D1BE20}, .data="\xE6\x9C\xAA\xE5\xA4\x84\xE7\x90\x86\xE6\xB6\x88\xE6\x81\xAF"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x3A14CBA4}, .data="\x73\x6F\x63\x6B\x65\x74\xE5\x85\xB3\xE9\x97\xAD"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x33CD9946}, .data="\x45\x56\x5F\x4E\x57\x5F\x52\x45\x53\x55\x4C\x54\x5F\x43\x4C\x4F\x53\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 18, .hash = 0x054C1F0C}, .data="\x73\x6F\x63\x6B\x65\x74\xE5\x8F\x91\xE9\x80\x81\xE5\xAE\x8C\xE6\x88\x90"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0xB98726B6}, .data="\x73\x6F\x63\x6B\x65\x74\xE7\xBD\x91\xE7\xBB\x9C\xE7\x8A\xB6\xE6\x80\x81\xE5\x8F\x98\xE6\x9B\xB4"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x731BEFDF}, .data="\x72\x65\x71\x75\x65\x73\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1620FFD}, .data="\x66\x6F\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xC214ACA1}, .data="\x4F\x54\x41\x5F\x54\x41\x53\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x1250BA2A}, .data="\x6C\x69\x62\x66\x6F\x74\x61\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x27A1F12B}, .data="\x73\x74\x61\x74\x75\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 31, .hash = 0xEEE5AAE1}, .data="\x53\x49\x4D\xE5\x8D\xA1\xE9\x94\x81\x70\x69\x6E\x2C\xE8\xAF\xB7\xE8\xA7\xA3\xE9\x94\x81\xE5\x90\x8E\xE4\xBD\xBF\xE7\x94\xA8"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x56081DD2}, .data="\x53\x49\x4D\x5F\x50\x49\x4E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x7D608D16}, .data="\x4E\x4F\x52\x44\x59"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 40, .hash = 0x84B29FD9}, .data="\xE8\xAF\x86\xE5\x88\xAB\xE5\x88\xB0\xE4\xBA\x86\x53\x49\x4D\xE5\x8D\xA1\xE7\x8A\xB6\xE6\x80\x81\xEF\xBC\x9A\x52\x44\x59\x20\x69\x63\x63\x69\x64\xEF\xBC\x9A\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0C52A}, .data="\x52\x44\x59"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x9D0505D7}, .data="\x47\x45\x54\x5F\x4E\x55\x4D\x42\x45\x52\x20\x69\x63\x63\x69\x64\x20"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x53A4DABF}, .data="\x47\x45\x54\x5F\x4E\x55\x4D\x42\x45\x52"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0x8B68A6B9}, .data="\x73\x69\x6D\x20\x73\x74\x61\x74\x75\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x97A07791}, .data="\x69\x63\x63\x69\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF166208C}, .data="\x74\x69\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB089DD}, .data="\x74\x61\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF17B423D}, .data="\x72\x73\x72\x71"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF178CC2A}, .data="\x72\x73\x72\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1663835}, .data="\x72\x73\x73\x69"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0E3ED}, .data="\x63\x73\x71"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2A457E05}, .data="\x6D\x6F\x62\x69\x6C\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98D440B9}, .data="\x2B\x20\x63\x73\x71"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x5298035E}, .data="\x43\x4C\x4F\x53\x45\x44"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3EE13E09}, .data="\x64\x69\x73\x63\x6F\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16A735E}, .data="\x6E\x65\x74\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x628B19D5}, .data="\x45\x56\x45\x4E\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x68363C40}, .data="\x69\x73\x5F\x66\x75\x6C\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC35AB45}, .data="\x54\x58\x5F\x4F\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x649B0234}, .data="\x4F\x4E\x5F\x4C\x49\x4E\x45"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8F109AF5}, .data="\x72\x65\x73\x75\x6C\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF163B63B}, .data="\x73\x75\x63\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x75EA0E99}, .data="\x74\x69\x6D\x65\x6F\x75\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1577F56}, .data="\x4C\x49\x4E\x4B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2114865C}, .data="\x6C\x69\x6E\x6B\x75\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x0AAD21AE}, .data="\x53\x49\x4D\x5F\x49\x4E\x44"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9655B9EE}, .data="\x63\x6C\x6F\x73\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B622}, .data="\x74\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x38F1B6C8}, .data="\x6C\x69\x73\x74\x65\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xBED8526A}, .data="\x63\x6F\x6E\x6E\x65\x63\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x84A405E9}, .data="\x77\x61\x69\x74\x4C\x69\x6E\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xEB2D4D81}, .data="\x6C\x69\x62\x6E\x65\x74\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x1632B779}, .data="\x73\x79\x73\x5F\x77\x61\x69\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x9B1E7F19}, .data="\x73\x79\x73\x5F\x73\x65\x6E\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xAA57D437}, .data="\x6E\x6F\x20\x63\x62\x20\x66\x75\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xF59C93E8}, .data="\x74\x61\x73\x6B\x43\x42"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xE628ECDA}, .data="\x63\x6C\x65\x61\x6E\x4D\x73\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x11A5147E}, .data="\x70\x61\x72\x61\x6D\x34"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE7E208DD}, .data="\x70\x61\x72\x61\x6D\x33"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xFD0D39B5}, .data="\x70\x61\x72\x61\x6D\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA0057C22}, .data="\x70\x61\x72\x61\x6D\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9F103991}, .data="\x73\x65\x6E\x64\x4D\x73\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD41BDB9E}, .data="\x66\x69\x6E\x69\x73\x68"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x814E702F}, .data="\x74\x61\x72\x67\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x9CC40010}, .data="\x77\x61\x69\x74\x4D\x73\x67"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xD1507446}, .data="\x77\x61\x69\x74\x54\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x4DFBCFB8}, .data="\x74\x61\x73\x6B\x44\x65\x6C"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A53D}, .data="\x54\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x3B181560}, .data="\x6D\x73\x67\x51\x75\x65\x75\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98BC2363}, .data="\x63\x62\x46\x75\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xCDB58E09}, .data="\x74\x61\x73\x6B\x4E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 10, .hash = 0xF1A3DF85}, .data="\x74\x61\x73\x6B\x49\x6E\x69\x74\x45\x78"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xC31FB6C4}, .data="\x74\x61\x73\x6B\x4C\x69\x73\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8FDF468A}, .data="\x73\x79\x73\x5F\x63\x77"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D0}, .data="\x77"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186E7}, .data="\x66"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186EB}, .data="\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186D5}, .data="\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x0B5B0100}, .data="\x63\x77\x61\x69\x74\x4D\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0xC2DB339C}, .data="\x40\x2F\x6C\x75\x61\x2F\x73\x79\x73\x70\x6C\x75\x73\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0x79B9A0E7}, .data="\x68\x61\x72\x64\x66\x61\x75\x6C\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x3C6E9CD4}, .data="\x64\x65\x66\x61\x75\x6C\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0F609}, .data="\x62\x73\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0EC59}, .data="\x76\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165B5CB}, .data="\x66\x65\x65\x64"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1704F40}, .data="\x69\x6E\x69\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0A2F2}, .data="\x64\x62"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3B35B976}, .data="\x6C\x62\x73\x4C\x6F\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x99826962}, .data="\x6C\x69\x62\x66\x6F\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x8141E313}, .data="\x6C\x69\x62\x6E\x65\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x22EB7D3F}, .data="\x73\x79\x73\x70\x6C\x75\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF178681B}, .data="\x6D\x61\x69\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 32, .hash = 0xBCA5F4A5}, .data="\x30\x4C\x6B\x5A\x78\x39\x4B\x6E\x33\x74\x4F\x68\x74\x57\x37\x75\x6F\x64\x34\x38\x78\x68\x69\x6C\x56\x4E\x72\x56\x73\x53\x63\x56"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xB6623912}, .data="\x50\x52\x4F\x44\x55\x43\x54\x5F\x4B\x45\x59"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xADA17CDC}, .data="\x31\x2E\x30\x2E\x35"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xBF6255DA}, .data="\x56\x45\x52\x53\x49\x4F\x4E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16FEAF3}, .data="\x69\x52\x54\x55"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x36A7F719}, .data="\x50\x52\x4F\x4A\x45\x43\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x98D931A1}, .data="\x75\x6C\x77\x69\x70"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xEB73BDF9}, .data="\x31\x31\x33\x2E\x32\x32\x39\x38\x33\x35\x35"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x5F21B25A}, .data="\x30\x32\x33\x2E\x34\x30\x36\x34\x37\x36\x39"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 25, .hash = 0x6A6F4B79}, .data="\x53\x65\x72\x76\x65\x72\x20\x63\x6F\x6E\x6E\x65\x63\x74\x69\x6F\x6E\x20\x66\x61\x69\x6C\x65\x64\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 14, .hash = 0x03470729}, .data="\x4E\x45\x54\x5F\x53\x45\x4E\x54\x5F\x52\x44\x59\x5F\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xAC879B24}, .data="\x44\x54\x55\x5F\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 2, .hash = 0x23B0B7C7}, .data="\x7B\x7D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2EE0E212}, .data="\x43\x6F\x6F\x6B\x69\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF125744E}, .data="\x56\x61\x72\x79"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 1, .hash = 0xD60186AB}, .data="\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 24, .hash = 0xD22F57DC}, .data="\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 29, .hash = 0x2222F6BA}, .data="\x53\x61\x74\x2C\x20\x31\x31\x20\x4D\x61\x79\x20\x32\x30\x32\x34\x20\x30\x37\x3A\x32\x36\x3A\x34\x39\x20\x47\x4D\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF165726B}, .data="\x44\x61\x74\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x14D171F6}, .data="\x6E\x67\x69\x6E\x78\x2F\x31\x2E\x31\x37\x2E\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x2C4EF355}, .data="\x53\x65\x72\x76\x65\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 17, .hash = 0x988BBFBE}, .data="\x6E\x65\x74\x6C\x61\x62\x2E\x6C\x75\x61\x74\x6F\x73\x2E\x63\x6F\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x88CDCDA3}, .data="\x40\x64\x74\x75\x6C\x69\x62\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xBAB2469A}, .data="\x40\x63\x72\x65\x61\x74\x65\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB021CA}, .data="\x72\x73\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xF7534D0E}, .data="\x73\x75\x63\x63\x75\x73\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB2BC47}, .data="\x6F\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB31251}, .data="\x4F\x54\x41"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 28, .hash = 0x497A7306}, .data="\xE7\x9F\xAD\xE4\xBF\xA1\xE6\x88\x96\xE7\x94\xB5\xE8\xAF\x9D\xE8\xAF\xB7\xE6\xB1\x82\xE6\x9B\xB4\xE6\x96\xB0\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x4D7EC4AA}, .data="\xE8\xB5\xB0\xE5\x88\xB0\xE8\xBF\x99\xE9\x87\x8C\xE4\xBA\x86"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 39, .hash = 0x32DE5CFC}, .data="\x44\x54\x55\x20\x50\x61\x72\x61\x6D\x65\x74\x65\x72\x73\x20\x6F\x72\x20\x66\x69\x72\x6D\x77\x61\x72\x65\x20\x61\x72\x65\x20\x75\x70\x64\x61\x74\x65\x64\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF101FE74}, .data="\x65\x6E\x64\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 15, .hash = 0x98FC7F49}, .data="\x49\x52\x54\x55\x5F\x55\x50\x44\x41\x54\x45\x5F\x52\x45\x53"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xA68D4478}, .data="\x73\x74\x61\x72\x74\x21"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 22, .hash = 0x886E0A0D}, .data="\x2D\x2D\x2D\x2D\x2D\x20\x75\x70\x64\x61\x74\x65\x20\x66\x69\x72\x6D\x77\x61\x72\x65\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1661841}, .data="\x43\x4F\x64\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 34, .hash = 0xF49A184E}, .data="\x50\x61\x72\x61\x6D\x65\x74\x65\x72\x73\x20\x69\x73\x73\x75\x65\x64\x20\x66\x72\x6F\x6D\x20\x74\x68\x65\x20\x73\x65\x72\x76\x65\x72\x3A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x1C7ED314}, .data="\x26\x70\x72\x6F\x6A\x65\x63\x74\x5F\x6B\x65\x79\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x529027F7}, .data="\x26\x70\x61\x72\x61\x6D\x5F\x76\x65\x72\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 20, .hash = 0xB7DC01BF}, .data="\x2F\x70\x61\x72\x61\x6D\x3F\x70\x72\x6F\x64\x75\x63\x74\x5F\x6E\x61\x6D\x65\x3D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 40, .hash = 0x2D8E857D}, .data="\x68\x74\x74\x70\x3A\x2F\x2F\x64\x74\x75\x2E\x6F\x70\x65\x6E\x6C\x75\x61\x74\x2E\x63\x6F\x6D\x2F\x61\x70\x69\x2F\x73\x69\x74\x65\x2F\x64\x65\x76\x69\x63\x65\x2F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x7D82AF60}, .data="\x64\x74\x75\x55\x52\x4C\x2B\x2B\x2B\x2B\x2B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB1520D}, .data="\x47\x45\x54"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xE5FE0AE4}, .data="\x70\x72\x6F\x64\x75\x63\x74\x5F\x6E\x61\x6D\x65"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x468C032E}, .data="\x64\x74\x75\x2E\x68\x6F\x73\x74\x2B\x2B\x2B\x2B\x2B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0xA254E595}, .data="\x62\x6C\x69\x6E\x6B\x50\x77\x6D"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3A8FF07A}, .data="\x6C\x65\x64\x70\x69\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF16E170E}, .data="\x64\x61\x72\x6B"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9B3CFCE0}, .data="\x6C\x69\x67\x68\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x3852DE16}, .data="\x6C\x65\x64\x50\x69\x6E"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 13, .hash = 0x96228BB1}, .data="\x52\x54\x4F\x53\x3E\x4D\x45\x4D\x49\x4E\x46\x4F\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xDF64CD05}, .data="\x52\x54\x4F\x53\x3E\x4D\x45\x4D\x49\x4E\x46\x4F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0xC7ED9A57}, .data="\x40\x64\x65\x66\x61\x75\x6C\x74\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0xACDF0E3F}, .data="\x45\x43\x36\x31\x38"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x8B099302}, .data="\x40\x64\x62\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0x48C2CBC8}, .data="\x40\x6C\x62\x73\x4C\x6F\x63\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 12, .hash = 0x675EA829}, .data="\x40\x6C\x69\x62\x66\x6F\x74\x61\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 11, .hash = 0xDF4F1B4D}, .data="\x40\x6C\x69\x62\x6E\x65\x74\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0xFAEFD112}, .data="\x6D\x65\x6D\x2E\x73\x79\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 9, .hash = 0xF5E1AF56}, .data="\x40\x6D\x61\x69\x6E\x2E\x6C\x75\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0xE4D9EEB5}, .data="\x68\x74\x31\x36\x32\x31"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF171AA71}, .data="\x6E\x61\x70\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x623EB64E}, .data="\x68\x6D\x65\x74\x61"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 7, .hash = 0x85362CD6}, .data="\x4D\x43\x4F\x44\x45\x52\x2A"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x95D6E544}, .data="\x63\x6F\x64\x65\x63"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x980B9067}, .data="\x61\x75\x64\x69\x6F"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0D740}, .data="\x69\x32\x73"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 4, .hash = 0xF1033A00}, .data="\x75\x38\x67\x32"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 6, .hash = 0x25D4A27B}, .data="\x73\x65\x6E\x73\x6F\x72"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 3, .hash = 0x5CB0DF38}, .data="\x73\x6D\x73"},
+
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x0953B716}, .data="\x6D\x65\x6D\x5F\x73\x74\x61\x74"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 5, .hash = 0x9A138761}, .data="\x31\x2E\x30\x2E\x30"},
+    {.str={.tt = LUA_TSHRSTR, .marked = 4, .extra = 0, .shrlen = 8, .hash = 0x2110019F}, .data="\x68\x74\x74\x70\x64\x65\x6D\x6F"},
+#endif
+    {.str={.shrlen=0}}
+};