Multi Arguments

- New: webui_get_int_at()
- New: webui_get_string_at()
- New: webui_get_bool_at()
- New: webui_get_size_at()
- Change: webui_interface_bind
- Removed: `e->data` becomes `webui_get_xxx_at(e, 0)`
This commit is contained in:
Hassan DRAGA 2023-10-05 20:03:12 -04:00
parent 39f9ab0cd7
commit b09c0dca94
6 changed files with 815 additions and 877 deletions

View File

@ -1435,441 +1435,333 @@ unsigned char webui_javascript_bridge[] = {
0x6c, 0x61, 0x63, 0x65, 0x28, 0x75, 0x72, 0x6c, 0x29, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20,
0x20, 0x23, 0x69, 0x73, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, 0x28, 0x75, 0x72, 0x6c,
0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x55,
0x52, 0x4c, 0x28, 0x75, 0x72, 0x6c, 0x29, 0x2e, 0x68, 0x6f,
0x73, 0x74, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x67, 0x6c, 0x6f,
0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x6f,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x6f, 0x73,
0x74, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x23,
0x63, 0x6c, 0x6f, 0x73, 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f,
0x77, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x28, 0x29, 0x20, 0x7b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x54, 0x69,
0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61,
0x6c, 0x54, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x73,
0x65, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d,
0x2c, 0x20, 0x31, 0x65, 0x33, 0x29, 0x3b, 0x0a, 0x20, 0x20,
0x7d, 0x0a, 0x20, 0x20, 0x23, 0x74, 0x6f, 0x55, 0x69, 0x6e,
0x74, 0x31, 0x36, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29,
0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20,
0x26, 0x20, 0x36, 0x35, 0x35, 0x33, 0x35, 0x3b, 0x0a, 0x20,
0x20, 0x7d, 0x0a, 0x20, 0x20, 0x23, 0x63, 0x61, 0x6c, 0x6c,
0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x28, 0x66, 0x6e,
0x2c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x7b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x68, 0x69,
0x73, 0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f,
0x6d, 0x69, 0x73, 0x65, 0x49, 0x44, 0x5b, 0x30, 0x5d, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
0x20, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x20, 0x3d, 0x20,
0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x55, 0x69,
0x6e, 0x74, 0x31, 0x36, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69,
0x73, 0x65, 0x49, 0x44, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68,
0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65,
0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x61, 0x6c,
0x6c, 0x20, 0x5b, 0x24, 0x7b, 0x66, 0x6e, 0x7d, 0x5d, 0x28,
0x24, 0x7b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x29, 0x20,
0x28, 0x49, 0x44, 0x3a, 0x24, 0x7b, 0x74, 0x68, 0x69, 0x73,
0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d,
0x69, 0x73, 0x65, 0x49, 0x44, 0x5b, 0x30, 0x5d, 0x7d, 0x29,
0x60, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f,
0x6e, 0x73, 0x74, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x20, 0x3d, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72,
0x72, 0x61, 0x79, 0x2e, 0x6f, 0x66, 0x28, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
0x57, 0x45, 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e,
0x41, 0x54, 0x55, 0x52, 0x45, 0x2c, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x20, 0x23, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x57, 0x69, 0x6e,
0x64, 0x6f, 0x77, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x28, 0x29,
0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74,
0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x6f,
0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6c,
0x6f, 0x73, 0x65, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x7d, 0x2c, 0x20, 0x31, 0x65, 0x33, 0x29, 0x3b, 0x0a,
0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x23, 0x74, 0x6f, 0x55,
0x69, 0x6e, 0x74, 0x31, 0x36, 0x28, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x20, 0x26, 0x20, 0x36, 0x35, 0x35, 0x33, 0x35, 0x3b,
0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x23, 0x63, 0x61,
0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x28,
0x66, 0x6e, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x61, 0x72, 0x67,
0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d,
0x2d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61, 0x6c,
0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x49, 0x44,
0x5b, 0x30, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63,
0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x49,
0x64, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
0x74, 0x6f, 0x55, 0x69, 0x6e, 0x74, 0x31, 0x36, 0x28, 0x74,
0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50,
0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x49, 0x44, 0x5b, 0x30,
0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
0x74, 0x20, 0x61, 0x72, 0x67, 0x73, 0x4c, 0x65, 0x6e, 0x67,
0x74, 0x68, 0x73, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x73,
0x2e, 0x6d, 0x61, 0x70, 0x28, 0x28, 0x61, 0x72, 0x67, 0x29,
0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65,
0x6f, 0x66, 0x20, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x3d, 0x3d,
0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29,
0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72,
0x67, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c,
0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e,
0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e,
0x63, 0x6f, 0x64, 0x65, 0x28, 0x61, 0x72, 0x67, 0x2e, 0x74,
0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29,
0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x7d, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22,
0x3b, 0x22, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
0x65, 0x74, 0x20, 0x61, 0x72, 0x67, 0x73, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20,
0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79,
0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f,
0x72, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x61,
0x72, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x72, 0x67, 0x73,
0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x6c, 0x65, 0x74, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x61,
0x72, 0x67, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, 0x20, 0x7b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x66,
0x66, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65,
0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78,
0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29,
0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x61, 0x72,
0x67, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x28, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63,
0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x20,
0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74,
0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x61, 0x72, 0x67,
0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x20, 0x2b, 0x20, 0x62, 0x75, 0x66,
0x66, 0x65, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
0x20, 0x2b, 0x20, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x2e, 0x73, 0x65,
0x74, 0x28, 0x61, 0x72, 0x67, 0x73, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x2c, 0x20, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x2e, 0x73,
0x65, 0x74, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2c,
0x20, 0x61, 0x72, 0x67, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6d,
0x70, 0x5b, 0x61, 0x72, 0x67, 0x73, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20,
0x2b, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x6c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x5d, 0x20, 0x3d, 0x20, 0x30,
0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x72,
0x67, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x3d,
0x20, 0x74, 0x65, 0x6d, 0x70, 0x3b, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e,
0x73, 0x74, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x20,
0x3d, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72,
0x61, 0x79, 0x2e, 0x6f, 0x66, 0x28, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x57,
0x45, 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41,
0x54, 0x55, 0x52, 0x45, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f,
0x2f, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x28, 0x34,
0x20, 0x42, 0x79, 0x74, 0x65, 0x73, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20,
0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30,
0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f,
0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x28, 0x34, 0x20,
0x42, 0x79, 0x74, 0x65, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x2f, 0x2f, 0x20, 0x49, 0x44, 0x20, 0x28, 0x32,
0x20, 0x42, 0x79, 0x74, 0x65, 0x73, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
0x43, 0x4d, 0x44, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x46,
0x55, 0x4e, 0x43, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x2e, 0x2e, 0x2e, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65,
0x78, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28,
0x29, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x66,
0x6e, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e,
0x2e, 0x2e, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74,
0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e,
0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x53, 0x74, 0x72,
0x69, 0x6e, 0x67, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e,
0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x29, 0x2c, 0x0a,
0x20, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x2f, 0x2f, 0x20, 0x49, 0x44, 0x20, 0x28, 0x32, 0x20,
0x42, 0x79, 0x74, 0x65, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43,
0x4d, 0x44, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x46, 0x55,
0x4e, 0x43, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x2e, 0x2e, 0x2e, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78,
0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29,
0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x66, 0x6e,
0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30,
0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x2e,
0x2e, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74, 0x45,
0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x65,
0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x61, 0x72, 0x67, 0x73,
0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x29, 0x2c, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x2c, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x2e, 0x2e, 0x74, 0x79,
0x70, 0x65, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x22, 0x20, 0x3f, 0x20, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65,
0x78, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28,
0x29, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x29,
0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73,
0x2e, 0x23, 0x61, 0x64, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2c, 0x20, 0x74,
0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52,
0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x4f, 0x4b,
0x45, 0x4e, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74,
0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64, 0x49, 0x44,
0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2c, 0x20, 0x63,
0x61, 0x6c, 0x6c, 0x49, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x69,
0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f,
0x4c, 0x5f, 0x49, 0x44, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65,
0x77, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x28,
0x28, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x29, 0x20,
0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61, 0x6c,
0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x52, 0x65,
0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5b, 0x63, 0x61, 0x6c, 0x6c,
0x49, 0x64, 0x5d, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x6f,
0x6c, 0x76, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x2e,
0x73, 0x65, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x29, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x20,
0x20, 0x7d, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x2d, 0x2d,
0x20, 0x41, 0x50, 0x49, 0x73, 0x20, 0x2d, 0x2d, 0x2d, 0x2d,
0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x2e, 0x2e, 0x61, 0x72,
0x67, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2c, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74,
0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f,
0x6b, 0x65, 0x6e, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e,
0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f,
0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x29, 0x3b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x64,
0x64, 0x49, 0x44, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x2c, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x2c, 0x20,
0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54,
0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x49, 0x44, 0x29, 0x3b, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x20, 0x6e, 0x65, 0x77, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69,
0x73, 0x65, 0x28, 0x28, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76,
0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73,
0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5b, 0x63,
0x61, 0x6c, 0x6c, 0x49, 0x64, 0x5d, 0x20, 0x3d, 0x20, 0x72,
0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x3b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
0x77, 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x70, 0x61,
0x63, 0x6b, 0x65, 0x74, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65,
0x72, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29,
0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x2f, 0x2f,
0x20, 0x2d, 0x2d, 0x20, 0x41, 0x50, 0x49, 0x73, 0x20, 0x2d,
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
0x2d, 0x2d, 0x0a, 0x20, 0x20, 0x2f, 0x2a, 0x2a, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x43, 0x61, 0x6c, 0x6c, 0x20, 0x61,
0x20, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x20, 0x62,
0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f,
0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6e,
0x74, 0x65, 0x6e, 0x64, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x62, 0x69,
0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x20,
0x2d, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x20,
0x62, 0x69, 0x6e, 0x64, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2e,
0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x40, 0x70, 0x61, 0x72,
0x61, 0x6d, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x20, 0x2d, 0x20, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x74,
0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x64,
0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70,
0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x4a, 0x53, 0x4f, 0x4e,
0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x64, 0x61, 0x74,
0x61, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x28, 0x73, 0x74,
0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x6e, 0x75, 0x6d, 0x62,
0x65, 0x72, 0x2c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c,
0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x62,
0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x2c, 0x20, 0x75, 0x6e,
0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x2e, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x20, 0x40, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x2d, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65,
0x20, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x20, 0x63,
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x61, 0x73,
0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x20, 0x63, 0x6f, 0x6d, 0x70,
0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x40,
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20,
0x20, 0x2a, 0x20, 0x5f, 0x5f, 0x42, 0x61, 0x63, 0x6b, 0x65,
0x6e, 0x64, 0x20, 0x28, 0x43, 0x29, 0x5f, 0x5f, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x60, 0x60, 0x60, 0x63, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x77, 0x65, 0x62, 0x75, 0x69, 0x5f,
0x62, 0x69, 0x6e, 0x64, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f,
0x77, 0x2c, 0x20, 0x22, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x77,
0x64, 0x22, 0x2c, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x77, 0x6f, 0x72, 0x6b,
0x69, 0x6e, 0x67, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
0x6f, 0x72, 0x79, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x20, 0x60, 0x60, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x5f, 0x5f, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64,
0x20, 0x28, 0x4a, 0x53, 0x29, 0x5f, 0x5f, 0x0a, 0x20, 0x20,
0x20, 0x2a, 0x20, 0x60, 0x60, 0x60, 0x6a, 0x73, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
0x63, 0x77, 0x64, 0x20, 0x3d, 0x20, 0x61, 0x77, 0x61, 0x69,
0x74, 0x20, 0x77, 0x65, 0x62, 0x75, 0x69, 0x2e, 0x63, 0x61,
0x6c, 0x6c, 0x28, 0x22, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x77,
0x64, 0x22, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x60, 0x60, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x40,
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20,
0x20, 0x2a, 0x20, 0x5f, 0x5f, 0x42, 0x61, 0x63, 0x6b, 0x65,
0x6e, 0x64, 0x20, 0x28, 0x43, 0x29, 0x5f, 0x5f, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x60, 0x60, 0x60, 0x63, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x77, 0x65, 0x62, 0x75, 0x69, 0x5f,
0x62, 0x69, 0x6e, 0x64, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f,
0x77, 0x2c, 0x20, 0x22, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f,
0x66, 0x69, 0x6c, 0x65, 0x22, 0x2c, 0x20, 0x77, 0x72, 0x69,
0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x3b, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x20, 0x60, 0x60, 0x60, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x5f, 0x5f, 0x46, 0x72, 0x6f, 0x6e,
0x74, 0x65, 0x6e, 0x64, 0x20, 0x28, 0x4a, 0x53, 0x29, 0x5f,
0x5f, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x60, 0x60, 0x60,
0x6a, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x77, 0x65,
0x62, 0x75, 0x69, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x22,
0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65,
0x22, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
0x74, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65,
0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x2e,
0x74, 0x68, 0x65, 0x6e, 0x28, 0x28, 0x29, 0x20, 0x3d, 0x3e,
0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c,
0x6f, 0x67, 0x28, 0x22, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73,
0x73, 0x22, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x20, 0x2e, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x28, 0x29,
0x20, 0x3d, 0x3e, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
0x65, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x43,
0x61, 0x6e, 0x27, 0x74, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65,
0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x22,
0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x60, 0x60,
0x60, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x40, 0x65, 0x78,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x20, 0x5f, 0x5f, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
0x20, 0x28, 0x43, 0x29, 0x5f, 0x5f, 0x0a, 0x20, 0x20, 0x20,
0x2a, 0x20, 0x60, 0x60, 0x60, 0x63, 0x0a, 0x20, 0x20, 0x20,
0x2a, 0x20, 0x2f, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x28, 0x29, 0x20,
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68,
0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e,
0x67, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x20, 0x73, 0x74, 0x72,
0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x2f,
0x2f, 0x27, 0x7b, 0x20, 0x22, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x22, 0x3a, 0x20, 0x31, 0x2c, 0x20, 0x22, 0x6c, 0x69, 0x73,
0x74, 0x22, 0x3a, 0x20, 0x5b, 0x20, 0x31, 0x2c, 0x20, 0x32,
0x2c, 0x20, 0x33, 0x20, 0x5d, 0x2c, 0x20, 0x22, 0x69, 0x73,
0x47, 0x6f, 0x6f, 0x64, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75,
0x65, 0x20, 0x7d, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x77, 0x65, 0x62, 0x75, 0x69, 0x5f, 0x62, 0x69, 0x6e, 0x64,
0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2c, 0x20, 0x22,
0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x64, 0x61,
0x74, 0x61, 0x73, 0x22, 0x2c, 0x20, 0x63, 0x6f, 0x6d, 0x70,
0x6c, 0x65, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x29,
0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x60, 0x60, 0x60,
0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x5f, 0x5f, 0x46, 0x72,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x28, 0x4a, 0x53,
0x29, 0x5f, 0x5f, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x60,
0x60, 0x60, 0x6a, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x74, 0x79, 0x70, 0x65, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
0x65, 0x78, 0x44, 0x61, 0x74, 0x61, 0x73, 0x20, 0x3d, 0x20,
0x7b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x3a, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65,
0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x6c,
0x69, 0x73, 0x74, 0x3a, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65,
0x72, 0x5b, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x20, 0x69, 0x73, 0x47, 0x6f, 0x6f, 0x64, 0x3a, 0x20, 0x62,
0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x0a, 0x20, 0x20,
0x20, 0x2a, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
0x20, 0x7b, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20,
0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x73, 0x47, 0x6f,
0x6f, 0x64, 0x20, 0x7d, 0x20, 0x3d, 0x20, 0x61, 0x77, 0x61,
0x69, 0x74, 0x20, 0x77, 0x65, 0x62, 0x75, 0x69, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x20, 0x2e, 0x63, 0x61, 0x6c, 0x6c,
0x3c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x44, 0x61,
0x74, 0x61, 0x73, 0x3e, 0x28, 0x22, 0x63, 0x6f, 0x6d, 0x70,
0x6c, 0x65, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x22,
0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x0a, 0x20, 0x20,
0x20, 0x2a, 0x20, 0x2f, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x20, 0x3d, 0x20, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x20, 0x2f, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x3d, 0x20,
0x5b, 0x20, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33, 0x20,
0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x2f, 0x2f,
0x69, 0x73, 0x47, 0x6f, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x74,
0x72, 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x60, 0x60, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x2f, 0x0a,
0x20, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x63, 0x61,
0x6c, 0x6c, 0x28, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67,
0x4e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x62, 0x69, 0x6e, 0x64,
0x69, 0x6e, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20,
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x20, 0x20, 0x2f, 0x2a,
0x2a, 0x0a, 0x20, 0x20, 0x2a, 0x20, 0x43, 0x61, 0x6c, 0x6c,
0x20, 0x61, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
0x20, 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x2a, 0x20, 0x40,
0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x66, 0x6e, 0x20, 0x2d,
0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6e,
0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x2a, 0x20, 0x40, 0x70,
0x61, 0x72, 0x61, 0x6d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20,
0x2d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x6f, 0x20,
0x62, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x6f,
0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65,
0x6e, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x0a, 0x20, 0x20, 0x2a, 0x20, 0x40, 0x72, 0x65, 0x74,
0x75, 0x72, 0x6e, 0x20, 0x2d, 0x20, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68,
0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x20,
0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x73,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x2a, 0x20,
0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x2d,
0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73,
0x20, 0x3d, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x77,
0x65, 0x62, 0x75, 0x69, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28,
0x22, 0x6d, 0x79, 0x49, 0x44, 0x22, 0x2c, 0x20, 0x31, 0x32,
0x33, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x22,
0x48, 0x69, 0x22, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x55,
0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28,
0x5b, 0x30, 0x78, 0x34, 0x32, 0x2c, 0x20, 0x30, 0x78, 0x34,
0x33, 0x2c, 0x20, 0x30, 0x78, 0x34, 0x34, 0x5d, 0x29, 0x29,
0x3b, 0x0a, 0x20, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x61,
0x73, 0x79, 0x6e, 0x63, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x28,
0x66, 0x6e, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x61, 0x72, 0x67,
0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
0x66, 0x20, 0x28, 0x21, 0x66, 0x6e, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x2e, 0x72,
0x65, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6e, 0x65, 0x77, 0x20,
0x53, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x45, 0x72, 0x72, 0x6f,
0x72, 0x28, 0x22, 0x4e, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x64,
0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69,
0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
0x22, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
0x66, 0x20, 0x28, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
0x77, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65,
0x2e, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6e, 0x65,
0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x57,
0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x69,
0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x29, 0x29, 0x3b, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74,
0x68, 0x69, 0x73, 0x2e, 0x23, 0x68, 0x61, 0x73, 0x45, 0x76,
0x65, 0x6e, 0x74, 0x73, 0x20, 0x26, 0x26, 0x20, 0x21, 0x74,
0x68, 0x69, 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e, 0x64, 0x4c,
0x69, 0x73, 0x74, 0x2e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
0x65, 0x73, 0x28, 0x60, 0x24, 0x7b, 0x74, 0x68, 0x69, 0x73,
0x2e, 0x23, 0x77, 0x69, 0x6e, 0x4e, 0x75, 0x6d, 0x7d, 0x2f,
0x24, 0x7b, 0x66, 0x6e, 0x7d, 0x60, 0x29, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x2e,
0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6e, 0x65, 0x77,
0x20, 0x53, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x45, 0x72, 0x72,
0x6f, 0x72, 0x28, 0x22, 0x4e, 0x6f, 0x20, 0x62, 0x69, 0x6e,
0x64, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20,
0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
0x64, 0x22, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e,
0x23, 0x77, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
0x75, 0x72, 0x6e, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73,
0x65, 0x2e, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6e,
0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22,
0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20,
0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x29, 0x29, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21,
0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x68, 0x61, 0x73, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x26, 0x26, 0x20, 0x21,
0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e, 0x64,
0x4c, 0x69, 0x73, 0x74, 0x2e, 0x69, 0x6e, 0x63, 0x6c, 0x75,
0x64, 0x65, 0x73, 0x28, 0x60, 0x24, 0x7b, 0x74, 0x68, 0x69,
0x73, 0x2e, 0x23, 0x77, 0x69, 0x6e, 0x4e, 0x75, 0x6d, 0x7d,
0x2f, 0x24, 0x7b, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67,
0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x60, 0x29, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x2e,
0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x65, 0x77, 0x20,
0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x45,
0x72, 0x72, 0x6f, 0x72, 0x28, 0x60, 0x4e, 0x6f, 0x20, 0x62,
0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x61, 0x73,
0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x72,
0x20, 0x22, 0x24, 0x7b, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e,
0x67, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x22, 0x60, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x3d, 0x20,
0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73,
0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d,
0x69, 0x73, 0x65, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4e, 0x61,
0x6d, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x3d,
0x3d, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x30, 0x20, 0x3f,
0x20, 0x22, 0x22, 0x20, 0x3a, 0x20, 0x74, 0x79, 0x70, 0x65,
0x6f, 0x66, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69,
0x6e, 0x67, 0x22, 0x20, 0x3f, 0x20, 0x70, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x20, 0x3a, 0x20, 0x74, 0x79, 0x70, 0x65,
0x6f, 0x66, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x22, 0x20, 0x3f, 0x20, 0x70, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x20, 0x3a, 0x20, 0x4a, 0x53, 0x4f, 0x4e,
0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79,
0x28, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x4a,
0x53, 0x4f, 0x4e, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x79, 0x20, 0x7b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
0x75, 0x72, 0x6e, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x70,
0x61, 0x72, 0x73, 0x65, 0x28, 0x72, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x7d, 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x20, 0x7b, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20,
0x20, 0x7d, 0x0a, 0x20, 0x20, 0x2f, 0x2a, 0x2a, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65,
0x20, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x61, 0x63, 0x74, 0x69,
0x76, 0x61, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x75, 0x69,
0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x20, 0x6c, 0x6f, 0x67,
0x67, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x73, 0x74,
0x61, 0x74, 0x75, 0x73, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67,
0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x74, 0x6f,
0x20, 0x73, 0x65, 0x74, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x2f, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x67,
0x67, 0x69, 0x6e, 0x67, 0x28, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
0x66, 0x20, 0x28, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29,
0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63,
0x20, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x60, 0x4e, 0x6f, 0x20,
0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x61,
0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x66, 0x6f,
0x72, 0x20, 0x22, 0x24, 0x7b, 0x66, 0x6e, 0x7d, 0x22, 0x60,
0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f,
0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63,
0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67,
0x28, 0x22, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e,
0x20, 0x4c, 0x6f, 0x67, 0x20, 0x45, 0x6e, 0x61, 0x62, 0x6c,
0x65, 0x64, 0x2e, 0x22, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c,
0x6f, 0x67, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73,
0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
0x67, 0x28, 0x22, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
0x3e, 0x20, 0x4c, 0x6f, 0x67, 0x20, 0x44, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x64, 0x2e, 0x22, 0x29, 0x3b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e,
0x23, 0x6c, 0x6f, 0x67, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c,
0x73, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e,
0x20, 0x43, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x5b,
0x24, 0x7b, 0x66, 0x6e, 0x7d, 0x28, 0x2e, 0x2e, 0x2e, 0x29,
0x5d, 0x60, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63,
0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x77, 0x61, 0x69,
0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61,
0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x28,
0x66, 0x6e, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x61, 0x72, 0x67,
0x73, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x72,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x21, 0x3d,
0x3d, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x3b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3b, 0x0a,
0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x2f, 0x2a, 0x2a, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x20, 0x45, 0x6e, 0x63, 0x6f, 0x64,
0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x73, 0x20, 0x69, 0x6e,
0x74, 0x6f, 0x20, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x20,
0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x20, 0x20,
0x20, 0x2a, 0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20,
0x64, 0x61, 0x74, 0x61, 0x73, 0x20, 0x2d, 0x20, 0x73, 0x74,
0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x72, 0x20, 0x4a, 0x53,
0x4f, 0x4e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x65, 0x6e,
0x63, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x73,
0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x64,
0x61, 0x74, 0x61, 0x73, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x22,
0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x20, 0x62, 0x74, 0x6f, 0x61, 0x28, 0x64, 0x61, 0x74,
0x61, 0x73, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x62, 0x74, 0x6f, 0x61,
0x28, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69,
0x6e, 0x67, 0x69, 0x66, 0x79, 0x28, 0x64, 0x61, 0x74, 0x61,
0x73, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x2a, 0x20, 0x41, 0x63, 0x74, 0x69, 0x76,
0x65, 0x20, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x61, 0x63, 0x74,
0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x75,
0x69, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x20, 0x6c, 0x6f,
0x67, 0x67, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x20, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x40, 0x70, 0x61,
0x72, 0x61, 0x6d, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x74,
0x0a, 0x20, 0x20, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x73,
0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x28,
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29, 0x20, 0x7b, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x74,
0x61, 0x74, 0x75, 0x73, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x57, 0x65, 0x62,
0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x4c, 0x6f, 0x67, 0x20,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x22, 0x29,
0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68,
0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x20, 0x3d, 0x20,
0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x57, 0x65,
0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x4c, 0x6f, 0x67,
0x20, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e,
0x22, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x20,
0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20,
0x20, 0x2f, 0x2a, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20,
0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x61, 0x20, 0x62,
0x61, 0x73, 0x65, 0x36, 0x34, 0x20, 0x73, 0x74, 0x72, 0x69,
0x6e, 0x67, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x6e,
0x79, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x20, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x20, 0x28, 0x73, 0x74, 0x72, 0x69,
0x6e, 0x67, 0x2c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72,
0x2c, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c, 0x20, 0x6f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x62, 0x6f, 0x6f,
0x6c, 0x65, 0x61, 0x6e, 0x29, 0x2e, 0x0a, 0x20, 0x20, 0x20,
0x2a, 0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x62,
0x36, 0x34, 0x20, 0x2d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x36,
0x34, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74,
0x6f, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x64, 0x65,
0x63, 0x6f, 0x64, 0x65, 0x28, 0x62, 0x36, 0x34, 0x29, 0x20,
0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x79, 0x20,
0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e,
0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x61, 0x74, 0x6f, 0x62,
0x28, 0x62, 0x36, 0x34, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x7d, 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x20,
0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x74, 0x6f, 0x62, 0x28,
0x62, 0x36, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x3b, 0x0a, 0x61,
0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73,
0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x6c, 0x6f, 0x61,
0x64, 0x22, 0x2c, 0x20, 0x28, 0x29, 0x20, 0x3d, 0x3e, 0x20,
0x7b, 0x0a, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x61, 0x64,
0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74,
0x65, 0x6e, 0x65, 0x72, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x6d, 0x65,
0x6e, 0x75, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28,
0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x3d, 0x3e, 0x20,
0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x65, 0x76,
0x65, 0x6e, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x28, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x20, 0x20,
0x61, 0x64, 0x64, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c,
0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x65, 0x78,
0x74, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x62, 0x61, 0x73,
0x65, 0x36, 0x34, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20,
0x2a, 0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x64,
0x61, 0x74, 0x61, 0x20, 0x2d, 0x20, 0x74, 0x65, 0x78, 0x74,
0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20,
0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x63, 0x6f,
0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x20, 0x62, 0x74, 0x6f, 0x61, 0x28, 0x64, 0x61, 0x74,
0x61, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20,
0x2f, 0x2a, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x44,
0x65, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x62, 0x61, 0x73, 0x65,
0x36, 0x34, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20,
0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x65, 0x78, 0x74, 0x0a,
0x20, 0x20, 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x2a,
0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x64, 0x61,
0x74, 0x61, 0x20, 0x2d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x36,
0x34, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20,
0x20, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x63,
0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20,
0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x61, 0x74, 0x6f, 0x62, 0x28, 0x64, 0x61,
0x74, 0x61, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d,
0x3b, 0x0a, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74,
0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22,
0x6c, 0x6f, 0x61, 0x64, 0x22, 0x2c, 0x20, 0x28, 0x29, 0x20,
0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x64, 0x6f, 0x63,
0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79,
0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c,
0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x2c,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74,
0x65, 0x78, 0x74, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x2c, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74,
0x29, 0x20, 0x3d, 0x3e, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74,
0x2e, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x61,
0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x20,
0x20, 0x29, 0x3b, 0x0a, 0x7d, 0x29, 0x3b, 0x0a,
0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78,
0x74, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x2c, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20,
0x3d, 0x3e, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70,
0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x66, 0x61,
0x75, 0x6c, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x3b,
0x0a, 0x20, 0x20, 0x61, 0x64, 0x64, 0x52, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75,
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63,
0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x6d, 0x65, 0x6e, 0x75,
0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x65, 0x76,
0x65, 0x6e, 0x74, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x65, 0x76,
0x65, 0x6e, 0x74, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x72,
0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28,
0x29, 0x0a, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x7d, 0x29, 0x3b,
0x0a,
0x00
};

View File

@ -17,13 +17,10 @@
//@ts-ignore use *.ts import real extension
import { AsyncFunction, addRefreshableEventListener } from './utils.ts'
type B64string = string
type JSONValue =
type DataTypes =
| string
| number
| boolean
| { [x: string]: JSONValue | undefined }
| JSONValue[]
| Uint8Array
class WebuiBridge {
@ -157,11 +154,6 @@ class WebuiBridge {
const { href } = event.target as HTMLAnchorElement
if (this.#hasEvents) {
if (this.#log) console.log(`WebUI -> DOM -> Navigation Click Event [${href}]`)
// if (this.#isExternalLink(href)) {
// this.#close(this.#CMD_NAVIGATION, href)
// } else {
// this.#sendEventNavigation(href)
// }
this.#sendEventNavigation(href)
}
else {
@ -174,8 +166,7 @@ class WebuiBridge {
// Prevent F5 refresh
document.addEventListener('keydown', (event) => {
// Disable F5
if (this.#log) return
if (this.#log) return // Allowed in debug mode
if (event.key === 'F5') event.preventDefault()
})
@ -195,7 +186,6 @@ class WebuiBridge {
}
#close(reason = 0, value = '') {
// if (reason === this.#CMD_NAVIGATION) this.#sendEventNavigation(value)
this.#wsStatus = false
this.#closeReason = reason
this.#closeValue = value
@ -236,7 +226,6 @@ class WebuiBridge {
}
stringBytes.push(buffer[i]);
}
// Convert the array of bytes to a string
const stringText = new TextDecoder().decode(new Uint8Array(stringBytes));
return stringText;
@ -256,27 +245,23 @@ class WebuiBridge {
if (value < 0 || value > 0xFFFFFFFF) {
throw new Error('Number is out of the range for 4 bytes representation.');
}
if (index < 0 || index > buffer.length - 4) {
throw new Error('Index out of bounds or insufficient space in buffer.');
}
// WebUI expect Little-endian (Work for Little/Big endian platforms)
buffer[index] = value & 0xFF;
buffer[index] = value & 0xFF; // Least significant byte
buffer[index + 1] = (value >>> 8) & 0xFF;
buffer[index + 2] = (value >>> 16) & 0xFF;
buffer[index + 3] = (value >>> 24) & 0xFF;
buffer[index + 3] = (value >>> 24) & 0xFF; // Most significant byte
}
#addID(buffer: Uint8Array, value: number, index: number): void {
if (value < 0 || value > 0xFFFF) {
throw new Error('Number is out of the range for 2 bytes representation.');
}
if (index < 0 || index > buffer.length - 2) {
throw new Error('Index out of bounds or insufficient space in buffer.');
}
// WebUI expect Little-endian (Work for Little/Big endian platforms)
buffer[index] = value & 0xFF; // Least significant byte
buffer[index + 1] = (value >>> 8) & 0xFF; // Most significant byte
@ -284,28 +269,23 @@ class WebuiBridge {
#start() {
this.#callPromiseID[0] = 0
if (this.#bindList.includes(this.#winNum + '/')) {
this.#hasEvents = true
}
this.#ws = new WebSocket(
`ws://localhost:${this.#port}/_webui_ws_connect`
)
this.#ws.binaryType = 'arraybuffer'
this.#ws.onopen = () => {
this.#wsStatus = true
this.#wsStatusOnce = true
if (this.#log) console.log('WebUI -> Connected')
this.#clicksListener()
}
this.#ws.onerror = () => {
if (this.#log) console.log('WebUI -> Connection Failed')
this.#freezeUi()
}
this.#ws.onclose = (event) => {
this.#wsStatus = false
if (this.#closeReason === this.#CMD_NAVIGATION) {
@ -323,17 +303,13 @@ class WebuiBridge {
}
}
}
this.#ws.onmessage = async (event) => {
const buffer8 = new Uint8Array(event.data)
if (buffer8.length < this.#PROTOCOL_SIZE) return
if (buffer8[this.#PROTOCOL_SIGN] !== this.#WEBUI_SIGNATURE) return
if(this.#isTextBasedCommand(buffer8[this.#PROTOCOL_CMD])) {
// UTF8 Text based commands
const callId = this.#getID(buffer8, this.#PROTOCOL_ID)
// Process Command
switch (buffer8[this.#PROTOCOL_CMD]) {
case this.#CMD_CALL_FUNC:
@ -344,9 +320,7 @@ class WebuiBridge {
// 2: [ID]
// 3: [CMD]
// 4: [Call Response]
const callResponse = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA)
if (this.#log) {
console.log(`WebUI -> CMD -> Call Response [${callResponse}]`)
}
@ -368,7 +342,6 @@ class WebuiBridge {
// 2: [ID]
// 3: [CMD]
// 4: [URL]
const url = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA)
console.log(`WebUI -> CMD -> Navigation [${url}]`)
this.#close(this.#CMD_NAVIGATION, url)
@ -380,7 +353,6 @@ class WebuiBridge {
// 2: [ID]
// 3: [CMD]
// 4: [New Element]
const newElement = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA)
console.log(`WebUI -> CMD -> New Bind ID [${newElement}]`)
if(!this.#bindList.includes(newElement))
@ -395,16 +367,13 @@ class WebuiBridge {
// 2: [ID]
// 3: [CMD]
// 4: [Script]
const script = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA)
const scriptSanitize = script.replace(
/(?:\r\n|\r|\n)/g,
'\n'
)
if (this.#log)
console.log(`WebUI -> CMD -> JS [${scriptSanitize}]`)
// Get callback result
let FunReturn = 'undefined'
let FunError = false
@ -414,28 +383,23 @@ class WebuiBridge {
FunError = true
FunReturn = e.message
}
// Stop if this is a quick call
if (buffer8[this.#PROTOCOL_CMD] === this.#CMD_JS_QUICK) return
// Get the call return
if (FunReturn === undefined) {
FunReturn = 'undefined'
}
// Logging
if (this.#log && !FunError)
console.log(`WebUI -> CMD -> JS -> Return Success [${FunReturn}]`)
if (this.#log && FunError)
console.log(`WebUI -> CMD -> JS -> Return Error [${FunReturn}]`)
// Protocol
// 0: [SIGNATURE]
// 1: [TOKEN]
// 2: [ID]
// 3: [CMD]
// 4: [Error, Script Response]
const Return8 = Uint8Array.of(
this.#WEBUI_SIGNATURE,
0, 0, 0, 0, // Token (4 Bytes)
@ -444,10 +408,8 @@ class WebuiBridge {
FunError ? 1 : 0,
...new TextEncoder().encode(FunReturn)
)
this.#addToken(Return8, this.#token, this.#PROTOCOL_TOKEN)
this.#addID(Return8, callId, this.#PROTOCOL_ID)
if (this.#wsStatus) this.#ws.send(Return8.buffer)
}
break
@ -457,7 +419,6 @@ class WebuiBridge {
// 1: [TOKEN]
// 2: [ID]
// 3: [CMD]
if (!this.#log)
globalThis.close()
else {
@ -469,7 +430,6 @@ class WebuiBridge {
}
else {
// Raw binary commands
// Process Command
switch (buffer8[this.#PROTOCOL_CMD]) {
case this.#CMD_SEND_RAW:
@ -480,17 +440,13 @@ class WebuiBridge {
// 2: [ID]
// 3: [CMD]
// 4: [Function,Null,Raw Data]
// Get function name
const functionName: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA)
// Get the raw data
const rawDataIndex: number = 2 + functionName.length + 1
const userRawData = buffer8.subarray(rawDataIndex);
if (this.#log)
console.log(`WebUI -> CMD -> Send Raw ${buffer8.length} bytes to [${functionName}()]`)
// Call the user function, and pass the raw data
if (typeof window[functionName] === 'function')
window[functionName](userRawData);
@ -502,7 +458,6 @@ class WebuiBridge {
}
}
}
#clicksListener() {
Object.keys(window).forEach((key) => {
if (/^on(click)/.test(key)) {
@ -521,7 +476,6 @@ class WebuiBridge {
}
})
}
#sendClick(elem: string) {
if (this.#wsStatus) {
// Protocol
@ -553,7 +507,6 @@ class WebuiBridge {
if (this.#log) console.log(`WebUI -> Send Click [${elem}]`)
}
}
#sendEventNavigation(url: string) {
if(url !== '') {
if(this.#hasEvents) {
@ -572,10 +525,8 @@ class WebuiBridge {
this.#CMD_NAVIGATION,
...new TextEncoder().encode(url)
)
this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN)
// this.#addID(packet, 0, this.#PROTOCOL_ID)
this.#ws.send(packet.buffer)
}
}
@ -586,33 +537,49 @@ class WebuiBridge {
}
}
}
#isExternalLink(url: string) {
return new URL(url).host === globalThis.location.host
}
#closeWindowTimer() {
setTimeout(function () {
globalThis.close()
}, 1000)
}
#toUint16(value: number): number {
return value & 0xFFFF;
}
#callPromise(fn: string, value: any) {
#callPromise(fn: string, ...args: DataTypes[]) {
--this.#callPromiseID[0]
const callId = this.#toUint16(this.#callPromiseID[0])
if (this.#log) console.log(`WebUI -> Call [${fn}](${value}) (ID:${this.#callPromiseID[0]})`)
// Combine lengths
let argsLengths = args.map(arg => {
if (typeof arg === 'object') {
// Uint8Array
return arg.length;
} else {
// string, number, boolean
return new TextEncoder().encode(arg.toString()).length;
}
}).join(';');
// Combine values
let argsValues: Uint8Array = new Uint8Array()
for (const arg of args) {
let buffer: Uint8Array
if (typeof arg === 'object') {
buffer = arg; // Uint8Array
} else {
// string, number, boolean
buffer = new TextEncoder().encode(arg.toString())
}
const temp = new Uint8Array(argsValues.length + buffer.length + 1)
temp.set(argsValues, 0)
temp.set(buffer, argsValues.length)
temp[argsValues.length + buffer.length] = 0x00;
argsValues = temp
}
// Protocol
// 0: [SIGNATURE]
// 1: [TOKEN]
// 2: [ID]
// 3: [CMD]
// 4: [Element ID, Null, Len, Null, Data, Null]
// 4: [Fn, Null, {Len;Len;...}, Null, {Data,Null,Data,Null...}, Null]
const packet = Uint8Array.of(
this.#WEBUI_SIGNATURE,
0, 0, 0, 0, // Token (4 Bytes)
@ -620,15 +587,13 @@ class WebuiBridge {
this.#CMD_CALL_FUNC,
...new TextEncoder().encode(fn),
0,
...new TextEncoder().encode(String(value.length)),
...new TextEncoder().encode(argsLengths),
0,
...typeof value === 'object' ? value : new TextEncoder().encode(value),
...argsValues,
0
)
this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN)
this.#addID(packet, callId, this.#PROTOCOL_ID)
return new Promise((resolve) => {
this.#callPromiseResolve[callId] = resolve
this.#ws.send(packet.buffer)
@ -636,100 +601,39 @@ class WebuiBridge {
}
// -- APIs --------------------------
/**
* Call a backend binding from the frontend.
* @param bindingName - Backend bind name.
* @param payload - Payload to send to the binding, accept any JSON valid data
* (string, number, array, object, boolean, undefined).
* @return - Response of the backend callback as JSON compatible value.
* @example
* __Backend (C)__
* ```c
* webui_bind(window, "get_cwd", get_current_working_directory);
* ```
* __Frontend (JS)__
* ```js
* const cwd = await webui.call("get_cwd");
* ```
* @example
* __Backend (C)__
* ```c
* webui_bind(window, "write_file", write_file);
* ```
* __Frontend (JS)__
* ```js
* webui.call("write_file", "content to write")
* .then(() => console.log("Success"))
* .catch(() => console.error("Can't write the file"))
* ```
* @example
* __Backend (C)__
* ```c
* //complex_datas() returns the following JSON string
* //'{ "count": 1, "list": [ 1, 2, 3 ], "isGood": true }'
* webui_bind(window, "complex_datas", complex_datas);
* ```
* __Frontend (JS)__
* ```js
* type ComplexDatas = {
* count: number;
* list: number[];
* isGood: boolean;
* }
*
* const { count, list, isGood } = await webui
* .call<ComplexDatas>("complex_datas");
*
* //count = 1;
* //list = [ 1, 2, 3 ];
* //isGood = true;
* ```
*/
async call<
Response extends JSONValue = string,
Payload extends JSONValue = JSONValue
>(bindingName: string, payload?: Payload): Promise<Response | void> {
if (!bindingName)
* Call a backend function
*
* @param fn - binding name
* @param data - data to be send to the backend function
* @return - Response of the backend callback string
* @example - const res = await webui.call("myID", 123, true, "Hi", new Uint8Array([0x42, 0x43, 0x44]));
*/
async call(fn: string, ...args: DataTypes[]): Promise<DataTypes> {
if (!fn)
return Promise.reject(new SyntaxError('No binding name is provided'))
if (!this.#wsStatus)
return Promise.reject(new Error('WebSocket is not connected'))
// Check binding list
if (
!this.#hasEvents &&
!this.#bindList.includes(`${this.#winNum}/${bindingName}`)
)
return Promise.reject(
new ReferenceError(`No binding was found for "${bindingName}"`)
)
if (!this.#hasEvents && !this.#bindList.includes(`${this.#winNum}/${fn}`))
return Promise.reject(new ReferenceError(`No binding was found for "${fn}"`))
// Get the binding response
const response = (await this.#callPromise(
bindingName,
payload === undefined
? ''
: typeof payload === 'string' // String()
? payload
: typeof payload === 'object' // Uint8Array()
? payload
: JSON.stringify(payload) // JSON String
)) as string | void
// Call backend and wait for response
if (this.#log) console.log(`WebUI -> Calling [${fn}(...)]`)
const response = (await this.#callPromise(fn, ...args)) as string
// Handle response type (void, string or JSON value)
if (response === undefined) return
// WebUI lib accept `DataTypes` but return only string
if (typeof response !== 'string') return ""
try {
return JSON.parse(response)
} catch {
//@ts-ignore string is a valid JSON value
return response
}
return response
}
/**
* Active or deactivate webui debug logging.
* @param status - log status to set.
* Active or deactivate webui debug logging
*
* @param status - log status to set
*/
setLogging(status: boolean) {
if (status) {
@ -740,35 +644,27 @@ class WebuiBridge {
this.#log = false
}
}
/**
* Encode datas into base64 string.
* @param datas - string or JSON value.
* Encode text into base64 string
*
* @param data - text string
*/
encode(datas: JSONValue): B64string {
if (typeof datas === 'string') return btoa(datas)
return btoa(JSON.stringify(datas))
encode(data: string): string {
return btoa(data)
}
/**
* Decode a base64 string into any JSON valid format
* (string, number, array, object, boolean).
* @param b64 - base64 string to decode.
* Decode base64 string into text
*
* @param data - base64 string
*/
decode<T extends JSONValue>(b64: B64string): T {
try {
return JSON.parse(atob(b64))
} catch {
//@ts-ignore string a valid JSON value
return atob(b64)
}
decode(data: string): string {
return atob(data)
}
}
// Export
type webui = WebuiBridge
export default webui
export type { WebuiBridge }
// Wait for the html to be parsed
addEventListener('load', () => {
document.body.addEventListener('contextmenu', (event) =>

View File

@ -5,69 +5,78 @@
void my_function_string(webui_event_t* e) {
// JavaScript:
// webui.call('MyID_One', 'Hello');
// webui.call('MyID_One', 'Hello', 'World`);
const char* str = webui_get_string(e);
printf("my_function_string: %s\n", str); // Hello
const char* str_1 = webui_get_string(e); // Or webui_get_string_at(e, 0);
const char* str_2 = webui_get_string_at(e, 1);
// Need Multiple Arguments?
//
// WebUI support only one argument. To get multiple arguments
// you can send a JSON string from JavaScript then decode it.
// Example:
//
// my_json = my_json_decoder(str);
// foo = my_json[0];
// bar = my_json[1];
printf("my_function_string 1: %s\n", str_1); // Hello
printf("my_function_string 2: %s\n", str_2); // World
}
void my_function_integer(webui_event_t* e) {
// JavaScript:
// webui.call('MyID_Two', 123456789);
// webui.call('MyID_Two', 123, 456, 789);
long long number = webui_get_int(e);
printf("my_function_integer: %lld\n", number); // 123456789
long long number_1 = webui_get_int(e); // Or webui_get_int_at(e, 0);
long long number_2 = webui_get_int_at(e, 1);
long long number_3 = webui_get_int_at(e, 2);
printf("my_function_integer 1: %lld\n", number_1); // 123
printf("my_function_integer 2: %lld\n", number_2); // 456
printf("my_function_integer 3: %lld\n", number_3); // 789
}
void my_function_boolean(webui_event_t* e) {
// JavaScript:
// webui.call('MyID_Three', true);
// webui.call('MyID_Three', true, false);
bool status = webui_get_bool(e); // True
if(status)
printf("my_function_boolean: True\n");
else
printf("my_function_boolean: False\n");
bool status_1 = webui_get_bool(e); // Or webui_get_bool_at(e, 0);
bool status_2 = webui_get_bool_at(e, 1);
printf("my_function_boolean 1: %s\n", (status_1 ? "True" : "False")); // True
printf("my_function_boolean 2: %s\n", (status_2 ? "True" : "False")); // False
}
void my_function_raw_binary(webui_event_t* e) {
// JavaScript:
// webui.call('MyID_RawBinary', new Uint8Array([0x42, 0x43, 0x44]));
// webui.call('MyID_RawBinary', new Uint8Array([0x41]), new Uint8Array([0x42, 0x43]));
const unsigned char* raw = (const unsigned char*)e->data;
long long len = e->size;
const unsigned char* raw_1 = (const unsigned char*)webui_get_string(e); // Or webui_get_string_at(e, 0);
const unsigned char* raw_2 = (const unsigned char*)webui_get_string_at(e, 1);
printf("my_function_raw_binary: %lld bytes\n", len);
printf("my_function_raw_binary: ");
for (size_t i = 0; i < len; i++)
printf("0x%02x ", raw[i]);
size_t len_1 = webui_get_size(e); // Or webui_get_size_at(e, 0);
size_t len_2 = webui_get_size_at(e, 1);
// Print raw_1
printf("my_function_raw_binary 1 (%zu bytes): ", len_1);
for (size_t i = 0; i < len_1; i++)
printf("0x%02x ", raw_1[i]);
printf("\n");
// Print raw_2
printf("my_function_raw_binary 2 (%zu bytes): ", len_2);
for (size_t i = 0; i < len_2; i++)
printf("0x%02x ", raw_2[i]);
printf("\n");
}
void my_function_with_response(webui_event_t* e) {
// JavaScript:
// const result = webui.call('MyID_Four', number);
// webui.call('MyID_Four', number, 2).then(...)
long long number = webui_get_int(e);
number = number * 2;
printf("my_function_with_response: %lld\n", number);
long long number = webui_get_int(e); // Or webui_get_int_at(e, 0);
long long times = webui_get_int_at(e, 1);
int res = number * times;
printf("my_function_with_response: %lld * %lld = %lld\n", number, times, res);
// Send back the response to JavaScript
webui_return_int(e, number);
webui_return_int(e, res);
}
int main() {
@ -95,13 +104,13 @@ int main() {
" <body>"
" <h1>WebUI - Call C from JavaScript</h1>"
" <p>Call C functions with arguments (<em>See the logs in your terminal</em>)</p>"
" <button onclick=\"webui.call('MyID_One', 'Hello');\">Call my_function_string()</button>"
" <button onclick=\"webui.call('MyID_One', 'Hello', 'World');\">Call my_function_string()</button>"
" <br>"
" <button onclick=\"webui.call('MyID_Two', 123456789);\">Call my_function_integer()</button>"
" <button onclick=\"webui.call('MyID_Two', 123, 456, 789);\">Call my_function_integer()</button>"
" <br>"
" <button onclick=\"webui.call('MyID_Three', true);\">Call my_function_boolean()</button>"
" <button onclick=\"webui.call('MyID_Three', true, false);\">Call my_function_boolean()</button>"
" <br>"
" <button onclick=\"webui.call('MyID_RawBinary', new Uint8Array([0x41, 0x42, 0x43]));\">Call my_function_raw_binary()</button>"
" <button onclick=\"webui.call('MyID_RawBinary', new Uint8Array([0x41]), new Uint8Array([0x42, 0x43]));\">Call my_function_raw_binary()</button>"
" <br>"
" <p>Call a C function that returns a response</p>"
" <button onclick=\"MyJS();\">Call my_function_with_response()</button>"
@ -110,7 +119,7 @@ int main() {
" function MyJS() {"
" const MyInput = document.getElementById('MyInputID');"
" const number = MyInput.value;"
" webui.call('MyID_Four', number).then((response) => {"
" webui.call('MyID_Four', number, 2).then((response) => {"
" MyInput.value = response;"
" });"
" }"

View File

@ -26,12 +26,13 @@ void events(webui_event_t* e) {
else if(e->event_type == WEBUI_EVENT_MOUSE_CLICK)
printf("Click. \n");
else if(e->event_type == WEBUI_EVENT_NAVIGATION) {
printf("Starting navigation to: %s \n", (char *)e->data);
const char* url = webui_get_string(e);
printf("Starting navigation to: %s \n", url);
// Because we used `webui_bind(MyWindow, "", events);`
// then all `href` link clicks will be blocked by WebUI, so
// we need to use `webui_navigate()` to control the navigation
webui_navigate(e->window, (char *)e->data);
// WebUI will block all `href` link clicks and sent here instead.
// We can then control the behaviour of links as needed.
webui_navigate(e->window, url);
}
}

View File

@ -11,10 +11,13 @@
#ifndef _WEBUI_H
#define _WEBUI_H
#define WEBUI_VERSION "2.4.0"
#define WEBUI_VERSION "2.4.0 (Beta)"
// Max windows, servers and threads
#define WEBUI_MAX_IDS (512)
#define WEBUI_MAX_IDS (256)
// Max allowed argument's index
#define WEBUI_MAX_ARG (16)
// Dynamic Library Exports
#if defined(_MSC_VER) || defined(__TINYC__)
@ -138,8 +141,6 @@ typedef struct webui_event_t {
size_t window; // The window object number
size_t event_type; // Event type
char* element; // HTML element ID
char* data; // JavaScript data
size_t size; // JavaScript data len
size_t event_number; // Internal WebUI
} webui_event_t;
@ -492,15 +493,30 @@ WEBUI_EXPORT bool webui_script(size_t window, const char* script, size_t timeout
// Chose between Deno and Nodejs as runtime for .js and .ts files.
WEBUI_EXPORT void webui_set_runtime(size_t window, size_t runtime);
// Parse argument as integer.
// Get an argument as integer at a specific index
WEBUI_EXPORT long long int webui_get_int_at(webui_event_t* e, size_t index);
// Get the first argument as integer
WEBUI_EXPORT long long int webui_get_int(webui_event_t* e);
// Parse argument as string.
// Get an argument as string at a specific index
WEBUI_EXPORT const char* webui_get_string_at(webui_event_t* e, size_t index);
// Get the first argument as string
WEBUI_EXPORT const char* webui_get_string(webui_event_t* e);
// Parse argument as boolean.
// Get an argument as boolean at a specific index
WEBUI_EXPORT bool webui_get_bool_at(webui_event_t* e, size_t index);
// Get the first argument as boolean
WEBUI_EXPORT bool webui_get_bool(webui_event_t* e);
// Get the size in bytes of an argument at a specific index
WEBUI_EXPORT size_t webui_get_size_at(webui_event_t* e, size_t index);
// Get size in bytes of the first argument
WEBUI_EXPORT size_t webui_get_size(webui_event_t* e);
// Return the response to JavaScript as integer.
WEBUI_EXPORT void webui_return_int(webui_event_t* e, long long int n);
@ -512,8 +528,8 @@ WEBUI_EXPORT void webui_return_bool(webui_event_t* e, bool b);
// -- Wrapper's Interface -------------
// Bind a specific html element click event with a function. Empty element means all events. This replaces `webui_bind()`. The func is (Window, EventType, Element, Data, DataSize, EventNumber).
WEBUI_EXPORT size_t webui_interface_bind(size_t window, const char* element, void (*func)(size_t, size_t, char*, char*, size_t, size_t));
// Bind a specific html element click event with a function. Empty element means all events. This replaces `webui_bind()`. The func is (Window, EventType, Element, EventNumber).
WEBUI_EXPORT size_t webui_interface_bind(size_t window, const char* element, void (*func)(size_t, size_t, char*, size_t));
// When using `webui_interface_bind()`, you may need this function to easily set your callback response.
WEBUI_EXPORT void webui_interface_set_response(size_t window, size_t event_number, const char* response);

View File

@ -81,10 +81,12 @@ typedef struct _webui_timer_t {
struct timespec now;
} _webui_timer_t;
// Events
typedef struct webui_event_core_t {
char* response; // Callback response
} webui_event_core_t;
// Event data
typedef struct webui_event_inf_t {
char* event_data[WEBUI_MAX_ARG]; // Event data (string | num | bool | raw)
size_t event_size[WEBUI_MAX_ARG]; // Event data size (in bytes)
char* response; // Event response (string)
} webui_event_inf_t;
// Window
typedef struct _webui_window_t {
@ -119,7 +121,6 @@ typedef struct _webui_window_t {
unsigned int y;
bool position_set;
size_t process_id;
webui_event_core_t* event_core[WEBUI_MAX_IDS];
#ifdef _WIN32
HANDLE server_thread;
#else
@ -128,6 +129,8 @@ typedef struct _webui_window_t {
const void* (*files_handler)(const char* filename, int* length);
uint32_t token;
struct mg_connection* mg_connection;
webui_event_inf_t* events[WEBUI_MAX_IDS];
size_t events_count;
} _webui_window_t;
// Core
@ -137,14 +140,14 @@ typedef struct _webui_core_t {
size_t used_ports[WEBUI_MAX_IDS];
size_t startup_timeout;
volatile bool exit_now;
volatile bool run_done[256]; // 1 Byte ID
volatile bool run_done[WEBUI_MAX_IDS]; // 2 Bytes ID
char* run_userBuffer[WEBUI_MAX_IDS];
size_t run_userBufferLen[WEBUI_MAX_IDS];
bool run_error[WEBUI_MAX_IDS];
uint16_t run_last_id;
bool initialized;
void (*cb[WEBUI_MAX_IDS])(webui_event_t* e);
void (*cb_interface[WEBUI_MAX_IDS])(size_t, size_t, char*, char*, size_t, size_t);
void (*cb_interface[WEBUI_MAX_IDS])(size_t, size_t, char*, size_t);
char* executable_path;
void *ptr_list[WEBUI_MAX_IDS * 2];
size_t ptr_position;
@ -216,7 +219,7 @@ static size_t _webui_get_free_port(void);
static void _webui_free_port(size_t port);
static char* _webui_get_current_path(void);
static void _webui_ws_send(_webui_window_t* win, char* packet, size_t packets_size);
static void _webui_window_event(_webui_window_t* win, int event_type, char* element, char* data, size_t event_number, char* webui_internal_id);
static void _webui_window_event(_webui_window_t* win, int event_type, char* element, size_t event_number, char* webui_internal_id);
static int _webui_cmd_sync(_webui_window_t* win, char* cmd, bool show);
static int _webui_cmd_async(_webui_window_t* win, char* cmd, bool show);
static int _webui_run_browser(_webui_window_t* win, char* cmd);
@ -255,7 +258,6 @@ static void* _webui_malloc(size_t size);
static void _webui_sleep(long unsigned int ms);
static size_t _webui_find_the_best_browser(_webui_window_t* win);
static bool _webui_is_process_running(const char* process_name);
static size_t _webui_get_free_event_core_pos(_webui_window_t* win);
static void _webui_print_hex(const char* data, size_t len);
static void _webui_print_ascii(const char* data, size_t len);
static void _webui_panic(void);
@ -319,13 +321,6 @@ void webui_run(size_t window, const char* script) {
if(!win->connected)
return;
// Initializing pipe
uint16_t run_id = _webui_get_run_id();
_webui_core.run_done[run_id] = false;
_webui_core.run_error[run_id] = false;
_webui_core.run_userBuffer[run_id] = NULL;
_webui_core.run_userBufferLen[run_id] = 0;
// Packet Protocol Format:
// [...]
// [CMD]
@ -657,8 +652,8 @@ void webui_destroy(size_t window) {
// Free events
for (size_t i = 1; i < WEBUI_MAX_IDS; i++) {
if (win->event_core[i] != NULL)
_webui_free_mem((void*)win->event_core[i]);
if (win->events[i] != NULL)
_webui_free_mem((void*)win->events[i]);
}
// Free window struct
@ -1062,44 +1057,124 @@ size_t webui_bind(size_t window, const char* element, void (*func)(webui_event_t
return cb_index;
}
const char* webui_get_string(webui_event_t* e) {
const char* webui_get_string_at(webui_event_t* e, size_t index) {
#ifdef WEBUI_LOG
printf("[User] webui_get_string()...\n");
printf("[User] webui_get_string_at([%zu])...\n", index);
#endif
// Initialization
_webui_init();
if (_webui_core.exit_now) return NULL;
if (e->data != NULL) {
size_t len = _webui_strlen(e->data);
if(index >= WEBUI_MAX_ARG)
return NULL;
// Dereference
if (_webui_core.exit_now || _webui_core.wins[e->window] == NULL) return NULL;
_webui_window_t* win = _webui_core.wins[e->window];
// Get event inf
webui_event_inf_t* event_inf = win->events[e->event_number];
if(event_inf == NULL)
return NULL;
if (event_inf->event_data[index] != NULL) {
size_t len = _webui_strlen(event_inf->event_data[index]);
if (len > 0 && len <= WEBUI_MAX_BUF)
return (const char* ) e->data;
return (const char*)event_inf->event_data[index];
}
return "";
}
long long int webui_get_int(webui_event_t* e) {
long long int webui_get_int_at(webui_event_t* e, size_t index) {
#ifdef WEBUI_LOG
printf("[User] webui_get_int()...\n");
printf("[User] webui_get_int_at([%zu])...\n", index);
#endif
// Initialization & Dereference
// are done by webui_get_string()
if(index >= WEBUI_MAX_ARG)
return 0;
const char* str = webui_get_string_at(e, index);
if(str == NULL)
return 0;
size_t len = _webui_strlen(str);
if (len > 0 && len <= 20) {
// 64-bit max is -9,223,372,036,854,775,808 (20 character)
char* endptr;
return strtoll((const char*)str, &endptr, 10);
}
return 0;
}
bool webui_get_bool_at(webui_event_t* e, size_t index) {
#ifdef WEBUI_LOG
printf("[User] webui_get_bool_at([%zu])...\n", index);
#endif
// Initialization & Dereference
// are done by webui_get_string()
if(index >= WEBUI_MAX_ARG)
return false;
const char* str = webui_get_string_at(e, index);
if(str == NULL)
return false;
if (str[0] == '0' || str[0] == 'f' || str[0] == 'F') // `0` | `false` | `FALSE`
return false;
return true;
}
size_t webui_get_size_at(webui_event_t* e, size_t index) {
#ifdef WEBUI_LOG
printf("[User] webui_get_size_at([%zu])...\n", index);
#endif
// Initialization
_webui_init();
if (_webui_core.exit_now) return 0;
char* endptr;
if (e->data != NULL) {
size_t len = _webui_strlen(e->data);
if (len > 0 && len <= 20) // 64-bit max is -9,223,372,036,854,775,808 (20 character)
return strtoll((const char* ) e->data, &endptr, 10);
}
if(index >= WEBUI_MAX_ARG)
return 0;
return 0;
// Dereference
if (_webui_core.exit_now || _webui_core.wins[e->window] == NULL) return 0;
_webui_window_t* win = _webui_core.wins[e->window];
// Get event inf
webui_event_inf_t* event_inf = win->events[e->event_number];
if(event_inf == NULL)
return 0;
return event_inf->event_size[index];
}
const char* webui_get_string(webui_event_t* e) {
#ifdef WEBUI_LOG
printf("[User] webui_get_string()...\n");
#endif
return webui_get_string_at(e, 0);
}
long long int webui_get_int(webui_event_t* e) {
#ifdef WEBUI_LOG
printf("[User] webui_get_int()...\n");
#endif
return webui_get_int_at(e, 0);
}
bool webui_get_bool(webui_event_t* e) {
@ -1108,15 +1183,16 @@ bool webui_get_bool(webui_event_t* e) {
printf("[User] webui_get_bool()...\n");
#endif
// Initialization
_webui_init();
if (_webui_core.exit_now) return false;
return webui_get_bool_at(e, 0);
}
const char* str = webui_get_string(e);
if (str[0] == 't' || str[0] == 'T') // true || True
return true;
size_t webui_get_size(webui_event_t* e) {
return false;
#ifdef WEBUI_LOG
printf("[User] webui_get_size()...\n");
#endif
return webui_get_size_at(e, 0);
}
void webui_return_int(webui_event_t* e, long long int n) {
@ -1132,14 +1208,14 @@ void webui_return_int(webui_event_t* e, long long int n) {
if (_webui_core.exit_now || _webui_core.wins[e->window] == NULL) return;
_webui_window_t* win = _webui_core.wins[e->window];
// Get buffer
if (win->event_core[e->event_number] == NULL)
// Get event inf
webui_event_inf_t* event_inf = win->events[e->event_number];
if(event_inf == NULL)
return;
char** response = &win->event_core[e->event_number]->response;
// Free
if (*response != NULL)
_webui_free_mem((void*)*response);
if (event_inf->response != NULL)
_webui_free_mem((void*)event_inf->response);
// Int to Str
// 64-bit max is -9,223,372,036,854,775,808 (20 character)
@ -1147,7 +1223,7 @@ void webui_return_int(webui_event_t* e, long long int n) {
sprintf(buf, "%lld", n);
// Set response
*response = buf;
event_inf->response = buf;
}
void webui_return_string(webui_event_t* e, const char* s) {
@ -1166,14 +1242,14 @@ void webui_return_string(webui_event_t* e, const char* s) {
if (_webui_core.exit_now || _webui_core.wins[e->window] == NULL) return;
_webui_window_t* win = _webui_core.wins[e->window];
// Get buffer
if (win->event_core[e->event_number] == NULL)
// Get event inf
webui_event_inf_t* event_inf = win->events[e->event_number];
if(event_inf == NULL)
return;
char** response = &win->event_core[e->event_number]->response;
// Free
if (*response != NULL)
_webui_free_mem((void*)*response);
if (event_inf->response != NULL)
_webui_free_mem((void*)event_inf->response);
// Copy Str
int len = _webui_strlen(s);
@ -1181,7 +1257,38 @@ void webui_return_string(webui_event_t* e, const char* s) {
memcpy(buf, s, len);
// Set response
*response = buf;
event_inf->response = buf;
}
void webui_return_bool(webui_event_t* e, bool b) {
#ifdef WEBUI_LOG
printf("[User] webui_return_bool([%d])...\n", b);
#endif
// Initialization
_webui_init();
// Dereference
if (_webui_core.exit_now || _webui_core.wins[e->window] == NULL) return;
_webui_window_t* win = _webui_core.wins[e->window];
// Get event inf
webui_event_inf_t* event_inf = win->events[e->event_number];
if(event_inf == NULL)
return;
// Free
if (event_inf->response != NULL)
_webui_free_mem((void*)event_inf->response);
// Bool to Str
int len = 1;
char* buf = (char*) _webui_malloc(len);
sprintf(buf, "%d", b);
// Set response
event_inf->response = buf;
}
size_t webui_get_parent_process_id(size_t window) {
@ -1289,37 +1396,6 @@ size_t webui_get_child_process_id(size_t window) {
#endif
}
void webui_return_bool(webui_event_t* e, bool b) {
#ifdef WEBUI_LOG
printf("[User] webui_return_bool([%d])...\n", b);
#endif
// Initialization
_webui_init();
// Dereference
if (_webui_core.exit_now || _webui_core.wins[e->window] == NULL) return;
_webui_window_t* win = _webui_core.wins[e->window];
// Get buffer
if (win->event_core[e->event_number] == NULL)
return;
char** response = &win->event_core[e->event_number]->response;
// Free
if (*response != NULL)
_webui_free_mem((void*)*response);
// Bool to Str
int len = 1;
char* buf = (char*) _webui_malloc(len);
sprintf(buf, "%d", b);
// Set response
*response = buf;
}
void webui_set_hide(size_t window, bool status) {
#ifdef WEBUI_LOG
@ -1830,7 +1906,6 @@ static void _webui_interface_bind_handler(webui_event_t* e) {
printf("[Core]\t\t_webui_interface_bind_handler() -> User callback @ 0x%p\n", _webui_core.cb_interface[cb_index]);
printf("[Core]\t\t_webui_interface_bind_handler() -> e->event_type [%zu]\n", e->event_type);
printf("[Core]\t\t_webui_interface_bind_handler() -> e->element [%s]\n", e->element);
printf("[Core]\t\t_webui_interface_bind_handler() -> e->data [%s]\n", e->data);
printf("[Core]\t\t_webui_interface_bind_handler() -> e->event_number %zu\n", e->event_number);
#endif
@ -1838,22 +1913,29 @@ static void _webui_interface_bind_handler(webui_event_t* e) {
#ifdef WEBUI_LOG
printf("[Core]\t\t_webui_interface_bind_handler() -> Calling user callback...\n[Call]\n");
#endif
_webui_core.cb_interface[cb_index](e->window, e->event_type, e->element, e->data, e->size, e->event_number);
_webui_core.cb_interface[cb_index](e->window, e->event_type, e->element, e->event_number);
}
// Free
_webui_free_mem((void*)webui_internal_id);
#ifdef WEBUI_LOG
// Print cb response
char* response = NULL;
if (win->event_core[e->event_number] != NULL)
response = *(&win->event_core[e->event_number]->response);
// Get event inf
webui_event_inf_t* event_inf = win->events[e->event_number];
if(event_inf != NULL) {
if (event_inf->response != NULL)
response = event_inf->response;
}
printf("[Core]\t\t_webui_interface_bind_handler() -> user-callback response [%s]\n", response);
#endif
}
size_t webui_interface_bind(size_t window, const char* element, void (*func)(size_t, size_t, char*, char*, size_t, size_t)) {
size_t webui_interface_bind(size_t window, const char* element, void (*func)(size_t, size_t, char*, size_t)) {
#ifdef WEBUI_LOG
printf("[User] webui_interface_bind([%zu], [%s], [0x%p])...\n", window, element, func);
@ -1880,21 +1962,23 @@ void webui_interface_set_response(size_t window, size_t event_number, const char
if (_webui_core.exit_now || _webui_core.wins[window] == NULL) return;
_webui_window_t* win = _webui_core.wins[window];
// Get internal response buffer
if (win->event_core[event_number] != NULL) {
// Get event inf
webui_event_inf_t* event_inf = win->events[event_number];
if(event_inf == NULL)
return;
char** buffer = NULL;
buffer = &win->event_core[event_number]->response;
// Free
if (event_inf->response != NULL)
_webui_free_mem((void*)event_inf->response);
// Set the response
size_t len = _webui_strlen(response);
*buffer = (char*) _webui_malloc(len);
strcpy(*buffer, response);
// Set the response
size_t len = _webui_strlen(response);
event_inf->response = (char*) _webui_malloc(len);
strcpy(event_inf->response, response);
#ifdef WEBUI_LOG
printf("[User] webui_interface_set_response() -> Internal buffer [%s] \n", *buffer);
#endif
}
#ifdef WEBUI_LOG
printf("[User] webui_interface_set_response() -> Internal buffer [%s] \n", event_inf->response);
#endif
}
bool webui_interface_is_app_running(void) {
@ -1990,7 +2074,7 @@ static bool _webui_ptr_exist(void* ptr) {
static void _webui_ptr_add(void* ptr, size_t size) {
#ifdef WEBUI_LOG
// printf("[Core]\t\t_webui_ptr_add(0x%p)...\n", ptr);
printf("[Core]\t\t_webui_ptr_add(0x%p)...\n", ptr);
#endif
if (ptr == NULL)
@ -2117,7 +2201,7 @@ static size_t _webui_round_to_memory_block(size_t size) {
static void* _webui_malloc(size_t size) {
#ifdef WEBUI_LOG
// printf("[Core]\t\t_webui_malloc([%zu])...\n", size);
printf("[Core]\t\t_webui_malloc([%zu])...\n", size);
#endif
// Make sure we have the null
@ -2174,22 +2258,6 @@ static _webui_window_t* _webui_dereference_win_ptr(void* ptr) {
return NULL;
}
static size_t _webui_get_free_event_core_pos(_webui_window_t* win) {
#ifdef WEBUI_LOG
printf("[Core]\t\t_webui_get_free_event_core_pos()...\n");
#endif
for (size_t i = 1; i < WEBUI_MAX_IDS; i++) {
if (win->event_core[i] == NULL)
return i;
}
// Fatal. No free pos found
// let's use the first pos
return 0;
}
static void _webui_sleep(long unsigned int ms) {
#ifdef WEBUI_LOG
@ -2354,7 +2422,10 @@ static uint16_t _webui_get_run_id(void) {
printf("[Core]\t\t_webui_get_run_id()...\n");
#endif
return ++_webui_core.run_last_id;
if(_webui_core.run_last_id >= WEBUI_MAX_IDS)
_webui_core.run_last_id = 0;
return _webui_core.run_last_id++;
}
static bool _webui_socket_test_listen_mg(size_t port_num) {
@ -4835,7 +4906,7 @@ static bool _webui_show_window(_webui_window_t* win, const char* content, bool i
return true;
}
static void _webui_window_event(_webui_window_t* win, int event_type, char* element, char* data, size_t event_number, char* webui_internal_id) {
static void _webui_window_event(_webui_window_t* win, int event_type, char* element, size_t event_number, char* webui_internal_id) {
#ifdef WEBUI_LOG
printf("[Core]\t\t_webui_window_event([%s], [%s])...\n", webui_internal_id, element);
@ -4846,7 +4917,6 @@ static void _webui_window_event(_webui_window_t* win, int event_type, char* elem
e.window = win->window_number;
e.event_type = event_type;
e.element = element;
e.data = data;
e.event_number = event_number;
// Check for all events-bind functions
@ -4886,9 +4956,6 @@ static void _webui_window_event(_webui_window_t* win, int event_type, char* elem
#ifdef WEBUI_LOG
printf("[Core]\t\t_webui_window_event() -> Finished.\n");
#endif
// Free event
_webui_free_mem((void*)webui_internal_id);
}
static void _webui_ws_send(_webui_window_t* win, char* packet, size_t packets_size) {
@ -6000,14 +6067,27 @@ static WEBUI_THREAD_RECEIVE
// Generate WebUI internal id
char* webui_internal_id = _webui_generate_internal_id(win, element);
// New event inf
webui_event_inf_t* event_inf = (webui_event_inf_t*) _webui_malloc(sizeof(webui_event_inf_t));
if(win->events_count >= WEBUI_MAX_ARG)
win->events_count = 0;
size_t event_num = win->events_count++;
win->events[event_num] = event_inf;
// Set arguments
// ...
_webui_window_event(
win, // Event -> Window
WEBUI_EVENT_MOUSE_CLICK, // Event -> Type of this event
element, // Event -> HTML Element
NULL, // Event -> User Custom Data
0, // Event -> Event Number
event_num, // Event -> Event Number
webui_internal_id // Extras -> WebUI Internal ID
);
// Free event
_webui_free_mem((void*)webui_internal_id);
_webui_free_mem((void*)event_inf);
}
else if ((unsigned char)packet[WEBUI_PROTOCOL_CMD] == WEBUI_CMD_JS) {
@ -6018,44 +6098,47 @@ static WEBUI_THREAD_RECEIVE
// 1: [Error, ScriptResponse]
// Get pipe id
if (_webui_core.run_userBuffer[packet_id] != NULL) {
if(packet_id < WEBUI_MAX_IDS) {
_webui_core.run_done[packet_id] = false;
if (_webui_core.run_userBuffer[packet_id] != NULL) {
// Get js-error
bool error = true;
if ((unsigned char)packet[WEBUI_PROTOCOL_DATA] == 0x00)
error = false;
_webui_core.run_done[packet_id] = false;
// Get data part
char* data = (char*)&packet[WEBUI_PROTOCOL_DATA + 1];
size_t data_len = _webui_strlen(data);
// Get js-error
bool error = true;
if ((unsigned char)packet[WEBUI_PROTOCOL_DATA] == 0x00)
error = false;
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> WEBUI_CMD_JS \n", recvNum);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> run_id = 0x%02x (%u) \n", recvNum, packet_id, packet_id);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> error = %s \n", recvNum, error ? "true" : "false");
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> %zu bytes of data\n", recvNum, data_len);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> data = [%s] @ 0x%p\n", recvNum, data, data);
#endif
// Get data part
char* data = (char*)&packet[WEBUI_PROTOCOL_DATA + 1];
size_t data_len = _webui_strlen(data);
// Set pipe
_webui_core.run_error[packet_id] = error;
if (data_len > 0) {
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> WEBUI_CMD_JS \n", recvNum);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> run_id = 0x%02x (%u) \n", recvNum, packet_id, packet_id);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> error = %s \n", recvNum, error ? "true" : "false");
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> %zu bytes of data\n", recvNum, data_len);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> data = [%s] @ 0x%p\n", recvNum, data, data);
#endif
// Copy response to the user's response buffer directly
size_t response_len = data_len + 1;
size_t bytes_to_cpy = (response_len <= _webui_core.run_userBufferLen[packet_id] ? response_len : _webui_core.run_userBufferLen[packet_id]);
memcpy(_webui_core.run_userBuffer[packet_id], data, bytes_to_cpy);
// Set pipe
_webui_core.run_error[packet_id] = error;
if (data_len > 0) {
// Copy response to the user's response buffer directly
size_t response_len = data_len + 1;
size_t bytes_to_cpy = (response_len <= _webui_core.run_userBufferLen[packet_id] ? response_len : _webui_core.run_userBufferLen[packet_id]);
memcpy(_webui_core.run_userBuffer[packet_id], data, bytes_to_cpy);
}
else {
// Empty Result
memcpy(_webui_core.run_userBuffer[packet_id], 0x00, 1);
}
// Send ready signal to webui_script()
_webui_core.run_done[packet_id] = true;
}
else {
// Empty Result
memcpy(_webui_core.run_userBuffer[packet_id], 0x00, 1);
}
// Send ready signal to webui_script()
_webui_core.run_done[packet_id] = true;
}
}
else if ((unsigned char)packet[WEBUI_PROTOCOL_CMD] == WEBUI_CMD_NAVIGATION) {
@ -6082,14 +6165,28 @@ static WEBUI_THREAD_RECEIVE
// Generate WebUI internal id
char* webui_internal_id = _webui_generate_internal_id(win, "");
// New event inf
webui_event_inf_t* event_inf = (webui_event_inf_t*) _webui_malloc(sizeof(webui_event_inf_t));
if(win->events_count >= WEBUI_MAX_ARG)
win->events_count = 0;
size_t event_num = win->events_count++;
win->events[event_num] = event_inf;
// Set arguments
event_inf->event_data[0] = url;
event_inf->event_size[0] = url_len;
_webui_window_event(
win, // Event -> Window
WEBUI_EVENT_NAVIGATION, // Event -> Type of this event
"", // Event -> HTML Element
url, // Event -> User Custom Data
0, // Event -> Event Number
event_num, // Event -> Event Number
webui_internal_id // Extras -> WebUI Internal ID
);
// Free event
_webui_free_mem((void*)webui_internal_id);
_webui_free_mem((void*)event_inf);
}
}
else if ((unsigned char)packet[WEBUI_PROTOCOL_CMD] == WEBUI_CMD_CALL_FUNC) {
@ -6097,90 +6194,91 @@ static WEBUI_THREAD_RECEIVE
// Function Call
// 0: [Header]
// 1: [Element, Null, Len, Null, Data, Null]
// 1: [Fn, Null, {Len;Len;...}, Null, {Data,Null,Data,Null...}, Null]
// Get html element id
char* element = (char*)&packet[WEBUI_PROTOCOL_DATA];
size_t element_strlen = _webui_strlen(element);
size_t element_len = _webui_strlen(element);
// Get data len (As str)
char* len_s = (char*)&packet[WEBUI_PROTOCOL_DATA + element_strlen + 1];
size_t len_s_strlen = _webui_strlen(len_s);
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> WEBUI_CMD_CALL_FUNC \n", recvNum);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Call ID: [%u] \n", recvNum, packet_id);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Element: [%s] \n", recvNum, element);
#endif
// Generate WebUI internal id
char* webui_internal_id = _webui_generate_internal_id(win, element);
// Get data len
long long int len = 0;
char* endptr;
if (len_s_strlen > 0 && len_s_strlen <= 20) { // 64-bit max is -9,223,372,036,854,775,808 (20 character)
// New event inf
webui_event_inf_t* event_inf = (webui_event_inf_t*) _webui_malloc(sizeof(webui_event_inf_t));
if(win->events_count >= WEBUI_MAX_ARG)
win->events_count = 0;
size_t event_num = win->events_count++;
win->events[event_num] = event_inf;
// Loop trough args
char* args_lens = (char*)&packet[WEBUI_PROTOCOL_DATA + element_len + 1];
char* args_ptr = (char*)&packet[WEBUI_PROTOCOL_DATA + element_len + 1 + _webui_strlen(args_lens) + 1];
char* token = strtok(args_lens, ";");
size_t token_num = 0;
while (token != NULL) {
char* data = NULL;
len = strtoll((const char*)len_s, &endptr, 10);
if (len > 0)
// Get data
data = (char*)&packet[WEBUI_PROTOCOL_DATA + element_strlen + 1 + len_s_strlen + 1];
size_t arg_len = (size_t)strtoul(token, NULL, 10);
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> WEBUI_CMD_CALL_FUNC \n", recvNum);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Call ID: [%u] \n", recvNum, packet_id);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Element: [%s] \n", recvNum, element);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Data size: %lld Bytes \n", recvNum, len);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Data: Hex [ ", recvNum);
_webui_print_hex(data, len);
printf("]\n");
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Data: ASCII [ ", recvNum);
_webui_print_ascii(data, len);
printf("]\n");
#endif
if(arg_len > 0) {
// Generate WebUI internal id
char* webui_internal_id = _webui_generate_internal_id(win, element);
// Create new event core to hold the response
webui_event_core_t* event_core = (webui_event_core_t*) _webui_malloc(sizeof(webui_event_core_t));
size_t event_core_pos = _webui_get_free_event_core_pos(win);
win->event_core[event_core_pos] = event_core;
char** response = &win->event_core[event_core_pos]->response;
// Create new event
webui_event_t e;
e.window = win->window_number;
e.event_type = WEBUI_EVENT_CALLBACK;
e.element = element;
e.data = data;
e.size = (size_t)len;
e.event_number = event_core_pos;
// Call user function
size_t cb_index = _webui_get_cb_index(webui_internal_id);
if (cb_index > 0 && _webui_core.cb[cb_index] != NULL) {
// Call user cb
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Calling user callback...\n[Call]\n", recvNum);
#endif
_webui_core.cb[cb_index](&e);
// Set argument
event_inf->event_size[token_num] = arg_len;
event_inf->event_data[token_num] = args_ptr;
}
// Check the response
if (_webui_is_empty(*response))
*response = (char*)"";
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> user-callback response [%s]\n", recvNum, *response);
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Argument %zu: %zu bytes\n", recvNum, token_num, arg_len);
#endif
// Packet Protocol Format:
// [...]
// [CMD]
// [CallResponse]
// Send the packet
_webui_send(win, win->token, packet_id, WEBUI_CMD_CALL_FUNC, (*response), _webui_strlen(*response));
// Free
_webui_free_mem((void*)webui_internal_id);
_webui_free_mem((void*)*response);
_webui_free_mem((void*)event_core);
args_ptr = args_ptr + (arg_len + 1);
token_num++;
token = strtok(NULL, ";");
}
// Create new event
webui_event_t e;
e.window = win->window_number;
e.event_type = WEBUI_EVENT_CALLBACK;
e.element = element;
e.event_number = event_num;
// Call user function
size_t cb_index = _webui_get_cb_index(webui_internal_id);
if (cb_index > 0 && _webui_core.cb[cb_index] != NULL) {
// Call user cb
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> Calling user callback...\n[Call]\n", recvNum);
#endif
_webui_core.cb[cb_index](&e);
}
// Check the response
if (_webui_is_empty(event_inf->response))
event_inf->response = (char*)"";
#ifdef WEBUI_LOG
printf("[Core]\t\t[Thread %zu] _webui_receive_thread() -> user-callback response [%s]\n", recvNum, event_inf->response);
#endif
// Packet Protocol Format:
// [...]
// [CMD]
// [CallResponse]
// Send the packet
_webui_send(win, win->token, packet_id, WEBUI_CMD_CALL_FUNC, event_inf->response, _webui_strlen(event_inf->response));
// Free event
_webui_free_mem((void*)webui_internal_id);
_webui_free_mem((void*)event_inf->response);
_webui_free_mem((void*)event_inf);
}
#ifdef WEBUI_LOG
else {
@ -6229,14 +6327,27 @@ static WEBUI_THREAD_RECEIVE
// Generate WebUI internal id
char* webui_internal_id = _webui_generate_internal_id(win, "");
// New event inf
webui_event_inf_t* event_inf = (webui_event_inf_t*) _webui_malloc(sizeof(webui_event_inf_t));
if(win->events_count >= WEBUI_MAX_ARG)
win->events_count = 0;
size_t event_num = win->events_count++;
win->events[event_num] = event_inf;
// Set arguments
// ...
_webui_window_event(
win, // Event -> Window
event_user, // Event -> Type of this event
"", // Event -> HTML Element
NULL, // Event -> User Custom Data
0, // Event -> Event Number
webui_internal_id // Extras -> WebUI Internal ID
);
// Free event
_webui_free_mem((void*)webui_internal_id);
_webui_free_mem((void*)event_inf);
}
}
else if (event_type == WEBUI_WS_CLOSE) {
@ -6257,14 +6368,27 @@ static WEBUI_THREAD_RECEIVE
// Generate WebUI internal id
char* webui_internal_id = _webui_generate_internal_id(win, "");
// New event inf
webui_event_inf_t* event_inf = (webui_event_inf_t*) _webui_malloc(sizeof(webui_event_inf_t));
if(win->events_count >= WEBUI_MAX_ARG)
win->events_count = 0;
size_t event_num = win->events_count++;
win->events[event_num] = event_inf;
// Set arguments
// ...
_webui_window_event(
win, // Event -> Window
WEBUI_EVENT_DISCONNECTED, // Event -> Type of this event
"", // Event -> HTML Element
NULL, // Event -> User Custom Data
0, // Event -> Event Number
webui_internal_id // Extras -> WebUI Internal ID
);
// Free event
_webui_free_mem((void*)webui_internal_id);
_webui_free_mem((void*)event_inf);
}
}
#ifdef WEBUI_LOG