aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rwxr-xr-xgenerate-emoji-sprite.py98
-rw-r--r--generated/Emoji.cpp2946
-rw-r--r--generated/Emoji.hpp15
-rw-r--r--images/emoji.pngbin0 -> 932613 bytes
-rw-r--r--include/Body.hpp3
-rw-r--r--include/ResourceLoader.hpp (renamed from include/FontLoader.hpp)12
-rw-r--r--include/Text.hpp2
-rw-r--r--plugins/Fourchan.hpp5
-rw-r--r--plugins/Matrix.hpp2
-rw-r--r--src/Body.cpp2
-rw-r--r--src/Entry.cpp2
-rw-r--r--src/ImageViewer.cpp2
-rw-r--r--src/QuickMedia.cpp4
-rw-r--r--src/ResourceLoader.cpp (renamed from src/FontLoader.cpp)29
-rw-r--r--src/SearchBar.cpp2
-rw-r--r--src/Text.cpp71
-rw-r--r--src/plugins/Fourchan.cpp266
-rw-r--r--src/plugins/Matrix.cpp6
19 files changed, 3281 insertions, 188 deletions
diff --git a/README.md b/README.md
index 93144ec..2e49c7a 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,8 @@ See project.conf \[dependencies].
`waifu2x-ncnn-vulkan` needs to be installed when using the `--upscale-images` or `--upscale-images-always` option.\
`xdg-utils` which provides `xdg-open` needs to be installed when downloading torrents with `nyaa.si` plugin.\
`ffmpeg (and ffprobe which is included in ffmpeg)` needs to be installed to upload videos with thumbnails on matrix.
+## License
+QuickMedia is free software licensed under GPL 3.0, see LICENSE for more details. `images/emoji.png` uses Noto Color Emoji, which is licensed under the Apache license, see: https://github.com/googlefonts/noto-emoji.
# Screenshots
## Youtube search
![](https://www.dec05eba.com/images/youtube.jpg)
diff --git a/generate-emoji-sprite.py b/generate-emoji-sprite.py
index b0e9dc3..849a81d 100755
--- a/generate-emoji-sprite.py
+++ b/generate-emoji-sprite.py
@@ -1,35 +1,73 @@
#!/usr/bin/env python3
-import requests
-from subprocess import Popen, PIPE
+from gi.repository import Gtk, Gdk, Pango, PangoCairo
+import cairo
-def create_image_with_text(text, image_filepath):
- process = Popen(["convert", "-size", "1024x", "-background", "#ff00ff", "-strip", "pango:" + text, image_filepath])
- _, _ = process.communicate()
+surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1024, 1512)
+context = cairo.Context(surface)
+pc = PangoCairo.create_context(context)
+layout = PangoCairo.create_layout(context)
+layout.set_font_description(Pango.FontDescription('NotoSans Emoji Normal 12'))
+layout.set_width(1024*Pango.SCALE)
+layout.set_wrap(Pango.WrapMode.CHAR)
-resp = requests.get("https://unicode.org/Public/emoji/13.1/emoji-test.txt")
-resp.raise_for_status()
-emoji_sequences = resp.text
-
-ss = []
+emoji_start = 0x1F000
+emoji_end = 0x1FB6F
emoji_characters = []
-for line in emoji_sequences.splitlines():
- if len(line) == 0 or line[0] == '#':
- continue
-
- columns = line.split(";")
- sequences = columns[0].strip().split()
- text = [chr(int(c, 16)) for c in sequences]
- emoji_characters.extend(text)
- ss.append(int(sequences[0], 16))
- #print(str(sequences))
-
-#print(str(len(emoji_characters)))
-create_image_with_text("".join(emoji_characters), "emoji.jpg")
-
-sow = list(set(ss))
-sow.sort()
-for i in range(len(sow) - 1):
- s1 = sow[i]
- s2 = sow[i + 1]
- print(str(s2-s1))
+i = emoji_start
+while i <= emoji_end:
+ emoji_characters.append(chr(i))
+ i += 1
+
+layout.set_text("".join(emoji_characters), -1)
+PangoCairo.show_layout(context, layout)
+surface.write_to_png('images/emoji.png')
+
+with open("generated/Emoji.hpp", "w") as header_file:
+ header_file.write("""#pragma once
+
+#include <stdint.h>
+
+// This file was automatically generated with generate-emoji-sprite.py, do not edit manually!
+
+namespace QuickMedia {
+ struct EmojiRectangle {
+ int x, y;
+ int width, height;
+ };
+
+ bool codepoint_is_emoji(uint32_t codepoint);
+ EmojiRectangle emoji_get_extents(uint32_t codepoint);
+}""")
+
+with open("generated/Emoji.cpp", "w") as source_file:
+ source_file.write("""#include "Emoji.hpp"
+#include <assert.h>
+
+// This file was automatically generated with generate-emoji-sprite.py, do not edit manually!
+
+namespace QuickMedia {
+ static EmojiRectangle emoji_extents[%s] = {
+""" % len(emoji_characters))
+
+ i = 0
+ index = 0
+ for e in emoji_characters:
+ emoji_pos = layout.index_to_pos(index)
+ source_file.write(" {%s, %s, %s, %s}%s\n" % (int(emoji_pos.x/Pango.SCALE), int(emoji_pos.y/Pango.SCALE), int(emoji_pos.width/Pango.SCALE), int(emoji_pos.height/Pango.SCALE), "," if i < len(emoji_characters) - 1 else ""))
+ i += 1
+ index += 4
+
+ source_file.write(
+""" };
+
+ bool codepoint_is_emoji(uint32_t codepoint) {
+ return codepoint >= 0x1F000 && codepoint <= 0x1FB6F;
+ }
+
+ EmojiRectangle emoji_get_extents(uint32_t codepoint) {
+ assert(codepoint_is_emoji(codepoint));
+ return emoji_extents[codepoint - 0x1F000];
+ }
+}
+""") \ No newline at end of file
diff --git a/generated/Emoji.cpp b/generated/Emoji.cpp
new file mode 100644
index 0000000..07b240b
--- /dev/null
+++ b/generated/Emoji.cpp
@@ -0,0 +1,2946 @@
+#include "Emoji.hpp"
+#include <assert.h>
+
+// This file was automatically generated with generate-emoji-sprite.py, do not edit manually!
+
+namespace QuickMedia {
+ static EmojiRectangle emoji_extents[2928] = {
+ {0, 0, 13, 21},
+ {13, 0, 13, 21},
+ {26, 0, 13, 21},
+ {39, 0, 13, 21},
+ {52, 0, 20, 21},
+ {72, 0, 13, 21},
+ {85, 0, 13, 21},
+ {98, 0, 13, 21},
+ {111, 0, 13, 21},
+ {124, 0, 13, 21},
+ {137, 0, 13, 21},
+ {150, 0, 13, 21},
+ {163, 0, 13, 21},
+ {176, 0, 13, 21},
+ {189, 0, 13, 21},
+ {202, 0, 13, 21},
+ {215, 0, 13, 21},
+ {228, 0, 13, 21},
+ {241, 0, 13, 21},
+ {254, 0, 13, 21},
+ {267, 0, 13, 21},
+ {280, 0, 13, 21},
+ {293, 0, 13, 21},
+ {306, 0, 13, 21},
+ {319, 0, 13, 21},
+ {332, 0, 13, 21},
+ {345, 0, 13, 21},
+ {358, 0, 13, 21},
+ {371, 0, 13, 21},
+ {384, 0, 13, 21},
+ {397, 0, 13, 21},
+ {410, 0, 13, 21},
+ {423, 0, 13, 21},
+ {436, 0, 13, 21},
+ {449, 0, 13, 21},
+ {462, 0, 13, 21},
+ {475, 0, 13, 21},
+ {488, 0, 13, 21},
+ {501, 0, 13, 21},
+ {514, 0, 13, 21},
+ {527, 0, 13, 21},
+ {540, 0, 13, 21},
+ {553, 0, 13, 21},
+ {566, 0, 13, 21},
+ {579, 0, 23, 21},
+ {602, 0, 23, 21},
+ {625, 0, 23, 21},
+ {648, 0, 23, 21},
+ {671, 0, 22, 21},
+ {693, 0, 22, 21},
+ {715, 0, 22, 21},
+ {737, 0, 22, 21},
+ {759, 0, 22, 21},
+ {781, 0, 22, 21},
+ {803, 0, 22, 21},
+ {825, 0, 22, 21},
+ {847, 0, 22, 21},
+ {869, 0, 22, 21},
+ {891, 0, 22, 21},
+ {913, 0, 22, 21},
+ {935, 0, 22, 21},
+ {957, 0, 22, 21},
+ {979, 0, 22, 21},
+ {1001, 0, 22, 21},
+ {0, 21, 22, 19},
+ {22, 21, 22, 19},
+ {44, 21, 22, 19},
+ {66, 21, 22, 19},
+ {88, 21, 22, 19},
+ {110, 21, 22, 19},
+ {132, 21, 22, 19},
+ {154, 21, 22, 19},
+ {176, 21, 22, 19},
+ {198, 21, 22, 19},
+ {220, 21, 22, 19},
+ {242, 21, 22, 19},
+ {264, 21, 22, 19},
+ {286, 21, 22, 19},
+ {308, 21, 22, 19},
+ {330, 21, 22, 19},
+ {352, 21, 22, 19},
+ {374, 21, 22, 19},
+ {396, 21, 22, 19},
+ {418, 21, 22, 19},
+ {440, 21, 22, 19},
+ {462, 21, 22, 19},
+ {484, 21, 22, 19},
+ {506, 21, 22, 19},
+ {528, 21, 22, 19},
+ {550, 21, 22, 19},
+ {572, 21, 22, 19},
+ {594, 21, 22, 19},
+ {616, 21, 22, 19},
+ {638, 21, 22, 19},
+ {660, 21, 22, 19},
+ {682, 21, 22, 19},
+ {704, 21, 22, 19},
+ {726, 21, 22, 19},
+ {748, 21, 13, 19},
+ {761, 21, 13, 19},
+ {774, 21, 13, 19},
+ {787, 21, 13, 19},
+ {800, 21, 13, 19},
+ {813, 21, 13, 19},
+ {826, 21, 13, 19},
+ {839, 21, 13, 19},
+ {852, 21, 13, 19},
+ {865, 21, 13, 19},
+ {878, 21, 13, 19},
+ {891, 21, 13, 19},
+ {904, 21, 13, 19},
+ {917, 21, 13, 19},
+ {930, 21, 13, 19},
+ {943, 21, 13, 19},
+ {956, 21, 13, 19},
+ {969, 21, 13, 19},
+ {982, 21, 13, 19},
+ {995, 21, 13, 19},
+ {1008, 21, 13, 19},
+ {0, 40, 13, 21},
+ {13, 40, 13, 21},
+ {26, 40, 13, 21},
+ {39, 40, 13, 21},
+ {52, 40, 13, 21},
+ {65, 40, 13, 21},
+ {78, 40, 13, 21},
+ {91, 40, 13, 21},
+ {104, 40, 13, 21},
+ {117, 40, 13, 21},
+ {130, 40, 13, 21},
+ {143, 40, 13, 21},
+ {156, 40, 13, 21},
+ {169, 40, 13, 21},
+ {182, 40, 13, 21},
+ {195, 40, 13, 21},
+ {208, 40, 13, 21},
+ {221, 40, 13, 21},
+ {234, 40, 13, 21},
+ {247, 40, 13, 21},
+ {260, 40, 13, 21},
+ {273, 40, 13, 21},
+ {286, 40, 13, 21},
+ {299, 40, 13, 21},
+ {312, 40, 13, 21},
+ {325, 40, 13, 21},
+ {338, 40, 13, 21},
+ {351, 40, 13, 21},
+ {364, 40, 13, 21},
+ {377, 40, 23, 21},
+ {400, 40, 23, 21},
+ {423, 40, 23, 21},
+ {446, 40, 23, 21},
+ {469, 40, 23, 21},
+ {492, 40, 23, 21},
+ {515, 40, 23, 21},
+ {538, 40, 23, 21},
+ {561, 40, 23, 21},
+ {584, 40, 23, 21},
+ {607, 40, 23, 21},
+ {630, 40, 23, 21},
+ {653, 40, 16, 21},
+ {669, 40, 16, 21},
+ {685, 40, 16, 21},
+ {701, 40, 16, 21},
+ {717, 40, 16, 21},
+ {733, 40, 16, 21},
+ {749, 40, 16, 21},
+ {765, 40, 16, 21},
+ {781, 40, 16, 21},
+ {797, 40, 16, 21},
+ {813, 40, 16, 21},
+ {829, 40, 16, 21},
+ {845, 40, 16, 21},
+ {861, 40, 16, 21},
+ {877, 40, 16, 21},
+ {893, 40, 23, 21},
+ {916, 40, 23, 21},
+ {939, 40, 16, 21},
+ {955, 40, 16, 21},
+ {971, 40, 16, 21},
+ {987, 40, 16, 21},
+ {1003, 40, 16, 21},
+ {0, 61, 16, 29},
+ {16, 61, 16, 29},
+ {32, 61, 16, 29},
+ {48, 61, 16, 29},
+ {64, 61, 16, 29},
+ {80, 61, 16, 29},
+ {96, 61, 16, 29},
+ {112, 61, 17, 29},
+ {129, 61, 16, 29},
+ {145, 61, 11, 29},
+ {156, 61, 23, 29},
+ {179, 61, 16, 29},
+ {195, 61, 16, 29},
+ {211, 61, 16, 29},
+ {227, 61, 16, 29},
+ {243, 61, 16, 29},
+ {259, 61, 16, 29},
+ {275, 61, 16, 29},
+ {291, 61, 16, 29},
+ {307, 61, 16, 29},
+ {323, 61, 16, 29},
+ {339, 61, 16, 29},
+ {355, 61, 16, 29},
+ {371, 61, 16, 29},
+ {387, 61, 16, 29},
+ {403, 61, 20, 29},
+ {423, 61, 23, 29},
+ {446, 61, 16, 29},
+ {462, 61, 16, 29},
+ {478, 61, 16, 29},
+ {494, 61, 16, 29},
+ {510, 61, 16, 29},
+ {526, 61, 16, 29},
+ {542, 61, 16, 29},
+ {558, 61, 16, 29},
+ {574, 61, 16, 29},
+ {590, 61, 16, 29},
+ {606, 61, 16, 29},
+ {622, 61, 16, 29},
+ {638, 61, 16, 29},
+ {654, 61, 16, 29},
+ {670, 61, 16, 29},
+ {686, 61, 11, 29},
+ {697, 61, 11, 29},
+ {708, 61, 11, 29},
+ {719, 61, 11, 29},
+ {730, 61, 11, 29},
+ {741, 61, 11, 29},
+ {752, 61, 11, 29},
+ {763, 61, 11, 29},
+ {774, 61, 11, 29},
+ {785, 61, 11, 29},
+ {796, 61, 11, 29},
+ {807, 61, 11, 29},
+ {818, 61, 11, 29},
+ {829, 61, 11, 29},
+ {840, 61, 11, 29},
+ {851, 61, 11, 29},
+ {862, 61, 11, 29},
+ {873, 61, 11, 29},
+ {884, 61, 11, 29},
+ {895, 61, 11, 29},
+ {906, 61, 11, 29},
+ {917, 61, 11, 29},
+ {928, 61, 23, 29},
+ {951, 61, 23, 29},
+ {974, 61, 23, 29},
+ {997, 61, 23, 29},
+ {0, 90, 23, 24},
+ {23, 90, 23, 24},
+ {46, 90, 23, 24},
+ {69, 90, 23, 24},
+ {92, 90, 23, 24},
+ {115, 90, 23, 24},
+ {138, 90, 16, 24},
+ {154, 90, 16, 24},
+ {170, 90, 16, 24},
+ {186, 90, 16, 24},
+ {202, 90, 16, 24},
+ {218, 90, 16, 24},
+ {234, 90, 16, 24},
+ {250, 90, 16, 24},
+ {266, 90, 16, 24},
+ {282, 90, 16, 24},
+ {298, 90, 16, 24},
+ {314, 90, 16, 24},
+ {330, 90, 16, 24},
+ {346, 90, 23, 24},
+ {369, 90, 23, 24},
+ {392, 90, 23, 24},
+ {415, 90, 16, 24},
+ {431, 90, 16, 24},
+ {447, 90, 16, 24},
+ {463, 90, 16, 24},
+ {479, 90, 16, 24},
+ {495, 90, 16, 24},
+ {511, 90, 16, 24},
+ {527, 90, 16, 24},
+ {543, 90, 16, 24},
+ {559, 90, 16, 24},
+ {575, 90, 16, 24},
+ {591, 90, 16, 24},
+ {607, 90, 16, 24},
+ {623, 90, 16, 24},
+ {639, 90, 16, 24},
+ {655, 90, 16, 24},
+ {671, 90, 16, 24},
+ {687, 90, 16, 24},
+ {703, 90, 16, 24},
+ {719, 90, 16, 24},
+ {735, 90, 16, 24},
+ {751, 90, 16, 24},
+ {767, 90, 16, 24},
+ {783, 90, 16, 24},
+ {799, 90, 16, 24},
+ {815, 90, 16, 24},
+ {831, 90, 16, 24},
+ {847, 90, 16, 24},
+ {863, 90, 16, 24},
+ {879, 90, 16, 24},
+ {895, 90, 16, 24},
+ {911, 90, 13, 24},
+ {924, 90, 16, 24},
+ {940, 90, 16, 24},
+ {956, 90, 16, 24},
+ {972, 90, 16, 24},
+ {988, 90, 16, 24},
+ {1004, 90, 16, 24},
+ {0, 114, 16, 24},
+ {16, 114, 16, 24},
+ {32, 114, 16, 24},
+ {48, 114, 16, 24},
+ {64, 114, 16, 24},
+ {80, 114, 16, 24},
+ {96, 114, 16, 24},
+ {112, 114, 16, 24},
+ {128, 114, 16, 24},
+ {144, 114, 16, 24},
+ {160, 114, 16, 24},
+ {176, 114, 16, 24},
+ {192, 114, 16, 24},
+ {208, 114, 16, 24},
+ {224, 114, 16, 24},
+ {240, 114, 16, 24},
+ {256, 114, 16, 24},
+ {272, 114, 16, 24},
+ {288, 114, 16, 24},
+ {304, 114, 16, 24},
+ {320, 114, 16, 24},
+ {336, 114, 16, 24},
+ {352, 114, 16, 24},
+ {368, 114, 16, 24},
+ {384, 114, 16, 24},
+ {400, 114, 16, 24},
+ {416, 114, 16, 24},
+ {432, 114, 16, 24},
+ {448, 114, 16, 24},
+ {464, 114, 16, 24},
+ {480, 114, 16, 24},
+ {496, 114, 16, 24},
+ {512, 114, 16, 24},
+ {528, 114, 16, 24},
+ {544, 114, 16, 24},
+ {560, 114, 16, 24},
+ {576, 114, 16, 24},
+ {592, 114, 16, 24},
+ {608, 114, 16, 24},
+ {624, 114, 16, 24},
+ {640, 114, 16, 24},
+ {656, 114, 16, 24},
+ {672, 114, 16, 24},
+ {688, 114, 16, 24},
+ {704, 114, 16, 24},
+ {720, 114, 16, 24},
+ {736, 114, 16, 24},
+ {752, 114, 16, 24},
+ {768, 114, 16, 24},
+ {784, 114, 16, 24},
+ {800, 114, 16, 24},
+ {816, 114, 16, 24},
+ {832, 114, 11, 24},
+ {843, 114, 12, 24},
+ {855, 114, 12, 24},
+ {867, 114, 23, 24},
+ {890, 114, 23, 24},
+ {913, 114, 23, 24},
+ {936, 114, 16, 24},
+ {952, 114, 16, 24},
+ {968, 114, 16, 24},
+ {984, 114, 16, 24},
+ {1000, 114, 16, 24},
+ {0, 138, 16, 24},
+ {16, 138, 16, 24},
+ {32, 138, 16, 24},
+ {48, 138, 16, 24},
+ {64, 138, 16, 24},
+ {80, 138, 16, 24},
+ {96, 138, 16, 24},
+ {112, 138, 16, 24},
+ {128, 138, 16, 24},
+ {144, 138, 16, 24},
+ {160, 138, 16, 24},
+ {176, 138, 16, 24},
+ {192, 138, 16, 24},
+ {208, 138, 16, 24},
+ {224, 138, 16, 24},
+ {240, 138, 16, 24},
+ {256, 138, 16, 24},
+ {272, 138, 16, 24},
+ {288, 138, 16, 24},
+ {304, 138, 16, 24},
+ {320, 138, 16, 24},
+ {336, 138, 16, 24},
+ {352, 138, 16, 24},
+ {368, 138, 16, 24},
+ {384, 138, 16, 24},
+ {400, 138, 20, 24},
+ {420, 138, 16, 24},
+ {436, 138, 16, 24},
+ {452, 138, 20, 24},
+ {472, 138, 20, 24},
+ {492, 138, 20, 24},
+ {512, 138, 20, 24},
+ {532, 138, 20, 24},
+ {552, 138, 20, 24},
+ {572, 138, 20, 24},
+ {592, 138, 20, 24},
+ {612, 138, 20, 24},
+ {632, 138, 20, 24},
+ {652, 138, 16, 24},
+ {668, 138, 16, 24},
+ {684, 138, 16, 24},
+ {700, 138, 16, 24},
+ {716, 138, 16, 24},
+ {732, 138, 16, 24},
+ {748, 138, 16, 24},
+ {764, 138, 16, 24},
+ {780, 138, 16, 24},
+ {796, 138, 16, 24},
+ {812, 138, 16, 24},
+ {828, 138, 16, 24},
+ {844, 138, 16, 24},
+ {860, 138, 16, 24},
+ {876, 138, 16, 24},
+ {892, 138, 16, 24},
+ {908, 138, 16, 24},
+ {924, 138, 16, 24},
+ {940, 138, 23, 24},
+ {963, 138, 23, 24},
+ {986, 138, 23, 24},
+ {0, 162, 23, 21},
+ {23, 162, 23, 21},
+ {46, 162, 23, 21},
+ {69, 162, 23, 21},
+ {92, 162, 23, 21},
+ {115, 162, 23, 21},
+ {138, 162, 23, 21},
+ {161, 162, 23, 21},
+ {184, 162, 23, 21},
+ {207, 162, 23, 21},
+ {230, 162, 23, 21},
+ {253, 162, 23, 21},
+ {276, 162, 23, 21},
+ {299, 162, 23, 21},
+ {322, 162, 23, 21},
+ {345, 162, 23, 21},
+ {368, 162, 23, 21},
+ {391, 162, 23, 21},
+ {414, 162, 23, 21},
+ {437, 162, 23, 21},
+ {460, 162, 23, 21},
+ {483, 162, 23, 21},
+ {506, 162, 23, 21},
+ {529, 162, 23, 21},
+ {552, 162, 23, 21},
+ {575, 162, 23, 21},
+ {598, 162, 23, 21},
+ {621, 162, 23, 21},
+ {644, 162, 23, 21},
+ {667, 162, 23, 21},
+ {690, 162, 23, 21},
+ {713, 162, 23, 21},
+ {736, 162, 23, 21},
+ {759, 162, 23, 21},
+ {782, 162, 23, 21},
+ {805, 162, 23, 21},
+ {828, 162, 23, 21},
+ {851, 162, 23, 21},
+ {874, 162, 23, 21},
+ {897, 162, 23, 21},
+ {920, 162, 23, 21},
+ {943, 162, 23, 21},
+ {966, 162, 23, 21},
+ {989, 162, 23, 21},
+ {0, 183, 23, 24},
+ {23, 183, 23, 24},
+ {46, 183, 23, 24},
+ {69, 183, 23, 24},
+ {92, 183, 23, 24},
+ {115, 183, 23, 24},
+ {138, 183, 23, 24},
+ {161, 183, 23, 24},
+ {184, 183, 23, 24},
+ {207, 183, 23, 24},
+ {230, 183, 20, 24},
+ {230, 183, 20, 24},
+ {250, 183, 20, 24},
+ {250, 183, 20, 24},
+ {270, 183, 20, 24},
+ {270, 183, 20, 24},
+ {290, 183, 20, 24},
+ {290, 183, 20, 24},
+ {310, 183, 20, 24},
+ {310, 183, 20, 24},
+ {330, 183, 20, 24},
+ {330, 183, 20, 24},
+ {350, 183, 20, 24},
+ {350, 183, 20, 24},
+ {370, 183, 20, 24},
+ {370, 183, 20, 24},
+ {390, 183, 30, 24},
+ {390, 183, 30, 24},
+ {420, 183, 20, 24},
+ {420, 183, 20, 24},
+ {440, 183, 20, 24},
+ {440, 183, 20, 24},
+ {460, 183, 20, 24},
+ {460, 183, 20, 24},
+ {480, 183, 30, 24},
+ {480, 183, 30, 24},
+ {510, 183, 16, 24},
+ {526, 183, 20, 24},
+ {546, 183, 16, 24},
+ {562, 183, 23, 24},
+ {585, 183, 23, 24},
+ {608, 183, 23, 24},
+ {631, 183, 23, 24},
+ {654, 183, 23, 24},
+ {677, 183, 23, 24},
+ {700, 183, 23, 24},
+ {723, 183, 23, 24},
+ {746, 183, 23, 24},
+ {769, 183, 23, 24},
+ {792, 183, 23, 24},
+ {815, 183, 23, 24},
+ {838, 183, 23, 24},
+ {861, 183, 16, 24},
+ {877, 183, 16, 24},
+ {893, 183, 16, 24},
+ {909, 183, 16, 24},
+ {925, 183, 16, 24},
+ {941, 183, 16, 24},
+ {957, 183, 16, 24},
+ {973, 183, 16, 24},
+ {989, 183, 16, 24},
+ {1005, 183, 16, 24},
+ {0, 207, 20, 24},
+ {20, 207, 16, 24},
+ {36, 207, 16, 24},
+ {52, 207, 16, 24},
+ {68, 207, 16, 24},
+ {84, 207, 16, 24},
+ {100, 207, 16, 24},
+ {116, 207, 16, 24},
+ {132, 207, 16, 24},
+ {148, 207, 16, 24},
+ {164, 207, 16, 24},
+ {180, 207, 16, 24},
+ {196, 207, 16, 24},
+ {212, 207, 16, 24},
+ {228, 207, 16, 24},
+ {244, 207, 16, 24},
+ {260, 207, 16, 24},
+ {276, 207, 16, 24},
+ {292, 207, 16, 24},
+ {308, 207, 16, 24},
+ {324, 207, 16, 24},
+ {340, 207, 20, 24},
+ {360, 207, 16, 24},
+ {376, 207, 16, 24},
+ {392, 207, 20, 24},
+ {412, 207, 20, 24},
+ {432, 207, 20, 24},
+ {452, 207, 20, 24},
+ {472, 207, 20, 24},
+ {492, 207, 16, 24},
+ {508, 207, 20, 24},
+ {528, 207, 20, 24},
+ {548, 207, 20, 24},
+ {568, 207, 16, 24},
+ {584, 207, 23, 24},
+ {607, 207, 23, 24},
+ {630, 207, 23, 24},
+ {653, 207, 23, 24},
+ {676, 207, 16, 24},
+ {692, 207, 16, 24},
+ {708, 207, 16, 24},
+ {724, 207, 16, 24},
+ {740, 207, 16, 24},
+ {756, 207, 16, 24},
+ {772, 207, 16, 24},
+ {788, 207, 16, 24},
+ {804, 207, 16, 24},
+ {820, 207, 23, 24},
+ {843, 207, 23, 24},
+ {866, 207, 23, 24},
+ {889, 207, 23, 24},
+ {912, 207, 23, 24},
+ {935, 207, 23, 24},
+ {958, 207, 23, 24},
+ {981, 207, 20, 24},
+ {1001, 207, 20, 24},
+ {0, 231, 23, 21},
+ {23, 231, 23, 21},
+ {46, 231, 23, 21},
+ {69, 231, 23, 21},
+ {92, 231, 23, 21},
+ {115, 231, 23, 21},
+ {138, 231, 23, 21},
+ {161, 231, 23, 21},
+ {184, 231, 23, 21},
+ {207, 231, 23, 21},
+ {230, 231, 23, 21},
+ {253, 231, 23, 21},
+ {276, 231, 23, 21},
+ {299, 231, 23, 21},
+ {322, 231, 23, 21},
+ {345, 231, 23, 21},
+ {368, 231, 23, 21},
+ {391, 231, 23, 21},
+ {414, 231, 23, 21},
+ {437, 231, 23, 21},
+ {460, 231, 23, 21},
+ {483, 231, 23, 21},
+ {506, 231, 23, 21},
+ {529, 231, 23, 21},
+ {552, 231, 23, 21},
+ {575, 231, 23, 21},
+ {598, 231, 23, 21},
+ {621, 231, 23, 21},
+ {644, 231, 23, 21},
+ {667, 231, 23, 21},
+ {690, 231, 23, 21},
+ {713, 231, 23, 21},
+ {736, 231, 23, 21},
+ {759, 231, 23, 21},
+ {782, 231, 23, 21},
+ {805, 231, 23, 21},
+ {828, 231, 23, 21},
+ {851, 231, 23, 21},
+ {874, 231, 23, 21},
+ {897, 231, 23, 21},
+ {920, 231, 23, 21},
+ {943, 231, 23, 21},
+ {966, 231, 23, 21},
+ {989, 231, 23, 21},
+ {0, 252, 23, 21},
+ {23, 252, 23, 21},
+ {46, 252, 23, 21},
+ {69, 252, 23, 21},
+ {92, 252, 23, 21},
+ {115, 252, 23, 21},
+ {138, 252, 23, 21},
+ {161, 252, 23, 21},
+ {184, 252, 23, 21},
+ {207, 252, 23, 21},
+ {230, 252, 23, 21},
+ {253, 252, 23, 21},
+ {276, 252, 23, 21},
+ {299, 252, 23, 21},
+ {322, 252, 23, 21},
+ {345, 252, 23, 21},
+ {368, 252, 23, 21},
+ {391, 252, 23, 21},
+ {414, 252, 23, 21},
+ {437, 252, 23, 21},
+ {460, 252, 23, 21},
+ {483, 252, 23, 21},
+ {506, 252, 23, 21},
+ {529, 252, 23, 21},
+ {552, 252, 23, 21},
+ {575, 252, 23, 21},
+ {598, 252, 23, 21},
+ {621, 252, 23, 21},
+ {644, 252, 23, 21},
+ {667, 252, 23, 21},
+ {690, 252, 23, 21},
+ {713, 252, 23, 21},
+ {736, 252, 23, 21},
+ {759, 252, 23, 21},
+ {782, 252, 23, 21},
+ {805, 252, 23, 21},
+ {828, 252, 23, 21},
+ {851, 252, 23, 21},
+ {874, 252, 23, 21},
+ {897, 252, 23, 21},
+ {920, 252, 23, 21},
+ {943, 252, 23, 21},
+ {966, 252, 23, 21},
+ {989, 252, 23, 21},
+ {0, 273, 23, 21},
+ {23, 273, 23, 21},
+ {46, 273, 23, 21},
+ {69, 273, 23, 21},
+ {92, 273, 23, 21},
+ {115, 273, 23, 21},
+ {138, 273, 23, 21},
+ {161, 273, 23, 21},
+ {184, 273, 23, 21},
+ {207, 273, 23, 21},
+ {230, 273, 23, 21},
+ {253, 273, 23, 21},
+ {276, 273, 23, 21},
+ {299, 273, 23, 21},
+ {322, 273, 23, 21},
+ {345, 273, 23, 21},
+ {368, 273, 23, 21},
+ {391, 273, 23, 21},
+ {414, 273, 23, 21},
+ {437, 273, 23, 21},
+ {460, 273, 23, 21},
+ {483, 273, 23, 21},
+ {506, 273, 23, 21},
+ {529, 273, 23, 21},
+ {552, 273, 23, 21},
+ {575, 273, 23, 21},
+ {598, 273, 23, 21},
+ {621, 273, 23, 21},
+ {644, 273, 23, 21},
+ {667, 273, 23, 21},
+ {690, 273, 23, 21},
+ {713, 273, 23, 21},
+ {736, 273, 23, 21},
+ {759, 273, 23, 21},
+ {782, 273, 23, 21},
+ {805, 273, 23, 21},
+ {828, 273, 23, 21},
+ {851, 273, 23, 21},
+ {874, 273, 23, 21},
+ {897, 273, 23, 21},
+ {920, 273, 23, 21},
+ {943, 273, 23, 21},
+ {966, 273, 23, 21},
+ {989, 273, 23, 21},
+ {0, 294, 23, 21},
+ {23, 294, 23, 21},
+ {46, 294, 23, 21},
+ {69, 294, 23, 21},
+ {92, 294, 23, 21},
+ {115, 294, 23, 21},
+ {138, 294, 23, 21},
+ {161, 294, 23, 21},
+ {184, 294, 23, 21},
+ {207, 294, 23, 21},
+ {230, 294, 23, 21},
+ {253, 294, 23, 21},
+ {276, 294, 23, 21},
+ {299, 294, 23, 21},
+ {322, 294, 23, 21},
+ {345, 294, 23, 21},
+ {368, 294, 23, 21},
+ {391, 294, 23, 21},
+ {414, 294, 23, 21},
+ {437, 294, 23, 21},
+ {460, 294, 23, 21},
+ {483, 294, 23, 21},
+ {506, 294, 23, 21},
+ {529, 294, 23, 21},
+ {552, 294, 23, 21},
+ {575, 294, 23, 21},
+ {598, 294, 23, 21},
+ {621, 294, 23, 21},
+ {644, 294, 23, 21},
+ {667, 294, 23, 21},
+ {690, 294, 23, 21},
+ {713, 294, 23, 21},
+ {736, 294, 23, 21},
+ {759, 294, 23, 21},
+ {782, 294, 23, 21},
+ {805, 294, 23, 21},
+ {828, 294, 23, 21},
+ {851, 294, 23, 21},
+ {874, 294, 23, 21},
+ {897, 294, 23, 21},
+ {920, 294, 23, 21},
+ {943, 294, 23, 21},
+ {966, 294, 20, 21},
+ {986, 294, 20, 21},
+ {0, 315, 20, 29},
+ {20, 315, 20, 29},
+ {40, 315, 20, 29},
+ {60, 315, 20, 29},
+ {80, 315, 20, 29},
+ {100, 315, 20, 29},
+ {120, 315, 20, 29},
+ {140, 315, 20, 29},
+ {160, 315, 20, 29},
+ {180, 315, 20, 29},
+ {200, 315, 20, 29},
+ {220, 315, 20, 29},
+ {240, 315, 20, 29},
+ {260, 315, 20, 29},
+ {280, 315, 20, 29},
+ {300, 315, 20, 29},
+ {320, 315, 20, 29},
+ {340, 315, 20, 29},
+ {360, 315, 20, 29},
+ {380, 315, 20, 29},
+ {400, 315, 20, 29},
+ {420, 315, 20, 29},
+ {440, 315, 20, 29},
+ {460, 315, 20, 29},
+ {480, 315, 20, 29},
+ {500, 315, 20, 29},
+ {520, 315, 20, 29},
+ {540, 315, 20, 29},
+ {560, 315, 20, 29},
+ {580, 315, 20, 29},
+ {600, 315, 20, 29},
+ {620, 315, 11, 29},
+ {631, 315, 11, 29},
+ {642, 315, 14, 29},
+ {656, 315, 19, 29},
+ {675, 315, 17, 29},
+ {692, 315, 18, 29},
+ {710, 315, 18, 29},
+ {728, 315, 20, 29},
+ {748, 315, 18, 29},
+ {766, 315, 18, 29},
+ {784, 315, 18, 29},
+ {802, 315, 17, 29},
+ {819, 315, 20, 29},
+ {839, 315, 20, 29},
+ {859, 315, 20, 29},
+ {879, 315, 20, 29},
+ {899, 315, 20, 29},
+ {919, 315, 20, 29},
+ {939, 315, 20, 29},
+ {959, 315, 20, 29},
+ {979, 315, 20, 29},
+ {999, 315, 12, 29},
+ {0, 344, 20, 18},
+ {20, 344, 20, 18},
+ {40, 344, 20, 18},
+ {60, 344, 20, 18},
+ {80, 344, 20, 18},
+ {100, 344, 20, 18},
+ {120, 344, 20, 18},
+ {140, 344, 20, 18},
+ {160, 344, 20, 18},
+ {180, 344, 20, 18},
+ {200, 344, 20, 18},
+ {220, 344, 20, 18},
+ {240, 344, 20, 18},
+ {260, 344, 20, 18},
+ {280, 344, 20, 18},
+ {300, 344, 20, 18},
+ {320, 344, 20, 18},
+ {340, 344, 20, 18},
+ {360, 344, 20, 18},
+ {380, 344, 20, 18},
+ {400, 344, 20, 18},
+ {420, 344, 20, 18},
+ {440, 344, 20, 18},
+ {460, 344, 20, 18},
+ {480, 344, 20, 18},
+ {500, 344, 20, 18},
+ {520, 344, 20, 18},
+ {540, 344, 20, 18},
+ {560, 344, 20, 18},
+ {580, 344, 20, 18},
+ {600, 344, 20, 18},
+ {620, 344, 20, 18},
+ {640, 344, 20, 18},
+ {660, 344, 20, 18},
+ {680, 344, 20, 18},
+ {700, 344, 20, 18},
+ {720, 344, 20, 18},
+ {740, 344, 20, 18},
+ {760, 344, 20, 18},
+ {780, 344, 20, 18},
+ {800, 344, 20, 18},
+ {820, 344, 20, 18},
+ {840, 344, 20, 18},
+ {860, 344, 20, 18},
+ {880, 344, 20, 18},
+ {900, 344, 20, 18},
+ {920, 344, 20, 18},
+ {940, 344, 20, 18},
+ {960, 344, 20, 18},
+ {980, 344, 20, 18},
+ {1000, 344, 20, 18},
+ {0, 362, 20, 29},
+ {20, 362, 20, 29},
+ {40, 362, 20, 29},
+ {60, 362, 20, 29},
+ {80, 362, 20, 29},
+ {100, 362, 20, 29},
+ {120, 362, 20, 29},
+ {140, 362, 20, 29},
+ {160, 362, 20, 29},
+ {180, 362, 20, 29},
+ {200, 362, 20, 29},
+ {220, 362, 20, 29},
+ {240, 362, 20, 29},
+ {260, 362, 20, 29},
+ {280, 362, 20, 29},
+ {300, 362, 20, 29},
+ {320, 362, 20, 29},
+ {340, 362, 20, 29},
+ {360, 362, 20, 29},
+ {380, 362, 17, 29},
+ {397, 362, 20, 29},
+ {417, 362, 20, 29},
+ {437, 362, 20, 29},
+ {457, 362, 20, 29},
+ {477, 362, 20, 29},
+ {497, 362, 20, 29},
+ {517, 362, 20, 29},
+ {537, 362, 20, 29},
+ {557, 362, 20, 29},
+ {577, 362, 20, 29},
+ {597, 362, 20, 29},
+ {617, 362, 20, 29},
+ {637, 362, 20, 29},
+ {657, 362, 20, 29},
+ {677, 362, 20, 29},
+ {697, 362, 20, 29},
+ {717, 362, 20, 29},
+ {737, 362, 20, 29},
+ {757, 362, 20, 29},
+ {777, 362, 20, 29},
+ {797, 362, 20, 29},
+ {817, 362, 20, 29},
+ {837, 362, 17, 29},
+ {854, 362, 14, 29},
+ {868, 362, 10, 29},
+ {878, 362, 12, 29},
+ {890, 362, 17, 29},
+ {907, 362, 9, 29},
+ {916, 362, 9, 29},
+ {925, 362, 18, 29},
+ {943, 362, 16, 29},
+ {959, 362, 15, 29},
+ {974, 362, 18, 29},
+ {992, 362, 18, 29},
+ {0, 391, 20, 29},
+ {20, 391, 20, 29},
+ {40, 391, 20, 29},
+ {60, 391, 20, 29},
+ {80, 391, 20, 29},
+ {100, 391, 20, 29},
+ {120, 391, 20, 29},
+ {140, 391, 20, 29},
+ {160, 391, 20, 29},
+ {180, 391, 20, 29},
+ {200, 391, 20, 29},
+ {220, 391, 20, 29},
+ {240, 391, 20, 29},
+ {260, 391, 20, 29},
+ {280, 391, 20, 29},
+ {300, 391, 20, 29},
+ {320, 391, 20, 29},
+ {340, 391, 20, 29},
+ {360, 391, 20, 29},
+ {380, 391, 20, 29},
+ {400, 391, 20, 29},
+ {420, 391, 20, 29},
+ {440, 391, 20, 29},
+ {460, 391, 20, 29},
+ {480, 391, 20, 29},
+ {500, 391, 20, 29},
+ {520, 391, 20, 29},
+ {540, 391, 20, 29},
+ {560, 391, 20, 29},
+ {580, 391, 20, 29},
+ {600, 391, 20, 29},
+ {620, 391, 20, 29},
+ {640, 391, 20, 29},
+ {660, 391, 20, 29},
+ {680, 391, 20, 29},
+ {700, 391, 20, 29},
+ {720, 391, 20, 29},
+ {740, 391, 20, 29},
+ {760, 391, 20, 29},
+ {780, 391, 20, 29},
+ {800, 391, 20, 29},
+ {820, 391, 20, 29},
+ {840, 391, 20, 29},
+ {860, 391, 20, 29},
+ {880, 391, 20, 29},
+ {900, 391, 18, 29},
+ {918, 391, 20, 29},
+ {938, 391, 20, 29},
+ {958, 391, 20, 29},
+ {978, 391, 20, 29},
+ {998, 391, 20, 29},
+ {0, 420, 20, 29},
+ {20, 420, 18, 29},
+ {38, 420, 18, 29},
+ {56, 420, 18, 29},
+ {74, 420, 18, 29},
+ {92, 420, 18, 29},
+ {110, 420, 18, 29},
+ {128, 420, 18, 29},
+ {146, 420, 18, 29},
+ {164, 420, 18, 29},
+ {182, 420, 18, 29},
+ {200, 420, 18, 29},
+ {218, 420, 18, 29},
+ {236, 420, 20, 29},
+ {256, 420, 20, 29},
+ {276, 420, 20, 29},
+ {296, 420, 20, 29},
+ {316, 420, 20, 29},
+ {336, 420, 20, 29},
+ {356, 420, 20, 29},
+ {376, 420, 20, 29},
+ {396, 420, 20, 29},
+ {416, 420, 20, 29},
+ {436, 420, 20, 29},
+ {456, 420, 20, 29},
+ {476, 420, 20, 29},
+ {496, 420, 20, 29},
+ {516, 420, 20, 29},
+ {536, 420, 20, 29},
+ {556, 420, 20, 29},
+ {576, 420, 14, 29},
+ {590, 420, 14, 29},
+ {604, 420, 18, 29},
+ {622, 420, 20, 29},
+ {642, 420, 15, 29},
+ {657, 420, 15, 29},
+ {672, 420, 18, 29},
+ {690, 420, 20, 29},
+ {710, 420, 20, 29},
+ {730, 420, 40, 29},
+ {750, 420, 100, 29},
+ {750, 420, 100, 29},
+ {750, 420, 100, 29},
+ {750, 420, 100, 29},
+ {750, 420, 100, 29},
+ {850, 420, 20, 29},
+ {870, 420, 20, 29},
+ {890, 420, 20, 29},
+ {910, 420, 20, 29},
+ {930, 420, 20, 29},
+ {950, 420, 20, 29},
+ {970, 420, 20, 29},
+ {990, 420, 20, 29},
+ {0, 449, 20, 18},
+ {20, 449, 20, 18},
+ {40, 449, 20, 18},
+ {60, 449, 20, 18},
+ {80, 449, 20, 18},
+ {100, 449, 20, 18},
+ {120, 449, 20, 18},
+ {140, 449, 20, 18},
+ {160, 449, 20, 18},
+ {180, 449, 20, 18},
+ {200, 449, 20, 18},
+ {220, 449, 20, 18},
+ {240, 449, 20, 18},
+ {260, 449, 20, 18},
+ {280, 449, 20, 18},
+ {300, 449, 20, 18},
+ {320, 449, 20, 18},
+ {340, 449, 20, 18},
+ {360, 449, 20, 18},
+ {380, 449, 20, 18},
+ {400, 449, 20, 18},
+ {420, 449, 20, 18},
+ {440, 449, 20, 18},
+ {460, 449, 20, 18},
+ {480, 449, 20, 18},
+ {500, 449, 20, 18},
+ {520, 449, 20, 18},
+ {540, 449, 20, 18},
+ {560, 449, 20, 18},
+ {580, 449, 20, 18},
+ {600, 449, 20, 18},
+ {620, 449, 20, 18},
+ {640, 449, 20, 18},
+ {660, 449, 20, 18},
+ {680, 449, 20, 18},
+ {700, 449, 20, 18},
+ {720, 449, 20, 18},
+ {740, 449, 20, 18},
+ {760, 449, 20, 18},
+ {780, 449, 20, 18},
+ {800, 449, 20, 18},
+ {820, 449, 20, 18},
+ {840, 449, 20, 18},
+ {860, 449, 20, 18},
+ {880, 449, 20, 18},
+ {900, 449, 20, 18},
+ {920, 449, 20, 18},
+ {940, 449, 20, 18},
+ {960, 449, 20, 18},
+ {980, 449, 20, 18},
+ {1000, 449, 20, 18},
+ {0, 468, 20, 29},
+ {20, 468, 20, 29},
+ {40, 468, 20, 29},
+ {60, 468, 20, 29},
+ {80, 468, 17, 29},
+ {97, 468, 20, 29},
+ {117, 468, 16, 29},
+ {133, 468, 20, 29},
+ {153, 468, 20, 29},
+ {173, 468, 20, 29},
+ {193, 468, 20, 29},
+ {213, 468, 20, 29},
+ {233, 468, 20, 29},
+ {253, 468, 20, 29},
+ {273, 468, 20, 29},
+ {293, 468, 20, 29},
+ {313, 468, 20, 29},
+ {333, 468, 20, 29},
+ {353, 468, 20, 29},
+ {373, 468, 20, 29},
+ {393, 468, 20, 29},
+ {413, 468, 20, 29},
+ {433, 468, 20, 29},
+ {453, 468, 20, 29},
+ {473, 468, 20, 29},
+ {493, 468, 20, 29},
+ {513, 468, 20, 29},
+ {533, 468, 20, 29},
+ {553, 468, 20, 29},
+ {573, 468, 20, 29},
+ {593, 468, 20, 29},
+ {613, 468, 20, 29},
+ {633, 468, 20, 29},
+ {653, 468, 20, 29},
+ {673, 468, 20, 29},
+ {693, 468, 20, 29},
+ {713, 468, 20, 29},
+ {733, 468, 20, 29},
+ {753, 468, 20, 29},
+ {773, 468, 20, 29},
+ {793, 468, 20, 29},
+ {813, 468, 20, 29},
+ {833, 468, 20, 29},
+ {853, 468, 20, 29},
+ {873, 468, 20, 29},
+ {893, 468, 20, 29},
+ {913, 468, 20, 29},
+ {933, 468, 20, 29},
+ {953, 468, 20, 29},
+ {973, 468, 20, 29},
+ {993, 468, 20, 29},
+ {0, 497, 20, 18},
+ {20, 497, 20, 18},
+ {40, 497, 20, 18},
+ {60, 497, 20, 18},
+ {80, 497, 20, 18},
+ {100, 497, 20, 18},
+ {120, 497, 20, 18},
+ {140, 497, 20, 18},
+ {160, 497, 20, 18},
+ {180, 497, 20, 18},
+ {200, 497, 20, 18},
+ {220, 497, 20, 18},
+ {240, 497, 20, 18},
+ {260, 497, 20, 18},
+ {280, 497, 20, 18},
+ {300, 497, 20, 18},
+ {320, 497, 20, 18},
+ {340, 497, 20, 18},
+ {360, 497, 20, 18},
+ {380, 497, 20, 18},
+ {400, 497, 20, 18},
+ {420, 497, 20, 18},
+ {440, 497, 20, 18},
+ {460, 497, 20, 18},
+ {480, 497, 20, 18},
+ {500, 497, 20, 18},
+ {520, 497, 20, 18},
+ {540, 497, 20, 18},
+ {560, 497, 20, 18},
+ {580, 497, 20, 18},
+ {600, 497, 20, 18},
+ {620, 497, 20, 18},
+ {640, 497, 20, 18},
+ {660, 497, 20, 18},
+ {680, 497, 20, 18},
+ {700, 497, 20, 18},
+ {720, 497, 20, 18},
+ {740, 497, 20, 18},
+ {760, 497, 20, 18},
+ {780, 497, 20, 18},
+ {800, 497, 20, 18},
+ {820, 497, 20, 18},
+ {840, 497, 20, 18},
+ {860, 497, 20, 18},
+ {880, 497, 20, 18},
+ {900, 497, 20, 18},
+ {920, 497, 20, 18},
+ {940, 497, 20, 18},
+ {960, 497, 20, 18},
+ {980, 497, 20, 18},
+ {1000, 497, 20, 18},
+ {0, 516, 20, 18},
+ {20, 516, 20, 18},
+ {40, 516, 20, 18},
+ {60, 516, 20, 18},
+ {80, 516, 20, 18},
+ {100, 516, 20, 18},
+ {120, 516, 20, 18},
+ {140, 516, 20, 18},
+ {160, 516, 20, 18},
+ {180, 516, 20, 18},
+ {200, 516, 20, 18},
+ {220, 516, 20, 18},
+ {240, 516, 20, 18},
+ {260, 516, 20, 18},
+ {280, 516, 20, 18},
+ {300, 516, 20, 18},
+ {320, 516, 20, 18},
+ {340, 516, 20, 18},
+ {360, 516, 20, 18},
+ {380, 516, 20, 18},
+ {400, 516, 20, 18},
+ {420, 516, 20, 18},
+ {440, 516, 20, 18},
+ {460, 516, 20, 18},
+ {480, 516, 20, 18},
+ {500, 516, 20, 18},
+ {520, 516, 20, 18},
+ {540, 516, 20, 18},
+ {560, 516, 20, 18},
+ {580, 516, 20, 18},
+ {600, 516, 20, 18},
+ {620, 516, 20, 18},
+ {640, 516, 20, 18},
+ {660, 516, 20, 18},
+ {680, 516, 20, 18},
+ {700, 516, 20, 18},
+ {720, 516, 20, 18},
+ {740, 516, 20, 18},
+ {760, 516, 20, 18},
+ {780, 516, 20, 18},
+ {800, 516, 20, 18},
+ {820, 516, 20, 18},
+ {840, 516, 20, 18},
+ {860, 516, 20, 18},
+ {880, 516, 20, 18},
+ {900, 516, 20, 18},
+ {920, 516, 20, 18},
+ {940, 516, 20, 18},
+ {960, 516, 20, 18},
+ {980, 516, 20, 18},
+ {1000, 516, 20, 18},
+ {0, 535, 20, 29},
+ {20, 535, 20, 29},
+ {40, 535, 20, 29},
+ {60, 535, 20, 29},
+ {80, 535, 20, 29},
+ {100, 535, 20, 29},
+ {120, 535, 20, 29},
+ {140, 535, 20, 29},
+ {160, 535, 20, 29},
+ {180, 535, 20, 29},
+ {200, 535, 20, 29},
+ {220, 535, 20, 29},
+ {240, 535, 20, 29},
+ {260, 535, 20, 29},
+ {280, 535, 20, 29},
+ {300, 535, 20, 29},
+ {320, 535, 20, 29},
+ {340, 535, 20, 29},
+ {360, 535, 20, 29},
+ {380, 535, 20, 29},
+ {400, 535, 20, 29},
+ {420, 535, 20, 29},
+ {440, 535, 20, 29},
+ {460, 535, 20, 29},
+ {480, 535, 20, 29},
+ {500, 535, 20, 29},
+ {520, 535, 20, 29},
+ {540, 535, 20, 29},
+ {560, 535, 20, 29},
+ {580, 535, 20, 29},
+ {600, 535, 20, 29},
+ {620, 535, 20, 29},
+ {640, 535, 20, 29},
+ {660, 535, 20, 29},
+ {680, 535, 20, 29},
+ {700, 535, 20, 29},
+ {720, 535, 20, 29},
+ {740, 535, 20, 29},
+ {760, 535, 20, 29},
+ {780, 535, 20, 29},
+ {800, 535, 20, 29},
+ {820, 535, 16, 29},
+ {836, 535, 18, 29},
+ {854, 535, 20, 29},
+ {874, 535, 20, 29},
+ {894, 535, 20, 29},
+ {914, 535, 20, 29},
+ {934, 535, 20, 29},
+ {954, 535, 20, 29},
+ {974, 535, 20, 29},
+ {994, 535, 20, 29},
+ {0, 564, 20, 18},
+ {20, 564, 20, 18},
+ {40, 564, 20, 18},
+ {60, 564, 20, 18},
+ {80, 564, 20, 18},
+ {100, 564, 20, 18},
+ {120, 564, 20, 18},
+ {140, 564, 20, 18},
+ {160, 564, 20, 18},
+ {180, 564, 20, 18},
+ {200, 564, 20, 18},
+ {220, 564, 20, 18},
+ {240, 564, 20, 18},
+ {260, 564, 20, 18},
+ {280, 564, 20, 18},
+ {300, 564, 20, 18},
+ {320, 564, 20, 18},
+ {340, 564, 20, 18},
+ {360, 564, 20, 18},
+ {380, 564, 20, 18},
+ {400, 564, 20, 18},
+ {420, 564, 20, 18},
+ {440, 564, 20, 18},
+ {460, 564, 20, 18},
+ {480, 564, 20, 18},
+ {500, 564, 20, 18},
+ {520, 564, 20, 18},
+ {540, 564, 20, 18},
+ {560, 564, 20, 18},
+ {580, 564, 20, 18},
+ {600, 564, 20, 18},
+ {620, 564, 20, 18},
+ {640, 564, 20, 18},
+ {660, 564, 20, 18},
+ {680, 564, 20, 18},
+ {700, 564, 20, 18},
+ {720, 564, 20, 18},
+ {740, 564, 20, 18},
+ {760, 564, 20, 18},
+ {780, 564, 20, 18},
+ {800, 564, 20, 18},
+ {820, 564, 20, 18},
+ {840, 564, 20, 18},
+ {860, 564, 20, 18},
+ {880, 564, 20, 18},
+ {900, 564, 20, 18},
+ {920, 564, 20, 18},
+ {940, 564, 20, 18},
+ {960, 564, 20, 18},
+ {980, 564, 20, 18},
+ {1000, 564, 20, 18},
+ {0, 582, 20, 35},
+ {20, 582, 20, 35},
+ {40, 582, 20, 35},
+ {60, 582, 20, 35},
+ {80, 582, 15, 35},
+ {95, 582, 15, 35},
+ {110, 582, 16, 35},
+ {126, 582, 16, 35},
+ {142, 582, 14, 35},
+ {156, 582, 14, 35},
+ {170, 582, 14, 35},
+ {184, 582, 13, 35},
+ {197, 582, 11, 35},
+ {208, 582, 11, 35},
+ {219, 582, 11, 35},
+ {230, 582, 17, 35},
+ {247, 582, 17, 35},
+ {264, 582, 20, 35},
+ {284, 582, 20, 35},
+ {304, 582, 20, 35},
+ {324, 582, 20, 35},
+ {344, 582, 13, 35},
+ {357, 582, 20, 35},
+ {377, 582, 20, 35},
+ {397, 582, 20, 35},
+ {417, 582, 20, 35},
+ {437, 582, 20, 35},
+ {457, 582, 20, 35},
+ {477, 582, 20, 35},
+ {497, 582, 20, 35},
+ {517, 582, 20, 35},
+ {537, 582, 20, 35},
+ {557, 582, 20, 35},
+ {577, 582, 20, 35},
+ {597, 582, 20, 35},
+ {617, 582, 20, 35},
+ {637, 582, 20, 35},
+ {657, 582, 20, 35},
+ {677, 582, 20, 35},
+ {697, 582, 20, 35},
+ {717, 582, 20, 35},
+ {737, 582, 20, 35},
+ {757, 582, 20, 35},
+ {777, 582, 20, 35},
+ {797, 582, 20, 35},
+ {817, 582, 20, 35},
+ {837, 582, 17, 35},
+ {854, 582, 17, 35},
+ {871, 582, 17, 35},
+ {888, 582, 15, 35},
+ {903, 582, 20, 35},
+ {923, 582, 14, 35},
+ {937, 582, 19, 35},
+ {956, 582, 8, 35},
+ {964, 582, 20, 35},
+ {984, 582, 15, 35},
+ {999, 582, 17, 35},
+ {0, 617, 17, 29},
+ {17, 617, 20, 29},
+ {37, 617, 20, 29},
+ {57, 617, 17, 29},
+ {74, 617, 14, 29},
+ {88, 617, 16, 29},
+ {104, 617, 17, 29},
+ {121, 617, 20, 29},
+ {141, 617, 7, 29},
+ {148, 617, 17, 29},
+ {165, 617, 7, 29},
+ {172, 617, 16, 29},
+ {188, 617, 16, 29},
+ {204, 617, 16, 29},
+ {220, 617, 8, 29},
+ {228, 617, 19, 29},
+ {247, 617, 19, 29},
+ {266, 617, 19, 29},
+ {285, 617, 20, 29},
+ {305, 617, 19, 29},
+ {324, 617, 8, 29},
+ {332, 617, 15, 29},
+ {347, 617, 17, 29},
+ {364, 617, 15, 29},
+ {379, 617, 18, 29},
+ {397, 617, 17, 29},
+ {414, 617, 17, 29},
+ {431, 617, 19, 29},
+ {450, 617, 17, 29},
+ {467, 617, 20, 29},
+ {487, 617, 17, 29},
+ {504, 617, 15, 29},
+ {519, 617, 15, 29},
+ {534, 617, 13, 29},
+ {547, 617, 20, 29},
+ {567, 617, 20, 29},
+ {587, 617, 13, 29},
+ {600, 617, 20, 29},
+ {620, 617, 20, 29},
+ {640, 617, 20, 29},
+ {660, 617, 20, 29},
+ {680, 617, 20, 29},
+ {700, 617, 20, 29},
+ {720, 617, 13, 29},
+ {733, 617, 13, 29},
+ {746, 617, 13, 29},
+ {759, 617, 13, 29},
+ {772, 617, 13, 29},
+ {785, 617, 13, 29},
+ {798, 617, 20, 29},
+ {818, 617, 10, 29},
+ {828, 617, 18, 29},
+ {846, 617, 18, 29},
+ {864, 617, 17, 29},
+ {881, 617, 10, 29},
+ {891, 617, 14, 29},
+ {905, 617, 14, 29},
+ {919, 617, 14, 29},
+ {933, 617, 19, 29},
+ {952, 617, 17, 29},
+ {969, 617, 11, 29},
+ {980, 617, 11, 29},
+ {991, 617, 11, 29},
+ {1002, 617, 11, 29},
+ {0, 646, 21, 29},
+ {21, 646, 16, 29},
+ {37, 646, 17, 29},
+ {54, 646, 15, 29},
+ {69, 646, 15, 29},
+ {84, 646, 15, 29},
+ {99, 646, 13, 29},
+ {112, 646, 13, 29},
+ {125, 646, 13, 29},
+ {138, 646, 17, 29},
+ {155, 646, 17, 29},
+ {172, 646, 17, 29},
+ {189, 646, 16, 29},
+ {205, 646, 16, 29},
+ {221, 646, 20, 29},
+ {241, 646, 18, 29},
+ {259, 646, 16, 29},
+ {275, 646, 11, 29},
+ {286, 646, 12, 29},
+ {298, 646, 12, 29},
+ {310, 646, 15, 29},
+ {325, 646, 12, 29},
+ {337, 646, 12, 29},
+ {349, 646, 15, 29},
+ {364, 646, 13, 29},
+ {377, 646, 13, 29},
+ {390, 646, 16, 29},
+ {406, 646, 13, 29},
+ {419, 646, 13, 29},
+ {432, 646, 16, 29},
+ {448, 646, 14, 29},
+ {462, 646, 13, 29},
+ {475, 646, 13, 29},
+ {488, 646, 17, 29},
+ {505, 646, 11, 29},
+ {516, 646, 15, 29},
+ {531, 646, 15, 29},
+ {546, 646, 14, 29},
+ {560, 646, 12, 29},
+ {572, 646, 20, 29},
+ {592, 646, 20, 29},
+ {612, 646, 13, 29},
+ {625, 646, 16, 29},
+ {641, 646, 16, 29},
+ {657, 646, 13, 29},
+ {670, 646, 16, 29},
+ {686, 646, 18, 29},
+ {704, 646, 16, 29},
+ {720, 646, 17, 29},
+ {737, 646, 16, 29},
+ {753, 646, 16, 29},
+ {769, 646, 16, 29},
+ {785, 646, 16, 29},
+ {801, 646, 18, 29},
+ {819, 646, 18, 29},
+ {837, 646, 20, 29},
+ {857, 646, 21, 29},
+ {878, 646, 17, 29},
+ {895, 646, 17, 29},
+ {912, 646, 20, 29},
+ {932, 646, 20, 29},
+ {952, 646, 19, 29},
+ {971, 646, 19, 29},
+ {990, 646, 15, 29},
+ {1005, 646, 17, 29},
+ {0, 675, 12, 29},
+ {12, 675, 13, 29},
+ {25, 675, 15, 29},
+ {40, 675, 13, 29},
+ {53, 675, 12, 29},
+ {65, 675, 14, 29},
+ {79, 675, 22, 29},
+ {101, 675, 20, 29},
+ {121, 675, 20, 29},
+ {141, 675, 20, 29},
+ {161, 675, 20, 29},
+ {181, 675, 20, 29},
+ {201, 675, 20, 29},
+ {221, 675, 20, 29},
+ {241, 675, 20, 29},
+ {261, 675, 20, 29},
+ {281, 675, 20, 29},
+ {301, 675, 20, 29},
+ {321, 675, 20, 29},
+ {341, 675, 20, 29},
+ {361, 675, 20, 29},
+ {381, 675, 20, 29},
+ {401, 675, 20, 29},
+ {421, 675, 20, 29},
+ {441, 675, 20, 29},
+ {461, 675, 20, 29},
+ {481, 675, 20, 29},
+ {501, 675, 20, 29},
+ {521, 675, 20, 29},
+ {541, 675, 20, 29},
+ {561, 675, 20, 29},
+ {581, 675, 20, 29},
+ {601, 675, 20, 29},
+ {621, 675, 20, 29},
+ {641, 675, 20, 29},
+ {661, 675, 20, 29},
+ {681, 675, 20, 29},
+ {701, 675, 20, 29},
+ {721, 675, 20, 29},
+ {741, 675, 20, 29},
+ {761, 675, 20, 29},
+ {781, 675, 20, 29},
+ {801, 675, 20, 29},
+ {821, 675, 20, 29},
+ {841, 675, 20, 29},
+ {861, 675, 20, 29},
+ {881, 675, 20, 29},
+ {901, 675, 20, 29},
+ {921, 675, 20, 29},
+ {941, 675, 20, 29},
+ {961, 675, 20, 29},
+ {981, 675, 20, 29},
+ {1001, 675, 20, 29},
+ {0, 704, 20, 29},
+ {20, 704, 20, 29},
+ {40, 704, 20, 29},
+ {60, 704, 20, 29},
+ {80, 704, 20, 29},
+ {100, 704, 20, 29},
+ {120, 704, 20, 29},
+ {140, 704, 20, 29},
+ {160, 704, 20, 29},
+ {180, 704, 20, 29},
+ {200, 704, 20, 29},
+ {220, 704, 20, 29},
+ {240, 704, 20, 29},
+ {260, 704, 20, 29},
+ {280, 704, 20, 29},
+ {300, 704, 20, 29},
+ {320, 704, 20, 29},
+ {340, 704, 20, 29},
+ {360, 704, 20, 29},
+ {380, 704, 20, 29},
+ {400, 704, 20, 29},
+ {420, 704, 20, 29},
+ {440, 704, 20, 29},
+ {460, 704, 20, 29},
+ {480, 704, 20, 29},
+ {500, 704, 20, 29},
+ {520, 704, 20, 29},
+ {540, 704, 20, 29},
+ {560, 704, 20, 29},
+ {580, 704, 20, 29},
+ {600, 704, 20, 29},
+ {620, 704, 20, 29},
+ {640, 704, 20, 29},
+ {660, 704, 20, 29},
+ {680, 704, 20, 29},
+ {700, 704, 20, 29},
+ {720, 704, 20, 29},
+ {740, 704, 20, 29},
+ {760, 704, 20, 29},
+ {780, 704, 14, 29},
+ {794, 704, 15, 29},
+ {809, 704, 15, 29},
+ {824, 704, 14, 29},
+ {838, 704, 15, 29},
+ {853, 704, 14, 29},
+ {867, 704, 14, 29},
+ {881, 704, 15, 29},
+ {896, 704, 16, 29},
+ {912, 704, 16, 29},
+ {928, 704, 16, 29},
+ {944, 704, 16, 29},
+ {960, 704, 18, 29},
+ {978, 704, 18, 29},
+ {996, 704, 18, 29},
+ {0, 733, 18, 29},
+ {18, 733, 16, 29},
+ {34, 733, 16, 29},
+ {50, 733, 16, 29},
+ {66, 733, 16, 29},
+ {82, 733, 17, 29},
+ {99, 733, 17, 29},
+ {116, 733, 17, 29},
+ {133, 733, 17, 29},
+ {150, 733, 16, 29},
+ {166, 733, 16, 29},
+ {182, 733, 16, 29},
+ {198, 733, 16, 29},
+ {214, 733, 17, 29},
+ {231, 733, 12, 29},
+ {243, 733, 17, 29},
+ {260, 733, 12, 29},
+ {272, 733, 20, 29},
+ {292, 733, 20, 29},
+ {312, 733, 11, 29},
+ {323, 733, 12, 29},
+ {335, 733, 14, 29},
+ {349, 733, 20, 29},
+ {369, 733, 11, 29},
+ {380, 733, 11, 29},
+ {391, 733, 12, 29},
+ {403, 733, 11, 29},
+ {414, 733, 8, 29},
+ {422, 733, 9, 29},
+ {431, 733, 19, 29},
+ {450, 733, 19, 29},
+ {469, 733, 19, 29},
+ {488, 733, 19, 29},
+ {507, 733, 20, 29},
+ {527, 733, 20, 29},
+ {547, 733, 20, 29},
+ {567, 733, 20, 29},
+ {587, 733, 20, 29},
+ {607, 733, 20, 29},
+ {627, 733, 20, 29},
+ {647, 733, 20, 29},
+ {667, 733, 20, 29},
+ {687, 733, 20, 29},
+ {707, 733, 20, 29},
+ {727, 733, 20, 29},
+ {747, 733, 20, 29},
+ {767, 733, 20, 29},
+ {787, 733, 20, 29},
+ {807, 733, 20, 29},
+ {827, 733, 20, 29},
+ {847, 733, 20, 29},
+ {867, 733, 20, 29},
+ {887, 733, 20, 29},
+ {907, 733, 20, 29},
+ {927, 733, 20, 29},
+ {947, 733, 20, 29},
+ {967, 733, 20, 29},
+ {987, 733, 20, 29},
+ {0, 762, 20, 29},
+ {20, 762, 20, 29},
+ {40, 762, 20, 29},
+ {60, 762, 20, 29},
+ {80, 762, 20, 29},
+ {100, 762, 20, 29},
+ {120, 762, 20, 29},
+ {140, 762, 20, 29},
+ {160, 762, 20, 29},
+ {180, 762, 20, 29},
+ {200, 762, 20, 29},
+ {220, 762, 20, 29},
+ {240, 762, 20, 29},
+ {260, 762, 20, 29},
+ {280, 762, 20, 29},
+ {300, 762, 20, 29},
+ {320, 762, 20, 29},
+ {340, 762, 20, 29},
+ {360, 762, 20, 29},
+ {380, 762, 20, 29},
+ {400, 762, 20, 29},
+ {420, 762, 20, 29},
+ {440, 762, 20, 29},
+ {460, 762, 20, 29},
+ {480, 762, 20, 29},
+ {500, 762, 20, 29},
+ {520, 762, 20, 29},
+ {540, 762, 20, 29},
+ {560, 762, 20, 29},
+ {580, 762, 20, 29},
+ {600, 762, 20, 29},
+ {620, 762, 20, 29},
+ {640, 762, 20, 29},
+ {660, 762, 20, 29},
+ {680, 762, 20, 29},
+ {700, 762, 20, 29},
+ {720, 762, 20, 29},
+ {740, 762, 20, 29},
+ {760, 762, 20, 29},
+ {780, 762, 20, 29},
+ {800, 762, 20, 29},
+ {820, 762, 20, 29},
+ {840, 762, 20, 29},
+ {860, 762, 20, 29},
+ {880, 762, 20, 29},
+ {900, 762, 16, 29},
+ {916, 762, 16, 29},
+ {932, 762, 16, 29},
+ {948, 762, 9, 29},
+ {957, 762, 9, 29},
+ {966, 762, 18, 29},
+ {984, 762, 20, 29},
+ {1004, 762, 16, 29},
+ {0, 791, 13, 35},
+ {13, 791, 17, 35},
+ {30, 791, 20, 35},
+ {50, 791, 20, 35},
+ {70, 791, 20, 35},
+ {90, 791, 23, 35},
+ {113, 791, 23, 35},
+ {136, 791, 20, 35},
+ {156, 791, 20, 35},
+ {176, 791, 20, 35},
+ {196, 791, 23, 35},
+ {219, 791, 23, 35},
+ {242, 791, 23, 35},
+ {265, 791, 23, 35},
+ {288, 791, 23, 35},
+ {311, 791, 23, 35},
+ {334, 791, 23, 35},
+ {357, 791, 23, 35},
+ {380, 791, 16, 35},
+ {396, 791, 14, 35},
+ {410, 791, 11, 35},
+ {421, 791, 18, 35},
+ {439, 791, 18, 35},
+ {457, 791, 17, 35},
+ {474, 791, 11, 35},
+ {485, 791, 15, 35},
+ {500, 791, 16, 35},
+ {516, 791, 18, 35},
+ {534, 791, 12, 35},
+ {546, 791, 20, 35},
+ {566, 791, 20, 35},
+ {586, 791, 23, 35},
+ {609, 791, 23, 35},
+ {632, 791, 23, 35},
+ {655, 791, 17, 35},
+ {672, 791, 15, 35},
+ {687, 791, 18, 35},
+ {705, 791, 18, 35},
+ {723, 791, 20, 35},
+ {743, 791, 20, 35},
+ {763, 791, 20, 35},
+ {783, 791, 20, 35},
+ {803, 791, 20, 35},
+ {823, 791, 20, 35},
+ {843, 791, 20, 35},
+ {863, 791, 20, 35},
+ {883, 791, 20, 35},
+ {903, 791, 23, 35},
+ {926, 791, 23, 35},
+ {949, 791, 23, 35},
+ {972, 791, 18, 35},
+ {990, 791, 14, 35},
+ {1004, 791, 14, 35},
+ {0, 826, 14, 34},
+ {14, 826, 14, 34},
+ {28, 826, 18, 34},
+ {46, 826, 19, 34},
+ {65, 826, 17, 34},
+ {82, 826, 11, 34},
+ {93, 826, 13, 34},
+ {106, 826, 13, 34},
+ {119, 826, 13, 34},
+ {132, 826, 8, 34},
+ {140, 826, 11, 34},
+ {151, 826, 11, 34},
+ {162, 826, 14, 34},
+ {176, 826, 14, 34},
+ {190, 826, 11, 34},
+ {201, 826, 15, 34},
+ {216, 826, 18, 34},
+ {234, 826, 13, 34},
+ {247, 826, 13, 34},
+ {260, 826, 13, 34},
+ {273, 826, 13, 34},
+ {286, 826, 9, 34},
+ {295, 826, 19, 34},
+ {314, 826, 16, 34},
+ {330, 826, 15, 34},
+ {345, 826, 18, 34},
+ {363, 826, 16, 34},
+ {379, 826, 10, 34},
+ {389, 826, 10, 34},
+ {399, 826, 10, 34},
+ {409, 826, 15, 34},
+ {424, 826, 10, 34},
+ {434, 826, 6, 34},
+ {440, 826, 22, 34},
+ {462, 826, 8, 34},
+ {470, 826, 8, 34},
+ {478, 826, 8, 34},
+ {486, 826, 13, 34},
+ {499, 826, 12, 34},
+ {511, 826, 12, 34},
+ {523, 826, 10, 34},
+ {533, 826, 10, 34},
+ {543, 826, 8, 34},
+ {551, 826, 7, 34},
+ {558, 826, 8, 34},
+ {566, 826, 10, 34},
+ {576, 826, 8, 34},
+ {584, 826, 15, 34},
+ {599, 826, 17, 34},
+ {616, 826, 10, 34},
+ {626, 826, 10, 34},
+ {636, 826, 13, 34},
+ {649, 826, 11, 34},
+ {660, 826, 15, 34},
+ {675, 826, 12, 34},
+ {687, 826, 15, 34},
+ {702, 826, 10, 34},
+ {712, 826, 15, 34},
+ {727, 826, 15, 34},
+ {742, 826, 14, 34},
+ {756, 826, 8, 34},
+ {764, 826, 15, 34},
+ {779, 826, 11, 34},
+ {790, 826, 11, 34},
+ {801, 826, 14, 34},
+ {815, 826, 16, 34},
+ {831, 826, 8, 34},
+ {839, 826, 13, 34},
+ {852, 826, 23, 34},
+ {875, 826, 16, 34},
+ {891, 826, 15, 34},
+ {906, 826, 13, 34},
+ {919, 826, 7, 34},
+ {926, 826, 9, 34},
+ {935, 826, 9, 34},
+ {944, 826, 12, 34},
+ {956, 826, 9, 34},
+ {965, 826, 20, 34},
+ {985, 826, 15, 34},
+ {1000, 826, 15, 34},
+ {0, 860, 14, 35},
+ {14, 860, 11, 35},
+ {25, 860, 13, 35},
+ {38, 860, 15, 35},
+ {53, 860, 13, 35},
+ {66, 860, 9, 35},
+ {75, 860, 17, 35},
+ {92, 860, 17, 35},
+ {109, 860, 16, 35},
+ {125, 860, 19, 35},
+ {144, 860, 15, 35},
+ {159, 860, 16, 35},
+ {175, 860, 16, 35},
+ {191, 860, 22, 35},
+ {213, 860, 12, 35},
+ {225, 860, 14, 35},
+ {239, 860, 13, 35},
+ {252, 860, 15, 35},
+ {267, 860, 10, 35},
+ {277, 860, 11, 35},
+ {288, 860, 12, 35},
+ {300, 860, 11, 35},
+ {311, 860, 13, 35},
+ {324, 860, 18, 35},
+ {342, 860, 17, 35},
+ {359, 860, 15, 35},
+ {374, 860, 9, 35},
+ {383, 860, 15, 35},
+ {398, 860, 13, 35},
+ {411, 860, 15, 35},
+ {426, 860, 13, 35},
+ {439, 860, 16, 35},
+ {455, 860, 17, 35},
+ {472, 860, 23, 35},
+ {495, 860, 23, 35},
+ {518, 860, 23, 35},
+ {541, 860, 23, 35},
+ {564, 860, 23, 35},
+ {587, 860, 23, 35},
+ {610, 860, 23, 35},
+ {633, 860, 23, 35},
+ {656, 860, 23, 35},
+ {679, 860, 23, 35},
+ {702, 860, 23, 35},
+ {725, 860, 23, 35},
+ {748, 860, 8, 35},
+ {756, 860, 14, 35},
+ {770, 860, 8, 35},
+ {778, 860, 14, 35},
+ {792, 860, 6, 35},
+ {798, 860, 14, 35},
+ {812, 860, 14, 35},
+ {826, 860, 14, 35},
+ {840, 860, 14, 35},
+ {854, 860, 14, 35},
+ {868, 860, 14, 35},
+ {882, 860, 14, 35},
+ {896, 860, 4, 35},
+ {900, 860, 5, 35},
+ {905, 860, 13, 35},
+ {918, 860, 13, 35},
+ {931, 860, 13, 35},
+ {944, 860, 13, 35},
+ {957, 860, 13, 35},
+ {970, 860, 13, 35},
+ {983, 860, 13, 35},
+ {996, 860, 13, 35},
+ {1009, 860, 13, 35},
+ {0, 895, 4, 29},
+ {4, 895, 5, 29},
+ {9, 895, 10, 29},
+ {19, 895, 18, 29},
+ {37, 895, 18, 29},
+ {55, 895, 18, 29},
+ {73, 895, 3, 29},
+ {76, 895, 4, 29},
+ {80, 895, 7, 29},
+ {87, 895, 12, 29},
+ {99, 895, 14, 29},
+ {113, 895, 14, 29},
+ {127, 895, 14, 29},
+ {141, 895, 14, 29},
+ {155, 895, 14, 29},
+ {169, 895, 14, 29},
+ {183, 895, 14, 29},
+ {197, 895, 11, 29},
+ {208, 895, 11, 29},
+ {219, 895, 11, 29},
+ {230, 895, 11, 29},
+ {241, 895, 12, 29},
+ {253, 895, 12, 29},
+ {265, 895, 12, 29},
+ {277, 895, 13, 29},
+ {290, 895, 13, 29},
+ {303, 895, 14, 29},
+ {317, 895, 14, 29},
+ {331, 895, 14, 29},
+ {345, 895, 14, 29},
+ {359, 895, 13, 29},
+ {372, 895, 13, 29},
+ {385, 895, 13, 29},
+ {398, 895, 13, 29},
+ {411, 895, 13, 29},
+ {424, 895, 13, 29},
+ {437, 895, 14, 29},
+ {451, 895, 14, 29},
+ {465, 895, 14, 29},
+ {479, 895, 14, 29},
+ {493, 895, 14, 29},
+ {507, 895, 12, 29},
+ {519, 895, 12, 29},
+ {531, 895, 12, 29},
+ {543, 895, 12, 29},
+ {555, 895, 14, 29},
+ {569, 895, 14, 29},
+ {583, 895, 14, 29},
+ {597, 895, 14, 29},
+ {611, 895, 14, 29},
+ {625, 895, 13, 29},
+ {638, 895, 13, 29},
+ {651, 895, 12, 29},
+ {663, 895, 12, 29},
+ {675, 895, 12, 29},
+ {687, 895, 14, 29},
+ {701, 895, 13, 29},
+ {714, 895, 14, 29},
+ {728, 895, 14, 29},
+ {742, 895, 15, 29},
+ {757, 895, 15, 29},
+ {772, 895, 15, 29},
+ {787, 895, 23, 29},
+ {810, 895, 23, 29},
+ {833, 895, 23, 29},
+ {856, 895, 23, 29},
+ {879, 895, 23, 29},
+ {902, 895, 23, 29},
+ {925, 895, 23, 29},
+ {948, 895, 23, 29},
+ {971, 895, 23, 29},
+ {994, 895, 23, 29},
+ {0, 924, 23, 29},
+ {23, 924, 20, 29},
+ {43, 924, 20, 29},
+ {63, 924, 20, 29},
+ {83, 924, 20, 29},
+ {103, 924, 20, 29},
+ {123, 924, 20, 29},
+ {143, 924, 20, 29},
+ {163, 924, 20, 29},
+ {183, 924, 20, 29},
+ {203, 924, 20, 29},
+ {223, 924, 20, 29},
+ {243, 924, 20, 29},
+ {263, 924, 23, 29},
+ {286, 924, 23, 29},
+ {309, 924, 23, 29},
+ {332, 924, 23, 29},
+ {355, 924, 23, 29},
+ {378, 924, 23, 29},
+ {401, 924, 23, 29},
+ {424, 924, 23, 29},
+ {447, 924, 23, 29},
+ {470, 924, 23, 29},
+ {493, 924, 23, 29},
+ {516, 924, 23, 29},
+ {539, 924, 23, 29},
+ {562, 924, 23, 29},
+ {585, 924, 23, 29},
+ {608, 924, 23, 29},
+ {631, 924, 23, 29},
+ {654, 924, 23, 29},
+ {677, 924, 23, 29},
+ {700, 924, 23, 29},
+ {723, 924, 13, 29},
+ {736, 924, 6, 29},
+ {742, 924, 13, 29},
+ {755, 924, 6, 29},
+ {761, 924, 13, 29},
+ {774, 924, 9, 29},
+ {783, 924, 13, 29},
+ {796, 924, 9, 29},
+ {805, 924, 15, 29},
+ {820, 924, 13, 29},
+ {833, 924, 15, 29},
+ {848, 924, 13, 29},
+ {861, 924, 23, 29},
+ {884, 924, 23, 29},
+ {907, 924, 23, 29},
+ {930, 924, 23, 29},
+ {953, 924, 14, 29},
+ {967, 924, 6, 29},
+ {973, 924, 14, 29},
+ {987, 924, 6, 29},
+ {993, 924, 14, 29},
+ {1007, 924, 7, 29},
+ {0, 953, 14, 29},
+ {14, 953, 7, 29},
+ {21, 953, 14, 29},
+ {35, 953, 8, 29},
+ {43, 953, 14, 29},
+ {57, 953, 8, 29},
+ {65, 953, 14, 29},
+ {79, 953, 10, 29},
+ {89, 953, 14, 29},
+ {103, 953, 10, 29},
+ {113, 953, 14, 29},
+ {127, 953, 9, 29},
+ {136, 953, 14, 29},
+ {150, 953, 9, 29},
+ {159, 953, 13, 29},
+ {172, 953, 9, 29},
+ {181, 953, 13, 29},
+ {194, 953, 9, 29},
+ {203, 953, 13, 29},
+ {216, 953, 9, 29},
+ {225, 953, 13, 29},
+ {238, 953, 9, 29},
+ {247, 953, 13, 29},
+ {260, 953, 11, 29},
+ {271, 953, 13, 29},
+ {284, 953, 11, 29},
+ {295, 953, 16, 29},
+ {311, 953, 11, 29},
+ {322, 953, 16, 29},
+ {338, 953, 11, 29},
+ {349, 953, 13, 29},
+ {362, 953, 9, 29},
+ {371, 953, 13, 29},
+ {384, 953, 9, 29},
+ {393, 953, 8, 29},
+ {401, 953, 10, 29},
+ {411, 953, 8, 29},
+ {419, 953, 10, 29},
+ {429, 953, 6, 29},
+ {435, 953, 13, 29},
+ {448, 953, 6, 29},
+ {454, 953, 13, 29},
+ {467, 953, 9, 29},
+ {476, 953, 16, 29},
+ {492, 953, 9, 29},
+ {501, 953, 16, 29},
+ {517, 953, 17, 29},
+ {534, 953, 16, 29},
+ {550, 953, 17, 29},
+ {567, 953, 16, 29},
+ {583, 953, 23, 29},
+ {606, 953, 23, 29},
+ {629, 953, 23, 29},
+ {652, 953, 23, 29},
+ {675, 953, 23, 29},
+ {698, 953, 23, 29},
+ {721, 953, 23, 29},
+ {744, 953, 23, 29},
+ {767, 953, 13, 29},
+ {780, 953, 8, 29},
+ {788, 953, 13, 29},
+ {801, 953, 8, 29},
+ {809, 953, 11, 29},
+ {820, 953, 11, 29},
+ {831, 953, 11, 29},
+ {842, 953, 11, 29},
+ {853, 953, 17, 29},
+ {870, 953, 8, 29},
+ {878, 953, 23, 29},
+ {901, 953, 23, 29},
+ {924, 953, 23, 29},
+ {947, 953, 23, 29},
+ {970, 953, 23, 29},
+ {993, 953, 23, 29},
+ {0, 982, 13, 29},
+ {13, 982, 11, 29},
+ {24, 982, 13, 29},
+ {37, 982, 11, 29},
+ {48, 982, 10, 29},
+ {58, 982, 10, 29},
+ {68, 982, 10, 29},
+ {78, 982, 10, 29},
+ {88, 982, 13, 29},
+ {101, 982, 11, 29},
+ {112, 982, 13, 29},
+ {125, 982, 11, 29},
+ {136, 982, 10, 29},
+ {146, 982, 10, 29},
+ {156, 982, 10, 29},
+ {166, 982, 10, 29},
+ {176, 982, 13, 29},
+ {189, 982, 11, 29},
+ {200, 982, 13, 29},
+ {213, 982, 11, 29},
+ {224, 982, 11, 29},
+ {235, 982, 11, 29},
+ {246, 982, 11, 29},
+ {257, 982, 11, 29},
+ {268, 982, 13, 29},
+ {281, 982, 11, 29},
+ {292, 982, 13, 29},
+ {305, 982, 11, 29},
+ {316, 982, 11, 29},
+ {327, 982, 11, 29},
+ {338, 982, 11, 29},
+ {349, 982, 11, 29},
+ {360, 982, 13, 29},
+ {373, 982, 11, 29},
+ {384, 982, 13, 29},
+ {397, 982, 11, 29},
+ {408, 982, 12, 29},
+ {420, 982, 12, 29},
+ {432, 982, 12, 29},
+ {444, 982, 12, 29},
+ {456, 982, 23, 29},
+ {479, 982, 23, 29},
+ {502, 982, 23, 29},
+ {525, 982, 23, 29},
+ {548, 982, 23, 29},
+ {571, 982, 23, 29},
+ {594, 982, 23, 29},
+ {617, 982, 23, 29},
+ {640, 982, 6, 29},
+ {646, 982, 9, 29},
+ {655, 982, 6, 29},
+ {661, 982, 9, 29},
+ {670, 982, 9, 29},
+ {679, 982, 13, 29},
+ {692, 982, 9, 29},
+ {701, 982, 13, 29},
+ {714, 982, 13, 29},
+ {727, 982, 8, 29},
+ {735, 982, 13, 29},
+ {748, 982, 8, 29},
+ {756, 982, 7, 29},
+ {763, 982, 5, 29},
+ {768, 982, 4, 29},
+ {772, 982, 4, 29},
+ {776, 982, 16, 29},
+ {792, 982, 16, 29},
+ {808, 982, 16, 29},
+ {824, 982, 16, 29},
+ {840, 982, 16, 29},
+ {856, 982, 16, 29},
+ {872, 982, 16, 29},
+ {888, 982, 16, 29},
+ {904, 982, 16, 29},
+ {920, 982, 16, 29},
+ {936, 982, 16, 29},
+ {952, 982, 16, 29},
+ {968, 982, 7, 29},
+ {975, 982, 6, 29},
+ {981, 982, 23, 29},
+ {0, 1011, 23, 21},
+ {23, 1011, 23, 21},
+ {46, 1011, 23, 21},
+ {69, 1011, 23, 21},
+ {92, 1011, 23, 21},
+ {115, 1011, 23, 21},
+ {138, 1011, 23, 21},
+ {161, 1011, 23, 21},
+ {184, 1011, 23, 21},
+ {207, 1011, 23, 21},
+ {230, 1011, 23, 21},
+ {253, 1011, 23, 21},
+ {276, 1011, 23, 21},
+ {299, 1011, 23, 21},
+ {322, 1011, 23, 21},
+ {345, 1011, 23, 21},
+ {368, 1011, 23, 21},
+ {391, 1011, 23, 21},
+ {414, 1011, 23, 21},
+ {437, 1011, 23, 21},
+ {460, 1011, 23, 21},
+ {483, 1011, 23, 21},
+ {506, 1011, 23, 21},
+ {529, 1011, 23, 21},
+ {552, 1011, 23, 21},
+ {575, 1011, 23, 21},
+ {598, 1011, 23, 21},
+ {621, 1011, 23, 21},
+ {644, 1011, 23, 21},
+ {667, 1011, 23, 21},
+ {690, 1011, 23, 21},
+ {713, 1011, 23, 21},
+ {736, 1011, 23, 21},
+ {759, 1011, 23, 21},
+ {782, 1011, 23, 21},
+ {805, 1011, 23, 21},
+ {828, 1011, 23, 21},
+ {851, 1011, 23, 21},
+ {874, 1011, 23, 21},
+ {897, 1011, 23, 21},
+ {920, 1011, 23, 21},
+ {943, 1011, 23, 21},
+ {966, 1011, 23, 21},
+ {989, 1011, 23, 21},
+ {0, 1032, 23, 22},
+ {23, 1032, 23, 22},
+ {46, 1032, 23, 22},
+ {69, 1032, 23, 22},
+ {92, 1032, 23, 22},
+ {115, 1032, 23, 22},
+ {138, 1032, 23, 22},
+ {161, 1032, 23, 22},
+ {184, 1032, 23, 22},
+ {207, 1032, 23, 22},
+ {230, 1032, 23, 22},
+ {253, 1032, 23, 22},
+ {276, 1032, 23, 22},
+ {299, 1032, 23, 22},
+ {322, 1032, 23, 22},
+ {345, 1032, 23, 22},
+ {368, 1032, 23, 22},
+ {391, 1032, 23, 22},
+ {414, 1032, 23, 22},
+ {437, 1032, 23, 22},
+ {460, 1032, 23, 22},
+ {483, 1032, 23, 22},
+ {506, 1032, 23, 22},
+ {529, 1032, 23, 22},
+ {552, 1032, 23, 22},
+ {575, 1032, 23, 22},
+ {598, 1032, 23, 22},
+ {621, 1032, 23, 22},
+ {644, 1032, 23, 22},
+ {667, 1032, 23, 22},
+ {690, 1032, 23, 22},
+ {713, 1032, 23, 22},
+ {736, 1032, 23, 22},
+ {759, 1032, 23, 22},
+ {782, 1032, 23, 22},
+ {805, 1032, 23, 22},
+ {828, 1032, 23, 22},
+ {851, 1032, 23, 22},
+ {874, 1032, 23, 22},
+ {897, 1032, 23, 22},
+ {920, 1032, 23, 22},
+ {943, 1032, 23, 22},
+ {966, 1032, 23, 22},
+ {989, 1032, 23, 22},
+ {0, 1054, 23, 21},
+ {23, 1054, 23, 21},
+ {46, 1054, 23, 21},
+ {69, 1054, 23, 21},
+ {92, 1054, 23, 21},
+ {115, 1054, 20, 21},
+ {135, 1054, 20, 21},
+ {155, 1054, 20, 21},
+ {175, 1054, 20, 21},
+ {195, 1054, 20, 21},
+ {215, 1054, 20, 21},
+ {235, 1054, 20, 21},
+ {255, 1054, 20, 21},
+ {275, 1054, 20, 21},
+ {295, 1054, 20, 21},
+ {315, 1054, 20, 21},
+ {335, 1054, 20, 21},
+ {355, 1054, 20, 21},
+ {375, 1054, 20, 21},
+ {395, 1054, 20, 21},
+ {415, 1054, 20, 21},
+ {435, 1054, 20, 21},
+ {455, 1054, 20, 21},
+ {475, 1054, 20, 21},
+ {495, 1054, 20, 21},
+ {515, 1054, 20, 21},
+ {535, 1054, 20, 21},
+ {555, 1054, 20, 21},
+ {575, 1054, 20, 21},
+ {595, 1054, 20, 21},
+ {615, 1054, 20, 21},
+ {635, 1054, 20, 21},
+ {655, 1054, 20, 21},
+ {675, 1054, 20, 21},
+ {695, 1054, 20, 21},
+ {715, 1054, 20, 21},
+ {735, 1054, 20, 21},
+ {755, 1054, 20, 21},
+ {775, 1054, 20, 21},
+ {795, 1054, 20, 21},
+ {815, 1054, 20, 21},
+ {835, 1054, 20, 21},
+ {855, 1054, 20, 21},
+ {875, 1054, 20, 21},
+ {895, 1054, 20, 21},
+ {915, 1054, 20, 21},
+ {935, 1054, 20, 21},
+ {955, 1054, 20, 21},
+ {975, 1054, 20, 21},
+ {995, 1054, 20, 21},
+ {0, 1075, 20, 29},
+ {20, 1075, 20, 29},
+ {40, 1075, 14, 29},
+ {54, 1075, 20, 29},
+ {74, 1075, 20, 29},
+ {94, 1075, 20, 29},
+ {114, 1075, 20, 29},
+ {134, 1075, 20, 29},
+ {154, 1075, 20, 29},
+ {174, 1075, 20, 29},
+ {194, 1075, 20, 29},
+ {214, 1075, 20, 29},
+ {234, 1075, 20, 29},
+ {254, 1075, 17, 29},
+ {271, 1075, 20, 29},
+ {291, 1075, 20, 29},
+ {311, 1075, 20, 29},
+ {331, 1075, 20, 29},
+ {351, 1075, 20, 29},
+ {371, 1075, 20, 29},
+ {391, 1075, 20, 29},
+ {411, 1075, 20, 29},
+ {431, 1075, 20, 29},
+ {451, 1075, 20, 29},
+ {471, 1075, 20, 29},
+ {491, 1075, 20, 29},
+ {511, 1075, 20, 29},
+ {531, 1075, 20, 29},
+ {551, 1075, 20, 29},
+ {571, 1075, 20, 29},
+ {591, 1075, 20, 29},
+ {611, 1075, 20, 29},
+ {631, 1075, 20, 29},
+ {651, 1075, 20, 29},
+ {671, 1075, 20, 29},
+ {691, 1075, 20, 29},
+ {711, 1075, 20, 29},
+ {731, 1075, 20, 29},
+ {751, 1075, 20, 29},
+ {771, 1075, 20, 29},
+ {791, 1075, 20, 29},
+ {811, 1075, 20, 29},
+ {831, 1075, 20, 29},
+ {851, 1075, 20, 29},
+ {871, 1075, 20, 29},
+ {891, 1075, 20, 29},
+ {911, 1075, 20, 29},
+ {931, 1075, 20, 29},
+ {951, 1075, 20, 29},
+ {971, 1075, 20, 29},
+ {991, 1075, 20, 29},
+ {0, 1104, 20, 21},
+ {20, 1104, 20, 21},
+ {40, 1104, 20, 21},
+ {60, 1104, 20, 21},
+ {80, 1104, 20, 21},
+ {100, 1104, 20, 21},
+ {120, 1104, 20, 21},
+ {140, 1104, 20, 21},
+ {160, 1104, 20, 21},
+ {180, 1104, 20, 21},
+ {200, 1104, 20, 21},
+ {220, 1104, 20, 21},
+ {240, 1104, 20, 21},
+ {260, 1104, 23, 21},
+ {283, 1104, 20, 21},
+ {303, 1104, 20, 21},
+ {323, 1104, 20, 21},
+ {343, 1104, 20, 21},
+ {363, 1104, 20, 21},
+ {383, 1104, 20, 21},
+ {403, 1104, 20, 21},
+ {423, 1104, 20, 21},
+ {443, 1104, 20, 21},
+ {463, 1104, 20, 21},
+ {483, 1104, 20, 21},
+ {503, 1104, 20, 21},
+ {523, 1104, 20, 21},
+ {543, 1104, 20, 21},
+ {563, 1104, 20, 21},
+ {583, 1104, 20, 21},
+ {603, 1104, 20, 21},
+ {623, 1104, 20, 21},
+ {643, 1104, 20, 21},
+ {663, 1104, 20, 21},
+ {683, 1104, 20, 21},
+ {703, 1104, 20, 21},
+ {723, 1104, 20, 21},
+ {743, 1104, 20, 21},
+ {763, 1104, 20, 21},
+ {783, 1104, 20, 21},
+ {803, 1104, 20, 21},
+ {823, 1104, 20, 21},
+ {843, 1104, 20, 21},
+ {863, 1104, 20, 21},
+ {883, 1104, 20, 21},
+ {903, 1104, 20, 21},
+ {923, 1104, 20, 21},
+ {943, 1104, 20, 21},
+ {963, 1104, 20, 21},
+ {983, 1104, 20, 21},
+ {1003, 1104, 20, 21},
+ {0, 1125, 20, 21},
+ {20, 1125, 20, 21},
+ {40, 1125, 20, 21},
+ {60, 1125, 20, 21},
+ {80, 1125, 20, 21},
+ {100, 1125, 20, 21},
+ {120, 1125, 20, 21},
+ {140, 1125, 20, 21},
+ {160, 1125, 20, 21},
+ {180, 1125, 20, 21},
+ {200, 1125, 20, 21},
+ {220, 1125, 20, 21},
+ {240, 1125, 20, 21},
+ {260, 1125, 20, 21},
+ {280, 1125, 20, 21},
+ {300, 1125, 20, 21},
+ {320, 1125, 20, 21},
+ {340, 1125, 20, 21},
+ {360, 1125, 20, 21},
+ {380, 1125, 20, 21},
+ {400, 1125, 20, 21},
+ {420, 1125, 20, 21},
+ {440, 1125, 20, 21},
+ {460, 1125, 20, 21},
+ {480, 1125, 20, 21},
+ {500, 1125, 20, 21},
+ {520, 1125, 20, 21},
+ {540, 1125, 20, 21},
+ {560, 1125, 20, 21},
+ {580, 1125, 20, 21},
+ {600, 1125, 20, 21},
+ {620, 1125, 20, 21},
+ {640, 1125, 20, 21},
+ {660, 1125, 20, 21},
+ {680, 1125, 20, 21},
+ {700, 1125, 20, 21},
+ {720, 1125, 20, 21},
+ {740, 1125, 20, 21},
+ {760, 1125, 20, 21},
+ {780, 1125, 20, 21},
+ {800, 1125, 20, 21},
+ {820, 1125, 20, 21},
+ {840, 1125, 20, 21},
+ {860, 1125, 20, 21},
+ {880, 1125, 20, 21},
+ {900, 1125, 23, 21},
+ {923, 1125, 20, 21},
+ {943, 1125, 20, 21},
+ {963, 1125, 20, 21},
+ {983, 1125, 20, 21},
+ {1003, 1125, 20, 21},
+ {0, 1146, 20, 21},
+ {20, 1146, 20, 21},
+ {40, 1146, 20, 21},
+ {60, 1146, 20, 21},
+ {80, 1146, 20, 21},
+ {100, 1146, 20, 21},
+ {120, 1146, 20, 21},
+ {140, 1146, 20, 21},
+ {160, 1146, 20, 21},
+ {180, 1146, 20, 21},
+ {200, 1146, 20, 21},
+ {220, 1146, 20, 21},
+ {240, 1146, 20, 21},
+ {260, 1146, 20, 21},
+ {280, 1146, 20, 21},
+ {300, 1146, 20, 21},
+ {320, 1146, 20, 21},
+ {340, 1146, 20, 21},
+ {360, 1146, 20, 21},
+ {380, 1146, 20, 21},
+ {400, 1146, 20, 21},
+ {420, 1146, 20, 21},
+ {440, 1146, 20, 21},
+ {460, 1146, 20, 21},
+ {480, 1146, 20, 21},
+ {500, 1146, 20, 21},
+ {520, 1146, 20, 21},
+ {540, 1146, 20, 21},
+ {560, 1146, 20, 21},
+ {580, 1146, 20, 21},
+ {600, 1146, 20, 21},
+ {620, 1146, 20, 21},
+ {640, 1146, 20, 21},
+ {660, 1146, 20, 21},
+ {680, 1146, 20, 21},
+ {700, 1146, 20, 21},
+ {720, 1146, 20, 21},
+ {740, 1146, 20, 21},
+ {760, 1146, 20, 21},
+ {780, 1146, 20, 21},
+ {800, 1146, 20, 21},
+ {820, 1146, 20, 21},
+ {840, 1146, 20, 21},
+ {860, 1146, 20, 21},
+ {880, 1146, 20, 21},
+ {900, 1146, 20, 21},
+ {920, 1146, 23, 21},
+ {943, 1146, 23, 21},
+ {966, 1146, 23, 21},
+ {989, 1146, 23, 21},
+ {0, 1167, 23, 21},
+ {23, 1167, 23, 21},
+ {46, 1167, 23, 21},
+ {69, 1167, 23, 21},
+ {92, 1167, 23, 21},
+ {115, 1167, 23, 21},
+ {138, 1167, 23, 21},
+ {161, 1167, 23, 21},
+ {184, 1167, 23, 21},
+ {207, 1167, 23, 21},
+ {230, 1167, 23, 21},
+ {253, 1167, 23, 21},
+ {276, 1167, 23, 21},
+ {299, 1167, 23, 21},
+ {322, 1167, 23, 21},
+ {345, 1167, 23, 21},
+ {368, 1167, 23, 21},
+ {391, 1167, 23, 21},
+ {414, 1167, 23, 21},
+ {437, 1167, 23, 21},
+ {460, 1167, 23, 21},
+ {483, 1167, 23, 21},
+ {506, 1167, 23, 21},
+ {529, 1167, 23, 21},
+ {552, 1167, 23, 21},
+ {575, 1167, 23, 21},
+ {598, 1167, 23, 21},
+ {621, 1167, 23, 21},
+ {644, 1167, 23, 21},
+ {667, 1167, 23, 21},
+ {690, 1167, 23, 21},
+ {713, 1167, 23, 21},
+ {736, 1167, 23, 21},
+ {759, 1167, 23, 21},
+ {782, 1167, 23, 21},
+ {805, 1167, 23, 21},
+ {828, 1167, 23, 21},
+ {851, 1167, 23, 21},
+ {874, 1167, 23, 21},
+ {897, 1167, 23, 21},
+ {920, 1167, 23, 21},
+ {943, 1167, 23, 21},
+ {966, 1167, 23, 21},
+ {989, 1167, 23, 21},
+ {0, 1188, 23, 21},
+ {23, 1188, 23, 21},
+ {46, 1188, 23, 21},
+ {69, 1188, 23, 21},
+ {92, 1188, 23, 21},
+ {115, 1188, 23, 21},
+ {138, 1188, 23, 21},
+ {161, 1188, 23, 21},
+ {184, 1188, 23, 21},
+ {207, 1188, 23, 21},
+ {230, 1188, 23, 21},
+ {253, 1188, 23, 21},
+ {276, 1188, 23, 21},
+ {299, 1188, 23, 21},
+ {322, 1188, 23, 21},
+ {345, 1188, 23, 21},
+ {368, 1188, 23, 21},
+ {391, 1188, 23, 21},
+ {414, 1188, 23, 21},
+ {437, 1188, 23, 21},
+ {460, 1188, 23, 21},
+ {483, 1188, 23, 21},
+ {506, 1188, 23, 21},
+ {529, 1188, 23, 21},
+ {552, 1188, 23, 21},
+ {575, 1188, 23, 21},
+ {598, 1188, 23, 21},
+ {621, 1188, 23, 21},
+ {644, 1188, 23, 21},
+ {667, 1188, 23, 21},
+ {690, 1188, 23, 21},
+ {713, 1188, 23, 21},
+ {736, 1188, 23, 21},
+ {759, 1188, 23, 21},
+ {782, 1188, 23, 21},
+ {805, 1188, 23, 21},
+ {828, 1188, 23, 21},
+ {851, 1188, 23, 21},
+ {874, 1188, 23, 21},
+ {897, 1188, 23, 21},
+ {920, 1188, 23, 21},
+ {943, 1188, 23, 21},
+ {966, 1188, 23, 21},
+ {989, 1188, 23, 21},
+ {0, 1209, 23, 21},
+ {23, 1209, 23, 21},
+ {46, 1209, 23, 21},
+ {69, 1209, 23, 21},
+ {92, 1209, 23, 21},
+ {115, 1209, 23, 21},
+ {138, 1209, 23, 21},
+ {161, 1209, 23, 21},
+ {184, 1209, 23, 21},
+ {207, 1209, 23, 21},
+ {230, 1209, 23, 21},
+ {253, 1209, 23, 21},
+ {276, 1209, 23, 21},
+ {299, 1209, 23, 21},
+ {322, 1209, 23, 21},
+ {345, 1209, 23, 21},
+ {368, 1209, 23, 21},
+ {391, 1209, 23, 21},
+ {414, 1209, 23, 21},
+ {437, 1209, 23, 21},
+ {460, 1209, 20, 21},
+ {480, 1209, 20, 21},
+ {500, 1209, 20, 21},
+ {520, 1209, 20, 21},
+ {540, 1209, 20, 21},
+ {560, 1209, 23, 21},
+ {583, 1209, 23, 21},
+ {606, 1209, 23, 21},
+ {629, 1209, 20, 21},
+ {649, 1209, 20, 21},
+ {669, 1209, 20, 21},
+ {689, 1209, 23, 21},
+ {712, 1209, 23, 21},
+ {735, 1209, 23, 21},
+ {758, 1209, 23, 21},
+ {781, 1209, 23, 21},
+ {804, 1209, 20, 21},
+ {824, 1209, 20, 21},
+ {844, 1209, 20, 21},
+ {864, 1209, 20, 21},
+ {884, 1209, 20, 21},
+ {904, 1209, 20, 21},
+ {924, 1209, 20, 21},
+ {944, 1209, 23, 21},
+ {967, 1209, 23, 21},
+ {990, 1209, 23, 21},
+ {0, 1230, 23, 21},
+ {23, 1230, 23, 21},
+ {46, 1230, 23, 21},
+ {69, 1230, 23, 21},
+ {92, 1230, 23, 21},
+ {115, 1230, 23, 21},
+ {138, 1230, 20, 21},
+ {158, 1230, 20, 21},
+ {178, 1230, 20, 21},
+ {198, 1230, 20, 21},
+ {218, 1230, 20, 21},
+ {238, 1230, 20, 21},
+ {258, 1230, 20, 21},
+ {278, 1230, 20, 21},
+ {298, 1230, 20, 21},
+ {318, 1230, 20, 21},
+ {338, 1230, 20, 21},
+ {358, 1230, 20, 21},
+ {378, 1230, 20, 21},
+ {398, 1230, 20, 21},
+ {418, 1230, 20, 21},
+ {438, 1230, 20, 21},
+ {458, 1230, 20, 21},
+ {478, 1230, 20, 21},
+ {498, 1230, 20, 21},
+ {518, 1230, 20, 21},
+ {538, 1230, 20, 21},
+ {558, 1230, 20, 21},
+ {578, 1230, 20, 21},
+ {598, 1230, 20, 21},
+ {618, 1230, 20, 21},
+ {638, 1230, 23, 21},
+ {661, 1230, 23, 21},
+ {684, 1230, 23, 21},
+ {707, 1230, 23, 21},
+ {730, 1230, 23, 21},
+ {753, 1230, 23, 21},
+ {776, 1230, 23, 21},
+ {799, 1230, 20, 21},
+ {819, 1230, 20, 21},
+ {839, 1230, 20, 21},
+ {859, 1230, 20, 21},
+ {879, 1230, 20, 21},
+ {899, 1230, 20, 21},
+ {919, 1230, 20, 21},
+ {939, 1230, 23, 21},
+ {962, 1230, 23, 21},
+ {985, 1230, 23, 21},
+ {0, 1251, 23, 21},
+ {23, 1251, 23, 21},
+ {46, 1251, 23, 21},
+ {69, 1251, 23, 21},
+ {92, 1251, 23, 21},
+ {115, 1251, 23, 21},
+ {138, 1251, 20, 21},
+ {158, 1251, 20, 21},
+ {178, 1251, 20, 21},
+ {198, 1251, 23, 21},
+ {221, 1251, 23, 21},
+ {244, 1251, 23, 21},
+ {267, 1251, 23, 21},
+ {290, 1251, 23, 21},
+ {313, 1251, 23, 21},
+ {336, 1251, 23, 21},
+ {359, 1251, 23, 21},
+ {382, 1251, 23, 21},
+ {405, 1251, 23, 21},
+ {428, 1251, 23, 21},
+ {451, 1251, 23, 21},
+ {474, 1251, 23, 21},
+ {497, 1251, 20, 21},
+ {517, 1251, 20, 21},
+ {537, 1251, 20, 21},
+ {557, 1251, 20, 21},
+ {577, 1251, 20, 21},
+ {597, 1251, 20, 21},
+ {617, 1251, 20, 21},
+ {637, 1251, 23, 21},
+ {660, 1251, 23, 21},
+ {683, 1251, 23, 21},
+ {706, 1251, 23, 21},
+ {729, 1251, 23, 21},
+ {752, 1251, 23, 21},
+ {775, 1251, 23, 21},
+ {798, 1251, 23, 21},
+ {821, 1251, 23, 21},
+ {844, 1251, 23, 21},
+ {867, 1251, 23, 21},
+ {890, 1251, 23, 21},
+ {913, 1251, 23, 21},
+ {936, 1251, 23, 21},
+ {959, 1251, 23, 21},
+ {982, 1251, 23, 21},
+ {0, 1272, 23, 21},
+ {23, 1272, 23, 21},
+ {46, 1272, 23, 21},
+ {69, 1272, 23, 21},
+ {92, 1272, 23, 21},
+ {115, 1272, 23, 21},
+ {138, 1272, 23, 21},
+ {161, 1272, 23, 21},
+ {184, 1272, 23, 21},
+ {207, 1272, 23, 21},
+ {230, 1272, 23, 21},
+ {253, 1272, 23, 21},
+ {276, 1272, 23, 21},
+ {299, 1272, 23, 21},
+ {322, 1272, 23, 21},
+ {345, 1272, 23, 21},
+ {368, 1272, 23, 21},
+ {391, 1272, 23, 21},
+ {414, 1272, 23, 21},
+ {437, 1272, 23, 21},
+ {460, 1272, 23, 21},
+ {483, 1272, 23, 21},
+ {506, 1272, 23, 21},
+ {529, 1272, 23, 21},
+ {552, 1272, 23, 21},
+ {575, 1272, 23, 21},
+ {598, 1272, 23, 21},
+ {621, 1272, 23, 21},
+ {644, 1272, 23, 21},
+ {667, 1272, 23, 21},
+ {690, 1272, 23, 21},
+ {713, 1272, 23, 21},
+ {736, 1272, 23, 21},
+ {759, 1272, 23, 21},
+ {782, 1272, 23, 21},
+ {805, 1272, 23, 21},
+ {828, 1272, 23, 21},
+ {851, 1272, 23, 21},
+ {874, 1272, 23, 21},
+ {897, 1272, 23, 21},
+ {920, 1272, 23, 21},
+ {943, 1272, 23, 21},
+ {966, 1272, 23, 21},
+ {989, 1272, 23, 21},
+ {0, 1293, 23, 21},
+ {23, 1293, 23, 21},
+ {46, 1293, 23, 21},
+ {69, 1293, 23, 21},
+ {92, 1293, 23, 21},
+ {115, 1293, 23, 21},
+ {138, 1293, 23, 21},
+ {161, 1293, 23, 21},
+ {184, 1293, 23, 21},
+ {207, 1293, 23, 21},
+ {230, 1293, 23, 21},
+ {253, 1293, 23, 21},
+ {276, 1293, 23, 21},
+ {299, 1293, 23, 21},
+ {322, 1293, 23, 21},
+ {345, 1293, 23, 21},
+ {368, 1293, 23, 21},
+ {391, 1293, 23, 21},
+ {414, 1293, 23, 21},
+ {437, 1293, 23, 21},
+ {460, 1293, 23, 21},
+ {483, 1293, 23, 21},
+ {506, 1293, 23, 21},
+ {529, 1293, 23, 21},
+ {552, 1293, 23, 21},
+ {575, 1293, 23, 21},
+ {598, 1293, 23, 21},
+ {621, 1293, 23, 21},
+ {644, 1293, 23, 21},
+ {667, 1293, 23, 21},
+ {690, 1293, 23, 21},
+ {713, 1293, 23, 21},
+ {736, 1293, 23, 21},
+ {759, 1293, 23, 21},
+ {782, 1293, 23, 21},
+ {805, 1293, 23, 21},
+ {828, 1293, 23, 21},
+ {851, 1293, 23, 21},
+ {874, 1293, 23, 21},
+ {897, 1293, 23, 21},
+ {920, 1293, 23, 21},
+ {943, 1293, 23, 21},
+ {966, 1293, 23, 21},
+ {989, 1293, 23, 21},
+ {0, 1314, 23, 21},
+ {23, 1314, 23, 21},
+ {46, 1314, 23, 21},
+ {69, 1314, 23, 21},
+ {92, 1314, 23, 21},
+ {115, 1314, 23, 21},
+ {138, 1314, 23, 21},
+ {161, 1314, 23, 21},
+ {184, 1314, 23, 21},
+ {207, 1314, 23, 21},
+ {230, 1314, 23, 21},
+ {253, 1314, 23, 21},
+ {276, 1314, 23, 21},
+ {299, 1314, 23, 21},
+ {322, 1314, 23, 21},
+ {345, 1314, 23, 21},
+ {368, 1314, 23, 21},
+ {391, 1314, 23, 21},
+ {414, 1314, 23, 21},
+ {437, 1314, 23, 21},
+ {460, 1314, 23, 21},
+ {483, 1314, 23, 21},
+ {506, 1314, 23, 21},
+ {529, 1314, 23, 21},
+ {552, 1314, 23, 21},
+ {575, 1314, 23, 21},
+ {598, 1314, 23, 21},
+ {621, 1314, 23, 21},
+ {644, 1314, 23, 21},
+ {667, 1314, 23, 21},
+ {690, 1314, 23, 21},
+ {713, 1314, 23, 21},
+ {736, 1314, 23, 21},
+ {759, 1314, 23, 21},
+ {782, 1314, 23, 21},
+ {805, 1314, 23, 21},
+ {828, 1314, 23, 21},
+ {851, 1314, 23, 21},
+ {874, 1314, 23, 21},
+ {897, 1314, 23, 21},
+ {920, 1314, 23, 21},
+ {943, 1314, 23, 21},
+ {966, 1314, 23, 21},
+ {989, 1314, 23, 21},
+ {0, 1335, 23, 21},
+ {23, 1335, 23, 21},
+ {46, 1335, 23, 21},
+ {69, 1335, 23, 21},
+ {92, 1335, 23, 21}
+ };
+
+ bool codepoint_is_emoji(uint32_t codepoint) {
+ return codepoint >= 0x1F000 && codepoint <= 0x1FB6F;
+ }
+
+ EmojiRectangle emoji_get_extents(uint32_t codepoint) {
+ assert(codepoint_is_emoji(codepoint));
+ return emoji_extents[codepoint - 0x1F000];
+ }
+}
diff --git a/generated/Emoji.hpp b/generated/Emoji.hpp
new file mode 100644
index 0000000..89ebde3
--- /dev/null
+++ b/generated/Emoji.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <stdint.h>
+
+// This file was automatically generated with generate-emoji-sprite.py, do not edit manually!
+
+namespace QuickMedia {
+ struct EmojiRectangle {
+ int x, y;
+ int width, height;
+ };
+
+ bool codepoint_is_emoji(uint32_t codepoint);
+ EmojiRectangle emoji_get_extents(uint32_t codepoint);
+} \ No newline at end of file
diff --git a/images/emoji.png b/images/emoji.png
new file mode 100644
index 0000000..8bb210f
--- /dev/null
+++ b/images/emoji.png
Binary files differ
diff --git a/include/Body.hpp b/include/Body.hpp
index 236a02d..43e2946 100644
--- a/include/Body.hpp
+++ b/include/Body.hpp
@@ -174,7 +174,7 @@ namespace QuickMedia {
BodyItem* get_selected() const;
std::shared_ptr<BodyItem> get_selected_shared();
- // Returns null if not visible item
+ // Returns null if no visible items. This is the item we can see the end of
BodyItem* get_last_fully_visible_item();
void clamp_selection();
@@ -205,6 +205,7 @@ namespace QuickMedia {
void set_page_scroll(float scroll) { page_scroll = scroll; }
float get_page_scroll() const { return page_scroll; }
+ // This is the item we can see the end of
bool is_last_item_fully_visible() const { return last_item_fully_visible; }
bool is_body_full_with_items() const { return items_cut_off; }
diff --git a/include/FontLoader.hpp b/include/ResourceLoader.hpp
index bff0f18..a332ba4 100644
--- a/include/FontLoader.hpp
+++ b/include/ResourceLoader.hpp
@@ -1,9 +1,12 @@
#pragma once
-#include <string>
-
namespace sf {
class Font;
+ class Texture;
+}
+
+namespace QuickMedia {
+ void set_resource_loader_root_path(const char *resource_root);
}
namespace QuickMedia::FontLoader {
@@ -16,4 +19,9 @@ namespace QuickMedia::FontLoader {
// Note: not thread-safe
sf::Font* get_font(FontType font_type);
+}
+
+namespace QuickMedia::TextureLoader {
+ // Note: not thread-safe
+ sf::Texture* get_texture(const char *filepath);
} \ No newline at end of file
diff --git a/include/Text.hpp b/include/Text.hpp
index f102c59..135a89c 100644
--- a/include/Text.hpp
+++ b/include/Text.hpp
@@ -139,7 +139,7 @@ namespace QuickMedia
sf::String str; // TODO: Remove this for non-editable text??? also replace with std::string? then we get more efficient editing of text
const bool bold_font;
unsigned int characterSize;
- sf::VertexArray vertices[2];
+ sf::VertexArray vertices[3];
float maxWidth;
sf::Vector2f position;
sf::Color color;
diff --git a/plugins/Fourchan.hpp b/plugins/Fourchan.hpp
index b9e5b74..903d534 100644
--- a/plugins/Fourchan.hpp
+++ b/plugins/Fourchan.hpp
@@ -14,11 +14,12 @@ namespace QuickMedia {
const std::string resources_root;
};
- class FourchanThreadListPage : public Page {
+ class FourchanThreadListPage : public LazyFetchPage {
public:
- FourchanThreadListPage(Program *program, std::string title, std::string board_id) : Page(program), title(std::move(title)), board_id(std::move(board_id)) {}
+ FourchanThreadListPage(Program *program, std::string title, std::string board_id) : LazyFetchPage(program), title(std::move(title)), board_id(std::move(board_id)) {}
const char* get_title() const override { return title.c_str(); }
PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
+ PluginResult lazy_fetch(BodyItems &result_items) override;
const std::string title;
const std::string board_id;
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index 71d9664..8e96c54 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -256,7 +256,7 @@ namespace QuickMedia {
MatrixRoomTagsPage *room_tags_page;
MatrixInvitesPage *invites_page;
private:
- void update_room_description(RoomData *room, Messages &new_messages, bool is_initial_sync);
+ void update_room_description(RoomData *room, Messages &new_messages, bool is_initial_sync, bool sync_is_cache);
void update_pending_room_messages(MatrixPageType page_type);
private:
struct RoomMessagesData {
diff --git a/src/Body.cpp b/src/Body.cpp
index b456841..5c2a66c 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -1,7 +1,7 @@
#include "../include/Body.hpp"
#include "../include/QuickMedia.hpp"
#include "../include/Scale.hpp"
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
#include "../plugins/Plugin.hpp"
#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/OpenGL.hpp>
diff --git a/src/Entry.cpp b/src/Entry.cpp
index cc05aa0..c18006f 100644
--- a/src/Entry.cpp
+++ b/src/Entry.cpp
@@ -1,5 +1,5 @@
#include "../include/Entry.hpp"
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Event.hpp>
diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp
index be03781..8704c15 100644
--- a/src/ImageViewer.cpp
+++ b/src/ImageViewer.cpp
@@ -2,7 +2,7 @@
#include "../include/Notification.hpp"
#include "../include/Storage.hpp"
#include "../include/SfmlFixes.hpp"
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
#include "../plugins/Manga.hpp"
#include <cmath>
#include <SFML/Window/Event.hpp>
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index c9ab3e1..f494d35 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -20,7 +20,7 @@
#include "../include/Entry.hpp"
#include "../include/NetUtils.hpp"
#include "../include/SfmlFixes.hpp"
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
#include "../include/AsyncTask.hpp"
#include "../external/hash-library/sha256.h"
@@ -340,6 +340,8 @@ namespace QuickMedia {
resources_root = "../../../";
}
+ set_resource_loader_root_path(resources_root.c_str());
+
if(!circle_mask_shader.loadFromFile(resources_root + "shaders/circle_mask.glsl", sf::Shader::Type::Fragment)) {
fprintf(stderr, "Failed to load %s/shaders/circle_mask.glsl", resources_root.c_str());
abort();
diff --git a/src/FontLoader.cpp b/src/ResourceLoader.cpp
index ca33377..9a6060d 100644
--- a/src/FontLoader.cpp
+++ b/src/ResourceLoader.cpp
@@ -1,9 +1,19 @@
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
#include <SFML/Graphics/Font.hpp>
+#include <SFML/Graphics/Texture.hpp>
#include <array>
+#include <unordered_map>
#include <assert.h>
+static std::string resource_root;
static std::array<std::unique_ptr<sf::Font>, 3> font_cache;
+static std::unordered_map<std::string, std::unique_ptr<sf::Texture>> texture_cache;
+
+namespace QuickMedia {
+ void set_resource_loader_root_path(const char *new_resource_root) {
+ resource_root = new_resource_root;
+ }
+}
namespace QuickMedia::FontLoader {
sf::Font* get_font(FontType font_type) {
@@ -49,4 +59,21 @@ namespace QuickMedia::FontLoader {
}
return font;
}
+}
+
+namespace QuickMedia::TextureLoader {
+ sf::Texture* get_texture(const char *filepath) {
+ assert(!resource_root.empty());
+ std::string str = filepath;
+ auto it = texture_cache.find(str);
+ if(it != texture_cache.end())
+ return it->second.get();
+
+ auto new_texture = std::make_unique<sf::Texture>();
+ sf::Texture *result = new_texture.get();
+ if(!new_texture->loadFromFile(resource_root + str))
+ fprintf(stderr, "Failed to load image: %s%s\n", resource_root.c_str(), filepath);
+ texture_cache[str] = std::move(new_texture);
+ return result;
+ }
} \ No newline at end of file
diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp
index dea9951..9b02903 100644
--- a/src/SearchBar.cpp
+++ b/src/SearchBar.cpp
@@ -1,6 +1,6 @@
#include "../include/SearchBar.hpp"
#include "../include/Scale.hpp"
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Clipboard.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
diff --git a/src/Text.cpp b/src/Text.cpp
index b463f92..539f211 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -1,5 +1,6 @@
#include "../include/Text.hpp"
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
+#include "../generated/Emoji.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Clipboard.hpp>
#include <SFML/Window/Event.hpp>
@@ -46,6 +47,7 @@ namespace QuickMedia
{
vertices[0].setPrimitiveType(sf::PrimitiveType::Quads);
vertices[1].setPrimitiveType(sf::PrimitiveType::Quads);
+ vertices[2].setPrimitiveType(sf::PrimitiveType::Quads);
setString(std::move(_str));
}
@@ -226,9 +228,17 @@ namespace QuickMedia
return size;
}
- static size_t find_end_of_non_cjk(const sf::Uint32 *str, size_t size) {
+ static size_t find_end_of_emoji(const sf::Uint32 *str, size_t size) {
for(size_t i = 0; i < size; ++i) {
- if(is_cjk_codepoint(str[i]))
+ if(!codepoint_is_emoji(str[i]))
+ return i;
+ }
+ return size;
+ }
+
+ static size_t find_end_of_non_cjk_and_non_emoji(const sf::Uint32 *str, size_t size) {
+ for(size_t i = 0; i < size; ++i) {
+ if(is_cjk_codepoint(str[i]) || codepoint_is_emoji(str[i]))
return i;
}
return size;
@@ -240,13 +250,18 @@ namespace QuickMedia
size_t size = str.getSize();
while(index < size) {
size_t offset;
- bool is_cjk = is_cjk_codepoint(str[index]);
- if(is_cjk)
+ TextElement::TextType text_type = TextElement::TextType::LATIN;
+ if(is_cjk_codepoint(str[index])) {
+ text_type = TextElement::TextType::CJK;
offset = find_end_of_cjk(str.getData() + index + 1, size - index - 1);
- else
- offset = find_end_of_non_cjk(str.getData() + index + 1, size - index - 1);
+ } else if(codepoint_is_emoji(str[index])) {
+ text_type = TextElement::TextType::EMOJI;
+ offset = find_end_of_emoji(str.getData() + index + 1, size - index - 1);
+ } else {
+ offset = find_end_of_non_cjk_and_non_emoji(str.getData() + index + 1, size - index - 1);
+ }
textElements.push_back({ StringViewUtf32(str.getData() + index, offset + 1), TextElement::Type::TEXT });
- textElements.back().text_type = is_cjk ? TextElement::TextType::CJK : TextElement::TextType::LATIN;
+ textElements.back().text_type = text_type;
index += 1 + offset;
}
}
@@ -317,6 +332,7 @@ namespace QuickMedia
vertices_linear.clear();
vertices[0].clear();
vertices[1].clear();
+ vertices[2].clear();
boundingBox = sf::FloatRect();
sf::Font *latin_font;
@@ -325,7 +341,8 @@ namespace QuickMedia
else
latin_font = FontLoader::get_font(FontLoader::FontType::LATIN);
- float hspace = latin_font->getGlyph(' ', characterSize, false).advance + characterSpacing;
+ float latin_font_height = latin_font->getGlyph(' ', characterSize, false).advance;
+ float hspace = latin_font_height + characterSpacing;
float vspace = latin_font->getLineSpacing(characterSize); // TODO: What about japanese font???
sf::Vector2f glyphPos;
@@ -338,6 +355,35 @@ namespace QuickMedia
if(textElement.text_type == TextElement::TextType::CJK) {
ff = FontLoader::get_font(FontLoader::FontType::CJK);
vertices_index = 1;
+ } else if(textElement.text_type == TextElement::TextType::EMOJI) {
+ vertices_index = 2;
+ textElement.position = glyphPos;
+ for(size_t i = 0; i < textElement.text.size; ++i)
+ {
+ sf::Uint32 codePoint = textElement.text[i];
+ int vertexStart = vertices[vertices_index].getVertexCount();
+ EmojiRectangle emoji_rec = emoji_get_extents(codePoint);
+
+ const float font_height_offset = -latin_font_height * 1.0f;
+ sf::Vector2f vertexTopLeft(glyphPos.x, glyphPos.y + font_height_offset - emoji_rec.height * 0.5f);
+ sf::Vector2f vertexTopRight(glyphPos.x + emoji_rec.width, glyphPos.y + font_height_offset - emoji_rec.height * 0.5f);
+ sf::Vector2f vertexBottomLeft(glyphPos.x, glyphPos.y + font_height_offset + emoji_rec.height * 0.5f);
+ sf::Vector2f vertexBottomRight(glyphPos.x + emoji_rec.width, glyphPos.y + font_height_offset + emoji_rec.height * 0.5f);
+
+ sf::Vector2f textureTopLeft(emoji_rec.x, emoji_rec.y);
+ sf::Vector2f textureTopRight(emoji_rec.x + emoji_rec.width, emoji_rec.y);
+ sf::Vector2f textureBottomLeft(emoji_rec.x, emoji_rec.y + emoji_rec.height);
+ sf::Vector2f textureBottomRight(emoji_rec.x + emoji_rec.width, emoji_rec.y + emoji_rec.height);
+
+ vertices[vertices_index].append({ vertexTopLeft, sf::Color::White, textureTopLeft });
+ vertices[vertices_index].append({ vertexTopRight, sf::Color::White, textureTopRight });
+ vertices[vertices_index].append({ vertexBottomRight, sf::Color::White, textureBottomRight });
+ vertices[vertices_index].append({ vertexBottomLeft, sf::Color::White, textureBottomLeft });
+
+ glyphPos.x += emoji_rec.width + characterSpacing;
+ vertices_linear.push_back({vertices_index, vertexStart, 0, codePoint});
+ }
+ continue;
}
//vertices[vertices_index].resize(vertices[vertices_index].getVertexCount() + 4 * textElement.text.size); // TODO: Precalculate
@@ -818,6 +864,13 @@ namespace QuickMedia
states.texture = &font->getTexture(characterSize);
target.draw(vertices[i], states);
}
+
+ if(vertices[2].getVertexCount() > 0) {
+ sf::RenderStates states;
+ states.transform.translate(pos);
+ states.texture = TextureLoader::get_texture("images/emoji.png");
+ target.draw(vertices[2], states);
+ }
if(!editable) return true;
pos.y -= floor(vspace * 2.0f);
diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp
index d042a2a..2c62ba1 100644
--- a/src/plugins/Fourchan.cpp
+++ b/src/plugins/Fourchan.cpp
@@ -135,139 +135,7 @@ namespace QuickMedia {
}
PluginResult FourchanBoardsPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
- Json::Value json_root;
- DownloadResult result = download_json(json_root, fourchan_url + url + "/catalog.json", {}, true);
- if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
-
- if(!json_root.isArray())
- return PluginResult::ERR;
-
- BodyItems result_items;
-
- for(const Json::Value &page_data : json_root) {
- if(!page_data.isObject())
- continue;
-
- const Json::Value &threads = page_data["threads"];
- if(!threads.isArray())
- continue;
-
- for(const Json::Value &thread : threads) {
- if(!thread.isObject())
- continue;
-
- const Json::Value &sub = thread["sub"];
- const char *sub_begin = "";
- const char *sub_end = sub_begin;
- sub.getString(&sub_begin, &sub_end);
-
- const Json::Value &com = thread["com"];
- const char *comment_begin = "";
- const char *comment_end = comment_begin;
- com.getString(&comment_begin, &comment_end);
-
- const Json::Value &thread_num = thread["no"];
- if(!thread_num.isNumeric())
- continue;
-
- std::string title_text;
- extract_comment_pieces(sub_begin, sub_end - sub_begin,
- [&title_text](const CommentPiece &cp) {
- switch(cp.type) {
- case CommentPiece::Type::TEXT:
- title_text.append(cp.text.data, cp.text.size);
- break;
- case CommentPiece::Type::QUOTE:
- title_text += '>';
- title_text.append(cp.text.data, cp.text.size);
- //comment_text += '\n';
- break;
- case CommentPiece::Type::QUOTELINK: {
- title_text.append(cp.text.data, cp.text.size);
- break;
- }
- case CommentPiece::Type::LINE_CONTINUE: {
- if(!title_text.empty() && title_text.back() == '\n') {
- title_text.pop_back();
- }
- break;
- }
- }
- }
- );
- if(!title_text.empty() && title_text.back() == '\n')
- title_text.back() = ' ';
- html_unescape_sequences(title_text);
-
- std::string comment_text;
- extract_comment_pieces(comment_begin, comment_end - comment_begin,
- [&comment_text](const CommentPiece &cp) {
- switch(cp.type) {
- case CommentPiece::Type::TEXT:
- comment_text.append(cp.text.data, cp.text.size);
- break;
- case CommentPiece::Type::QUOTE:
- comment_text += '>';
- comment_text.append(cp.text.data, cp.text.size);
- //comment_text += '\n';
- break;
- case CommentPiece::Type::QUOTELINK: {
- comment_text.append(cp.text.data, cp.text.size);
- break;
- }
- case CommentPiece::Type::LINE_CONTINUE: {
- if(!comment_text.empty() && comment_text.back() == '\n') {
- comment_text.pop_back();
- }
- break;
- }
- }
- }
- );
- html_unescape_sequences(comment_text);
- // TODO: Do the same when wrapping is implemented
- // TODO: Remove this
- int num_lines = 0;
- for(size_t i = 0; i < comment_text.size(); ++i) {
- if(comment_text[i] == '\n') {
- ++num_lines;
- if(num_lines == 6) {
- comment_text = comment_text.substr(0, i) + " (...)";
- break;
- }
- }
- }
- auto body_item = BodyItem::create(std::move(comment_text));
- body_item->set_author(std::move(title_text));
- body_item->url = std::to_string(thread_num.asInt64());
-
- const Json::Value &ext = thread["ext"];
- const Json::Value &tim = thread["tim"];
- if(tim.isNumeric() && ext.isString()) {
- std::string ext_str = ext.asString();
- if(ext_str == ".png" || ext_str == ".jpg" || ext_str == ".jpeg" || ext_str == ".webm" || ext_str == ".mp4" || ext_str == ".gif") {
- } else {
- fprintf(stderr, "TODO: Support file extension: %s\n", ext_str.c_str());
- }
- // "s" means small, that's the url 4chan uses for thumbnails.
- // thumbnails always has .jpg extension even if they are gifs or webm.
- body_item->thumbnail_url = fourchan_image_url + url + "/" + std::to_string(tim.asInt64()) + "s.jpg";
-
- sf::Vector2i thumbnail_size(64, 64);
- const Json::Value &tn_w = thread["tn_w"];
- const Json::Value &tn_h = thread["tn_h"];
- if(tn_w.isNumeric() && tn_h.isNumeric())
- thumbnail_size = sf::Vector2i(tn_w.asInt() * 0.5, tn_h.asInt() * 0.5);
- body_item->thumbnail_size = std::move(thumbnail_size);
- }
-
- result_items.push_back(std::move(body_item));
- }
- }
-
- auto body = create_body();
- body->items = std::move(result_items);
- result_tabs.push_back(Tab{std::move(body), std::make_unique<FourchanThreadListPage>(program, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ result_tabs.push_back(Tab{create_body(), std::make_unique<FourchanThreadListPage>(program, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
return PluginResult::OK;
}
@@ -462,6 +330,138 @@ namespace QuickMedia {
return PluginResult::OK;
}
+ PluginResult FourchanThreadListPage::lazy_fetch(BodyItems &result_items) {
+ Json::Value json_root;
+ DownloadResult result = download_json(json_root, fourchan_url + board_id + "/catalog.json?s=Index", {}, true);
+ if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
+
+ if(!json_root.isArray())
+ return PluginResult::ERR;
+
+ for(const Json::Value &page_data : json_root) {
+ if(!page_data.isObject())
+ continue;
+
+ const Json::Value &threads = page_data["threads"];
+ if(!threads.isArray())
+ continue;
+
+ for(const Json::Value &thread : threads) {
+ if(!thread.isObject())
+ continue;
+
+ const Json::Value &sub = thread["sub"];
+ const char *sub_begin = "";
+ const char *sub_end = sub_begin;
+ sub.getString(&sub_begin, &sub_end);
+
+ const Json::Value &com = thread["com"];
+ const char *comment_begin = "";
+ const char *comment_end = comment_begin;
+ com.getString(&comment_begin, &comment_end);
+
+ const Json::Value &thread_num = thread["no"];
+ if(!thread_num.isNumeric())
+ continue;
+
+ std::string title_text;
+ extract_comment_pieces(sub_begin, sub_end - sub_begin,
+ [&title_text](const CommentPiece &cp) {
+ switch(cp.type) {
+ case CommentPiece::Type::TEXT:
+ title_text.append(cp.text.data, cp.text.size);
+ break;
+ case CommentPiece::Type::QUOTE:
+ title_text += '>';
+ title_text.append(cp.text.data, cp.text.size);
+ //comment_text += '\n';
+ break;
+ case CommentPiece::Type::QUOTELINK: {
+ title_text.append(cp.text.data, cp.text.size);
+ break;
+ }
+ case CommentPiece::Type::LINE_CONTINUE: {
+ if(!title_text.empty() && title_text.back() == '\n') {
+ title_text.pop_back();
+ }
+ break;
+ }
+ }
+ }
+ );
+ if(!title_text.empty() && title_text.back() == '\n')
+ title_text.back() = ' ';
+ html_unescape_sequences(title_text);
+
+ std::string comment_text;
+ extract_comment_pieces(comment_begin, comment_end - comment_begin,
+ [&comment_text](const CommentPiece &cp) {
+ switch(cp.type) {
+ case CommentPiece::Type::TEXT:
+ comment_text.append(cp.text.data, cp.text.size);
+ break;
+ case CommentPiece::Type::QUOTE:
+ comment_text += '>';
+ comment_text.append(cp.text.data, cp.text.size);
+ //comment_text += '\n';
+ break;
+ case CommentPiece::Type::QUOTELINK: {
+ comment_text.append(cp.text.data, cp.text.size);
+ break;
+ }
+ case CommentPiece::Type::LINE_CONTINUE: {
+ if(!comment_text.empty() && comment_text.back() == '\n') {
+ comment_text.pop_back();
+ }
+ break;
+ }
+ }
+ }
+ );
+ html_unescape_sequences(comment_text);
+ // TODO: Do the same when wrapping is implemented
+ // TODO: Remove this
+ int num_lines = 0;
+ for(size_t i = 0; i < comment_text.size(); ++i) {
+ if(comment_text[i] == '\n') {
+ ++num_lines;
+ if(num_lines == 6) {
+ comment_text = comment_text.substr(0, i) + " (...)";
+ break;
+ }
+ }
+ }
+ auto body_item = BodyItem::create(std::move(comment_text));
+ body_item->set_author(std::move(title_text));
+ body_item->url = std::to_string(thread_num.asInt64());
+
+ const Json::Value &ext = thread["ext"];
+ const Json::Value &tim = thread["tim"];
+ if(tim.isNumeric() && ext.isString()) {
+ std::string ext_str = ext.asString();
+ if(ext_str == ".png" || ext_str == ".jpg" || ext_str == ".jpeg" || ext_str == ".webm" || ext_str == ".mp4" || ext_str == ".gif") {
+ } else {
+ fprintf(stderr, "TODO: Support file extension: %s\n", ext_str.c_str());
+ }
+ // "s" means small, that's the url 4chan uses for thumbnails.
+ // thumbnails always has .jpg extension even if they are gifs or webm.
+ body_item->thumbnail_url = fourchan_image_url + board_id + "/" + std::to_string(tim.asInt64()) + "s.jpg";
+
+ sf::Vector2i thumbnail_size(64, 64);
+ const Json::Value &tn_w = thread["tn_w"];
+ const Json::Value &tn_h = thread["tn_h"];
+ if(tn_w.isNumeric() && tn_h.isNumeric())
+ thumbnail_size = sf::Vector2i(tn_w.asInt() * 0.5, tn_h.asInt() * 0.5);
+ body_item->thumbnail_size = std::move(thumbnail_size);
+ }
+
+ result_items.push_back(std::move(body_item));
+ }
+ }
+
+ return PluginResult::OK;
+ }
+
PluginResult FourchanThreadPage::login(const std::string &token, const std::string &pin, std::string &response_msg) {
response_msg.clear();
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 1d0e1df..6dabad9 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -455,7 +455,7 @@ namespace QuickMedia {
});
}
- void MatrixQuickMedia::update_room_description(RoomData *room, Messages &new_messages, bool is_initial_sync) {
+ void MatrixQuickMedia::update_room_description(RoomData *room, Messages &new_messages, bool is_initial_sync, bool sync_is_cache) {
time_t read_marker_message_timestamp = 0;
std::shared_ptr<UserInfo> me = matrix->get_me(room);
if(me) {
@@ -485,7 +485,7 @@ namespace QuickMedia {
if(!room_body_item)
return;
- if(last_unread_message) {
+ if(last_unread_message && !sync_is_cache) {
std::string room_desc = "Unread: " + matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line_elipses(last_unread_message->body, 150);
int unread_notification_count = room->unread_notification_count;
if(unread_notification_count > 0)
@@ -523,7 +523,7 @@ namespace QuickMedia {
}
}
- update_room_description(room, messages, is_initial_sync);
+ update_room_description(room, messages, is_initial_sync, it.second.sync_is_cache);
}
pending_room_messages.clear();
}