From 247ddc9c4dc515759f2179c4672a88e1d468d4b8 Mon Sep 17 00:00:00 2001 From: feixh Date: Mon, 19 Aug 2019 12:31:15 -0700 Subject: [PATCH] init commit --- .gitignore | 12 + CMakeLists.txt | 79 + LICENSE | 31 + README.md | 215 + build.sh | 58 + cfg/atan.json | 10 + cfg/equidistant.json | 13 + cfg/estimator.json | 271 + cfg/estimator_latex.json | 122 + cfg/estimator_scenenet.json | 154 + cfg/estimator_sim.json | 77 + cfg/lyapunov_baseline.json | 156 + cfg/pointgrey_xsens.json | 228 + cfg/pointgrey_xsens_viewer.json | 28 + cfg/simulation.json | 8 + cfg/simulator.json | 60 + cfg/tuning.json | 155 + cfg/viewer.json | 27 + cfg/viewer_scenenet.json | 27 + cfg/vio.json | 14 + common/CMakeLists.txt | 19 + common/ProducerConsumerQueue.h | 189 + common/alias.h | 70 + common/atan.h | 142 + common/camera.h | 77 + common/component.h | 52 + common/equidist.h | 175 + common/example_process.cpp | 47 + common/pinhole.h | 69 + common/process.h | 91 + common/radtan.h | 134 + common/rodrigues.h | 254 + common/se3.h | 182 + common/test/test_rodrigues.cpp | 248 + common/test/test_se3.cpp | 0 common/utils.cpp | 149 + common/utils.h | 358 + experimental/CMakeLists.txt | 14 + experimental/async_dataloader.cpp | 195 + experimental/camera_factory.h | 438 + experimental/inproc_communication_zmq.cpp | 76 + experimental/test_camera_factory.cpp | 17 + format_all.sh | 1 + .../camchain-imucam-imucalib.yaml | 33 + .../pinhole-equi-512/imu-imucalib.yaml | 14 + .../pinhole-equi-512/imucalib-command.txt | 1 + .../tumvi_calib/pinhole-equi-512/imucalib.log | 187 + .../results-imucam-imucalib.txt | 121 + node/CMakeLists.txt | 61 + node/launch/sensors.launch | 65 + node/launch/tumvi.launch | 10 + node/launch/tumvi.xml | 28 + node/launch/xivo.launch | 10 + node/launch/xivo.xml | 28 + node/main.cpp | 25 + node/package.xml | 37 + node/ros_setup.h | 36 + node/simple_node.cpp | 136 + node/simple_node.h | 49 + print_stats.sh | 2 + pybind11/pyxivo.cpp | 94 + requirements.txt | 5 + run_all.sh | 18 + scripts/compareTraj.py | 54 + scripts/plot_state.py | 25 + scripts/pyxivo.py | 114 + scripts/run_and_eval_pyxivo.py | 88 + scripts/run_and_eval_xivo.py | 68 + scripts/scenenet_demo.py | 116 + scripts/tum_rgbd_benchmark_tools/associate.py | 128 + .../tum_rgbd_benchmark_tools/evaluate_ate.py | 195 + .../tum_rgbd_benchmark_tools/evaluate_rpe.py | 380 + src/CMakeLists.txt | 115 + src/adjustable_cameras.h | 163 + src/app/evaluate.cpp | 95 + src/app/simulation.cpp | 131 + src/app/singlethread_vio.cpp | 108 + src/app/vio.cpp | 103 + src/camera_manager.cpp | 56 + src/camera_manager.h | 137 + src/core.cpp | 26 + src/core.h | 170 + src/estimator.cpp | 977 + src/estimator.h | 245 + src/estimator_process.cpp | 59 + src/estimator_process.h | 97 + src/feature.cpp | 469 + src/feature.h | 199 + src/geometry.cpp | 160 + src/geometry.h | 23 + src/graph.cpp | 319 + src/graph.h | 79 + src/group.cpp | 34 + src/group.h | 80 + src/helpers.cpp | 152 + src/helpers.h | 45 + src/imu.cpp | 27 + src/imu.h | 42 + src/jac.h | 54 + src/manager.cpp | 362 + src/message_types.h | 57 + src/metrics.cpp | 132 + src/metrics.h | 37 + src/mm.cpp | 80 + src/mm.h | 36 + src/options.cpp | 25 + src/options.h | 45 + src/param.cpp | 20 + src/param.h | 26 + src/princedormand.cpp | 223 + src/project.h | 95 + src/publisher.cpp | 34 + src/publisher.h | 62 + src/rk4.cpp | 105 + src/simulator.cpp | 398 + src/simulator.h | 82 + src/test/test_estimator.cpp | 34 + src/test/test_geometry.cpp | 0 src/test/test_givens.cpp | 26 + src/test/test_matcher.cpp | 48 + src/test/test_qr.cpp | 22 + src/test/test_simulator.cpp | 33 + src/test/test_tracker.cpp | 40 + src/test/test_tumvi.cpp | 49 + src/test/test_viewer.cpp | 34 + src/tracker.cpp | 323 + src/tracker.h | 74 + src/tumvi.cpp | 121 + src/tumvi.h | 33 + src/update.cpp | 337 + src/viewer.cpp | 164 + src/viewer.h | 50 + src/visualize.cpp | 119 + src/visualize.h | 34 + thirdparty/Pangolin/.clang-format | 2 + thirdparty/Pangolin/.gitignore | 3 + thirdparty/Pangolin/.gitmodules | 3 + thirdparty/Pangolin/.travis.yml | 30 + thirdparty/Pangolin/CMakeLists.txt | 109 + .../Pangolin/CMakeModules/AndroidUtils.cmake | 245 + .../CMakeModules/CreateMethodCallFile.cmake | 11 + .../CMakeModules/EmbedBinaryFiles.cmake | 32 + .../Pangolin/CMakeModules/FindDC1394.cmake | 32 + .../CMakeModules/FindDepthSense.cmake | 43 + .../Pangolin/CMakeModules/FindEigen.cmake | 83 + .../Pangolin/CMakeModules/FindFFMPEG.cmake | 97 + .../Pangolin/CMakeModules/FindFREEGLUT.cmake | 44 + .../Pangolin/CMakeModules/FindGLEW.cmake | 53 + .../Pangolin/CMakeModules/FindGLUES.cmake | 38 + .../CMakeModules/FindLibRealSense.cmake | 33 + .../CMakeModules/FindLibRealSense2.cmake | 33 + .../Pangolin/CMakeModules/FindLz4.cmake | 26 + .../CMakeModules/FindMediaFoundation.cmake | 20 + .../Pangolin/CMakeModules/FindOculus.cmake | 63 + .../Pangolin/CMakeModules/FindOpenEXR.cmake | 33 + .../Pangolin/CMakeModules/FindOpenNI.cmake | 49 + .../Pangolin/CMakeModules/FindOpenNI2.cmake | 59 + .../Pangolin/CMakeModules/FindPleora.cmake | 143 + .../CMakeModules/FindROBOTVISION.cmake | 31 + .../Pangolin/CMakeModules/FindTeliCam.cmake | 58 + .../Pangolin/CMakeModules/FindTooN.cmake | 28 + .../Pangolin/CMakeModules/FindWayland.cmake | 66 + .../Pangolin/CMakeModules/FindXrandr.cmake | 32 + .../Pangolin/CMakeModules/Findlibusb1.cmake | 42 + .../Pangolin/CMakeModules/Findpthread.cmake | 42 + .../Pangolin/CMakeModules/Finduvc.cmake | 39 + .../Pangolin/CMakeModules/Findzstd.cmake | 35 + .../CMakeModules/SetPlatformVars.cmake | 56 + thirdparty/Pangolin/LICENCE | 22 + thirdparty/Pangolin/README.md | 176 + thirdparty/Pangolin/appveyor.yml | 25 + thirdparty/Pangolin/cmake_uninstall.cmake.in | 25 + thirdparty/Pangolin/examples/CMakeLists.txt | 33 + .../examples/HelloPangolin/CMakeLists.txt | 6 + .../Pangolin/examples/HelloPangolin/main.cpp | 34 + .../HelloPangolinOffscreen/CMakeLists.txt | 6 + .../examples/HelloPangolinOffscreen/main.cpp | 48 + .../HelloPangolinThreads/CMakeLists.txt | 6 + .../examples/HelloPangolinThreads/main.cpp | 64 + .../SharedMemoryCamera/CMakeLists.txt | 7 + .../examples/SharedMemoryCamera/main.cpp | 53 + .../examples/SimpleDisplay/CMakeLists.txt | 7 + .../Pangolin/examples/SimpleDisplay/app.cfg | 26 + .../Pangolin/examples/SimpleDisplay/main.cpp | 129 + .../SimpleDisplayImage/CMakeLists.txt | 6 + .../examples/SimpleDisplayImage/main.cpp | 72 + .../SimpleMultiDisplay/CMakeLists.txt | 6 + .../examples/SimpleMultiDisplay/app.cfg | 28 + .../examples/SimpleMultiDisplay/main.cpp | 106 + .../examples/SimplePlot/CMakeLists.txt | 6 + .../Pangolin/examples/SimplePlot/main.cpp | 49 + .../examples/SimpleRecord/CMakeLists.txt | 6 + .../Pangolin/examples/SimpleRecord/main.cpp | 94 + .../examples/SimpleScene/CMakeLists.txt | 6 + .../Pangolin/examples/SimpleScene/main.cpp | 40 + .../examples/SimpleVideo/CMakeLists.txt | 6 + .../Pangolin/examples/SimpleVideo/main.cpp | 111 + .../examples/VBODisplay/CMakeLists.txt | 19 + .../Pangolin/examples/VBODisplay/kernal.cu | 30 + .../Pangolin/examples/VBODisplay/main.cpp | 84 + thirdparty/Pangolin/external/CMakeLists.txt | 153 + .../include/experimental/optional.hpp | 1067 + thirdparty/Pangolin/include/mpark/variant.hpp | 2468 +++ .../include/pangolin/compat/glutbitmap.h | 92 + .../include/pangolin/compat/optional.h | 20 + .../include/pangolin/compat/type_traits.h | 49 + .../include/pangolin/compat/variant.h | 25 + .../pangolin/console/ConsoleInterpreter.h | 80 + .../include/pangolin/console/ConsoleView.h | 109 + .../include/pangolin/display/attach.h | 86 + .../pangolin/display/device/OsxWindow.h | 68 + .../display/device/PangolinNSApplication.h | 59 + .../display/device/PangolinNSGLView.h | 45 + .../pangolin/display/device/WinWindow.h | 89 + .../pangolin/display/device/X11GlContext.h | 0 .../pangolin/display/device/X11Window.h | 109 + .../pangolin/display/device/display_android.h | 333 + .../include/pangolin/display/display.h | 219 + .../pangolin/display/display_internal.h | 138 + .../include/pangolin/display/image_view.h | 74 + .../pangolin/display/opengl_render_state.h | 446 + .../include/pangolin/display/user_app.h | 43 + .../Pangolin/include/pangolin/display/view.h | 233 + .../include/pangolin/display/viewport.h | 65 + .../pangolin/display/widgets/widgets.h | 141 + .../include/pangolin/display/window.h | 90 + .../pangolin/factory/factory_registry.h | 114 + .../include/pangolin/geometry/geometry.h | 96 + .../include/pangolin/geometry/geometry_obj.h | 34 + .../include/pangolin/geometry/geometry_ply.h | 157 + .../include/pangolin/geometry/glgeometry.h | 87 + thirdparty/Pangolin/include/pangolin/gl/cg.h | 283 + .../Pangolin/include/pangolin/gl/colour.h | 173 + .../include/pangolin/gl/compat/gl2engine.h | 320 + .../include/pangolin/gl/compat/gl_es_compat.h | 60 + thirdparty/Pangolin/include/pangolin/gl/gl.h | 273 + .../Pangolin/include/pangolin/gl/gl.hpp | 864 + .../Pangolin/include/pangolin/gl/glchar.h | 78 + .../Pangolin/include/pangolin/gl/glcuda.h | 258 + .../Pangolin/include/pangolin/gl/gldraw.h | 518 + .../Pangolin/include/pangolin/gl/glfont.h | 78 + .../include/pangolin/gl/glformattraits.h | 214 + .../Pangolin/include/pangolin/gl/glinclude.h | 46 + .../Pangolin/include/pangolin/gl/glpangoglu.h | 80 + .../include/pangolin/gl/glpixformat.h | 95 + .../Pangolin/include/pangolin/gl/glplatform.h | 83 + .../Pangolin/include/pangolin/gl/glsl.h | 738 + .../Pangolin/include/pangolin/gl/glstate.h | 220 + .../Pangolin/include/pangolin/gl/gltext.h | 98 + .../include/pangolin/gl/gltexturecache.h | 116 + .../Pangolin/include/pangolin/gl/glvbo.h | 225 + .../include/pangolin/handler/handler.h | 116 + .../include/pangolin/handler/handler_enums.h | 94 + .../pangolin/handler/handler_glbuffer.h | 48 + .../include/pangolin/handler/handler_image.h | 162 + .../Pangolin/include/pangolin/image/copy.h | 45 + .../Pangolin/include/pangolin/image/image.h | 428 + .../include/pangolin/image/image_convert.h | 31 + .../include/pangolin/image/image_io.h | 65 + .../include/pangolin/image/image_utils.h | 185 + .../include/pangolin/image/managed_image.h | 175 + .../Pangolin/include/pangolin/image/memcpy.h | 110 + .../include/pangolin/image/pixel_format.h | 66 + .../include/pangolin/image/typed_image.h | 91 + .../pangolin/ios/PangolinAppDelegate.h | 36 + .../include/pangolin/ios/PangolinUIView.h | 22 + .../Pangolin/include/pangolin/log/packet.h | 70 + .../include/pangolin/log/packetstream.h | 111 + .../pangolin/log/packetstream_reader.h | 120 + .../pangolin/log/packetstream_source.h | 63 + .../include/pangolin/log/packetstream_tags.h | 46 + .../pangolin/log/packetstream_writer.h | 173 + .../include/pangolin/log/playback_session.h | 48 + .../Pangolin/include/pangolin/log/sync_time.h | 230 + .../Pangolin/include/pangolin/pangolin.h | 64 + .../Pangolin/include/pangolin/platform.h | 81 + .../Pangolin/include/pangolin/plot/datalog.h | 243 + .../Pangolin/include/pangolin/plot/plotter.h | 279 + .../Pangolin/include/pangolin/plot/range.h | 372 + .../include/pangolin/python/pyinterpreter.h | 70 + .../include/pangolin/python/pypangoio.h | 178 + .../include/pangolin/python/pypangolin_init.h | 40 + .../include/pangolin/python/pyuniqueobj.h | 111 + .../Pangolin/include/pangolin/python/pyvar.h | 271 + .../Pangolin/include/pangolin/scene/axis.h | 117 + .../include/pangolin/scene/interactive.h | 69 + .../pangolin/scene/interactive_index.h | 115 + .../include/pangolin/scene/renderable.h | 117 + .../include/pangolin/scene/scenehandler.h | 182 + .../Pangolin/include/pangolin/scene/tree.h | 49 + .../include/pangolin/tools/video_viewer.h | 106 + .../include/pangolin/utils/argagg.hpp | 1548 ++ .../Pangolin/include/pangolin/utils/assert.h | 60 + .../include/pangolin/utils/compontent_cast.h | 42 + .../include/pangolin/utils/file_extension.h | 74 + .../include/pangolin/utils/file_utils.h | 151 + .../pangolin/utils/fix_size_buffer_queue.h | 153 + .../include/pangolin/utils/format_string.h | 87 + .../Pangolin/include/pangolin/utils/log.h | 44 + .../include/pangolin/utils/memstreambuf.h | 55 + .../Pangolin/include/pangolin/utils/params.h | 80 + .../Pangolin/include/pangolin/utils/parse.h | 108 + .../include/pangolin/utils/picojson.h | 1414 ++ .../pangolin/utils/posix/condition_variable.h | 27 + .../include/pangolin/utils/posix/semaphore.h | 26 + .../utils/posix/shared_memory_buffer.h | 25 + .../include/pangolin/utils/registration.h | 64 + .../include/pangolin/utils/signal_slot.h | 56 + .../include/pangolin/utils/sigstate.h | 75 + .../include/pangolin/utils/simple_math.h | 446 + .../include/pangolin/utils/threadedfilebuf.h | 97 + .../Pangolin/include/pangolin/utils/timer.h | 116 + .../include/pangolin/utils/transform.h | 102 + .../include/pangolin/utils/type_convert.h | 210 + .../Pangolin/include/pangolin/utils/uri.h | 49 + .../include/pangolin/utils/variadic_all.h | 44 + .../include/pangolin/utils/xml/license.txt | 52 + .../include/pangolin/utils/xml/rapidxml.hpp | 2635 +++ .../pangolin/utils/xml/rapidxml_iterators.hpp | 174 + .../pangolin/utils/xml/rapidxml_print.hpp | 421 + .../pangolin/utils/xml/rapidxml_utils.hpp | 122 + .../pangolin/var/input_record_repeat.h | 86 + .../Pangolin/include/pangolin/var/var.h | 340 + .../Pangolin/include/pangolin/var/varextra.h | 92 + .../Pangolin/include/pangolin/var/varstate.h | 130 + .../Pangolin/include/pangolin/var/varvalue.h | 114 + .../include/pangolin/var/varvaluegeneric.h | 87 + .../Pangolin/include/pangolin/var/varvaluet.h | 46 + .../include/pangolin/var/varwrapper.h | 91 + .../include/pangolin/video/drivers/debayer.h | 116 + .../pangolin/video/drivers/deinterlace.h | 62 + .../pangolin/video/drivers/depthsense.h | 171 + .../include/pangolin/video/drivers/ffmpeg.h | 207 + .../include/pangolin/video/drivers/firewire.h | 254 + .../include/pangolin/video/drivers/images.h | 121 + .../pangolin/video/drivers/images_out.h | 60 + .../include/pangolin/video/drivers/join.h | 78 + .../include/pangolin/video/drivers/merge.h | 70 + .../include/pangolin/video/drivers/mirror.h | 96 + .../include/pangolin/video/drivers/openni.h | 72 + .../include/pangolin/video/drivers/openni2.h | 147 + .../pangolin/video/drivers/openni_common.h | 153 + .../include/pangolin/video/drivers/pack.h | 84 + .../include/pangolin/video/drivers/pango.h | 104 + .../video/drivers/pango_video_output.h | 70 + .../include/pangolin/video/drivers/pleora.h | 196 + .../include/pangolin/video/drivers/pvn.h | 77 + .../pangolin/video/drivers/realsense.h | 87 + .../pangolin/video/drivers/realsense2.h | 87 + .../pangolin/video/drivers/shared_memory.h | 37 + .../include/pangolin/video/drivers/shift.h | 73 + .../include/pangolin/video/drivers/split.h | 65 + .../include/pangolin/video/drivers/teli.h | 118 + .../include/pangolin/video/drivers/test.h | 66 + .../include/pangolin/video/drivers/thread.h | 112 + .../include/pangolin/video/drivers/truncate.h | 71 + .../include/pangolin/video/drivers/unpack.h | 84 + .../include/pangolin/video/drivers/uvc.h | 115 + .../video/drivers/uvc_mediafoundation.h | 82 + .../include/pangolin/video/drivers/v4l.h | 128 + .../pangolin/video/iostream_operators.h | 132 + .../pangolin/video/stream_encoder_factory.h | 22 + .../include/pangolin/video/stream_info.h | 100 + .../Pangolin/include/pangolin/video/video.h | 261 + .../include/pangolin/video/video_exception.h | 29 + .../include/pangolin/video/video_input.h | 140 + .../include/pangolin/video/video_interface.h | 183 + .../include/pangolin/video/video_output.h | 93 + .../pangolin/video/video_output_interface.h | 52 + .../pangolin/video/video_record_repeat.h | 31 + .../include/tinyobj/tiny_obj_loader.h | 2547 +++ thirdparty/Pangolin/package.xml | 16 + .../Pangolin/pyexamples/SimpleDisplay.py | 48 + thirdparty/Pangolin/pyexamples/SimplePlot.py | 35 + thirdparty/Pangolin/pyexamples/SimpleVideo.py | 57 + thirdparty/Pangolin/src/CMakeLists.txt | 770 + thirdparty/Pangolin/src/Doxyfile.in | 2281 +++ .../Pangolin/src/PangolinConfig.cmake.in | 14 + .../src/PangolinConfigVersion.cmake.in | 17 + .../src/_embed_/fonts/AnonymousPro.ttf | Bin 0 -> 158080 bytes .../src/_embed_/fonts/AnonymousPro.txt | 94 + thirdparty/Pangolin/src/config.h.in | 72 + .../Pangolin/src/console/ConsoleView.cpp | 327 + .../display/device/PangolinNSApplication.mm | 95 + .../src/display/device/PangolinNSGLView.mm | 325 + .../src/display/device/display_android.cpp | 1026 + .../src/display/device/display_headless.cpp | 166 + .../src/display/device/display_osx.mm | 246 + .../src/display/device/display_wayland.cpp | 1048 + .../src/display/device/display_win.cpp | 599 + .../src/display/device/display_x11.cpp | 531 + thirdparty/Pangolin/src/display/display.cpp | 660 + .../Pangolin/src/display/image_view.cpp | 223 + .../src/display/opengl_render_state.cpp | 707 + thirdparty/Pangolin/src/display/view.cpp | 582 + thirdparty/Pangolin/src/display/viewport.cpp | 113 + .../Pangolin/src/display/widgets/widgets.cpp | 680 + .../Pangolin/src/display/window_factory.cpp | 42 + thirdparty/Pangolin/src/geometry/geometry.cpp | 73 + .../Pangolin/src/geometry/geometry_obj.cpp | 254 + .../Pangolin/src/geometry/geometry_ply.cpp | 483 + .../Pangolin/src/geometry/glgeometry.cpp | 142 + thirdparty/Pangolin/src/geometry/tinyobj.cpp | 29 + .../Pangolin/src/gl/compat/gl2engine.cpp | 39 + thirdparty/Pangolin/src/gl/glchar.cpp | 70 + thirdparty/Pangolin/src/gl/gldraw.cpp | 51 + thirdparty/Pangolin/src/gl/glfont.cpp | 214 + thirdparty/Pangolin/src/gl/glpangoglu.cpp | 264 + thirdparty/Pangolin/src/gl/gltext.cpp | 202 + thirdparty/Pangolin/src/gl/gltexturecache.cpp | 38 + thirdparty/Pangolin/src/gl/stb_truetype.h | 4882 +++++ thirdparty/Pangolin/src/handler/handler.cpp | 401 + .../Pangolin/src/handler/handler_glbuffer.cpp | 45 + .../Pangolin/src/handler/handler_image.cpp | 462 + thirdparty/Pangolin/src/image/image_io.cpp | 177 + .../Pangolin/src/image/image_io_exr.cpp | 188 + .../Pangolin/src/image/image_io_jpg.cpp | 256 + .../Pangolin/src/image/image_io_lz4.cpp | 86 + .../src/image/image_io_packed12bit.cpp | 85 + .../Pangolin/src/image/image_io_pango.cpp | 62 + .../Pangolin/src/image/image_io_png.cpp | 234 + .../Pangolin/src/image/image_io_ppm.cpp | 104 + .../Pangolin/src/image/image_io_raw.cpp | 25 + .../Pangolin/src/image/image_io_tga.cpp | 53 + .../Pangolin/src/image/image_io_zstd.cpp | 125 + .../Pangolin/src/image/pixel_format.cpp | 70 + .../Pangolin/src/ios/PangolinAppDelegate.mm | 49 + thirdparty/Pangolin/src/ios/PangolinUIView.mm | 202 + thirdparty/Pangolin/src/log/packet.cpp | 79 + thirdparty/Pangolin/src/log/packetstream.cpp | 146 + .../Pangolin/src/log/packetstream_reader.cpp | 425 + .../Pangolin/src/log/packetstream_writer.cpp | 156 + .../Pangolin/src/log/playback_session.cpp | 26 + thirdparty/Pangolin/src/plot/datalog.cpp | 287 + thirdparty/Pangolin/src/plot/plotter.cpp | 1165 ++ .../Pangolin/src/python/pyinterpreter.cpp | 239 + .../Pangolin/src/python/pypangolin/attach.cpp | 48 + .../Pangolin/src/python/pypangolin/attach.hpp | 37 + .../Pangolin/src/python/pypangolin/colour.cpp | 48 + .../Pangolin/src/python/pypangolin/colour.hpp | 37 + .../src/python/pypangolin/datalog.cpp | 86 + .../src/python/pypangolin/datalog.hpp | 37 + .../src/python/pypangolin/display.cpp | 81 + .../src/python/pypangolin/display.hpp | 36 + .../src/python/pypangolin/gl_draw.cpp | 41 + .../src/python/pypangolin/gl_draw.hpp | 37 + .../src/python/pypangolin/handler.cpp | 58 + .../src/python/pypangolin/handler.hpp | 62 + .../Pangolin/src/python/pypangolin/image.cpp | 34 + .../Pangolin/src/python/pypangolin/image.hpp | 67 + .../src/python/pypangolin/image_view.cpp | 50 + .../src/python/pypangolin/image_view.hpp | 37 + .../python/pypangolin/opengl_render_state.cpp | 113 + .../python/pypangolin/opengl_render_state.hpp | 37 + .../Pangolin/src/python/pypangolin/params.cpp | 43 + .../Pangolin/src/python/pypangolin/params.hpp | 37 + .../src/python/pypangolin/pixel_format.cpp | 43 + .../src/python/pypangolin/pixel_format.hpp | 37 + .../src/python/pypangolin/plotter.cpp | 131 + .../src/python/pypangolin/plotter.hpp | 37 + .../src/python/pypangolin/pypangolin.h | 79 + .../Pangolin/src/python/pypangolin/var.cpp | 122 + .../Pangolin/src/python/pypangolin/var.hpp | 60 + .../Pangolin/src/python/pypangolin/video.cpp | 645 + .../Pangolin/src/python/pypangolin/video.hpp | 37 + .../Pangolin/src/python/pypangolin/view.cpp | 86 + .../Pangolin/src/python/pypangolin/view.hpp | 37 + .../src/python/pypangolin/viewport.cpp | 53 + .../src/python/pypangolin/viewport.hpp | 38 + .../Pangolin/src/python/pypangolin/widget.cpp | 36 + .../Pangolin/src/python/pypangolin/widget.hpp | 37 + .../Pangolin/src/python/pypangolin/window.cpp | 105 + .../Pangolin/src/python/pypangolin/window.hpp | 37 + .../Pangolin/src/python/pypangolin_init.cpp | 57 + .../Pangolin/src/python/pypangolin_module.cpp | 33 + .../Pangolin/src/tools/video_viewer.cpp | 446 + .../Pangolin/src/utils/file_extension.cpp | 223 + thirdparty/Pangolin/src/utils/file_utils.cpp | 496 + .../src/utils/posix/condition_variable.cpp | 89 + .../Pangolin/src/utils/posix/semaphore.cpp | 83 + .../src/utils/posix/shared_memory_buffer.cpp | 134 + thirdparty/Pangolin/src/utils/sigstate.cpp | 60 + .../Pangolin/src/utils/threadedfilebuf.cpp | 286 + thirdparty/Pangolin/src/utils/timer.cpp | 0 thirdparty/Pangolin/src/utils/uri.cpp | 104 + .../Pangolin/src/var/input_record_repeat.cpp | 183 + thirdparty/Pangolin/src/var/vars.cpp | 259 + .../Pangolin/src/video/drivers/debayer.cpp | 362 + .../src/video/drivers/deinterlace.cpp | 107 + .../Pangolin/src/video/drivers/depthsense.cpp | 656 + .../Pangolin/src/video/drivers/ffmpeg.cpp | 953 + .../Pangolin/src/video/drivers/firewire.cpp | 969 + .../Pangolin/src/video/drivers/images.cpp | 298 + .../Pangolin/src/video/drivers/images_out.cpp | 126 + .../Pangolin/src/video/drivers/join.cpp | 429 + .../Pangolin/src/video/drivers/json.cpp | 86 + .../Pangolin/src/video/drivers/merge.cpp | 165 + .../Pangolin/src/video/drivers/mirror.cpp | 589 + .../Pangolin/src/video/drivers/openni.cpp | 300 + .../Pangolin/src/video/drivers/openni2.cpp | 690 + .../Pangolin/src/video/drivers/pack.cpp | 260 + .../Pangolin/src/video/drivers/pango.cpp | 243 + .../src/video/drivers/pango_video_output.cpp | 303 + .../Pangolin/src/video/drivers/pleora.cpp | 744 + thirdparty/Pangolin/src/video/drivers/pvn.cpp | 136 + .../Pangolin/src/video/drivers/realsense.cpp | 100 + .../Pangolin/src/video/drivers/realsense2.cpp | 114 + .../src/video/drivers/shared_memory.cpp | 99 + .../Pangolin/src/video/drivers/shift.cpp | 159 + .../Pangolin/src/video/drivers/split.cpp | 158 + .../Pangolin/src/video/drivers/teli.cpp | 550 + .../Pangolin/src/video/drivers/test.cpp | 111 + .../Pangolin/src/video/drivers/thread.cpp | 269 + .../Pangolin/src/video/drivers/truncate.cpp | 110 + .../Pangolin/src/video/drivers/unpack.cpp | 268 + thirdparty/Pangolin/src/video/drivers/uvc.cpp | 364 + .../src/video/drivers/uvc_mediafoundation.cpp | 660 + thirdparty/Pangolin/src/video/drivers/v4l.cpp | 798 + .../src/video/stream_encoder_factory.cpp | 62 + thirdparty/Pangolin/src/video/video.cpp | 80 + thirdparty/Pangolin/src/video/video_input.cpp | 220 + .../src/video/video_interface_factory.cpp | 42 + .../Pangolin/src/video/video_output.cpp | 137 + .../video/video_output_interface_factory.cpp | 42 + thirdparty/Pangolin/test/CMakeLists.txt | 1 + thirdparty/Pangolin/test/log/CMakeLists.txt | 6 + thirdparty/Pangolin/test/log/testlog.cpp | 282 + thirdparty/Pangolin/tools/CMakeLists.txt | 17 + .../Pangolin/tools/ModelViewer/CMakeLists.txt | 6 + .../Pangolin/tools/ModelViewer/main.cpp | 270 + .../Pangolin/tools/ModelViewer/rendertree.h | 97 + .../Pangolin/tools/ModelViewer/shader.h | 134 + thirdparty/Pangolin/tools/ModelViewer/util.h | 30 + .../Pangolin/tools/Plotter/CMakeLists.txt | 53 + .../tools/Plotter/application-x-pangoplot.xml | 9 + .../Pangolin/tools/Plotter/csv_data_loader.h | 87 + thirdparty/Pangolin/tools/Plotter/main.cpp | 126 + .../tools/VideoConvert/CMakeLists.txt | 15 + .../Pangolin/tools/VideoConvert/main.cpp | 75 + .../Pangolin/tools/VideoJson/CMakeLists.txt | 18 + .../Pangolin/tools/VideoJson/main-print.cpp | 36 + .../tools/VideoJson/main-transform.cpp | 63 + .../Pangolin/tools/VideoViewer/CMakeLists.txt | 53 + .../tools/VideoViewer/application-x-pango.svg | 424 + .../tools/VideoViewer/application-x-pango.xml | 10 + .../Pangolin/tools/VideoViewer/main.cpp | 51 + thirdparty/abseil-cpp/.clang-format | 4 + thirdparty/abseil-cpp/.gitignore | 8 + .../abseil-cpp/ABSEIL_ISSUE_TEMPLATE.md | 22 + thirdparty/abseil-cpp/AUTHORS | 6 + .../abseil-cpp/CMake/AbseilHelpers.cmake | 272 + thirdparty/abseil-cpp/CMake/CMakeLists.txt.in | 15 + .../abseil-cpp/CMake/DownloadGTest.cmake | 32 + thirdparty/abseil-cpp/CMake/README.md | 107 + thirdparty/abseil-cpp/CMakeLists.txt | 106 + thirdparty/abseil-cpp/CONTRIBUTING.md | 138 + thirdparty/abseil-cpp/LICENSE | 204 + thirdparty/abseil-cpp/LTS.md | 13 + thirdparty/abseil-cpp/README.md | 114 + thirdparty/abseil-cpp/WORKSPACE | 29 + thirdparty/abseil-cpp/absl/BUILD.bazel | 51 + thirdparty/abseil-cpp/absl/CMakeLists.txt | 31 + .../abseil-cpp/absl/algorithm/BUILD.bazel | 81 + .../abseil-cpp/absl/algorithm/CMakeLists.txt | 63 + .../abseil-cpp/absl/algorithm/algorithm.h | 150 + .../absl/algorithm/algorithm_test.cc | 182 + .../abseil-cpp/absl/algorithm/container.h | 1642 ++ .../absl/algorithm/container_test.cc | 1012 + .../absl/algorithm/equal_benchmark.cc | 126 + thirdparty/abseil-cpp/absl/base/BUILD.bazel | 458 + .../abseil-cpp/absl/base/CMakeLists.txt | 396 + thirdparty/abseil-cpp/absl/base/attributes.h | 586 + .../abseil-cpp/absl/base/bit_cast_test.cc | 107 + thirdparty/abseil-cpp/absl/base/call_once.h | 216 + .../abseil-cpp/absl/base/call_once_test.cc | 102 + thirdparty/abseil-cpp/absl/base/casts.h | 189 + thirdparty/abseil-cpp/absl/base/config.h | 426 + .../abseil-cpp/absl/base/config_test.cc | 60 + .../absl/base/dynamic_annotations.cc | 129 + .../absl/base/dynamic_annotations.h | 388 + .../base/exception_safety_testing_test.cc | 954 + .../absl/base/inline_variable_test.cc | 62 + .../absl/base/inline_variable_test_a.cc | 25 + .../absl/base/inline_variable_test_b.cc | 25 + .../absl/base/internal/atomic_hook.h | 165 + .../absl/base/internal/atomic_hook_test.cc | 70 + .../abseil-cpp/absl/base/internal/bits.h | 193 + .../absl/base/internal/bits_test.cc | 97 + .../absl/base/internal/cycleclock.cc | 81 + .../absl/base/internal/cycleclock.h | 77 + .../absl/base/internal/direct_mmap.h | 153 + .../abseil-cpp/absl/base/internal/endian.h | 272 + .../absl/base/internal/endian_test.cc | 263 + .../base/internal/exception_safety_testing.cc | 75 + .../base/internal/exception_safety_testing.h | 1094 ++ .../absl/base/internal/exception_testing.h | 42 + .../abseil-cpp/absl/base/internal/hide_ptr.h | 47 + .../abseil-cpp/absl/base/internal/identity.h | 33 + .../absl/base/internal/inline_variable.h | 107 + .../base/internal/inline_variable_testing.h | 44 + .../abseil-cpp/absl/base/internal/invoke.h | 188 + .../absl/base/internal/low_level_alloc.cc | 614 + .../absl/base/internal/low_level_alloc.h | 122 + .../base/internal/low_level_alloc_test.cc | 157 + .../absl/base/internal/low_level_scheduling.h | 104 + .../absl/base/internal/per_thread_tls.h | 48 + .../absl/base/internal/pretty_function.h | 33 + .../absl/base/internal/raw_logging.cc | 234 + .../absl/base/internal/raw_logging.h | 180 + .../absl/base/internal/scheduling_mode.h | 54 + .../abseil-cpp/absl/base/internal/spinlock.cc | 228 + .../abseil-cpp/absl/base/internal/spinlock.h | 239 + .../absl/base/internal/spinlock_akaros.inc | 35 + .../absl/base/internal/spinlock_linux.inc | 72 + .../absl/base/internal/spinlock_posix.inc | 46 + .../absl/base/internal/spinlock_wait.cc | 81 + .../absl/base/internal/spinlock_wait.h | 91 + .../absl/base/internal/spinlock_win32.inc | 37 + .../abseil-cpp/absl/base/internal/sysinfo.cc | 404 + .../abseil-cpp/absl/base/internal/sysinfo.h | 63 + .../absl/base/internal/sysinfo_test.cc | 98 + .../absl/base/internal/thread_identity.cc | 133 + .../absl/base/internal/thread_identity.h | 240 + .../internal/thread_identity_benchmark.cc | 38 + .../base/internal/thread_identity_test.cc | 126 + .../absl/base/internal/throw_delegate.cc | 106 + .../absl/base/internal/throw_delegate.h | 71 + .../absl/base/internal/tsan_mutex_interface.h | 66 + .../absl/base/internal/unaligned_access.h | 317 + .../absl/base/internal/unscaledcycleclock.cc | 101 + .../absl/base/internal/unscaledcycleclock.h | 119 + .../abseil-cpp/absl/base/invoke_test.cc | 200 + .../abseil-cpp/absl/base/log_severity.h | 67 + thirdparty/abseil-cpp/absl/base/macros.h | 212 + .../abseil-cpp/absl/base/optimization.h | 165 + .../abseil-cpp/absl/base/policy_checks.h | 121 + thirdparty/abseil-cpp/absl/base/port.h | 26 + .../abseil-cpp/absl/base/raw_logging_test.cc | 79 + .../absl/base/spinlock_test_common.cc | 266 + .../abseil-cpp/absl/base/thread_annotations.h | 267 + .../absl/base/throw_delegate_test.cc | 94 + .../absl/compiler_config_setting.bzl | 39 + .../abseil-cpp/absl/container/BUILD.bazel | 647 + .../abseil-cpp/absl/container/CMakeLists.txt | 177 + .../abseil-cpp/absl/container/fixed_array.h | 518 + .../absl/container/fixed_array_benchmark.cc | 66 + .../fixed_array_exception_safety_test.cc | 117 + .../absl/container/fixed_array_test.cc | 872 + .../abseil-cpp/absl/container/flat_hash_map.h | 528 + .../absl/container/flat_hash_map_test.cc | 241 + .../abseil-cpp/absl/container/flat_hash_set.h | 439 + .../absl/container/flat_hash_set_test.cc | 126 + .../absl/container/inlined_vector.h | 1391 ++ .../container/inlined_vector_benchmark.cc | 385 + .../absl/container/inlined_vector_test.cc | 1795 ++ .../container/internal/compressed_tuple.h | 175 + .../internal/compressed_tuple_test.cc | 166 + .../container/internal/container_memory.h | 405 + .../internal/container_memory_test.cc | 188 + .../internal/hash_function_defaults.h | 143 + .../internal/hash_function_defaults_test.cc | 299 + .../internal/hash_generator_testing.cc | 72 + .../internal/hash_generator_testing.h | 150 + .../container/internal/hash_policy_testing.h | 178 + .../internal/hash_policy_testing_test.cc | 43 + .../container/internal/hash_policy_traits.h | 189 + .../internal/hash_policy_traits_test.cc | 142 + .../absl/container/internal/hashtable_debug.h | 108 + .../internal/hashtable_debug_hooks.h | 81 + .../absl/container/internal/layout.h | 732 + .../absl/container/internal/layout_test.cc | 1552 ++ .../container/internal/node_hash_policy.h | 88 + .../internal/node_hash_policy_test.cc | 67 + .../absl/container/internal/raw_hash_map.h | 185 + .../absl/container/internal/raw_hash_set.cc | 45 + .../absl/container/internal/raw_hash_set.h | 1929 ++ .../internal/raw_hash_set_allocator_test.cc | 428 + .../container/internal/raw_hash_set_test.cc | 1954 ++ .../internal/test_instance_tracker.cc | 27 + .../internal/test_instance_tracker.h | 262 + .../internal/test_instance_tracker_test.cc | 182 + .../absl/container/internal/tracked.h | 78 + .../internal/unordered_map_constructor_test.h | 404 + .../internal/unordered_map_lookup_test.h | 114 + .../internal/unordered_map_modifiers_test.h | 272 + .../container/internal/unordered_map_test.cc | 38 + .../internal/unordered_set_constructor_test.h | 408 + .../internal/unordered_set_lookup_test.h | 88 + .../internal/unordered_set_modifiers_test.h | 187 + .../container/internal/unordered_set_test.cc | 37 + .../abseil-cpp/absl/container/node_hash_map.h | 530 + .../absl/container/node_hash_map_test.cc | 218 + .../abseil-cpp/absl/container/node_hash_set.h | 439 + .../absl/container/node_hash_set_test.cc | 103 + thirdparty/abseil-cpp/absl/copts.bzl | 168 + .../abseil-cpp/absl/debugging/BUILD.bazel | 306 + .../abseil-cpp/absl/debugging/CMakeLists.txt | 217 + .../absl/debugging/failure_signal_handler.cc | 355 + .../absl/debugging/failure_signal_handler.h | 117 + .../debugging/failure_signal_handler_test.cc | 155 + .../debugging/internal/address_is_readable.cc | 133 + .../debugging/internal/address_is_readable.h | 29 + .../absl/debugging/internal/demangle.cc | 1862 ++ .../absl/debugging/internal/demangle.h | 67 + .../absl/debugging/internal/demangle_test.cc | 191 + .../absl/debugging/internal/elf_mem_image.cc | 380 + .../absl/debugging/internal/elf_mem_image.h | 130 + .../absl/debugging/internal/examine_stack.cc | 153 + .../absl/debugging/internal/examine_stack.h | 38 + .../debugging/internal/stack_consumption.cc | 172 + .../debugging/internal/stack_consumption.h | 45 + .../internal/stack_consumption_test.cc | 48 + .../internal/stacktrace_aarch64-inl.inc | 190 + .../debugging/internal/stacktrace_arm-inl.inc | 123 + .../debugging/internal/stacktrace_config.h | 70 + .../internal/stacktrace_generic-inl.inc | 60 + .../internal/stacktrace_powerpc-inl.inc | 246 + .../internal/stacktrace_unimplemented-inl.inc | 22 + .../internal/stacktrace_win32-inl.inc | 83 + .../debugging/internal/stacktrace_x86-inl.inc | 337 + .../absl/debugging/internal/symbolize.h | 123 + .../absl/debugging/internal/vdso_support.cc | 192 + .../absl/debugging/internal/vdso_support.h | 156 + .../abseil-cpp/absl/debugging/leak_check.cc | 48 + .../abseil-cpp/absl/debugging/leak_check.h | 109 + .../absl/debugging/leak_check_disable.cc | 20 + .../absl/debugging/leak_check_fail_test.cc | 41 + .../absl/debugging/leak_check_test.cc | 42 + .../abseil-cpp/absl/debugging/stacktrace.cc | 137 + .../abseil-cpp/absl/debugging/stacktrace.h | 225 + .../abseil-cpp/absl/debugging/symbolize.cc | 28 + .../abseil-cpp/absl/debugging/symbolize.h | 97 + .../absl/debugging/symbolize_elf.inc | 1473 ++ .../absl/debugging/symbolize_test.cc | 517 + .../debugging/symbolize_unimplemented.inc | 35 + .../absl/debugging/symbolize_win32.inc | 74 + thirdparty/abseil-cpp/absl/hash/BUILD.bazel | 113 + .../abseil-cpp/absl/hash/CMakeLists.txt | 79 + thirdparty/abseil-cpp/absl/hash/hash.h | 312 + thirdparty/abseil-cpp/absl/hash/hash_test.cc | 425 + .../abseil-cpp/absl/hash/hash_testing.h | 374 + .../abseil-cpp/absl/hash/internal/city.cc | 344 + .../abseil-cpp/absl/hash/internal/city.h | 92 + .../absl/hash/internal/city_test.cc | 593 + .../abseil-cpp/absl/hash/internal/hash.cc | 23 + .../abseil-cpp/absl/hash/internal/hash.h | 894 + .../absl/hash/internal/print_hash_of.cc | 23 + .../absl/hash/internal/spy_hash_state.h | 218 + thirdparty/abseil-cpp/absl/memory/BUILD.bazel | 63 + .../abseil-cpp/absl/memory/CMakeLists.txt | 68 + thirdparty/abseil-cpp/absl/memory/memory.h | 697 + .../memory/memory_exception_safety_test.cc | 52 + .../abseil-cpp/absl/memory/memory_test.cc | 613 + thirdparty/abseil-cpp/absl/meta/BUILD.bazel | 29 + .../abseil-cpp/absl/meta/CMakeLists.txt | 52 + thirdparty/abseil-cpp/absl/meta/type_traits.h | 436 + .../abseil-cpp/absl/meta/type_traits_test.cc | 956 + .../abseil-cpp/absl/numeric/BUILD.bazel | 68 + .../abseil-cpp/absl/numeric/CMakeLists.txt | 62 + thirdparty/abseil-cpp/absl/numeric/int128.cc | 251 + thirdparty/abseil-cpp/absl/numeric/int128.h | 711 + .../absl/numeric/int128_benchmark.cc | 221 + .../absl/numeric/int128_have_intrinsic.inc | 18 + .../absl/numeric/int128_no_intrinsic.inc | 18 + .../absl/numeric/int128_stream_test.cc | 666 + .../abseil-cpp/absl/numeric/int128_test.cc | 443 + .../abseil-cpp/absl/strings/BUILD.bazel | 661 + .../abseil-cpp/absl/strings/CMakeLists.txt | 462 + thirdparty/abseil-cpp/absl/strings/ascii.cc | 198 + thirdparty/abseil-cpp/absl/strings/ascii.h | 239 + .../absl/strings/ascii_benchmark.cc | 120 + .../abseil-cpp/absl/strings/ascii_test.cc | 361 + .../abseil-cpp/absl/strings/charconv.cc | 982 + thirdparty/abseil-cpp/absl/strings/charconv.h | 115 + .../absl/strings/charconv_benchmark.cc | 204 + .../abseil-cpp/absl/strings/charconv_test.cc | 766 + .../abseil-cpp/absl/strings/escaping.cc | 1111 ++ thirdparty/abseil-cpp/absl/strings/escaping.h | 162 + .../absl/strings/escaping_benchmark.cc | 94 + .../abseil-cpp/absl/strings/escaping_test.cc | 646 + .../absl/strings/internal/char_map.h | 154 + .../strings/internal/char_map_benchmark.cc | 61 + .../absl/strings/internal/char_map_test.cc | 172 + .../absl/strings/internal/charconv_bigint.cc | 357 + .../absl/strings/internal/charconv_bigint.h | 419 + .../strings/internal/charconv_bigint_test.cc | 203 + .../absl/strings/internal/charconv_parse.cc | 496 + .../absl/strings/internal/charconv_parse.h | 96 + .../strings/internal/charconv_parse_test.cc | 357 + .../strings/internal/escaping_test_common.h | 131 + .../absl/strings/internal/memutil.cc | 110 + .../absl/strings/internal/memutil.h | 146 + .../strings/internal/memutil_benchmark.cc | 323 + .../absl/strings/internal/memutil_test.cc | 179 + .../strings/internal/numbers_test_common.h | 179 + .../absl/strings/internal/ostringstream.cc | 34 + .../absl/strings/internal/ostringstream.h | 87 + .../internal/ostringstream_benchmark.cc | 106 + .../strings/internal/ostringstream_test.cc | 102 + .../strings/internal/resize_uninitialized.h | 69 + .../internal/resize_uninitialized_test.cc | 68 + .../absl/strings/internal/stl_type_traits.h | 246 + .../absl/strings/internal/str_format/arg.cc | 377 + .../absl/strings/internal/str_format/arg.h | 420 + .../strings/internal/str_format/arg_test.cc | 111 + .../absl/strings/internal/str_format/bind.cc | 229 + .../absl/strings/internal/str_format/bind.h | 197 + .../strings/internal/str_format/bind_test.cc | 131 + .../strings/internal/str_format/checker.h | 325 + .../internal/str_format/checker_test.cc | 150 + .../internal/str_format/convert_test.cc | 575 + .../strings/internal/str_format/extension.cc | 84 + .../strings/internal/str_format/extension.h | 412 + .../internal/str_format/extension_test.cc | 65 + .../internal/str_format/float_conversion.cc | 483 + .../internal/str_format/float_conversion.h | 21 + .../strings/internal/str_format/output.cc | 70 + .../absl/strings/internal/str_format/output.h | 101 + .../internal/str_format/output_test.cc | 78 + .../strings/internal/str_format/parser.cc | 309 + .../absl/strings/internal/str_format/parser.h | 292 + .../internal/str_format/parser_test.cc | 389 + .../absl/strings/internal/str_join_internal.h | 311 + .../strings/internal/str_split_internal.h | 453 + .../abseil-cpp/absl/strings/internal/utf8.cc | 51 + .../abseil-cpp/absl/strings/internal/utf8.h | 47 + .../absl/strings/internal/utf8_test.cc | 57 + thirdparty/abseil-cpp/absl/strings/match.cc | 47 + thirdparty/abseil-cpp/absl/strings/match.h | 89 + .../abseil-cpp/absl/strings/match_test.cc | 110 + thirdparty/abseil-cpp/absl/strings/numbers.cc | 912 + thirdparty/abseil-cpp/absl/strings/numbers.h | 184 + .../absl/strings/numbers_benchmark.cc | 263 + .../abseil-cpp/absl/strings/numbers_test.cc | 1185 ++ thirdparty/abseil-cpp/absl/strings/str_cat.cc | 239 + thirdparty/abseil-cpp/absl/strings/str_cat.h | 385 + .../absl/strings/str_cat_benchmark.cc | 140 + .../abseil-cpp/absl/strings/str_cat_test.cc | 550 + .../abseil-cpp/absl/strings/str_format.h | 512 + .../absl/strings/str_format_test.cc | 626 + thirdparty/abseil-cpp/absl/strings/str_join.h | 289 + .../absl/strings/str_join_benchmark.cc | 96 + .../abseil-cpp/absl/strings/str_join_test.cc | 472 + .../abseil-cpp/absl/strings/str_replace.cc | 79 + .../abseil-cpp/absl/strings/str_replace.h | 213 + .../absl/strings/str_replace_benchmark.cc | 122 + .../absl/strings/str_replace_test.cc | 341 + .../abseil-cpp/absl/strings/str_split.cc | 137 + .../abseil-cpp/absl/strings/str_split.h | 512 + .../absl/strings/str_split_benchmark.cc | 156 + .../abseil-cpp/absl/strings/str_split_test.cc | 935 + .../abseil-cpp/absl/strings/string_view.cc | 245 + .../abseil-cpp/absl/strings/string_view.h | 565 + .../absl/strings/string_view_benchmark.cc | 329 + .../absl/strings/string_view_test.cc | 1150 ++ thirdparty/abseil-cpp/absl/strings/strip.h | 89 + .../abseil-cpp/absl/strings/strip_test.cc | 201 + .../abseil-cpp/absl/strings/substitute.cc | 170 + .../abseil-cpp/absl/strings/substitute.h | 671 + .../absl/strings/substitute_test.cc | 192 + .../absl/strings/testdata/getline-1.txt | 3 + .../absl/strings/testdata/getline-2.txt | 1 + .../absl/synchronization/BUILD.bazel | 245 + .../absl/synchronization/CMakeLists.txt | 155 + .../absl/synchronization/barrier.cc | 50 + .../abseil-cpp/absl/synchronization/barrier.h | 77 + .../absl/synchronization/barrier_test.cc | 75 + .../absl/synchronization/blocking_counter.cc | 55 + .../absl/synchronization/blocking_counter.h | 97 + .../synchronization/blocking_counter_test.cc | 66 + .../internal/create_thread_identity.cc | 112 + .../internal/create_thread_identity.h | 53 + .../synchronization/internal/graphcycles.cc | 695 + .../synchronization/internal/graphcycles.h | 137 + .../internal/graphcycles_benchmark.cc | 44 + .../internal/graphcycles_test.cc | 462 + .../synchronization/internal/kernel_timeout.h | 151 + .../synchronization/internal/mutex_nonprod.cc | 318 + .../internal/mutex_nonprod.inc | 256 + .../internal/per_thread_sem.cc | 99 + .../synchronization/internal/per_thread_sem.h | 107 + .../internal/per_thread_sem_test.cc | 175 + .../synchronization/internal/thread_pool.h | 90 + .../absl/synchronization/internal/waiter.cc | 412 + .../absl/synchronization/internal/waiter.h | 139 + .../absl/synchronization/lifetime_test.cc | 132 + .../abseil-cpp/absl/synchronization/mutex.cc | 2687 +++ .../abseil-cpp/absl/synchronization/mutex.h | 1028 + .../absl/synchronization/mutex_benchmark.cc | 94 + .../absl/synchronization/mutex_test.cc | 1660 ++ .../absl/synchronization/notification.cc | 84 + .../absl/synchronization/notification.h | 112 + .../absl/synchronization/notification_test.cc | 127 + thirdparty/abseil-cpp/absl/time/BUILD.bazel | 115 + .../abseil-cpp/absl/time/CMakeLists.txt | 98 + thirdparty/abseil-cpp/absl/time/civil_time.cc | 88 + thirdparty/abseil-cpp/absl/time/civil_time.h | 486 + .../absl/time/civil_time_benchmark.cc | 57 + .../abseil-cpp/absl/time/civil_time_test.cc | 1073 + thirdparty/abseil-cpp/absl/time/clock.cc | 561 + thirdparty/abseil-cpp/absl/time/clock.h | 72 + .../abseil-cpp/absl/time/clock_benchmark.cc | 72 + thirdparty/abseil-cpp/absl/time/clock_test.cc | 118 + thirdparty/abseil-cpp/absl/time/duration.cc | 904 + .../absl/time/duration_benchmark.cc | 427 + .../abseil-cpp/absl/time/duration_test.cc | 1764 ++ thirdparty/abseil-cpp/absl/time/format.cc | 139 + .../abseil-cpp/absl/time/format_benchmark.cc | 64 + .../abseil-cpp/absl/time/format_test.cc | 435 + .../absl/time/internal/cctz/BUILD.bazel | 140 + .../internal/cctz/include/cctz/civil_time.h | 329 + .../cctz/include/cctz/civil_time_detail.h | 562 + .../internal/cctz/include/cctz/time_zone.h | 385 + .../cctz/include/cctz/zone_info_source.h | 96 + .../time/internal/cctz/src/cctz_benchmark.cc | 980 + .../internal/cctz/src/civil_time_detail.cc | 90 + .../time/internal/cctz/src/civil_time_test.cc | 1049 + .../time/internal/cctz/src/time_zone_fixed.cc | 138 + .../time/internal/cctz/src/time_zone_fixed.h | 49 + .../internal/cctz/src/time_zone_format.cc | 851 + .../cctz/src/time_zone_format_test.cc | 1426 ++ .../time/internal/cctz/src/time_zone_if.cc | 41 + .../time/internal/cctz/src/time_zone_if.h | 72 + .../time/internal/cctz/src/time_zone_impl.cc | 108 + .../time/internal/cctz/src/time_zone_impl.h | 90 + .../time/internal/cctz/src/time_zone_info.cc | 976 + .../time/internal/cctz/src/time_zone_info.h | 136 + .../time/internal/cctz/src/time_zone_libc.cc | 162 + .../time/internal/cctz/src/time_zone_libc.h | 53 + .../internal/cctz/src/time_zone_lookup.cc | 168 + .../cctz/src/time_zone_lookup_test.cc | 1343 ++ .../time/internal/cctz/src/time_zone_posix.cc | 155 + .../time/internal/cctz/src/time_zone_posix.h | 128 + .../absl/time/internal/cctz/src/tzfile.h | 119 + .../internal/cctz/src/zone_info_source.cc | 79 + .../internal/cctz/testdata/README.zoneinfo | 37 + .../absl/time/internal/cctz/testdata/version | 1 + .../cctz/testdata/zoneinfo/Africa/Abidjan | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Accra | Bin 0 -> 828 bytes .../cctz/testdata/zoneinfo/Africa/Addis_Ababa | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Algiers | Bin 0 -> 751 bytes .../cctz/testdata/zoneinfo/Africa/Asmara | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Asmera | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Bamako | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Bangui | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Banjul | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Bissau | Bin 0 -> 194 bytes .../cctz/testdata/zoneinfo/Africa/Blantyre | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Brazzaville | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Bujumbura | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Cairo | Bin 0 -> 1963 bytes .../cctz/testdata/zoneinfo/Africa/Casablanca | Bin 0 -> 1629 bytes .../cctz/testdata/zoneinfo/Africa/Ceuta | Bin 0 -> 2050 bytes .../cctz/testdata/zoneinfo/Africa/Conakry | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Dakar | Bin 0 -> 156 bytes .../testdata/zoneinfo/Africa/Dar_es_Salaam | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Djibouti | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Douala | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/El_Aaiun | Bin 0 -> 1459 bytes .../cctz/testdata/zoneinfo/Africa/Freetown | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Gaborone | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Harare | Bin 0 -> 157 bytes .../testdata/zoneinfo/Africa/Johannesburg | Bin 0 -> 262 bytes .../cctz/testdata/zoneinfo/Africa/Juba | Bin 0 -> 669 bytes .../cctz/testdata/zoneinfo/Africa/Kampala | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Khartoum | Bin 0 -> 699 bytes .../cctz/testdata/zoneinfo/Africa/Kigali | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Kinshasa | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Lagos | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Libreville | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Lome | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Luanda | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Lubumbashi | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Lusaka | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Malabo | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Maputo | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Maseru | Bin 0 -> 262 bytes .../cctz/testdata/zoneinfo/Africa/Mbabane | Bin 0 -> 262 bytes .../cctz/testdata/zoneinfo/Africa/Mogadishu | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Monrovia | Bin 0 -> 224 bytes .../cctz/testdata/zoneinfo/Africa/Nairobi | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Africa/Ndjamena | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Africa/Niamey | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Nouakchott | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Ouagadougou | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Porto-Novo | Bin 0 -> 157 bytes .../cctz/testdata/zoneinfo/Africa/Sao_Tome | Bin 0 -> 225 bytes .../cctz/testdata/zoneinfo/Africa/Timbuktu | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Africa/Tripoli | Bin 0 -> 641 bytes .../cctz/testdata/zoneinfo/Africa/Tunis | Bin 0 -> 701 bytes .../cctz/testdata/zoneinfo/Africa/Windhoek | Bin 0 -> 979 bytes .../cctz/testdata/zoneinfo/America/Adak | Bin 0 -> 2356 bytes .../cctz/testdata/zoneinfo/America/Anchorage | Bin 0 -> 2371 bytes .../cctz/testdata/zoneinfo/America/Anguilla | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Antigua | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Araguaina | Bin 0 -> 896 bytes .../zoneinfo/America/Argentina/Buenos_Aires | Bin 0 -> 1100 bytes .../zoneinfo/America/Argentina/Catamarca | Bin 0 -> 1100 bytes .../zoneinfo/America/Argentina/ComodRivadavia | Bin 0 -> 1100 bytes .../zoneinfo/America/Argentina/Cordoba | Bin 0 -> 1100 bytes .../testdata/zoneinfo/America/Argentina/Jujuy | Bin 0 -> 1072 bytes .../zoneinfo/America/Argentina/La_Rioja | Bin 0 -> 1114 bytes .../zoneinfo/America/Argentina/Mendoza | Bin 0 -> 1100 bytes .../zoneinfo/America/Argentina/Rio_Gallegos | Bin 0 -> 1100 bytes .../testdata/zoneinfo/America/Argentina/Salta | Bin 0 -> 1072 bytes .../zoneinfo/America/Argentina/San_Juan | Bin 0 -> 1114 bytes .../zoneinfo/America/Argentina/San_Luis | Bin 0 -> 1130 bytes .../zoneinfo/America/Argentina/Tucuman | Bin 0 -> 1128 bytes .../zoneinfo/America/Argentina/Ushuaia | Bin 0 -> 1100 bytes .../cctz/testdata/zoneinfo/America/Aruba | Bin 0 -> 198 bytes .../cctz/testdata/zoneinfo/America/Asuncion | Bin 0 -> 2068 bytes .../cctz/testdata/zoneinfo/America/Atikokan | Bin 0 -> 336 bytes .../cctz/testdata/zoneinfo/America/Atka | Bin 0 -> 2356 bytes .../cctz/testdata/zoneinfo/America/Bahia | Bin 0 -> 1036 bytes .../testdata/zoneinfo/America/Bahia_Banderas | Bin 0 -> 1574 bytes .../cctz/testdata/zoneinfo/America/Barbados | Bin 0 -> 330 bytes .../cctz/testdata/zoneinfo/America/Belem | Bin 0 -> 588 bytes .../cctz/testdata/zoneinfo/America/Belize | Bin 0 -> 964 bytes .../testdata/zoneinfo/America/Blanc-Sablon | Bin 0 -> 298 bytes .../cctz/testdata/zoneinfo/America/Boa_Vista | Bin 0 -> 644 bytes .../cctz/testdata/zoneinfo/America/Bogota | Bin 0 -> 262 bytes .../cctz/testdata/zoneinfo/America/Boise | Bin 0 -> 2394 bytes .../testdata/zoneinfo/America/Buenos_Aires | Bin 0 -> 1100 bytes .../testdata/zoneinfo/America/Cambridge_Bay | Bin 0 -> 2084 bytes .../testdata/zoneinfo/America/Campo_Grande | Bin 0 -> 2002 bytes .../cctz/testdata/zoneinfo/America/Cancun | Bin 0 -> 802 bytes .../cctz/testdata/zoneinfo/America/Caracas | Bin 0 -> 280 bytes .../cctz/testdata/zoneinfo/America/Catamarca | Bin 0 -> 1100 bytes .../cctz/testdata/zoneinfo/America/Cayenne | Bin 0 -> 210 bytes .../cctz/testdata/zoneinfo/America/Cayman | Bin 0 -> 194 bytes .../cctz/testdata/zoneinfo/America/Chicago | Bin 0 -> 3576 bytes .../cctz/testdata/zoneinfo/America/Chihuahua | Bin 0 -> 1508 bytes .../testdata/zoneinfo/America/Coral_Harbour | Bin 0 -> 336 bytes .../cctz/testdata/zoneinfo/America/Cordoba | Bin 0 -> 1100 bytes .../cctz/testdata/zoneinfo/America/Costa_Rica | Bin 0 -> 332 bytes .../cctz/testdata/zoneinfo/America/Creston | Bin 0 -> 224 bytes .../cctz/testdata/zoneinfo/America/Cuiaba | Bin 0 -> 1974 bytes .../cctz/testdata/zoneinfo/America/Curacao | Bin 0 -> 198 bytes .../testdata/zoneinfo/America/Danmarkshavn | Bin 0 -> 698 bytes .../cctz/testdata/zoneinfo/America/Dawson | Bin 0 -> 2084 bytes .../testdata/zoneinfo/America/Dawson_Creek | Bin 0 -> 1050 bytes .../cctz/testdata/zoneinfo/America/Denver | Bin 0 -> 2444 bytes .../cctz/testdata/zoneinfo/America/Detroit | Bin 0 -> 2174 bytes .../cctz/testdata/zoneinfo/America/Dominica | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Edmonton | Bin 0 -> 2388 bytes .../cctz/testdata/zoneinfo/America/Eirunepe | Bin 0 -> 676 bytes .../testdata/zoneinfo/America/El_Salvador | Bin 0 -> 236 bytes .../cctz/testdata/zoneinfo/America/Ensenada | Bin 0 -> 2342 bytes .../testdata/zoneinfo/America/Fort_Nelson | Bin 0 -> 2240 bytes .../cctz/testdata/zoneinfo/America/Fort_Wayne | Bin 0 -> 1666 bytes .../cctz/testdata/zoneinfo/America/Fortaleza | Bin 0 -> 728 bytes .../cctz/testdata/zoneinfo/America/Glace_Bay | Bin 0 -> 2192 bytes .../cctz/testdata/zoneinfo/America/Godthab | Bin 0 -> 1878 bytes .../cctz/testdata/zoneinfo/America/Goose_Bay | Bin 0 -> 3210 bytes .../cctz/testdata/zoneinfo/America/Grand_Turk | Bin 0 -> 1872 bytes .../cctz/testdata/zoneinfo/America/Grenada | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Guadeloupe | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Guatemala | Bin 0 -> 292 bytes .../cctz/testdata/zoneinfo/America/Guayaquil | Bin 0 -> 262 bytes .../cctz/testdata/zoneinfo/America/Guyana | Bin 0 -> 252 bytes .../cctz/testdata/zoneinfo/America/Halifax | Bin 0 -> 3424 bytes .../cctz/testdata/zoneinfo/America/Havana | Bin 0 -> 2428 bytes .../cctz/testdata/zoneinfo/America/Hermosillo | Bin 0 -> 440 bytes .../zoneinfo/America/Indiana/Indianapolis | Bin 0 -> 1666 bytes .../testdata/zoneinfo/America/Indiana/Knox | Bin 0 -> 2428 bytes .../testdata/zoneinfo/America/Indiana/Marengo | Bin 0 -> 1722 bytes .../zoneinfo/America/Indiana/Petersburg | Bin 0 -> 1904 bytes .../zoneinfo/America/Indiana/Tell_City | Bin 0 -> 1726 bytes .../testdata/zoneinfo/America/Indiana/Vevay | Bin 0 -> 1414 bytes .../zoneinfo/America/Indiana/Vincennes | Bin 0 -> 1694 bytes .../testdata/zoneinfo/America/Indiana/Winamac | Bin 0 -> 1778 bytes .../testdata/zoneinfo/America/Indianapolis | Bin 0 -> 1666 bytes .../cctz/testdata/zoneinfo/America/Inuvik | Bin 0 -> 1914 bytes .../cctz/testdata/zoneinfo/America/Iqaluit | Bin 0 -> 2032 bytes .../cctz/testdata/zoneinfo/America/Jamaica | Bin 0 -> 498 bytes .../cctz/testdata/zoneinfo/America/Jujuy | Bin 0 -> 1072 bytes .../cctz/testdata/zoneinfo/America/Juneau | Bin 0 -> 2353 bytes .../zoneinfo/America/Kentucky/Louisville | Bin 0 -> 2772 bytes .../zoneinfo/America/Kentucky/Monticello | Bin 0 -> 2352 bytes .../cctz/testdata/zoneinfo/America/Knox_IN | Bin 0 -> 2428 bytes .../cctz/testdata/zoneinfo/America/Kralendijk | Bin 0 -> 198 bytes .../cctz/testdata/zoneinfo/America/La_Paz | Bin 0 -> 248 bytes .../cctz/testdata/zoneinfo/America/Lima | Bin 0 -> 422 bytes .../testdata/zoneinfo/America/Los_Angeles | Bin 0 -> 2836 bytes .../cctz/testdata/zoneinfo/America/Louisville | Bin 0 -> 2772 bytes .../testdata/zoneinfo/America/Lower_Princes | Bin 0 -> 198 bytes .../cctz/testdata/zoneinfo/America/Maceio | Bin 0 -> 756 bytes .../cctz/testdata/zoneinfo/America/Managua | Bin 0 -> 454 bytes .../cctz/testdata/zoneinfo/America/Manaus | Bin 0 -> 616 bytes .../cctz/testdata/zoneinfo/America/Marigot | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Martinique | Bin 0 -> 248 bytes .../cctz/testdata/zoneinfo/America/Matamoros | Bin 0 -> 1402 bytes .../cctz/testdata/zoneinfo/America/Mazatlan | Bin 0 -> 1550 bytes .../cctz/testdata/zoneinfo/America/Mendoza | Bin 0 -> 1100 bytes .../cctz/testdata/zoneinfo/America/Menominee | Bin 0 -> 2274 bytes .../cctz/testdata/zoneinfo/America/Merida | Bin 0 -> 1442 bytes .../cctz/testdata/zoneinfo/America/Metlakatla | Bin 0 -> 1409 bytes .../testdata/zoneinfo/America/Mexico_City | Bin 0 -> 1604 bytes .../cctz/testdata/zoneinfo/America/Miquelon | Bin 0 -> 1682 bytes .../cctz/testdata/zoneinfo/America/Moncton | Bin 0 -> 3154 bytes .../cctz/testdata/zoneinfo/America/Monterrey | Bin 0 -> 1402 bytes .../cctz/testdata/zoneinfo/America/Montevideo | Bin 0 -> 1550 bytes .../cctz/testdata/zoneinfo/America/Montreal | Bin 0 -> 3494 bytes .../cctz/testdata/zoneinfo/America/Montserrat | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Nassau | Bin 0 -> 2270 bytes .../cctz/testdata/zoneinfo/America/New_York | Bin 0 -> 3536 bytes .../cctz/testdata/zoneinfo/America/Nipigon | Bin 0 -> 2122 bytes .../cctz/testdata/zoneinfo/America/Nome | Bin 0 -> 2367 bytes .../cctz/testdata/zoneinfo/America/Noronha | Bin 0 -> 728 bytes .../zoneinfo/America/North_Dakota/Beulah | Bin 0 -> 2380 bytes .../zoneinfo/America/North_Dakota/Center | Bin 0 -> 2380 bytes .../zoneinfo/America/North_Dakota/New_Salem | Bin 0 -> 2380 bytes .../cctz/testdata/zoneinfo/America/Ojinaga | Bin 0 -> 1508 bytes .../cctz/testdata/zoneinfo/America/Panama | Bin 0 -> 194 bytes .../testdata/zoneinfo/America/Pangnirtung | Bin 0 -> 2094 bytes .../cctz/testdata/zoneinfo/America/Paramaribo | Bin 0 -> 282 bytes .../cctz/testdata/zoneinfo/America/Phoenix | Bin 0 -> 344 bytes .../testdata/zoneinfo/America/Port-au-Prince | Bin 0 -> 1446 bytes .../testdata/zoneinfo/America/Port_of_Spain | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Porto_Acre | Bin 0 -> 648 bytes .../testdata/zoneinfo/America/Porto_Velho | Bin 0 -> 588 bytes .../testdata/zoneinfo/America/Puerto_Rico | Bin 0 -> 246 bytes .../testdata/zoneinfo/America/Punta_Arenas | Bin 0 -> 1902 bytes .../testdata/zoneinfo/America/Rainy_River | Bin 0 -> 2122 bytes .../testdata/zoneinfo/America/Rankin_Inlet | Bin 0 -> 1916 bytes .../cctz/testdata/zoneinfo/America/Recife | Bin 0 -> 728 bytes .../cctz/testdata/zoneinfo/America/Regina | Bin 0 -> 980 bytes .../cctz/testdata/zoneinfo/America/Resolute | Bin 0 -> 1916 bytes .../cctz/testdata/zoneinfo/America/Rio_Branco | Bin 0 -> 648 bytes .../cctz/testdata/zoneinfo/America/Rosario | Bin 0 -> 1100 bytes .../testdata/zoneinfo/America/Santa_Isabel | Bin 0 -> 2342 bytes .../cctz/testdata/zoneinfo/America/Santarem | Bin 0 -> 618 bytes .../cctz/testdata/zoneinfo/America/Santiago | Bin 0 -> 2529 bytes .../testdata/zoneinfo/America/Santo_Domingo | Bin 0 -> 482 bytes .../cctz/testdata/zoneinfo/America/Sao_Paulo | Bin 0 -> 2002 bytes .../testdata/zoneinfo/America/Scoresbysund | Bin 0 -> 1916 bytes .../cctz/testdata/zoneinfo/America/Shiprock | Bin 0 -> 2444 bytes .../cctz/testdata/zoneinfo/America/Sitka | Bin 0 -> 2329 bytes .../testdata/zoneinfo/America/St_Barthelemy | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/St_Johns | Bin 0 -> 3655 bytes .../cctz/testdata/zoneinfo/America/St_Kitts | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/St_Lucia | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/St_Thomas | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/St_Vincent | Bin 0 -> 156 bytes .../testdata/zoneinfo/America/Swift_Current | Bin 0 -> 560 bytes .../testdata/zoneinfo/America/Tegucigalpa | Bin 0 -> 264 bytes .../cctz/testdata/zoneinfo/America/Thule | Bin 0 -> 1514 bytes .../testdata/zoneinfo/America/Thunder_Bay | Bin 0 -> 2202 bytes .../cctz/testdata/zoneinfo/America/Tijuana | Bin 0 -> 2342 bytes .../cctz/testdata/zoneinfo/America/Toronto | Bin 0 -> 3494 bytes .../cctz/testdata/zoneinfo/America/Tortola | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Vancouver | Bin 0 -> 2892 bytes .../cctz/testdata/zoneinfo/America/Virgin | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/America/Whitehorse | Bin 0 -> 2084 bytes .../cctz/testdata/zoneinfo/America/Winnipeg | Bin 0 -> 2882 bytes .../cctz/testdata/zoneinfo/America/Yakutat | Bin 0 -> 2305 bytes .../testdata/zoneinfo/America/Yellowknife | Bin 0 -> 1966 bytes .../cctz/testdata/zoneinfo/Antarctica/Casey | Bin 0 -> 297 bytes .../cctz/testdata/zoneinfo/Antarctica/Davis | Bin 0 -> 297 bytes .../zoneinfo/Antarctica/DumontDUrville | Bin 0 -> 202 bytes .../testdata/zoneinfo/Antarctica/Macquarie | Bin 0 -> 1534 bytes .../cctz/testdata/zoneinfo/Antarctica/Mawson | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Antarctica/McMurdo | Bin 0 -> 2451 bytes .../cctz/testdata/zoneinfo/Antarctica/Palmer | Bin 0 -> 1418 bytes .../cctz/testdata/zoneinfo/Antarctica/Rothera | Bin 0 -> 172 bytes .../testdata/zoneinfo/Antarctica/South_Pole | Bin 0 -> 2451 bytes .../cctz/testdata/zoneinfo/Antarctica/Syowa | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Antarctica/Troll | Bin 0 -> 1162 bytes .../cctz/testdata/zoneinfo/Antarctica/Vostok | Bin 0 -> 173 bytes .../testdata/zoneinfo/Arctic/Longyearbyen | Bin 0 -> 2242 bytes .../internal/cctz/testdata/zoneinfo/Asia/Aden | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Asia/Almaty | Bin 0 -> 1017 bytes .../cctz/testdata/zoneinfo/Asia/Amman | Bin 0 -> 1863 bytes .../cctz/testdata/zoneinfo/Asia/Anadyr | Bin 0 -> 1208 bytes .../cctz/testdata/zoneinfo/Asia/Aqtau | Bin 0 -> 1003 bytes .../cctz/testdata/zoneinfo/Asia/Aqtobe | Bin 0 -> 1033 bytes .../cctz/testdata/zoneinfo/Asia/Ashgabat | Bin 0 -> 637 bytes .../cctz/testdata/zoneinfo/Asia/Ashkhabad | Bin 0 -> 637 bytes .../cctz/testdata/zoneinfo/Asia/Atyrau | Bin 0 -> 1011 bytes .../cctz/testdata/zoneinfo/Asia/Baghdad | Bin 0 -> 995 bytes .../cctz/testdata/zoneinfo/Asia/Bahrain | Bin 0 -> 211 bytes .../internal/cctz/testdata/zoneinfo/Asia/Baku | Bin 0 -> 1255 bytes .../cctz/testdata/zoneinfo/Asia/Bangkok | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Asia/Barnaul | Bin 0 -> 1241 bytes .../cctz/testdata/zoneinfo/Asia/Beirut | Bin 0 -> 2166 bytes .../cctz/testdata/zoneinfo/Asia/Bishkek | Bin 0 -> 999 bytes .../cctz/testdata/zoneinfo/Asia/Brunei | Bin 0 -> 215 bytes .../cctz/testdata/zoneinfo/Asia/Calcutta | Bin 0 -> 303 bytes .../cctz/testdata/zoneinfo/Asia/Chita | Bin 0 -> 1243 bytes .../cctz/testdata/zoneinfo/Asia/Choibalsan | Bin 0 -> 977 bytes .../cctz/testdata/zoneinfo/Asia/Chongqing | Bin 0 -> 545 bytes .../cctz/testdata/zoneinfo/Asia/Chungking | Bin 0 -> 545 bytes .../cctz/testdata/zoneinfo/Asia/Colombo | Bin 0 -> 404 bytes .../cctz/testdata/zoneinfo/Asia/Dacca | Bin 0 -> 361 bytes .../cctz/testdata/zoneinfo/Asia/Damascus | Bin 0 -> 2306 bytes .../cctz/testdata/zoneinfo/Asia/Dhaka | Bin 0 -> 361 bytes .../internal/cctz/testdata/zoneinfo/Asia/Dili | Bin 0 -> 239 bytes .../cctz/testdata/zoneinfo/Asia/Dubai | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Asia/Dushanbe | Bin 0 -> 607 bytes .../cctz/testdata/zoneinfo/Asia/Famagusta | Bin 0 -> 2028 bytes .../internal/cctz/testdata/zoneinfo/Asia/Gaza | Bin 0 -> 2286 bytes .../cctz/testdata/zoneinfo/Asia/Harbin | Bin 0 -> 545 bytes .../cctz/testdata/zoneinfo/Asia/Hebron | Bin 0 -> 2314 bytes .../cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh | Bin 0 -> 375 bytes .../cctz/testdata/zoneinfo/Asia/Hong_Kong | Bin 0 -> 1175 bytes .../internal/cctz/testdata/zoneinfo/Asia/Hovd | Bin 0 -> 907 bytes .../cctz/testdata/zoneinfo/Asia/Irkutsk | Bin 0 -> 1267 bytes .../cctz/testdata/zoneinfo/Asia/Istanbul | Bin 0 -> 2157 bytes .../cctz/testdata/zoneinfo/Asia/Jakarta | Bin 0 -> 383 bytes .../cctz/testdata/zoneinfo/Asia/Jayapura | Bin 0 -> 237 bytes .../cctz/testdata/zoneinfo/Asia/Jerusalem | Bin 0 -> 2256 bytes .../cctz/testdata/zoneinfo/Asia/Kabul | Bin 0 -> 220 bytes .../cctz/testdata/zoneinfo/Asia/Kamchatka | Bin 0 -> 1184 bytes .../cctz/testdata/zoneinfo/Asia/Karachi | Bin 0 -> 403 bytes .../cctz/testdata/zoneinfo/Asia/Kashgar | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Asia/Kathmandu | Bin 0 -> 224 bytes .../cctz/testdata/zoneinfo/Asia/Katmandu | Bin 0 -> 224 bytes .../cctz/testdata/zoneinfo/Asia/Khandyga | Bin 0 -> 1297 bytes .../cctz/testdata/zoneinfo/Asia/Kolkata | Bin 0 -> 303 bytes .../cctz/testdata/zoneinfo/Asia/Krasnoyarsk | Bin 0 -> 1229 bytes .../cctz/testdata/zoneinfo/Asia/Kuala_Lumpur | Bin 0 -> 415 bytes .../cctz/testdata/zoneinfo/Asia/Kuching | Bin 0 -> 507 bytes .../cctz/testdata/zoneinfo/Asia/Kuwait | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Asia/Macao | Bin 0 -> 1241 bytes .../cctz/testdata/zoneinfo/Asia/Macau | Bin 0 -> 1241 bytes .../cctz/testdata/zoneinfo/Asia/Magadan | Bin 0 -> 1244 bytes .../cctz/testdata/zoneinfo/Asia/Makassar | Bin 0 -> 274 bytes .../cctz/testdata/zoneinfo/Asia/Manila | Bin 0 -> 350 bytes .../cctz/testdata/zoneinfo/Asia/Muscat | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Asia/Nicosia | Bin 0 -> 2002 bytes .../cctz/testdata/zoneinfo/Asia/Novokuznetsk | Bin 0 -> 1183 bytes .../cctz/testdata/zoneinfo/Asia/Novosibirsk | Bin 0 -> 1241 bytes .../internal/cctz/testdata/zoneinfo/Asia/Omsk | Bin 0 -> 1229 bytes .../internal/cctz/testdata/zoneinfo/Asia/Oral | Bin 0 -> 1025 bytes .../cctz/testdata/zoneinfo/Asia/Phnom_Penh | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Asia/Pontianak | Bin 0 -> 381 bytes .../cctz/testdata/zoneinfo/Asia/Pyongyang | Bin 0 -> 253 bytes .../cctz/testdata/zoneinfo/Asia/Qatar | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Asia/Qyzylorda | Bin 0 -> 1017 bytes .../cctz/testdata/zoneinfo/Asia/Rangoon | Bin 0 -> 288 bytes .../cctz/testdata/zoneinfo/Asia/Riyadh | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Asia/Saigon | Bin 0 -> 375 bytes .../cctz/testdata/zoneinfo/Asia/Sakhalin | Bin 0 -> 1220 bytes .../cctz/testdata/zoneinfo/Asia/Samarkand | Bin 0 -> 605 bytes .../cctz/testdata/zoneinfo/Asia/Seoul | Bin 0 -> 517 bytes .../cctz/testdata/zoneinfo/Asia/Shanghai | Bin 0 -> 545 bytes .../cctz/testdata/zoneinfo/Asia/Singapore | Bin 0 -> 415 bytes .../cctz/testdata/zoneinfo/Asia/Srednekolymsk | Bin 0 -> 1230 bytes .../cctz/testdata/zoneinfo/Asia/Taipei | Bin 0 -> 781 bytes .../cctz/testdata/zoneinfo/Asia/Tashkent | Bin 0 -> 621 bytes .../cctz/testdata/zoneinfo/Asia/Tbilisi | Bin 0 -> 1071 bytes .../cctz/testdata/zoneinfo/Asia/Tehran | Bin 0 -> 1704 bytes .../cctz/testdata/zoneinfo/Asia/Tel_Aviv | Bin 0 -> 2256 bytes .../cctz/testdata/zoneinfo/Asia/Thimbu | Bin 0 -> 215 bytes .../cctz/testdata/zoneinfo/Asia/Thimphu | Bin 0 -> 215 bytes .../cctz/testdata/zoneinfo/Asia/Tokyo | Bin 0 -> 309 bytes .../cctz/testdata/zoneinfo/Asia/Tomsk | Bin 0 -> 1241 bytes .../cctz/testdata/zoneinfo/Asia/Ujung_Pandang | Bin 0 -> 274 bytes .../cctz/testdata/zoneinfo/Asia/Ulaanbaatar | Bin 0 -> 907 bytes .../cctz/testdata/zoneinfo/Asia/Ulan_Bator | Bin 0 -> 907 bytes .../cctz/testdata/zoneinfo/Asia/Urumqi | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Asia/Ust-Nera | Bin 0 -> 1276 bytes .../cctz/testdata/zoneinfo/Asia/Vientiane | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Asia/Vladivostok | Bin 0 -> 1230 bytes .../cctz/testdata/zoneinfo/Asia/Yakutsk | Bin 0 -> 1229 bytes .../cctz/testdata/zoneinfo/Asia/Yangon | Bin 0 -> 288 bytes .../cctz/testdata/zoneinfo/Asia/Yekaterinburg | Bin 0 -> 1267 bytes .../cctz/testdata/zoneinfo/Asia/Yerevan | Bin 0 -> 1199 bytes .../cctz/testdata/zoneinfo/Atlantic/Azores | Bin 0 -> 3484 bytes .../cctz/testdata/zoneinfo/Atlantic/Bermuda | Bin 0 -> 1990 bytes .../cctz/testdata/zoneinfo/Atlantic/Canary | Bin 0 -> 1897 bytes .../testdata/zoneinfo/Atlantic/Cape_Verde | Bin 0 -> 270 bytes .../cctz/testdata/zoneinfo/Atlantic/Faeroe | Bin 0 -> 1815 bytes .../cctz/testdata/zoneinfo/Atlantic/Faroe | Bin 0 -> 1815 bytes .../cctz/testdata/zoneinfo/Atlantic/Jan_Mayen | Bin 0 -> 2242 bytes .../cctz/testdata/zoneinfo/Atlantic/Madeira | Bin 0 -> 3475 bytes .../cctz/testdata/zoneinfo/Atlantic/Reykjavik | Bin 0 -> 1174 bytes .../testdata/zoneinfo/Atlantic/South_Georgia | Bin 0 -> 172 bytes .../cctz/testdata/zoneinfo/Atlantic/St_Helena | Bin 0 -> 156 bytes .../cctz/testdata/zoneinfo/Atlantic/Stanley | Bin 0 -> 1242 bytes .../cctz/testdata/zoneinfo/Australia/ACT | Bin 0 -> 2214 bytes .../cctz/testdata/zoneinfo/Australia/Adelaide | Bin 0 -> 2233 bytes .../cctz/testdata/zoneinfo/Australia/Brisbane | Bin 0 -> 443 bytes .../testdata/zoneinfo/Australia/Broken_Hill | Bin 0 -> 2269 bytes .../cctz/testdata/zoneinfo/Australia/Canberra | Bin 0 -> 2214 bytes .../cctz/testdata/zoneinfo/Australia/Currie | Bin 0 -> 2214 bytes .../cctz/testdata/zoneinfo/Australia/Darwin | Bin 0 -> 318 bytes .../cctz/testdata/zoneinfo/Australia/Eucla | Bin 0 -> 494 bytes .../cctz/testdata/zoneinfo/Australia/Hobart | Bin 0 -> 2326 bytes .../cctz/testdata/zoneinfo/Australia/LHI | Bin 0 -> 1880 bytes .../cctz/testdata/zoneinfo/Australia/Lindeman | Bin 0 -> 513 bytes .../testdata/zoneinfo/Australia/Lord_Howe | Bin 0 -> 1880 bytes .../testdata/zoneinfo/Australia/Melbourne | Bin 0 -> 2214 bytes .../cctz/testdata/zoneinfo/Australia/NSW | Bin 0 -> 2214 bytes .../cctz/testdata/zoneinfo/Australia/North | Bin 0 -> 318 bytes .../cctz/testdata/zoneinfo/Australia/Perth | Bin 0 -> 470 bytes .../testdata/zoneinfo/Australia/Queensland | Bin 0 -> 443 bytes .../cctz/testdata/zoneinfo/Australia/South | Bin 0 -> 2233 bytes .../cctz/testdata/zoneinfo/Australia/Sydney | Bin 0 -> 2214 bytes .../cctz/testdata/zoneinfo/Australia/Tasmania | Bin 0 -> 2326 bytes .../cctz/testdata/zoneinfo/Australia/Victoria | Bin 0 -> 2214 bytes .../cctz/testdata/zoneinfo/Australia/West | Bin 0 -> 470 bytes .../testdata/zoneinfo/Australia/Yancowinna | Bin 0 -> 2269 bytes .../cctz/testdata/zoneinfo/Brazil/Acre | Bin 0 -> 648 bytes .../cctz/testdata/zoneinfo/Brazil/DeNoronha | Bin 0 -> 728 bytes .../cctz/testdata/zoneinfo/Brazil/East | Bin 0 -> 2002 bytes .../cctz/testdata/zoneinfo/Brazil/West | Bin 0 -> 616 bytes .../time/internal/cctz/testdata/zoneinfo/CET | Bin 0 -> 2102 bytes .../internal/cctz/testdata/zoneinfo/CST6CDT | Bin 0 -> 2294 bytes .../cctz/testdata/zoneinfo/Canada/Atlantic | Bin 0 -> 3424 bytes .../cctz/testdata/zoneinfo/Canada/Central | Bin 0 -> 2882 bytes .../cctz/testdata/zoneinfo/Canada/Eastern | Bin 0 -> 3494 bytes .../cctz/testdata/zoneinfo/Canada/Mountain | Bin 0 -> 2388 bytes .../testdata/zoneinfo/Canada/Newfoundland | Bin 0 -> 3655 bytes .../cctz/testdata/zoneinfo/Canada/Pacific | Bin 0 -> 2892 bytes .../testdata/zoneinfo/Canada/Saskatchewan | Bin 0 -> 980 bytes .../cctz/testdata/zoneinfo/Canada/Yukon | Bin 0 -> 2084 bytes .../cctz/testdata/zoneinfo/Chile/Continental | Bin 0 -> 2529 bytes .../cctz/testdata/zoneinfo/Chile/EasterIsland | Bin 0 -> 2233 bytes .../time/internal/cctz/testdata/zoneinfo/Cuba | Bin 0 -> 2428 bytes .../time/internal/cctz/testdata/zoneinfo/EET | Bin 0 -> 1876 bytes .../time/internal/cctz/testdata/zoneinfo/EST | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/EST5EDT | Bin 0 -> 2294 bytes .../internal/cctz/testdata/zoneinfo/Egypt | Bin 0 -> 1963 bytes .../time/internal/cctz/testdata/zoneinfo/Eire | Bin 0 -> 3522 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+0 | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+1 | Bin 0 -> 120 bytes .../cctz/testdata/zoneinfo/Etc/GMT+10 | Bin 0 -> 121 bytes .../cctz/testdata/zoneinfo/Etc/GMT+11 | Bin 0 -> 121 bytes .../cctz/testdata/zoneinfo/Etc/GMT+12 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+2 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+3 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+4 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+5 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+6 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+7 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+8 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT+9 | Bin 0 -> 120 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-0 | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-1 | Bin 0 -> 121 bytes .../cctz/testdata/zoneinfo/Etc/GMT-10 | Bin 0 -> 122 bytes .../cctz/testdata/zoneinfo/Etc/GMT-11 | Bin 0 -> 122 bytes .../cctz/testdata/zoneinfo/Etc/GMT-12 | Bin 0 -> 122 bytes .../cctz/testdata/zoneinfo/Etc/GMT-13 | Bin 0 -> 122 bytes .../cctz/testdata/zoneinfo/Etc/GMT-14 | Bin 0 -> 122 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-2 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-3 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-4 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-5 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-6 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-7 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-8 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT-9 | Bin 0 -> 121 bytes .../internal/cctz/testdata/zoneinfo/Etc/GMT0 | Bin 0 -> 118 bytes .../cctz/testdata/zoneinfo/Etc/Greenwich | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Etc/UCT | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Etc/UTC | Bin 0 -> 118 bytes .../cctz/testdata/zoneinfo/Etc/Universal | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Etc/Zulu | Bin 0 -> 118 bytes .../cctz/testdata/zoneinfo/Europe/Amsterdam | Bin 0 -> 2940 bytes .../cctz/testdata/zoneinfo/Europe/Andorra | Bin 0 -> 1742 bytes .../cctz/testdata/zoneinfo/Europe/Astrakhan | Bin 0 -> 1183 bytes .../cctz/testdata/zoneinfo/Europe/Athens | Bin 0 -> 2262 bytes .../cctz/testdata/zoneinfo/Europe/Belfast | Bin 0 -> 3678 bytes .../cctz/testdata/zoneinfo/Europe/Belgrade | Bin 0 -> 1948 bytes .../cctz/testdata/zoneinfo/Europe/Berlin | Bin 0 -> 2326 bytes .../cctz/testdata/zoneinfo/Europe/Bratislava | Bin 0 -> 2329 bytes .../cctz/testdata/zoneinfo/Europe/Brussels | Bin 0 -> 2961 bytes .../cctz/testdata/zoneinfo/Europe/Bucharest | Bin 0 -> 2212 bytes .../cctz/testdata/zoneinfo/Europe/Budapest | Bin 0 -> 2396 bytes .../cctz/testdata/zoneinfo/Europe/Busingen | Bin 0 -> 1909 bytes .../cctz/testdata/zoneinfo/Europe/Chisinau | Bin 0 -> 2436 bytes .../cctz/testdata/zoneinfo/Europe/Copenhagen | Bin 0 -> 2151 bytes .../cctz/testdata/zoneinfo/Europe/Dublin | Bin 0 -> 3522 bytes .../cctz/testdata/zoneinfo/Europe/Gibraltar | Bin 0 -> 3052 bytes .../cctz/testdata/zoneinfo/Europe/Guernsey | Bin 0 -> 3678 bytes .../cctz/testdata/zoneinfo/Europe/Helsinki | Bin 0 -> 1900 bytes .../cctz/testdata/zoneinfo/Europe/Isle_of_Man | Bin 0 -> 3678 bytes .../cctz/testdata/zoneinfo/Europe/Istanbul | Bin 0 -> 2157 bytes .../cctz/testdata/zoneinfo/Europe/Jersey | Bin 0 -> 3678 bytes .../cctz/testdata/zoneinfo/Europe/Kaliningrad | Bin 0 -> 1509 bytes .../cctz/testdata/zoneinfo/Europe/Kiev | Bin 0 -> 2088 bytes .../cctz/testdata/zoneinfo/Europe/Kirov | Bin 0 -> 1153 bytes .../cctz/testdata/zoneinfo/Europe/Lisbon | Bin 0 -> 3469 bytes .../cctz/testdata/zoneinfo/Europe/Ljubljana | Bin 0 -> 1948 bytes .../cctz/testdata/zoneinfo/Europe/London | Bin 0 -> 3678 bytes .../cctz/testdata/zoneinfo/Europe/Luxembourg | Bin 0 -> 2960 bytes .../cctz/testdata/zoneinfo/Europe/Madrid | Bin 0 -> 2628 bytes .../cctz/testdata/zoneinfo/Europe/Malta | Bin 0 -> 2620 bytes .../cctz/testdata/zoneinfo/Europe/Mariehamn | Bin 0 -> 1900 bytes .../cctz/testdata/zoneinfo/Europe/Minsk | Bin 0 -> 1361 bytes .../cctz/testdata/zoneinfo/Europe/Monaco | Bin 0 -> 2944 bytes .../cctz/testdata/zoneinfo/Europe/Moscow | Bin 0 -> 1535 bytes .../cctz/testdata/zoneinfo/Europe/Nicosia | Bin 0 -> 2002 bytes .../cctz/testdata/zoneinfo/Europe/Oslo | Bin 0 -> 2242 bytes .../cctz/testdata/zoneinfo/Europe/Paris | Bin 0 -> 2962 bytes .../cctz/testdata/zoneinfo/Europe/Podgorica | Bin 0 -> 1948 bytes .../cctz/testdata/zoneinfo/Europe/Prague | Bin 0 -> 2329 bytes .../cctz/testdata/zoneinfo/Europe/Riga | Bin 0 -> 2226 bytes .../cctz/testdata/zoneinfo/Europe/Rome | Bin 0 -> 2683 bytes .../cctz/testdata/zoneinfo/Europe/Samara | Bin 0 -> 1215 bytes .../cctz/testdata/zoneinfo/Europe/San_Marino | Bin 0 -> 2683 bytes .../cctz/testdata/zoneinfo/Europe/Sarajevo | Bin 0 -> 1948 bytes .../cctz/testdata/zoneinfo/Europe/Saratov | Bin 0 -> 1183 bytes .../cctz/testdata/zoneinfo/Europe/Simferopol | Bin 0 -> 1481 bytes .../cctz/testdata/zoneinfo/Europe/Skopje | Bin 0 -> 1948 bytes .../cctz/testdata/zoneinfo/Europe/Sofia | Bin 0 -> 2121 bytes .../cctz/testdata/zoneinfo/Europe/Stockholm | Bin 0 -> 1909 bytes .../cctz/testdata/zoneinfo/Europe/Tallinn | Bin 0 -> 2178 bytes .../cctz/testdata/zoneinfo/Europe/Tirane | Bin 0 -> 2084 bytes .../cctz/testdata/zoneinfo/Europe/Tiraspol | Bin 0 -> 2436 bytes .../cctz/testdata/zoneinfo/Europe/Ulyanovsk | Bin 0 -> 1267 bytes .../cctz/testdata/zoneinfo/Europe/Uzhgorod | Bin 0 -> 2094 bytes .../cctz/testdata/zoneinfo/Europe/Vaduz | Bin 0 -> 1909 bytes .../cctz/testdata/zoneinfo/Europe/Vatican | Bin 0 -> 2683 bytes .../cctz/testdata/zoneinfo/Europe/Vienna | Bin 0 -> 2228 bytes .../cctz/testdata/zoneinfo/Europe/Vilnius | Bin 0 -> 2190 bytes .../cctz/testdata/zoneinfo/Europe/Volgograd | Bin 0 -> 1183 bytes .../cctz/testdata/zoneinfo/Europe/Warsaw | Bin 0 -> 2696 bytes .../cctz/testdata/zoneinfo/Europe/Zagreb | Bin 0 -> 1948 bytes .../cctz/testdata/zoneinfo/Europe/Zaporozhye | Bin 0 -> 2106 bytes .../cctz/testdata/zoneinfo/Europe/Zurich | Bin 0 -> 1909 bytes .../internal/cctz/testdata/zoneinfo/Factory | Bin 0 -> 120 bytes .../time/internal/cctz/testdata/zoneinfo/GB | Bin 0 -> 3678 bytes .../internal/cctz/testdata/zoneinfo/GB-Eire | Bin 0 -> 3678 bytes .../time/internal/cctz/testdata/zoneinfo/GMT | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/GMT+0 | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/GMT-0 | Bin 0 -> 118 bytes .../time/internal/cctz/testdata/zoneinfo/GMT0 | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Greenwich | Bin 0 -> 118 bytes .../time/internal/cctz/testdata/zoneinfo/HST | Bin 0 -> 119 bytes .../internal/cctz/testdata/zoneinfo/Hongkong | Bin 0 -> 1175 bytes .../internal/cctz/testdata/zoneinfo/Iceland | Bin 0 -> 1174 bytes .../testdata/zoneinfo/Indian/Antananarivo | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Indian/Chagos | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Indian/Christmas | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Indian/Cocos | Bin 0 -> 182 bytes .../cctz/testdata/zoneinfo/Indian/Comoro | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Indian/Kerguelen | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Indian/Mahe | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Indian/Maldives | Bin 0 -> 211 bytes .../cctz/testdata/zoneinfo/Indian/Mauritius | Bin 0 -> 253 bytes .../cctz/testdata/zoneinfo/Indian/Mayotte | Bin 0 -> 271 bytes .../cctz/testdata/zoneinfo/Indian/Reunion | Bin 0 -> 173 bytes .../time/internal/cctz/testdata/zoneinfo/Iran | Bin 0 -> 1704 bytes .../internal/cctz/testdata/zoneinfo/Israel | Bin 0 -> 2256 bytes .../internal/cctz/testdata/zoneinfo/Jamaica | Bin 0 -> 498 bytes .../internal/cctz/testdata/zoneinfo/Japan | Bin 0 -> 309 bytes .../internal/cctz/testdata/zoneinfo/Kwajalein | Bin 0 -> 250 bytes .../internal/cctz/testdata/zoneinfo/Libya | Bin 0 -> 641 bytes .../time/internal/cctz/testdata/zoneinfo/MET | Bin 0 -> 2102 bytes .../time/internal/cctz/testdata/zoneinfo/MST | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/MST7MDT | Bin 0 -> 2294 bytes .../cctz/testdata/zoneinfo/Mexico/BajaNorte | Bin 0 -> 2342 bytes .../cctz/testdata/zoneinfo/Mexico/BajaSur | Bin 0 -> 1550 bytes .../cctz/testdata/zoneinfo/Mexico/General | Bin 0 -> 1604 bytes .../time/internal/cctz/testdata/zoneinfo/NZ | Bin 0 -> 2451 bytes .../internal/cctz/testdata/zoneinfo/NZ-CHAT | Bin 0 -> 2078 bytes .../internal/cctz/testdata/zoneinfo/Navajo | Bin 0 -> 2444 bytes .../time/internal/cctz/testdata/zoneinfo/PRC | Bin 0 -> 545 bytes .../internal/cctz/testdata/zoneinfo/PST8PDT | Bin 0 -> 2294 bytes .../cctz/testdata/zoneinfo/Pacific/Apia | Bin 0 -> 1125 bytes .../cctz/testdata/zoneinfo/Pacific/Auckland | Bin 0 -> 2451 bytes .../testdata/zoneinfo/Pacific/Bougainville | Bin 0 -> 286 bytes .../cctz/testdata/zoneinfo/Pacific/Chatham | Bin 0 -> 2078 bytes .../cctz/testdata/zoneinfo/Pacific/Chuuk | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Easter | Bin 0 -> 2233 bytes .../cctz/testdata/zoneinfo/Pacific/Efate | Bin 0 -> 478 bytes .../cctz/testdata/zoneinfo/Pacific/Enderbury | Bin 0 -> 250 bytes .../cctz/testdata/zoneinfo/Pacific/Fakaofo | Bin 0 -> 212 bytes .../cctz/testdata/zoneinfo/Pacific/Fiji | Bin 0 -> 1090 bytes .../cctz/testdata/zoneinfo/Pacific/Funafuti | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Galapagos | Bin 0 -> 254 bytes .../cctz/testdata/zoneinfo/Pacific/Gambier | Bin 0 -> 172 bytes .../testdata/zoneinfo/Pacific/Guadalcanal | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Guam | Bin 0 -> 216 bytes .../cctz/testdata/zoneinfo/Pacific/Honolulu | Bin 0 -> 267 bytes .../cctz/testdata/zoneinfo/Pacific/Johnston | Bin 0 -> 267 bytes .../cctz/testdata/zoneinfo/Pacific/Kiritimati | Bin 0 -> 254 bytes .../cctz/testdata/zoneinfo/Pacific/Kosrae | Bin 0 -> 242 bytes .../cctz/testdata/zoneinfo/Pacific/Kwajalein | Bin 0 -> 250 bytes .../cctz/testdata/zoneinfo/Pacific/Majuro | Bin 0 -> 212 bytes .../cctz/testdata/zoneinfo/Pacific/Marquesas | Bin 0 -> 181 bytes .../cctz/testdata/zoneinfo/Pacific/Midway | Bin 0 -> 187 bytes .../cctz/testdata/zoneinfo/Pacific/Nauru | Bin 0 -> 268 bytes .../cctz/testdata/zoneinfo/Pacific/Niue | Bin 0 -> 257 bytes .../cctz/testdata/zoneinfo/Pacific/Norfolk | Bin 0 -> 314 bytes .../cctz/testdata/zoneinfo/Pacific/Noumea | Bin 0 -> 314 bytes .../cctz/testdata/zoneinfo/Pacific/Pago_Pago | Bin 0 -> 187 bytes .../cctz/testdata/zoneinfo/Pacific/Palau | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Pacific/Pitcairn | Bin 0 -> 214 bytes .../cctz/testdata/zoneinfo/Pacific/Pohnpei | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Ponape | Bin 0 -> 174 bytes .../testdata/zoneinfo/Pacific/Port_Moresby | Bin 0 -> 196 bytes .../cctz/testdata/zoneinfo/Pacific/Rarotonga | Bin 0 -> 593 bytes .../cctz/testdata/zoneinfo/Pacific/Saipan | Bin 0 -> 216 bytes .../cctz/testdata/zoneinfo/Pacific/Samoa | Bin 0 -> 187 bytes .../cctz/testdata/zoneinfo/Pacific/Tahiti | Bin 0 -> 173 bytes .../cctz/testdata/zoneinfo/Pacific/Tarawa | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Tongatapu | Bin 0 -> 384 bytes .../cctz/testdata/zoneinfo/Pacific/Truk | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Wake | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Wallis | Bin 0 -> 174 bytes .../cctz/testdata/zoneinfo/Pacific/Yap | Bin 0 -> 174 bytes .../internal/cctz/testdata/zoneinfo/Poland | Bin 0 -> 2696 bytes .../internal/cctz/testdata/zoneinfo/Portugal | Bin 0 -> 3469 bytes .../time/internal/cctz/testdata/zoneinfo/ROC | Bin 0 -> 781 bytes .../time/internal/cctz/testdata/zoneinfo/ROK | Bin 0 -> 517 bytes .../internal/cctz/testdata/zoneinfo/Singapore | Bin 0 -> 415 bytes .../internal/cctz/testdata/zoneinfo/Turkey | Bin 0 -> 2157 bytes .../time/internal/cctz/testdata/zoneinfo/UCT | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/US/Alaska | Bin 0 -> 2371 bytes .../cctz/testdata/zoneinfo/US/Aleutian | Bin 0 -> 2356 bytes .../cctz/testdata/zoneinfo/US/Arizona | Bin 0 -> 344 bytes .../cctz/testdata/zoneinfo/US/Central | Bin 0 -> 3576 bytes .../cctz/testdata/zoneinfo/US/East-Indiana | Bin 0 -> 1666 bytes .../cctz/testdata/zoneinfo/US/Eastern | Bin 0 -> 3536 bytes .../internal/cctz/testdata/zoneinfo/US/Hawaii | Bin 0 -> 267 bytes .../cctz/testdata/zoneinfo/US/Indiana-Starke | Bin 0 -> 2428 bytes .../cctz/testdata/zoneinfo/US/Michigan | Bin 0 -> 2174 bytes .../cctz/testdata/zoneinfo/US/Mountain | Bin 0 -> 2444 bytes .../cctz/testdata/zoneinfo/US/Pacific | Bin 0 -> 2836 bytes .../internal/cctz/testdata/zoneinfo/US/Samoa | Bin 0 -> 187 bytes .../time/internal/cctz/testdata/zoneinfo/UTC | Bin 0 -> 118 bytes .../internal/cctz/testdata/zoneinfo/Universal | Bin 0 -> 118 bytes .../time/internal/cctz/testdata/zoneinfo/W-SU | Bin 0 -> 1535 bytes .../time/internal/cctz/testdata/zoneinfo/WET | Bin 0 -> 1873 bytes .../time/internal/cctz/testdata/zoneinfo/Zulu | Bin 0 -> 118 bytes .../cctz/testdata/zoneinfo/iso3166.tab | 274 + .../internal/cctz/testdata/zoneinfo/localtime | Bin 0 -> 148 bytes .../cctz/testdata/zoneinfo/zone1970.tab | 382 + .../time/internal/get_current_time_chrono.inc | 29 + .../time/internal/get_current_time_posix.inc | 22 + .../absl/time/internal/test_util.cc | 123 + .../abseil-cpp/absl/time/internal/test_util.h | 31 + .../absl/time/internal/zoneinfo.inc | 729 + thirdparty/abseil-cpp/absl/time/time.cc | 485 + thirdparty/abseil-cpp/absl/time/time.h | 1537 ++ .../abseil-cpp/absl/time/time_benchmark.cc | 316 + thirdparty/abseil-cpp/absl/time/time_test.cc | 1201 ++ .../abseil-cpp/absl/time/time_zone_test.cc | 97 + thirdparty/abseil-cpp/absl/types/BUILD.bazel | 294 + .../abseil-cpp/absl/types/CMakeLists.txt | 228 + thirdparty/abseil-cpp/absl/types/any.h | 539 + .../absl/types/any_exception_safety_test.cc | 167 + thirdparty/abseil-cpp/absl/types/any_test.cc | 724 + .../abseil-cpp/absl/types/bad_any_cast.cc | 44 + .../abseil-cpp/absl/types/bad_any_cast.h | 71 + .../absl/types/bad_optional_access.cc | 46 + .../absl/types/bad_optional_access.h | 74 + .../absl/types/bad_variant_access.cc | 62 + .../absl/types/bad_variant_access.h | 78 + .../abseil-cpp/absl/types/internal/variant.h | 1623 ++ thirdparty/abseil-cpp/absl/types/optional.cc | 24 + thirdparty/abseil-cpp/absl/types/optional.h | 1142 ++ .../types/optional_exception_safety_test.cc | 282 + .../abseil-cpp/absl/types/optional_test.cc | 1626 ++ thirdparty/abseil-cpp/absl/types/span.h | 762 + thirdparty/abseil-cpp/absl/types/span_test.cc | 782 + thirdparty/abseil-cpp/absl/types/variant.h | 849 + .../absl/types/variant_benchmark.cc | 220 + .../types/variant_exception_safety_test.cc | 508 + .../abseil-cpp/absl/types/variant_test.cc | 2612 +++ .../abseil-cpp/absl/utility/BUILD.bazel | 33 + .../abseil-cpp/absl/utility/CMakeLists.txt | 52 + thirdparty/abseil-cpp/absl/utility/utility.h | 291 + .../abseil-cpp/absl/utility/utility_test.cc | 345 + thirdparty/eigen3/.hg_archival.txt | 4 + thirdparty/eigen3/.hgeol | 11 + thirdparty/eigen3/.hgignore | 34 + thirdparty/eigen3/.hgtags | 34 + thirdparty/eigen3/CMakeLists.txt | 600 + thirdparty/eigen3/COPYING.BSD | 26 + thirdparty/eigen3/COPYING.GPL | 674 + thirdparty/eigen3/COPYING.LGPL | 502 + thirdparty/eigen3/COPYING.MINPACK | 52 + thirdparty/eigen3/COPYING.MPL2 | 373 + thirdparty/eigen3/COPYING.README | 18 + thirdparty/eigen3/CTestConfig.cmake | 13 + thirdparty/eigen3/CTestCustom.cmake.in | 3 + thirdparty/eigen3/Eigen/CMakeLists.txt | 19 + thirdparty/eigen3/Eigen/Cholesky | 46 + thirdparty/eigen3/Eigen/CholmodSupport | 48 + thirdparty/eigen3/Eigen/Core | 537 + thirdparty/eigen3/Eigen/Dense | 7 + thirdparty/eigen3/Eigen/Eigen | 2 + thirdparty/eigen3/Eigen/Eigenvalues | 61 + thirdparty/eigen3/Eigen/Geometry | 62 + thirdparty/eigen3/Eigen/Householder | 30 + .../eigen3/Eigen/IterativeLinearSolvers | 48 + thirdparty/eigen3/Eigen/Jacobi | 33 + thirdparty/eigen3/Eigen/LU | 50 + thirdparty/eigen3/Eigen/MetisSupport | 35 + thirdparty/eigen3/Eigen/OrderingMethods | 73 + thirdparty/eigen3/Eigen/PaStiXSupport | 48 + thirdparty/eigen3/Eigen/PardisoSupport | 35 + thirdparty/eigen3/Eigen/QR | 51 + thirdparty/eigen3/Eigen/QtAlignedMalloc | 40 + thirdparty/eigen3/Eigen/SPQRSupport | 34 + thirdparty/eigen3/Eigen/SVD | 51 + thirdparty/eigen3/Eigen/Sparse | 36 + thirdparty/eigen3/Eigen/SparseCholesky | 45 + thirdparty/eigen3/Eigen/SparseCore | 69 + thirdparty/eigen3/Eigen/SparseLU | 46 + thirdparty/eigen3/Eigen/SparseQR | 37 + thirdparty/eigen3/Eigen/StdDeque | 27 + thirdparty/eigen3/Eigen/StdList | 26 + thirdparty/eigen3/Eigen/StdVector | 27 + thirdparty/eigen3/Eigen/SuperLUSupport | 64 + thirdparty/eigen3/Eigen/UmfPackSupport | 40 + thirdparty/eigen3/Eigen/src/Cholesky/LDLT.h | 672 + thirdparty/eigen3/Eigen/src/Cholesky/LLT.h | 542 + .../eigen3/Eigen/src/Cholesky/LLT_LAPACKE.h | 99 + .../Eigen/src/CholmodSupport/CholmodSupport.h | 639 + thirdparty/eigen3/Eigen/src/Core/Array.h | 331 + thirdparty/eigen3/Eigen/src/Core/ArrayBase.h | 226 + .../eigen3/Eigen/src/Core/ArrayWrapper.h | 209 + thirdparty/eigen3/Eigen/src/Core/Assign.h | 90 + .../eigen3/Eigen/src/Core/AssignEvaluator.h | 935 + thirdparty/eigen3/Eigen/src/Core/Assign_MKL.h | 178 + thirdparty/eigen3/Eigen/src/Core/BandMatrix.h | 353 + thirdparty/eigen3/Eigen/src/Core/Block.h | 452 + .../eigen3/Eigen/src/Core/BooleanRedux.h | 164 + .../eigen3/Eigen/src/Core/CommaInitializer.h | 160 + .../Eigen/src/Core/ConditionEstimator.h | 175 + .../eigen3/Eigen/src/Core/CoreEvaluators.h | 1688 ++ .../eigen3/Eigen/src/Core/CoreIterators.h | 127 + .../eigen3/Eigen/src/Core/CwiseBinaryOp.h | 184 + .../eigen3/Eigen/src/Core/CwiseNullaryOp.h | 866 + .../eigen3/Eigen/src/Core/CwiseTernaryOp.h | 197 + .../eigen3/Eigen/src/Core/CwiseUnaryOp.h | 103 + .../eigen3/Eigen/src/Core/CwiseUnaryView.h | 128 + thirdparty/eigen3/Eigen/src/Core/DenseBase.h | 611 + .../eigen3/Eigen/src/Core/DenseCoeffsBase.h | 681 + .../eigen3/Eigen/src/Core/DenseStorage.h | 570 + thirdparty/eigen3/Eigen/src/Core/Diagonal.h | 260 + .../eigen3/Eigen/src/Core/DiagonalMatrix.h | 343 + .../eigen3/Eigen/src/Core/DiagonalProduct.h | 28 + thirdparty/eigen3/Eigen/src/Core/Dot.h | 318 + thirdparty/eigen3/Eigen/src/Core/EigenBase.h | 159 + .../Eigen/src/Core/ForceAlignedAccess.h | 146 + thirdparty/eigen3/Eigen/src/Core/Fuzzy.h | 155 + .../eigen3/Eigen/src/Core/GeneralProduct.h | 455 + .../eigen3/Eigen/src/Core/GenericPacketMath.h | 593 + .../eigen3/Eigen/src/Core/GlobalFunctions.h | 187 + thirdparty/eigen3/Eigen/src/Core/IO.h | 225 + thirdparty/eigen3/Eigen/src/Core/Inverse.h | 118 + thirdparty/eigen3/Eigen/src/Core/Map.h | 171 + thirdparty/eigen3/Eigen/src/Core/MapBase.h | 299 + .../eigen3/Eigen/src/Core/MathFunctions.h | 1407 ++ .../eigen3/Eigen/src/Core/MathFunctionsImpl.h | 101 + thirdparty/eigen3/Eigen/src/Core/Matrix.h | 461 + thirdparty/eigen3/Eigen/src/Core/MatrixBase.h | 521 + .../eigen3/Eigen/src/Core/NestByValue.h | 110 + thirdparty/eigen3/Eigen/src/Core/NoAlias.h | 108 + thirdparty/eigen3/Eigen/src/Core/NumTraits.h | 248 + .../eigen3/Eigen/src/Core/PermutationMatrix.h | 633 + .../eigen3/Eigen/src/Core/PlainObjectBase.h | 1035 + thirdparty/eigen3/Eigen/src/Core/Product.h | 186 + .../eigen3/Eigen/src/Core/ProductEvaluators.h | 1112 ++ thirdparty/eigen3/Eigen/src/Core/Random.h | 182 + thirdparty/eigen3/Eigen/src/Core/Redux.h | 505 + thirdparty/eigen3/Eigen/src/Core/Ref.h | 283 + thirdparty/eigen3/Eigen/src/Core/Replicate.h | 142 + .../eigen3/Eigen/src/Core/ReturnByValue.h | 117 + thirdparty/eigen3/Eigen/src/Core/Reverse.h | 211 + thirdparty/eigen3/Eigen/src/Core/Select.h | 162 + .../eigen3/Eigen/src/Core/SelfAdjointView.h | 352 + .../eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h | 47 + thirdparty/eigen3/Eigen/src/Core/Solve.h | 188 + .../eigen3/Eigen/src/Core/SolveTriangular.h | 232 + thirdparty/eigen3/Eigen/src/Core/SolverBase.h | 130 + thirdparty/eigen3/Eigen/src/Core/StableNorm.h | 221 + thirdparty/eigen3/Eigen/src/Core/Stride.h | 111 + thirdparty/eigen3/Eigen/src/Core/Swap.h | 67 + thirdparty/eigen3/Eigen/src/Core/Transpose.h | 403 + .../eigen3/Eigen/src/Core/Transpositions.h | 407 + .../eigen3/Eigen/src/Core/TriangularMatrix.h | 983 + .../eigen3/Eigen/src/Core/VectorBlock.h | 96 + .../eigen3/Eigen/src/Core/VectorwiseOp.h | 695 + thirdparty/eigen3/Eigen/src/Core/Visitor.h | 273 + .../eigen3/Eigen/src/Core/arch/AVX/Complex.h | 451 + .../Eigen/src/Core/arch/AVX/MathFunctions.h | 439 + .../Eigen/src/Core/arch/AVX/PacketMath.h | 636 + .../Eigen/src/Core/arch/AVX/TypeCasting.h | 51 + .../src/Core/arch/AVX512/MathFunctions.h | 391 + .../Eigen/src/Core/arch/AVX512/PacketMath.h | 1316 ++ .../Eigen/src/Core/arch/AltiVec/Complex.h | 430 + .../src/Core/arch/AltiVec/MathFunctions.h | 322 + .../Eigen/src/Core/arch/AltiVec/PacketMath.h | 1061 + .../eigen3/Eigen/src/Core/arch/CUDA/Complex.h | 103 + .../eigen3/Eigen/src/Core/arch/CUDA/Half.h | 651 + .../Eigen/src/Core/arch/CUDA/MathFunctions.h | 91 + .../Eigen/src/Core/arch/CUDA/PacketMath.h | 333 + .../Eigen/src/Core/arch/CUDA/PacketMathHalf.h | 1123 ++ .../Eigen/src/Core/arch/CUDA/TypeCasting.h | 212 + .../Eigen/src/Core/arch/Default/ConjHelper.h | 29 + .../Eigen/src/Core/arch/Default/Settings.h | 49 + .../eigen3/Eigen/src/Core/arch/NEON/Complex.h | 490 + .../Eigen/src/Core/arch/NEON/MathFunctions.h | 91 + .../Eigen/src/Core/arch/NEON/PacketMath.h | 760 + .../eigen3/Eigen/src/Core/arch/SSE/Complex.h | 471 + .../Eigen/src/Core/arch/SSE/MathFunctions.h | 562 + .../Eigen/src/Core/arch/SSE/PacketMath.h | 895 + .../Eigen/src/Core/arch/SSE/TypeCasting.h | 77 + .../Eigen/src/Core/arch/ZVector/Complex.h | 397 + .../src/Core/arch/ZVector/MathFunctions.h | 137 + .../Eigen/src/Core/arch/ZVector/PacketMath.h | 945 + .../src/Core/functors/AssignmentFunctors.h | 168 + .../Eigen/src/Core/functors/BinaryFunctors.h | 475 + .../Eigen/src/Core/functors/NullaryFunctors.h | 188 + .../Eigen/src/Core/functors/StlFunctors.h | 136 + .../Eigen/src/Core/functors/TernaryFunctors.h | 25 + .../Eigen/src/Core/functors/UnaryFunctors.h | 792 + .../Core/products/GeneralBlockPanelKernel.h | 2149 ++ .../src/Core/products/GeneralMatrixMatrix.h | 492 + .../products/GeneralMatrixMatrixTriangular.h | 311 + .../GeneralMatrixMatrixTriangular_BLAS.h | 145 + .../Core/products/GeneralMatrixMatrix_BLAS.h | 122 + .../src/Core/products/GeneralMatrixVector.h | 619 + .../Core/products/GeneralMatrixVector_BLAS.h | 136 + .../Eigen/src/Core/products/Parallelizer.h | 163 + .../Core/products/SelfadjointMatrixMatrix.h | 521 + .../products/SelfadjointMatrixMatrix_BLAS.h | 287 + .../Core/products/SelfadjointMatrixVector.h | 260 + .../products/SelfadjointMatrixVector_BLAS.h | 118 + .../src/Core/products/SelfadjointProduct.h | 133 + .../Core/products/SelfadjointRank2Update.h | 93 + .../Core/products/TriangularMatrixMatrix.h | 466 + .../products/TriangularMatrixMatrix_BLAS.h | 315 + .../Core/products/TriangularMatrixVector.h | 350 + .../products/TriangularMatrixVector_BLAS.h | 255 + .../Core/products/TriangularSolverMatrix.h | 335 + .../products/TriangularSolverMatrix_BLAS.h | 163 + .../Core/products/TriangularSolverVector.h | 145 + .../eigen3/Eigen/src/Core/util/BlasUtil.h | 398 + .../eigen3/Eigen/src/Core/util/Constants.h | 547 + .../src/Core/util/DisableStupidWarnings.h | 75 + .../Eigen/src/Core/util/ForwardDeclarations.h | 302 + .../eigen3/Eigen/src/Core/util/MKL_support.h | 130 + .../eigen3/Eigen/src/Core/util/Macros.h | 1001 + .../eigen3/Eigen/src/Core/util/Memory.h | 985 + thirdparty/eigen3/Eigen/src/Core/util/Meta.h | 512 + .../eigen3/Eigen/src/Core/util/NonMPL2.h | 3 + .../src/Core/util/ReenableStupidWarnings.h | 27 + .../eigen3/Eigen/src/Core/util/StaticAssert.h | 218 + .../eigen3/Eigen/src/Core/util/XprHelper.h | 821 + .../src/Eigenvalues/ComplexEigenSolver.h | 346 + .../Eigen/src/Eigenvalues/ComplexSchur.h | 459 + .../src/Eigenvalues/ComplexSchur_LAPACKE.h | 91 + .../Eigen/src/Eigenvalues/EigenSolver.h | 622 + .../src/Eigenvalues/GeneralizedEigenSolver.h | 418 + .../GeneralizedSelfAdjointEigenSolver.h | 226 + .../src/Eigenvalues/HessenbergDecomposition.h | 374 + .../src/Eigenvalues/MatrixBaseEigenvalues.h | 160 + .../eigen3/Eigen/src/Eigenvalues/RealQZ.h | 654 + .../eigen3/Eigen/src/Eigenvalues/RealSchur.h | 546 + .../Eigen/src/Eigenvalues/RealSchur_LAPACKE.h | 77 + .../src/Eigenvalues/SelfAdjointEigenSolver.h | 870 + .../SelfAdjointEigenSolver_LAPACKE.h | 87 + .../src/Eigenvalues/Tridiagonalization.h | 556 + .../eigen3/Eigen/src/Geometry/AlignedBox.h | 392 + .../eigen3/Eigen/src/Geometry/AngleAxis.h | 247 + .../eigen3/Eigen/src/Geometry/EulerAngles.h | 114 + .../eigen3/Eigen/src/Geometry/Homogeneous.h | 497 + .../eigen3/Eigen/src/Geometry/Hyperplane.h | 282 + .../eigen3/Eigen/src/Geometry/OrthoMethods.h | 234 + .../Eigen/src/Geometry/ParametrizedLine.h | 195 + .../eigen3/Eigen/src/Geometry/Quaternion.h | 814 + .../eigen3/Eigen/src/Geometry/Rotation2D.h | 199 + .../eigen3/Eigen/src/Geometry/RotationBase.h | 206 + .../eigen3/Eigen/src/Geometry/Scaling.h | 170 + .../eigen3/Eigen/src/Geometry/Transform.h | 1542 ++ .../eigen3/Eigen/src/Geometry/Translation.h | 208 + .../eigen3/Eigen/src/Geometry/Umeyama.h | 166 + .../Eigen/src/Geometry/arch/Geometry_SSE.h | 161 + .../Eigen/src/Householder/BlockHouseholder.h | 103 + .../Eigen/src/Householder/Householder.h | 172 + .../src/Householder/HouseholderSequence.h | 470 + .../BasicPreconditioners.h | 226 + .../src/IterativeLinearSolvers/BiCGSTAB.h | 228 + .../ConjugateGradient.h | 245 + .../IncompleteCholesky.h | 400 + .../IterativeLinearSolvers/IncompleteLUT.h | 462 + .../IterativeSolverBase.h | 394 + .../LeastSquareConjugateGradient.h | 216 + .../IterativeLinearSolvers/SolveWithGuess.h | 115 + thirdparty/eigen3/Eigen/src/Jacobi/Jacobi.h | 463 + thirdparty/eigen3/Eigen/src/LU/Determinant.h | 101 + thirdparty/eigen3/Eigen/src/LU/FullPivLU.h | 891 + thirdparty/eigen3/Eigen/src/LU/InverseImpl.h | 415 + thirdparty/eigen3/Eigen/src/LU/PartialPivLU.h | 611 + .../Eigen/src/LU/PartialPivLU_LAPACKE.h | 83 + .../eigen3/Eigen/src/LU/arch/Inverse_SSE.h | 338 + .../Eigen/src/MetisSupport/MetisSupport.h | 137 + .../eigen3/Eigen/src/OrderingMethods/Amd.h | 445 + .../Eigen/src/OrderingMethods/Eigen_Colamd.h | 1843 ++ .../Eigen/src/OrderingMethods/Ordering.h | 157 + .../Eigen/src/PaStiXSupport/PaStiXSupport.h | 678 + .../Eigen/src/PardisoSupport/PardisoSupport.h | 543 + .../eigen3/Eigen/src/QR/ColPivHouseholderQR.h | 653 + .../src/QR/ColPivHouseholderQR_LAPACKE.h | 97 + .../src/QR/CompleteOrthogonalDecomposition.h | 562 + .../Eigen/src/QR/FullPivHouseholderQR.h | 676 + .../eigen3/Eigen/src/QR/HouseholderQR.h | 409 + .../Eigen/src/QR/HouseholderQR_LAPACKE.h | 68 + .../src/SPQRSupport/SuiteSparseQRSupport.h | 313 + thirdparty/eigen3/Eigen/src/SVD/BDCSVD.h | 1246 ++ thirdparty/eigen3/Eigen/src/SVD/JacobiSVD.h | 804 + .../eigen3/Eigen/src/SVD/JacobiSVD_LAPACKE.h | 91 + thirdparty/eigen3/Eigen/src/SVD/SVDBase.h | 313 + .../Eigen/src/SVD/UpperBidiagonalization.h | 414 + .../src/SparseCholesky/SimplicialCholesky.h | 689 + .../SparseCholesky/SimplicialCholesky_impl.h | 199 + .../eigen3/Eigen/src/SparseCore/AmbiVector.h | 377 + .../Eigen/src/SparseCore/CompressedStorage.h | 258 + .../ConservativeSparseSparseProduct.h | 352 + .../Eigen/src/SparseCore/MappedSparseMatrix.h | 67 + .../Eigen/src/SparseCore/SparseAssign.h | 216 + .../eigen3/Eigen/src/SparseCore/SparseBlock.h | 603 + .../Eigen/src/SparseCore/SparseColEtree.h | 206 + .../src/SparseCore/SparseCompressedBase.h | 341 + .../src/SparseCore/SparseCwiseBinaryOp.h | 726 + .../Eigen/src/SparseCore/SparseCwiseUnaryOp.h | 148 + .../Eigen/src/SparseCore/SparseDenseProduct.h | 320 + .../src/SparseCore/SparseDiagonalProduct.h | 138 + .../eigen3/Eigen/src/SparseCore/SparseDot.h | 98 + .../eigen3/Eigen/src/SparseCore/SparseFuzzy.h | 29 + .../eigen3/Eigen/src/SparseCore/SparseMap.h | 305 + .../Eigen/src/SparseCore/SparseMatrix.h | 1403 ++ .../Eigen/src/SparseCore/SparseMatrixBase.h | 405 + .../Eigen/src/SparseCore/SparsePermutation.h | 178 + .../Eigen/src/SparseCore/SparseProduct.h | 169 + .../eigen3/Eigen/src/SparseCore/SparseRedux.h | 49 + .../eigen3/Eigen/src/SparseCore/SparseRef.h | 397 + .../src/SparseCore/SparseSelfAdjointView.h | 656 + .../Eigen/src/SparseCore/SparseSolverBase.h | 124 + .../SparseSparseProductWithPruning.h | 198 + .../Eigen/src/SparseCore/SparseTranspose.h | 92 + .../src/SparseCore/SparseTriangularView.h | 189 + .../eigen3/Eigen/src/SparseCore/SparseUtil.h | 178 + .../Eigen/src/SparseCore/SparseVector.h | 478 + .../eigen3/Eigen/src/SparseCore/SparseView.h | 253 + .../Eigen/src/SparseCore/TriangularSolver.h | 315 + .../eigen3/Eigen/src/SparseLU/SparseLU.h | 775 + .../eigen3/Eigen/src/SparseLU/SparseLUImpl.h | 66 + .../Eigen/src/SparseLU/SparseLU_Memory.h | 226 + .../Eigen/src/SparseLU/SparseLU_Structs.h | 110 + .../src/SparseLU/SparseLU_SupernodalMatrix.h | 301 + .../Eigen/src/SparseLU/SparseLU_Utils.h | 80 + .../Eigen/src/SparseLU/SparseLU_column_bmod.h | 181 + .../Eigen/src/SparseLU/SparseLU_column_dfs.h | 179 + .../src/SparseLU/SparseLU_copy_to_ucol.h | 107 + .../Eigen/src/SparseLU/SparseLU_gemm_kernel.h | 280 + .../src/SparseLU/SparseLU_heap_relax_snode.h | 126 + .../Eigen/src/SparseLU/SparseLU_kernel_bmod.h | 130 + .../Eigen/src/SparseLU/SparseLU_panel_bmod.h | 223 + .../Eigen/src/SparseLU/SparseLU_panel_dfs.h | 258 + .../Eigen/src/SparseLU/SparseLU_pivotL.h | 137 + .../Eigen/src/SparseLU/SparseLU_pruneL.h | 136 + .../Eigen/src/SparseLU/SparseLU_relax_snode.h | 83 + .../eigen3/Eigen/src/SparseQR/SparseQR.h | 745 + .../eigen3/Eigen/src/StlSupport/StdDeque.h | 126 + .../eigen3/Eigen/src/StlSupport/StdList.h | 106 + .../eigen3/Eigen/src/StlSupport/StdVector.h | 131 + .../eigen3/Eigen/src/StlSupport/details.h | 84 + .../Eigen/src/SuperLUSupport/SuperLUSupport.h | 1027 + .../Eigen/src/UmfPackSupport/UmfPackSupport.h | 506 + thirdparty/eigen3/Eigen/src/misc/Image.h | 82 + thirdparty/eigen3/Eigen/src/misc/Kernel.h | 79 + thirdparty/eigen3/Eigen/src/misc/RealSvd2x2.h | 55 + thirdparty/eigen3/Eigen/src/misc/blas.h | 440 + thirdparty/eigen3/Eigen/src/misc/lapack.h | 152 + thirdparty/eigen3/Eigen/src/misc/lapacke.h | 16291 ++++++++++++++++ .../eigen3/Eigen/src/misc/lapacke_mangling.h | 17 + .../Eigen/src/plugins/ArrayCwiseBinaryOps.h | 332 + .../Eigen/src/plugins/ArrayCwiseUnaryOps.h | 552 + .../eigen3/Eigen/src/plugins/BlockMethods.h | 1058 + .../Eigen/src/plugins/CommonCwiseBinaryOps.h | 115 + .../Eigen/src/plugins/CommonCwiseUnaryOps.h | 163 + .../Eigen/src/plugins/MatrixCwiseBinaryOps.h | 152 + .../Eigen/src/plugins/MatrixCwiseUnaryOps.h | 85 + thirdparty/eigen3/INSTALL | 35 + thirdparty/eigen3/README.md | 3 + thirdparty/eigen3/bench/BenchSparseUtil.h | 149 + thirdparty/eigen3/bench/BenchTimer.h | 195 + thirdparty/eigen3/bench/BenchUtil.h | 92 + thirdparty/eigen3/bench/README.txt | 55 + .../eigen3/bench/analyze-blocking-sizes.cpp | 876 + thirdparty/eigen3/bench/basicbench.cxxlist | 28 + thirdparty/eigen3/bench/basicbenchmark.cpp | 35 + thirdparty/eigen3/bench/basicbenchmark.h | 63 + thirdparty/eigen3/bench/benchBlasGemm.cpp | 219 + thirdparty/eigen3/bench/benchCholesky.cpp | 142 + thirdparty/eigen3/bench/benchEigenSolver.cpp | 212 + thirdparty/eigen3/bench/benchFFT.cpp | 115 + thirdparty/eigen3/bench/benchGeometry.cpp | 134 + thirdparty/eigen3/bench/benchVecAdd.cpp | 135 + thirdparty/eigen3/bench/bench_gemm.cpp | 340 + .../eigen3/bench/bench_multi_compilers.sh | 28 + thirdparty/eigen3/bench/bench_norm.cpp | 360 + thirdparty/eigen3/bench/bench_reverse.cpp | 84 + thirdparty/eigen3/bench/bench_sum.cpp | 18 + thirdparty/eigen3/bench/bench_unrolling | 12 + .../eigen3/bench/benchmark-blocking-sizes.cpp | 677 + thirdparty/eigen3/bench/benchmark.cpp | 39 + thirdparty/eigen3/bench/benchmarkSlice.cpp | 38 + thirdparty/eigen3/bench/benchmarkX.cpp | 36 + thirdparty/eigen3/bench/benchmarkXcwise.cpp | 35 + thirdparty/eigen3/bench/benchmark_suite | 18 + thirdparty/eigen3/bench/btl/CMakeLists.txt | 107 + thirdparty/eigen3/bench/btl/COPYING | 340 + thirdparty/eigen3/bench/btl/README | 154 + .../bench/btl/actions/action_aat_product.hh | 145 + .../bench/btl/actions/action_ata_product.hh | 145 + .../bench/btl/actions/action_atv_product.hh | 134 + .../eigen3/bench/btl/actions/action_axpby.hh | 127 + .../eigen3/bench/btl/actions/action_axpy.hh | 139 + .../bench/btl/actions/action_cholesky.hh | 128 + .../eigen3/bench/btl/actions/action_ger.hh | 128 + .../bench/btl/actions/action_hessenberg.hh | 233 + .../bench/btl/actions/action_lu_decomp.hh | 124 + .../bench/btl/actions/action_lu_solve.hh | 136 + .../actions/action_matrix_matrix_product.hh | 150 + .../action_matrix_matrix_product_bis.hh | 152 + .../actions/action_matrix_vector_product.hh | 153 + .../bench/btl/actions/action_partial_lu.hh | 125 + .../eigen3/bench/btl/actions/action_rot.hh | 116 + .../eigen3/bench/btl/actions/action_symv.hh | 139 + .../eigen3/bench/btl/actions/action_syr2.hh | 133 + .../bench/btl/actions/action_trisolve.hh | 137 + .../btl/actions/action_trisolve_matrix.hh | 165 + .../eigen3/bench/btl/actions/action_trmm.hh | 165 + .../eigen3/bench/btl/actions/basic_actions.hh | 21 + .../eigen3/bench/btl/cmake/FindACML.cmake | 51 + .../eigen3/bench/btl/cmake/FindATLAS.cmake | 31 + .../eigen3/bench/btl/cmake/FindBLAZE.cmake | 31 + .../eigen3/bench/btl/cmake/FindBlitz.cmake | 40 + .../eigen3/bench/btl/cmake/FindCBLAS.cmake | 35 + .../eigen3/bench/btl/cmake/FindGMM.cmake | 17 + .../eigen3/bench/btl/cmake/FindMKL.cmake | 65 + .../eigen3/bench/btl/cmake/FindMTL4.cmake | 31 + .../eigen3/bench/btl/cmake/FindOPENBLAS.cmake | 17 + .../cmake/FindPackageHandleStandardArgs.cmake | 60 + .../eigen3/bench/btl/cmake/FindTvmet.cmake | 32 + .../cmake/MacroOptionalAddSubdirectory.cmake | 31 + .../eigen3/bench/btl/data/CMakeLists.txt | 32 + .../eigen3/bench/btl/data/action_settings.txt | 19 + .../bench/btl/data/gnuplot_common_settings.hh | 87 + thirdparty/eigen3/bench/btl/data/go_mean | 58 + thirdparty/eigen3/bench/btl/data/mean.cxx | 182 + .../bench/btl/data/mk_gnuplot_script.sh | 68 + .../eigen3/bench/btl/data/mk_mean_script.sh | 52 + .../eigen3/bench/btl/data/mk_new_gnuplot.sh | 54 + .../bench/btl/data/perlib_plot_settings.txt | 16 + .../eigen3/bench/btl/data/regularize.cxx | 131 + thirdparty/eigen3/bench/btl/data/smooth.cxx | 198 + .../eigen3/bench/btl/data/smooth_all.sh | 68 + .../eigen3/bench/btl/generic_bench/bench.hh | 168 + .../btl/generic_bench/bench_parameter.hh | 53 + .../eigen3/bench/btl/generic_bench/btl.hh | 242 + .../btl/generic_bench/init/init_function.hh | 54 + .../btl/generic_bench/init/init_matrix.hh | 64 + .../btl/generic_bench/init/init_vector.hh | 37 + .../btl/generic_bench/static/bench_static.hh | 80 + .../static/intel_bench_fixed_size.hh | 66 + .../static/static_size_generator.hh | 57 + .../generic_bench/timers/STL_perf_analyzer.hh | 82 + .../btl/generic_bench/timers/STL_timer.hh | 78 + .../timers/mixed_perf_analyzer.hh | 73 + .../timers/portable_perf_analyzer.hh | 103 + .../timers/portable_perf_analyzer_old.hh | 134 + .../generic_bench/timers/portable_timer.hh | 187 + .../generic_bench/timers/x86_perf_analyzer.hh | 108 + .../btl/generic_bench/timers/x86_timer.hh | 246 + .../btl/generic_bench/utils/size_lin_log.hh | 70 + .../bench/btl/generic_bench/utils/size_log.hh | 54 + .../bench/btl/generic_bench/utils/utilities.h | 90 + .../bench/btl/generic_bench/utils/xy_file.hh | 75 + .../eigen3/bench/btl/libs/BLAS/CMakeLists.txt | 47 + thirdparty/eigen3/bench/btl/libs/BLAS/blas.h | 675 + .../bench/btl/libs/BLAS/blas_interface.hh | 83 + .../btl/libs/BLAS/blas_interface_impl.hh | 147 + .../bench/btl/libs/BLAS/c_interface_base.h | 73 + .../eigen3/bench/btl/libs/BLAS/main.cpp | 73 + .../eigen3/bench/btl/libs/STL/CMakeLists.txt | 2 + .../bench/btl/libs/STL/STL_interface.hh | 244 + thirdparty/eigen3/bench/btl/libs/STL/main.cpp | 42 + .../bench/btl/libs/blaze/CMakeLists.txt | 13 + .../bench/btl/libs/blaze/blaze_interface.hh | 140 + .../eigen3/bench/btl/libs/blaze/main.cpp | 40 + .../bench/btl/libs/blitz/CMakeLists.txt | 17 + .../libs/blitz/blitz_LU_solve_interface.hh | 192 + .../bench/btl/libs/blitz/blitz_interface.hh | 147 + .../eigen3/bench/btl/libs/blitz/btl_blitz.cpp | 51 + .../bench/btl/libs/blitz/btl_tiny_blitz.cpp | 38 + .../btl/libs/blitz/tiny_blitz_interface.hh | 106 + .../bench/btl/libs/eigen2/CMakeLists.txt | 19 + .../bench/btl/libs/eigen2/btl_tiny_eigen2.cpp | 46 + .../bench/btl/libs/eigen2/eigen2_interface.hh | 168 + .../eigen3/bench/btl/libs/eigen2/main_adv.cpp | 44 + .../bench/btl/libs/eigen2/main_linear.cpp | 34 + .../bench/btl/libs/eigen2/main_matmat.cpp | 35 + .../bench/btl/libs/eigen2/main_vecmat.cpp | 36 + .../bench/btl/libs/eigen3/CMakeLists.txt | 65 + .../bench/btl/libs/eigen3/btl_tiny_eigen3.cpp | 46 + .../bench/btl/libs/eigen3/eigen3_interface.hh | 240 + .../eigen3/bench/btl/libs/eigen3/main_adv.cpp | 44 + .../bench/btl/libs/eigen3/main_linear.cpp | 35 + .../bench/btl/libs/eigen3/main_matmat.cpp | 35 + .../bench/btl/libs/eigen3/main_vecmat.cpp | 36 + .../eigen3/bench/btl/libs/gmm/CMakeLists.txt | 6 + .../btl/libs/gmm/gmm_LU_solve_interface.hh | 192 + .../bench/btl/libs/gmm/gmm_interface.hh | 144 + thirdparty/eigen3/bench/btl/libs/gmm/main.cpp | 51 + .../eigen3/bench/btl/libs/mtl4/.kdbgrc.main | 12 + .../eigen3/bench/btl/libs/mtl4/CMakeLists.txt | 6 + .../eigen3/bench/btl/libs/mtl4/main.cpp | 46 + .../btl/libs/mtl4/mtl4_LU_solve_interface.hh | 192 + .../bench/btl/libs/mtl4/mtl4_interface.hh | 144 + .../bench/btl/libs/tensors/CMakeLists.txt | 44 + .../bench/btl/libs/tensors/main_linear.cpp | 23 + .../bench/btl/libs/tensors/main_matmat.cpp | 21 + .../bench/btl/libs/tensors/main_vecmat.cpp | 21 + .../btl/libs/tensors/tensor_interface.hh | 105 + .../bench/btl/libs/tvmet/CMakeLists.txt | 6 + .../eigen3/bench/btl/libs/tvmet/main.cpp | 40 + .../bench/btl/libs/tvmet/tvmet_interface.hh | 104 + .../bench/btl/libs/ublas/CMakeLists.txt | 7 + .../eigen3/bench/btl/libs/ublas/main.cpp | 44 + .../bench/btl/libs/ublas/ublas_interface.hh | 141 + .../eigen3/bench/check_cache_queries.cpp | 101 + thirdparty/eigen3/bench/dense_solvers.cpp | 186 + thirdparty/eigen3/bench/eig33.cpp | 195 + thirdparty/eigen3/bench/geometry.cpp | 126 + .../bench/perf_monitoring/gemm/changesets.txt | 61 + .../bench/perf_monitoring/gemm/gemm.cpp | 67 + .../perf_monitoring/gemm/gemm_settings.txt | 15 + .../bench/perf_monitoring/gemm/lazy_gemm.cpp | 98 + .../gemm/lazy_gemm_settings.txt | 15 + .../bench/perf_monitoring/gemm/make_plot.sh | 38 + .../eigen3/bench/perf_monitoring/gemm/run.sh | 156 + thirdparty/eigen3/bench/product_threshold.cpp | 143 + thirdparty/eigen3/bench/quat_slerp.cpp | 247 + thirdparty/eigen3/bench/quatmul.cpp | 47 + thirdparty/eigen3/bench/sparse_cholesky.cpp | 216 + .../eigen3/bench/sparse_dense_product.cpp | 187 + thirdparty/eigen3/bench/sparse_lu.cpp | 132 + thirdparty/eigen3/bench/sparse_product.cpp | 323 + .../eigen3/bench/sparse_randomsetter.cpp | 125 + thirdparty/eigen3/bench/sparse_setter.cpp | 485 + thirdparty/eigen3/bench/sparse_transpose.cpp | 104 + thirdparty/eigen3/bench/sparse_trisolver.cpp | 220 + .../eigen3/bench/spbench/CMakeLists.txt | 85 + thirdparty/eigen3/bench/spbench/sp_solver.cpp | 125 + thirdparty/eigen3/bench/spbench/spbench.dtd | 31 + .../eigen3/bench/spbench/spbenchsolver.cpp | 87 + .../eigen3/bench/spbench/spbenchsolver.h | 554 + .../eigen3/bench/spbench/spbenchstyle.h | 95 + .../eigen3/bench/spbench/test_sparseLU.cpp | 93 + thirdparty/eigen3/bench/spmv.cpp | 233 + thirdparty/eigen3/bench/tensors/README | 21 + thirdparty/eigen3/bench/tensors/benchmark.h | 49 + .../eigen3/bench/tensors/benchmark_main.cc | 237 + .../tensors/contraction_benchmarks_cpu.cc | 39 + .../eigen3/bench/tensors/tensor_benchmarks.h | 478 + .../bench/tensors/tensor_benchmarks_cpu.cc | 168 + .../tensors/tensor_benchmarks_fp16_gpu.cu | 77 + .../bench/tensors/tensor_benchmarks_gpu.cu | 75 + .../bench/tensors/tensor_benchmarks_sycl.cc | 37 + thirdparty/eigen3/bench/vdw_new.cpp | 56 + thirdparty/eigen3/blas/BandTriangularSolver.h | 97 + thirdparty/eigen3/blas/CMakeLists.txt | 57 + thirdparty/eigen3/blas/GeneralRank1Update.h | 44 + .../eigen3/blas/PackedSelfadjointProduct.h | 53 + .../blas/PackedTriangularMatrixVector.h | 79 + .../blas/PackedTriangularSolverVector.h | 88 + thirdparty/eigen3/blas/README.txt | 6 + thirdparty/eigen3/blas/Rank2Update.h | 57 + thirdparty/eigen3/blas/common.h | 163 + thirdparty/eigen3/blas/complex_double.cpp | 20 + thirdparty/eigen3/blas/complex_single.cpp | 20 + thirdparty/eigen3/blas/double.cpp | 32 + thirdparty/eigen3/blas/f2c/chbmv.c | 487 + thirdparty/eigen3/blas/f2c/chpmv.c | 438 + thirdparty/eigen3/blas/f2c/complexdots.c | 84 + thirdparty/eigen3/blas/f2c/ctbmv.c | 647 + thirdparty/eigen3/blas/f2c/d_cnjg.c | 6 + thirdparty/eigen3/blas/f2c/datatypes.h | 24 + thirdparty/eigen3/blas/f2c/drotm.c | 215 + thirdparty/eigen3/blas/f2c/drotmg.c | 293 + thirdparty/eigen3/blas/f2c/dsbmv.c | 366 + thirdparty/eigen3/blas/f2c/dspmv.c | 316 + thirdparty/eigen3/blas/f2c/dtbmv.c | 428 + thirdparty/eigen3/blas/f2c/lsame.c | 117 + thirdparty/eigen3/blas/f2c/r_cnjg.c | 6 + thirdparty/eigen3/blas/f2c/srotm.c | 216 + thirdparty/eigen3/blas/f2c/srotmg.c | 295 + thirdparty/eigen3/blas/f2c/ssbmv.c | 368 + thirdparty/eigen3/blas/f2c/sspmv.c | 316 + thirdparty/eigen3/blas/f2c/stbmv.c | 428 + thirdparty/eigen3/blas/f2c/zhbmv.c | 488 + thirdparty/eigen3/blas/f2c/zhpmv.c | 438 + thirdparty/eigen3/blas/f2c/ztbmv.c | 647 + thirdparty/eigen3/blas/fortran/complexdots.f | 43 + thirdparty/eigen3/blas/level1_cplx_impl.h | 133 + thirdparty/eigen3/blas/level1_impl.h | 166 + thirdparty/eigen3/blas/level1_real_impl.h | 100 + thirdparty/eigen3/blas/level2_cplx_impl.h | 360 + thirdparty/eigen3/blas/level2_impl.h | 553 + thirdparty/eigen3/blas/level2_real_impl.h | 306 + thirdparty/eigen3/blas/level3_impl.h | 702 + thirdparty/eigen3/blas/single.cpp | 22 + thirdparty/eigen3/blas/testing/CMakeLists.txt | 40 + thirdparty/eigen3/blas/testing/cblat1.f | 724 + thirdparty/eigen3/blas/testing/cblat2.dat | 35 + thirdparty/eigen3/blas/testing/cblat2.f | 3279 ++++ thirdparty/eigen3/blas/testing/cblat3.dat | 23 + thirdparty/eigen3/blas/testing/cblat3.f | 3492 ++++ thirdparty/eigen3/blas/testing/dblat1.f | 1065 + thirdparty/eigen3/blas/testing/dblat2.dat | 34 + thirdparty/eigen3/blas/testing/dblat2.f | 3176 +++ thirdparty/eigen3/blas/testing/dblat3.dat | 20 + thirdparty/eigen3/blas/testing/dblat3.f | 2873 +++ thirdparty/eigen3/blas/testing/runblastest.sh | 45 + thirdparty/eigen3/blas/testing/sblat1.f | 1021 + thirdparty/eigen3/blas/testing/sblat2.dat | 34 + thirdparty/eigen3/blas/testing/sblat2.f | 3176 +++ thirdparty/eigen3/blas/testing/sblat3.dat | 20 + thirdparty/eigen3/blas/testing/sblat3.f | 2873 +++ thirdparty/eigen3/blas/testing/zblat1.f | 724 + thirdparty/eigen3/blas/testing/zblat2.dat | 35 + thirdparty/eigen3/blas/testing/zblat2.f | 3287 ++++ thirdparty/eigen3/blas/testing/zblat3.dat | 23 + thirdparty/eigen3/blas/testing/zblat3.f | 3502 ++++ thirdparty/eigen3/blas/xerbla.cpp | 23 + thirdparty/eigen3/cmake/Eigen3Config.cmake.in | 21 + .../eigen3/cmake/Eigen3ConfigLegacy.cmake.in | 30 + .../eigen3/cmake/EigenConfigureTesting.cmake | 61 + .../cmake/EigenDetermineOSVersion.cmake | 46 + .../cmake/EigenDetermineVSServicePack.cmake | 41 + thirdparty/eigen3/cmake/EigenTesting.cmake | 723 + thirdparty/eigen3/cmake/EigenUninstall.cmake | 40 + thirdparty/eigen3/cmake/FindAdolc.cmake | 20 + thirdparty/eigen3/cmake/FindBLAS.cmake | 1406 ++ thirdparty/eigen3/cmake/FindBLASEXT.cmake | 380 + thirdparty/eigen3/cmake/FindCholmod.cmake | 89 + thirdparty/eigen3/cmake/FindComputeCpp.cmake | 245 + thirdparty/eigen3/cmake/FindEigen2.cmake | 80 + thirdparty/eigen3/cmake/FindEigen3.cmake | 97 + thirdparty/eigen3/cmake/FindFFTW.cmake | 119 + thirdparty/eigen3/cmake/FindGLEW.cmake | 105 + thirdparty/eigen3/cmake/FindGMP.cmake | 21 + thirdparty/eigen3/cmake/FindGSL.cmake | 170 + thirdparty/eigen3/cmake/FindGoogleHash.cmake | 23 + thirdparty/eigen3/cmake/FindHWLOC.cmake | 331 + thirdparty/eigen3/cmake/FindLAPACK.cmake | 273 + thirdparty/eigen3/cmake/FindMPFR.cmake | 83 + thirdparty/eigen3/cmake/FindMetis.cmake | 264 + thirdparty/eigen3/cmake/FindPTSCOTCH.cmake | 423 + thirdparty/eigen3/cmake/FindPastix.cmake | 704 + thirdparty/eigen3/cmake/FindSPQR.cmake | 41 + thirdparty/eigen3/cmake/FindScotch.cmake | 369 + .../cmake/FindStandardMathLibrary.cmake | 64 + thirdparty/eigen3/cmake/FindSuperLU.cmake | 97 + thirdparty/eigen3/cmake/FindUmfpack.cmake | 53 + thirdparty/eigen3/cmake/RegexUtils.cmake | 19 + thirdparty/eigen3/cmake/UseEigen3.cmake | 6 + .../eigen3/cmake/language_support.cmake | 67 + thirdparty/eigen3/debug/gdb/__init__.py | 1 + thirdparty/eigen3/debug/gdb/printers.py | 214 + thirdparty/eigen3/debug/msvc/eigen.natvis | 235 + .../eigen3/debug/msvc/eigen_autoexp_part.dat | 295 + thirdparty/eigen3/demos/CMakeLists.txt | 13 + .../eigen3/demos/mandelbrot/CMakeLists.txt | 21 + thirdparty/eigen3/demos/mandelbrot/README | 10 + .../eigen3/demos/mandelbrot/mandelbrot.cpp | 213 + .../eigen3/demos/mandelbrot/mandelbrot.h | 71 + .../eigen3/demos/mix_eigen_and_c/README | 9 + .../demos/mix_eigen_and_c/binary_library.cpp | 185 + .../demos/mix_eigen_and_c/binary_library.h | 71 + .../eigen3/demos/mix_eigen_and_c/example.c | 65 + thirdparty/eigen3/demos/opengl/CMakeLists.txt | 28 + thirdparty/eigen3/demos/opengl/README | 13 + thirdparty/eigen3/demos/opengl/camera.cpp | 264 + thirdparty/eigen3/demos/opengl/camera.h | 118 + thirdparty/eigen3/demos/opengl/gpuhelper.cpp | 126 + thirdparty/eigen3/demos/opengl/gpuhelper.h | 207 + thirdparty/eigen3/demos/opengl/icosphere.cpp | 120 + thirdparty/eigen3/demos/opengl/icosphere.h | 30 + .../eigen3/demos/opengl/quaternion_demo.cpp | 656 + .../eigen3/demos/opengl/quaternion_demo.h | 114 + thirdparty/eigen3/demos/opengl/trackball.cpp | 59 + thirdparty/eigen3/demos/opengl/trackball.h | 42 + thirdparty/eigen3/doc/A05_PortingFrom2To3.dox | 299 + thirdparty/eigen3/doc/AsciiQuickReference.txt | 215 + thirdparty/eigen3/doc/B01_Experimental.dox | 52 + thirdparty/eigen3/doc/CMakeLists.txt | 112 + thirdparty/eigen3/doc/ClassHierarchy.dox | 129 + .../doc/CoeffwiseMathFunctionsTable.dox | 525 + .../doc/CustomizingEigen_CustomScalar.dox | 120 + .../doc/CustomizingEigen_InheritingMatrix.dox | 34 + .../doc/CustomizingEigen_NullaryExpr.dox | 86 + .../eigen3/doc/CustomizingEigen_Plugins.dox | 69 + .../doc/DenseDecompositionBenchmark.dox | 42 + thirdparty/eigen3/doc/Doxyfile.in | 1897 ++ .../doc/Eigen_Silly_Professor_64x64.png | Bin 0 -> 8355 bytes .../eigen3/doc/FixedSizeVectorizable.dox | 38 + .../eigen3/doc/FunctionsTakingEigenTypes.dox | 217 + thirdparty/eigen3/doc/HiPerformance.dox | 128 + .../eigen3/doc/InplaceDecomposition.dox | 115 + thirdparty/eigen3/doc/InsideEigenExample.dox | 495 + thirdparty/eigen3/doc/LeastSquares.dox | 70 + thirdparty/eigen3/doc/Manual.dox | 189 + .../eigen3/doc/MatrixfreeSolverExample.dox | 20 + thirdparty/eigen3/doc/NewExpressionType.dox | 143 + thirdparty/eigen3/doc/Overview.dox | 30 + thirdparty/eigen3/doc/PassingByValue.dox | 40 + thirdparty/eigen3/doc/Pitfalls.dox | 44 + .../eigen3/doc/PreprocessorDirectives.dox | 174 + thirdparty/eigen3/doc/QuickReference.dox | 785 + thirdparty/eigen3/doc/QuickStartGuide.dox | 100 + thirdparty/eigen3/doc/SparseLinearSystems.dox | 229 + .../eigen3/doc/SparseQuickReference.dox | 272 + thirdparty/eigen3/doc/StlContainers.dox | 62 + thirdparty/eigen3/doc/StorageOrders.dox | 86 + .../eigen3/doc/StructHavingEigenMembers.dox | 190 + thirdparty/eigen3/doc/TemplateKeyword.dox | 133 + thirdparty/eigen3/doc/TopicAliasing.dox | 237 + thirdparty/eigen3/doc/TopicAssertions.dox | 108 + thirdparty/eigen3/doc/TopicCMakeGuide.dox | 52 + .../doc/TopicEigenExpressionTemplates.dox | 12 + thirdparty/eigen3/doc/TopicLazyEvaluation.dox | 65 + .../doc/TopicLinearAlgebraDecompositions.dox | 275 + thirdparty/eigen3/doc/TopicMultithreading.dox | 54 + thirdparty/eigen3/doc/TopicResizing.dox | 11 + thirdparty/eigen3/doc/TopicScalarTypes.dox | 12 + thirdparty/eigen3/doc/TopicVectorization.dox | 9 + .../doc/TutorialAdvancedInitialization.dox | 162 + thirdparty/eigen3/doc/TutorialArrayClass.dox | 192 + .../eigen3/doc/TutorialBlockOperations.dox | 228 + thirdparty/eigen3/doc/TutorialGeometry.dox | 242 + .../eigen3/doc/TutorialLinearAlgebra.dox | 292 + thirdparty/eigen3/doc/TutorialMapClass.dox | 86 + .../eigen3/doc/TutorialMatrixArithmetic.dox | 214 + thirdparty/eigen3/doc/TutorialMatrixClass.dox | 265 + ...TutorialReductionsVisitorsBroadcasting.dox | 266 + .../eigen3/doc/TutorialReshapeSlicing.dox | 65 + thirdparty/eigen3/doc/TutorialSparse.dox | 365 + .../doc/TutorialSparse_example_details.dox | 4 + .../eigen3/doc/UnalignedArrayAssert.dox | 120 + .../eigen3/doc/UsingBlasLapackBackends.dox | 133 + thirdparty/eigen3/doc/UsingIntelMKL.dox | 109 + thirdparty/eigen3/doc/UsingNVCC.dox | 32 + thirdparty/eigen3/doc/WrongStackAlignment.dox | 56 + thirdparty/eigen3/doc/eigen_navtree_hacks.js | 244 + thirdparty/eigen3/doc/eigendoxy.css | 221 + .../eigen3/doc/eigendoxy_footer.html.in | 36 + .../eigen3/doc/eigendoxy_header.html.in | 59 + thirdparty/eigen3/doc/eigendoxy_layout.xml.in | 178 + thirdparty/eigen3/doc/eigendoxy_tabs.css | 59 + thirdparty/eigen3/doc/examples/.krazy | 2 + thirdparty/eigen3/doc/examples/CMakeLists.txt | 21 + .../examples/CustomizingEigen_Inheritance.cpp | 30 + thirdparty/eigen3/doc/examples/Cwise_erf.cpp | 9 + thirdparty/eigen3/doc/examples/Cwise_erfc.cpp | 9 + .../eigen3/doc/examples/Cwise_lgamma.cpp | 9 + .../doc/examples/DenseBase_middleCols_int.cpp | 15 + .../doc/examples/DenseBase_middleRows_int.cpp | 15 + .../DenseBase_template_int_middleCols.cpp | 15 + .../DenseBase_template_int_middleRows.cpp | 15 + .../doc/examples/QuickStart_example.cpp | 14 + .../examples/QuickStart_example2_dynamic.cpp | 15 + .../examples/QuickStart_example2_fixed.cpp | 15 + .../doc/examples/TemplateKeyword_flexible.cpp | 22 + .../doc/examples/TemplateKeyword_simple.cpp | 20 + .../eigen3/doc/examples/TutorialInplaceLU.cpp | 61 + .../examples/TutorialLinAlgComputeTwice.cpp | 23 + .../TutorialLinAlgExComputeSolveError.cpp | 14 + ...torialLinAlgExSolveColPivHouseholderQR.cpp | 17 + .../examples/TutorialLinAlgExSolveLDLT.cpp | 16 + .../TutorialLinAlgInverseDeterminant.cpp | 16 + .../examples/TutorialLinAlgRankRevealing.cpp | 20 + .../doc/examples/TutorialLinAlgSVDSolve.cpp | 15 + .../TutorialLinAlgSelfAdjointEigenSolver.cpp | 18 + .../examples/TutorialLinAlgSetThreshold.cpp | 16 + .../Tutorial_ArrayClass_accessors.cpp | 24 + .../examples/Tutorial_ArrayClass_addition.cpp | 23 + .../Tutorial_ArrayClass_cwise_other.cpp | 19 + .../examples/Tutorial_ArrayClass_interop.cpp | 22 + .../Tutorial_ArrayClass_interop_matrix.cpp | 26 + .../doc/examples/Tutorial_ArrayClass_mult.cpp | 16 + ...orial_BlockOperations_block_assignment.cpp | 18 + .../Tutorial_BlockOperations_colrow.cpp | 17 + .../Tutorial_BlockOperations_corner.cpp | 17 + .../Tutorial_BlockOperations_print_block.cpp | 20 + .../Tutorial_BlockOperations_vector.cpp | 14 + .../doc/examples/Tutorial_PartialLU_solve.cpp | 18 + ...ionsVisitorsBroadcasting_broadcast_1nn.cpp | 24 + ...sVisitorsBroadcasting_broadcast_simple.cpp | 21 + ...sBroadcasting_broadcast_simple_rowwise.cpp | 20 + ...ReductionsVisitorsBroadcasting_colwise.cpp | 13 + ...ReductionsVisitorsBroadcasting_maxnorm.cpp | 20 + ...nsVisitorsBroadcasting_reductions_bool.cpp | 21 + ...nsVisitorsBroadcasting_reductions_norm.cpp | 28 + ...rsBroadcasting_reductions_operatornorm.cpp | 18 + ...ReductionsVisitorsBroadcasting_rowwise.cpp | 13 + ...eductionsVisitorsBroadcasting_visitors.cpp | 26 + .../Tutorial_simple_example_dynamic_size.cpp | 22 + .../Tutorial_simple_example_fixed_size.cpp | 15 + .../eigen3/doc/examples/class_Block.cpp | 27 + .../doc/examples/class_CwiseBinaryOp.cpp | 18 + .../doc/examples/class_CwiseUnaryOp.cpp | 19 + .../examples/class_CwiseUnaryOp_ptrfun.cpp | 20 + .../eigen3/doc/examples/class_FixedBlock.cpp | 27 + .../doc/examples/class_FixedVectorBlock.cpp | 27 + .../eigen3/doc/examples/class_VectorBlock.cpp | 27 + .../examples/function_taking_eigenbase.cpp | 18 + .../doc/examples/function_taking_ref.cpp | 19 + .../eigen3/doc/examples/make_circulant.cpp | 11 + .../doc/examples/make_circulant.cpp.entry | 5 + .../doc/examples/make_circulant.cpp.evaluator | 32 + .../examples/make_circulant.cpp.expression | 20 + .../doc/examples/make_circulant.cpp.main | 8 + .../doc/examples/make_circulant.cpp.preamble | 4 + .../doc/examples/make_circulant.cpp.traits | 19 + .../eigen3/doc/examples/make_circulant2.cpp | 52 + .../eigen3/doc/examples/matrixfree_cg.cpp | 129 + .../eigen3/doc/examples/nullary_indexing.cpp | 66 + .../doc/examples/tut_arithmetic_add_sub.cpp | 22 + .../doc/examples/tut_arithmetic_dot_cross.cpp | 15 + .../examples/tut_arithmetic_matrix_mul.cpp | 19 + .../examples/tut_arithmetic_redux_basic.cpp | 16 + .../tut_arithmetic_scalar_mul_div.cpp | 17 + .../tut_matrix_coefficient_accessors.cpp | 18 + .../eigen3/doc/examples/tut_matrix_resize.cpp | 18 + .../examples/tut_matrix_resize_fixed_size.cpp | 12 + thirdparty/eigen3/doc/ftv2node.png | Bin 0 -> 86 bytes thirdparty/eigen3/doc/ftv2pnode.png | Bin 0 -> 229 bytes thirdparty/eigen3/doc/snippets/.krazy | 2 + .../doc/snippets/AngleAxis_mimic_euler.cpp | 5 + .../eigen3/doc/snippets/BiCGSTAB_simple.cpp | 11 + .../doc/snippets/BiCGSTAB_step_by_step.cpp | 14 + thirdparty/eigen3/doc/snippets/CMakeLists.txt | 26 + .../snippets/ColPivHouseholderQR_solve.cpp | 8 + .../snippets/ComplexEigenSolver_compute.cpp | 16 + .../ComplexEigenSolver_eigenvalues.cpp | 4 + .../ComplexEigenSolver_eigenvectors.cpp | 4 + .../doc/snippets/ComplexSchur_compute.cpp | 6 + .../doc/snippets/ComplexSchur_matrixT.cpp | 4 + .../doc/snippets/ComplexSchur_matrixU.cpp | 4 + thirdparty/eigen3/doc/snippets/Cwise_abs.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_abs2.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_acos.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_arg.cpp | 3 + .../doc/snippets/Cwise_array_power_array.cpp | 4 + thirdparty/eigen3/doc/snippets/Cwise_asin.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_atan.cpp | 2 + .../eigen3/doc/snippets/Cwise_boolean_and.cpp | 2 + .../eigen3/doc/snippets/Cwise_boolean_not.cpp | 5 + .../eigen3/doc/snippets/Cwise_boolean_or.cpp | 2 + .../eigen3/doc/snippets/Cwise_boolean_xor.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_ceil.cpp | 3 + thirdparty/eigen3/doc/snippets/Cwise_cos.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_cosh.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_cube.cpp | 2 + .../eigen3/doc/snippets/Cwise_equal_equal.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_exp.cpp | 2 + .../eigen3/doc/snippets/Cwise_floor.cpp | 3 + .../eigen3/doc/snippets/Cwise_greater.cpp | 2 + .../doc/snippets/Cwise_greater_equal.cpp | 2 + .../eigen3/doc/snippets/Cwise_inverse.cpp | 2 + .../eigen3/doc/snippets/Cwise_isFinite.cpp | 5 + .../eigen3/doc/snippets/Cwise_isInf.cpp | 5 + .../eigen3/doc/snippets/Cwise_isNaN.cpp | 5 + thirdparty/eigen3/doc/snippets/Cwise_less.cpp | 2 + .../eigen3/doc/snippets/Cwise_less_equal.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_log.cpp | 2 + .../eigen3/doc/snippets/Cwise_log10.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_max.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_min.cpp | 2 + .../eigen3/doc/snippets/Cwise_minus.cpp | 2 + .../eigen3/doc/snippets/Cwise_minus_equal.cpp | 3 + .../eigen3/doc/snippets/Cwise_not_equal.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_plus.cpp | 2 + .../eigen3/doc/snippets/Cwise_plus_equal.cpp | 3 + thirdparty/eigen3/doc/snippets/Cwise_pow.cpp | 2 + .../eigen3/doc/snippets/Cwise_product.cpp | 4 + .../eigen3/doc/snippets/Cwise_quotient.cpp | 2 + .../eigen3/doc/snippets/Cwise_round.cpp | 3 + .../doc/snippets/Cwise_scalar_power_array.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_sign.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_sin.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_sinh.cpp | 2 + .../eigen3/doc/snippets/Cwise_slash_equal.cpp | 3 + thirdparty/eigen3/doc/snippets/Cwise_sqrt.cpp | 2 + .../eigen3/doc/snippets/Cwise_square.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_tan.cpp | 2 + thirdparty/eigen3/doc/snippets/Cwise_tanh.cpp | 2 + .../eigen3/doc/snippets/Cwise_times_equal.cpp | 3 + .../doc/snippets/DenseBase_LinSpaced.cpp | 2 + .../doc/snippets/DenseBase_LinSpacedInt.cpp | 8 + .../doc/snippets/DenseBase_LinSpaced_seq.cpp | 2 + .../doc/snippets/DenseBase_setLinSpaced.cpp | 3 + .../snippets/DirectionWise_hnormalized.cpp | 7 + .../doc/snippets/DirectionWise_replicate.cpp | 4 + .../snippets/DirectionWise_replicate_int.cpp | 4 + .../EigenSolver_EigenSolver_MatrixType.cpp | 16 + .../doc/snippets/EigenSolver_compute.cpp | 6 + .../doc/snippets/EigenSolver_eigenvalues.cpp | 4 + .../doc/snippets/EigenSolver_eigenvectors.cpp | 4 + .../EigenSolver_pseudoEigenvectors.cpp | 9 + .../snippets/FullPivHouseholderQR_solve.cpp | 8 + .../eigen3/doc/snippets/FullPivLU_image.cpp | 9 + .../eigen3/doc/snippets/FullPivLU_kernel.cpp | 7 + .../eigen3/doc/snippets/FullPivLU_solve.cpp | 11 + .../doc/snippets/GeneralizedEigenSolver.cpp | 7 + .../HessenbergDecomposition_compute.cpp | 6 + .../HessenbergDecomposition_matrixH.cpp | 8 + .../HessenbergDecomposition_packedMatrix.cpp | 9 + .../snippets/HouseholderQR_householderQ.cpp | 7 + .../doc/snippets/HouseholderQR_solve.cpp | 9 + ...ouseholderSequence_HouseholderSequence.cpp | 31 + thirdparty/eigen3/doc/snippets/IOFormat.cpp | 14 + .../eigen3/doc/snippets/JacobiSVD_basic.cpp | 9 + .../eigen3/doc/snippets/Jacobi_makeGivens.cpp | 6 + .../eigen3/doc/snippets/Jacobi_makeJacobi.cpp | 8 + .../eigen3/doc/snippets/LLT_example.cpp | 12 + thirdparty/eigen3/doc/snippets/LLT_solve.cpp | 8 + .../snippets/LeastSquaresNormalEquations.cpp | 4 + .../eigen3/doc/snippets/LeastSquaresQR.cpp | 4 + .../doc/snippets/Map_general_stride.cpp | 5 + .../eigen3/doc/snippets/Map_inner_stride.cpp | 5 + .../eigen3/doc/snippets/Map_outer_stride.cpp | 3 + .../eigen3/doc/snippets/Map_placement_new.cpp | 5 + thirdparty/eigen3/doc/snippets/Map_simple.cpp | 3 + .../doc/snippets/MatrixBase_adjoint.cpp | 3 + .../eigen3/doc/snippets/MatrixBase_all.cpp | 7 + .../snippets/MatrixBase_applyOnTheLeft.cpp | 7 + .../snippets/MatrixBase_applyOnTheRight.cpp | 9 + .../eigen3/doc/snippets/MatrixBase_array.cpp | 4 + .../doc/snippets/MatrixBase_array_const.cpp | 4 + .../doc/snippets/MatrixBase_asDiagonal.cpp | 1 + .../doc/snippets/MatrixBase_block_int_int.cpp | 5 + .../MatrixBase_block_int_int_int_int.cpp | 5 + .../MatrixBase_bottomLeftCorner_int_int.cpp | 6 + .../MatrixBase_bottomRightCorner_int_int.cpp | 6 + .../snippets/MatrixBase_bottomRows_int.cpp | 6 + .../eigen3/doc/snippets/MatrixBase_cast.cpp | 3 + .../eigen3/doc/snippets/MatrixBase_col.cpp | 3 + .../doc/snippets/MatrixBase_colwise.cpp | 5 + ...trixBase_computeInverseAndDetWithCheck.cpp | 13 + .../MatrixBase_computeInverseWithCheck.cpp | 11 + .../doc/snippets/MatrixBase_cwiseAbs.cpp | 4 + .../doc/snippets/MatrixBase_cwiseAbs2.cpp | 4 + .../doc/snippets/MatrixBase_cwiseEqual.cpp | 7 + .../doc/snippets/MatrixBase_cwiseInverse.cpp | 4 + .../doc/snippets/MatrixBase_cwiseMax.cpp | 2 + .../doc/snippets/MatrixBase_cwiseMin.cpp | 2 + .../doc/snippets/MatrixBase_cwiseNotEqual.cpp | 7 + .../doc/snippets/MatrixBase_cwiseProduct.cpp | 4 + .../doc/snippets/MatrixBase_cwiseQuotient.cpp | 2 + .../doc/snippets/MatrixBase_cwiseSign.cpp | 4 + .../doc/snippets/MatrixBase_cwiseSqrt.cpp | 2 + .../doc/snippets/MatrixBase_diagonal.cpp | 4 + .../doc/snippets/MatrixBase_diagonal_int.cpp | 5 + .../MatrixBase_diagonal_template_int.cpp | 5 + .../doc/snippets/MatrixBase_eigenvalues.cpp | 3 + .../doc/snippets/MatrixBase_end_int.cpp | 5 + .../eigen3/doc/snippets/MatrixBase_eval.cpp | 12 + .../MatrixBase_fixedBlock_int_int.cpp | 5 + .../doc/snippets/MatrixBase_hnormalized.cpp | 6 + .../doc/snippets/MatrixBase_homogeneous.cpp | 6 + .../doc/snippets/MatrixBase_identity.cpp | 1 + .../snippets/MatrixBase_identity_int_int.cpp | 1 + .../doc/snippets/MatrixBase_inverse.cpp | 3 + .../doc/snippets/MatrixBase_isDiagonal.cpp | 6 + .../doc/snippets/MatrixBase_isIdentity.cpp | 5 + .../eigen3/doc/snippets/MatrixBase_isOnes.cpp | 5 + .../doc/snippets/MatrixBase_isOrthogonal.cpp | 6 + .../doc/snippets/MatrixBase_isUnitary.cpp | 5 + .../eigen3/doc/snippets/MatrixBase_isZero.cpp | 5 + .../doc/snippets/MatrixBase_leftCols_int.cpp | 6 + .../doc/snippets/MatrixBase_noalias.cpp | 3 + .../eigen3/doc/snippets/MatrixBase_ones.cpp | 2 + .../doc/snippets/MatrixBase_ones_int.cpp | 2 + .../doc/snippets/MatrixBase_ones_int_int.cpp | 1 + .../doc/snippets/MatrixBase_operatorNorm.cpp | 3 + .../eigen3/doc/snippets/MatrixBase_prod.cpp | 3 + .../eigen3/doc/snippets/MatrixBase_random.cpp | 1 + .../doc/snippets/MatrixBase_random_int.cpp | 1 + .../snippets/MatrixBase_random_int_int.cpp | 1 + .../doc/snippets/MatrixBase_replicate.cpp | 4 + .../snippets/MatrixBase_replicate_int_int.cpp | 4 + .../doc/snippets/MatrixBase_reverse.cpp | 8 + .../doc/snippets/MatrixBase_rightCols_int.cpp | 6 + .../eigen3/doc/snippets/MatrixBase_row.cpp | 3 + .../doc/snippets/MatrixBase_rowwise.cpp | 5 + .../snippets/MatrixBase_segment_int_int.cpp | 5 + .../eigen3/doc/snippets/MatrixBase_select.cpp | 6 + .../snippets/MatrixBase_selfadjointView.cpp | 6 + .../eigen3/doc/snippets/MatrixBase_set.cpp | 13 + .../doc/snippets/MatrixBase_setIdentity.cpp | 3 + .../doc/snippets/MatrixBase_setOnes.cpp | 3 + .../doc/snippets/MatrixBase_setRandom.cpp | 3 + .../doc/snippets/MatrixBase_setZero.cpp | 3 + .../doc/snippets/MatrixBase_start_int.cpp | 5 + .../MatrixBase_template_int_bottomRows.cpp | 6 + .../snippets/MatrixBase_template_int_end.cpp | 5 + ...template_int_int_block_int_int_int_int.cpp | 5 + ...Base_template_int_int_bottomLeftCorner.cpp | 6 + ...plate_int_int_bottomLeftCorner_int_int.cpp | 6 + ...ase_template_int_int_bottomRightCorner.cpp | 6 + ...late_int_int_bottomRightCorner_int_int.cpp | 6 + ...rixBase_template_int_int_topLeftCorner.cpp | 6 + ...template_int_int_topLeftCorner_int_int.cpp | 6 + ...ixBase_template_int_int_topRightCorner.cpp | 6 + ...emplate_int_int_topRightCorner_int_int.cpp | 6 + .../MatrixBase_template_int_leftCols.cpp | 6 + .../MatrixBase_template_int_rightCols.cpp | 6 + .../MatrixBase_template_int_segment.cpp | 5 + .../MatrixBase_template_int_start.cpp | 5 + .../MatrixBase_template_int_topRows.cpp | 6 + .../MatrixBase_topLeftCorner_int_int.cpp | 6 + .../MatrixBase_topRightCorner_int_int.cpp | 6 + .../doc/snippets/MatrixBase_topRows_int.cpp | 6 + .../doc/snippets/MatrixBase_transpose.cpp | 8 + .../snippets/MatrixBase_triangularView.cpp | 9 + .../eigen3/doc/snippets/MatrixBase_zero.cpp | 2 + .../doc/snippets/MatrixBase_zero_int.cpp | 2 + .../doc/snippets/MatrixBase_zero_int_int.cpp | 1 + .../eigen3/doc/snippets/Matrix_Map_stride.cpp | 7 + .../snippets/Matrix_resize_NoChange_int.cpp | 3 + .../eigen3/doc/snippets/Matrix_resize_int.cpp | 6 + .../snippets/Matrix_resize_int_NoChange.cpp | 3 + .../doc/snippets/Matrix_resize_int_int.cpp | 9 + .../doc/snippets/Matrix_setConstant_int.cpp | 3 + .../snippets/Matrix_setConstant_int_int.cpp | 3 + .../snippets/Matrix_setIdentity_int_int.cpp | 3 + .../doc/snippets/Matrix_setOnes_int.cpp | 3 + .../doc/snippets/Matrix_setOnes_int_int.cpp | 3 + .../doc/snippets/Matrix_setRandom_int.cpp | 3 + .../doc/snippets/Matrix_setRandom_int_int.cpp | 3 + .../doc/snippets/Matrix_setZero_int.cpp | 3 + .../doc/snippets/Matrix_setZero_int_int.cpp | 3 + .../doc/snippets/PartialPivLU_solve.cpp | 7 + .../doc/snippets/PartialRedux_count.cpp | 5 + .../doc/snippets/PartialRedux_maxCoeff.cpp | 3 + .../doc/snippets/PartialRedux_minCoeff.cpp | 3 + .../eigen3/doc/snippets/PartialRedux_norm.cpp | 3 + .../eigen3/doc/snippets/PartialRedux_prod.cpp | 3 + .../doc/snippets/PartialRedux_squaredNorm.cpp | 3 + .../eigen3/doc/snippets/PartialRedux_sum.cpp | 3 + .../eigen3/doc/snippets/RealQZ_compute.cpp | 17 + .../RealSchur_RealSchur_MatrixType.cpp | 10 + .../eigen3/doc/snippets/RealSchur_compute.cpp | 6 + ...ointEigenSolver_SelfAdjointEigenSolver.cpp | 7 + ...lver_SelfAdjointEigenSolver_MatrixType.cpp | 17 + ...ver_SelfAdjointEigenSolver_MatrixType2.cpp | 16 + ...fAdjointEigenSolver_compute_MatrixType.cpp | 7 + ...AdjointEigenSolver_compute_MatrixType2.cpp | 9 + .../SelfAdjointEigenSolver_eigenvalues.cpp | 4 + .../SelfAdjointEigenSolver_eigenvectors.cpp | 4 + ...AdjointEigenSolver_operatorInverseSqrt.cpp | 9 + .../SelfAdjointEigenSolver_operatorSqrt.cpp | 8 + .../snippets/SelfAdjointView_eigenvalues.cpp | 3 + .../snippets/SelfAdjointView_operatorNorm.cpp | 3 + .../doc/snippets/SparseMatrix_coeffs.cpp | 9 + .../doc/snippets/TopicAliasing_block.cpp | 7 + .../snippets/TopicAliasing_block_correct.cpp | 7 + .../doc/snippets/TopicAliasing_cwise.cpp | 20 + .../doc/snippets/TopicAliasing_mult1.cpp | 4 + .../doc/snippets/TopicAliasing_mult2.cpp | 10 + .../doc/snippets/TopicAliasing_mult3.cpp | 4 + .../doc/snippets/TopicAliasing_mult4.cpp | 5 + .../doc/snippets/TopicAliasing_mult5.cpp | 5 + .../snippets/TopicStorageOrders_example.cpp | 18 + .../eigen3/doc/snippets/Triangular_solve.cpp | 11 + ...lization_Tridiagonalization_MatrixType.cpp | 9 + .../snippets/Tridiagonalization_compute.cpp | 9 + .../Tridiagonalization_decomposeInPlace.cpp | 10 + .../snippets/Tridiagonalization_diagonal.cpp | 13 + ...iagonalization_householderCoefficients.cpp | 6 + .../Tridiagonalization_packedMatrix.cpp | 8 + .../Tutorial_AdvancedInitialization_Block.cpp | 5 + ..._AdvancedInitialization_CommaTemporary.cpp | 4 + .../Tutorial_AdvancedInitialization_Join.cpp | 11 + ...orial_AdvancedInitialization_LinSpaced.cpp | 7 + ...orial_AdvancedInitialization_ThreeWays.cpp | 20 + .../Tutorial_AdvancedInitialization_Zero.cpp | 13 + .../doc/snippets/Tutorial_Map_rowmajor.cpp | 7 + .../doc/snippets/Tutorial_Map_using.cpp | 21 + .../doc/snippets/Tutorial_ReshapeMat2Mat.cpp | 6 + .../doc/snippets/Tutorial_ReshapeMat2Vec.cpp | 11 + .../doc/snippets/Tutorial_SlicingCol.cpp | 11 + .../doc/snippets/Tutorial_SlicingVec.cpp | 4 + .../doc/snippets/Tutorial_commainit_01.cpp | 5 + .../doc/snippets/Tutorial_commainit_01b.cpp | 5 + .../doc/snippets/Tutorial_commainit_02.cpp | 7 + .../Tutorial_solve_matrix_inverse.cpp | 6 + .../snippets/Tutorial_solve_multiple_rhs.cpp | 10 + .../Tutorial_solve_reuse_decomposition.cpp | 13 + .../doc/snippets/Tutorial_solve_singular.cpp | 9 + .../snippets/Tutorial_solve_triangular.cpp | 8 + .../Tutorial_solve_triangular_inplace.cpp | 6 + .../doc/snippets/VectorwiseOp_homogeneous.cpp | 7 + .../doc/snippets/Vectorwise_reverse.cpp | 10 + .../eigen3/doc/snippets/class_FullPivLU.cpp | 16 + .../doc/snippets/compile_snippet.cpp.in | 20 + .../snippets/tut_arithmetic_redux_minmax.cpp | 12 + .../tut_arithmetic_transpose_aliasing.cpp | 5 + .../tut_arithmetic_transpose_conjugate.cpp | 12 + .../tut_arithmetic_transpose_inplace.cpp | 6 + .../tut_matrix_assignment_resizing.cpp | 5 + .../doc/special_examples/CMakeLists.txt | 35 + .../Tutorial_sparse_example.cpp | 38 + .../Tutorial_sparse_example_details.cpp | 44 + .../doc/special_examples/random_cpp11.cpp | 14 + thirdparty/eigen3/doc/tutorial.cpp | 62 + thirdparty/eigen3/eigen3.pc.in | 9 + thirdparty/eigen3/failtest/CMakeLists.txt | 75 + thirdparty/eigen3/failtest/bdcsvd_int.cpp | 14 + .../block_nonconst_ctor_on_const_xpr_0.cpp | 15 + .../block_nonconst_ctor_on_const_xpr_1.cpp | 15 + .../block_nonconst_ctor_on_const_xpr_2.cpp | 16 + .../block_on_const_type_actually_const_0.cpp | 16 + .../block_on_const_type_actually_const_1.cpp | 16 + thirdparty/eigen3/failtest/colpivqr_int.cpp | 14 + .../const_qualified_block_method_retval_0.cpp | 15 + .../const_qualified_block_method_retval_1.cpp | 15 + ...const_qualified_diagonal_method_retval.cpp | 15 + ...onst_qualified_transpose_method_retval.cpp | 15 + ...seunaryview_nonconst_ctor_on_const_xpr.cpp | 15 + ...unaryview_on_const_type_actually_const.cpp | 16 + .../diagonal_nonconst_ctor_on_const_xpr.cpp | 15 + .../diagonal_on_const_type_actually_const.cpp | 16 + .../eigen3/failtest/eigensolver_cplx.cpp | 14 + .../eigen3/failtest/eigensolver_int.cpp | 14 + .../eigen3/failtest/failtest_sanity_check.cpp | 5 + thirdparty/eigen3/failtest/fullpivlu_int.cpp | 14 + thirdparty/eigen3/failtest/fullpivqr_int.cpp | 14 + thirdparty/eigen3/failtest/jacobisvd_int.cpp | 14 + thirdparty/eigen3/failtest/ldlt_int.cpp | 14 + thirdparty/eigen3/failtest/llt_int.cpp | 14 + .../map_nonconst_ctor_on_const_ptr_0.cpp | 15 + .../map_nonconst_ctor_on_const_ptr_1.cpp | 15 + .../map_nonconst_ctor_on_const_ptr_2.cpp | 15 + .../map_nonconst_ctor_on_const_ptr_3.cpp | 15 + .../map_nonconst_ctor_on_const_ptr_4.cpp | 15 + .../map_on_const_type_actually_const_0.cpp | 15 + .../map_on_const_type_actually_const_1.cpp | 15 + .../eigen3/failtest/partialpivlu_int.cpp | 14 + thirdparty/eigen3/failtest/qr_int.cpp | 14 + thirdparty/eigen3/failtest/ref_1.cpp | 18 + thirdparty/eigen3/failtest/ref_2.cpp | 15 + thirdparty/eigen3/failtest/ref_3.cpp | 15 + thirdparty/eigen3/failtest/ref_4.cpp | 15 + thirdparty/eigen3/failtest/ref_5.cpp | 16 + ...adjointview_nonconst_ctor_on_const_xpr.cpp | 15 + ...jointview_on_const_type_actually_const.cpp | 16 + thirdparty/eigen3/failtest/sparse_ref_1.cpp | 18 + thirdparty/eigen3/failtest/sparse_ref_2.cpp | 15 + thirdparty/eigen3/failtest/sparse_ref_3.cpp | 15 + thirdparty/eigen3/failtest/sparse_ref_4.cpp | 15 + thirdparty/eigen3/failtest/sparse_ref_5.cpp | 16 + .../failtest/sparse_storage_mismatch.cpp | 16 + thirdparty/eigen3/failtest/swap_1.cpp | 14 + thirdparty/eigen3/failtest/swap_2.cpp | 14 + thirdparty/eigen3/failtest/ternary_1.cpp | 13 + thirdparty/eigen3/failtest/ternary_2.cpp | 13 + .../transpose_nonconst_ctor_on_const_xpr.cpp | 15 + ...transpose_on_const_type_actually_const.cpp | 16 + ...angularview_nonconst_ctor_on_const_xpr.cpp | 15 + ...gularview_on_const_type_actually_const.cpp | 16 + thirdparty/eigen3/lapack/CMakeLists.txt | 449 + thirdparty/eigen3/lapack/cholesky.cpp | 72 + thirdparty/eigen3/lapack/clacgv.f | 116 + thirdparty/eigen3/lapack/cladiv.f | 97 + thirdparty/eigen3/lapack/clarf.f | 232 + thirdparty/eigen3/lapack/clarfb.f | 771 + thirdparty/eigen3/lapack/clarfg.f | 203 + thirdparty/eigen3/lapack/clarft.f | 328 + thirdparty/eigen3/lapack/complex_double.cpp | 18 + thirdparty/eigen3/lapack/complex_single.cpp | 18 + thirdparty/eigen3/lapack/dladiv.f | 128 + thirdparty/eigen3/lapack/dlamch.f | 189 + thirdparty/eigen3/lapack/dlapy2.f | 104 + thirdparty/eigen3/lapack/dlapy3.f | 111 + thirdparty/eigen3/lapack/dlarf.f | 227 + thirdparty/eigen3/lapack/dlarfb.f | 762 + thirdparty/eigen3/lapack/dlarfg.f | 196 + thirdparty/eigen3/lapack/dlarft.f | 326 + thirdparty/eigen3/lapack/double.cpp | 18 + thirdparty/eigen3/lapack/dsecnd_NONE.f | 52 + thirdparty/eigen3/lapack/eigenvalues.cpp | 62 + thirdparty/eigen3/lapack/ilaclc.f | 118 + thirdparty/eigen3/lapack/ilaclr.f | 121 + thirdparty/eigen3/lapack/iladlc.f | 118 + thirdparty/eigen3/lapack/iladlr.f | 121 + thirdparty/eigen3/lapack/ilaslc.f | 118 + thirdparty/eigen3/lapack/ilaslr.f | 121 + thirdparty/eigen3/lapack/ilazlc.f | 118 + thirdparty/eigen3/lapack/ilazlr.f | 121 + thirdparty/eigen3/lapack/lapack_common.h | 29 + thirdparty/eigen3/lapack/lu.cpp | 89 + thirdparty/eigen3/lapack/second_NONE.f | 52 + thirdparty/eigen3/lapack/single.cpp | 18 + thirdparty/eigen3/lapack/sladiv.f | 128 + thirdparty/eigen3/lapack/slamch.f | 192 + thirdparty/eigen3/lapack/slapy2.f | 104 + thirdparty/eigen3/lapack/slapy3.f | 111 + thirdparty/eigen3/lapack/slarf.f | 227 + thirdparty/eigen3/lapack/slarfb.f | 763 + thirdparty/eigen3/lapack/slarfg.f | 196 + thirdparty/eigen3/lapack/slarft.f | 326 + thirdparty/eigen3/lapack/svd.cpp | 138 + thirdparty/eigen3/lapack/zlacgv.f | 116 + thirdparty/eigen3/lapack/zladiv.f | 97 + thirdparty/eigen3/lapack/zlarf.f | 232 + thirdparty/eigen3/lapack/zlarfb.f | 774 + thirdparty/eigen3/lapack/zlarfg.f | 203 + thirdparty/eigen3/lapack/zlarft.f | 327 + thirdparty/eigen3/scripts/CMakeLists.txt | 6 + thirdparty/eigen3/scripts/buildtests.in | 22 + .../eigen3/scripts/cdashtesting.cmake.in | 49 + thirdparty/eigen3/scripts/check.in | 21 + thirdparty/eigen3/scripts/debug.in | 3 + .../eigen3/scripts/eigen_gen_credits.cpp | 232 + thirdparty/eigen3/scripts/eigen_gen_docs | 24 + thirdparty/eigen3/scripts/release.in | 3 + thirdparty/eigen3/scripts/relicense.py | 69 + .../eigen3/signature_of_eigen3_matrix_library | 1 + thirdparty/eigen3/test/CMakeLists.txt | 390 + thirdparty/eigen3/test/adjoint.cpp | 200 + thirdparty/eigen3/test/array.cpp | 495 + thirdparty/eigen3/test/array_for_matrix.cpp | 304 + thirdparty/eigen3/test/array_of_string.cpp | 32 + thirdparty/eigen3/test/array_replicate.cpp | 82 + thirdparty/eigen3/test/array_reverse.cpp | 146 + thirdparty/eigen3/test/bandmatrix.cpp | 71 + thirdparty/eigen3/test/basicstuff.cpp | 280 + thirdparty/eigen3/test/bdcsvd.cpp | 112 + thirdparty/eigen3/test/bicgstab.cpp | 34 + thirdparty/eigen3/test/block.cpp | 279 + thirdparty/eigen3/test/boostmultiprec.cpp | 201 + thirdparty/eigen3/test/bug1213.cpp | 13 + thirdparty/eigen3/test/bug1213.h | 8 + thirdparty/eigen3/test/bug1213_main.cpp | 18 + thirdparty/eigen3/test/cholesky.cpp | 526 + thirdparty/eigen3/test/cholmod_support.cpp | 57 + thirdparty/eigen3/test/commainitializer.cpp | 106 + thirdparty/eigen3/test/conjugate_gradient.cpp | 34 + .../eigen3/test/conservative_resize.cpp | 134 + thirdparty/eigen3/test/constructor.cpp | 84 + thirdparty/eigen3/test/corners.cpp | 118 + thirdparty/eigen3/test/ctorleak.cpp | 69 + thirdparty/eigen3/test/cuda_basic.cu | 170 + thirdparty/eigen3/test/cuda_common.h | 101 + thirdparty/eigen3/test/denseLM.cpp | 190 + thirdparty/eigen3/test/dense_storage.cpp | 76 + thirdparty/eigen3/test/determinant.cpp | 67 + thirdparty/eigen3/test/diagonal.cpp | 106 + thirdparty/eigen3/test/diagonalmatrices.cpp | 167 + thirdparty/eigen3/test/dontalign.cpp | 63 + thirdparty/eigen3/test/dynalloc.cpp | 175 + thirdparty/eigen3/test/eigen2support.cpp | 66 + .../eigen3/test/eigensolver_complex.cpp | 177 + .../test/eigensolver_generalized_real.cpp | 104 + .../eigen3/test/eigensolver_generic.cpp | 166 + .../eigen3/test/eigensolver_selfadjoint.cpp | 274 + thirdparty/eigen3/test/evaluator_common.h | 0 thirdparty/eigen3/test/evaluators.cpp | 499 + thirdparty/eigen3/test/exceptions.cpp | 113 + thirdparty/eigen3/test/fastmath.cpp | 99 + thirdparty/eigen3/test/first_aligned.cpp | 51 + thirdparty/eigen3/test/geo_alignedbox.cpp | 189 + thirdparty/eigen3/test/geo_eulerangles.cpp | 112 + thirdparty/eigen3/test/geo_homogeneous.cpp | 125 + thirdparty/eigen3/test/geo_hyperplane.cpp | 198 + thirdparty/eigen3/test/geo_orthomethods.cpp | 133 + .../eigen3/test/geo_parametrizedline.cpp | 104 + thirdparty/eigen3/test/geo_quaternion.cpp | 302 + .../eigen3/test/geo_transformations.cpp | 645 + thirdparty/eigen3/test/half_float.cpp | 264 + thirdparty/eigen3/test/hessenberg.cpp | 62 + thirdparty/eigen3/test/householder.cpp | 138 + .../eigen3/test/incomplete_cholesky.cpp | 65 + .../eigen3/test/inplace_decomposition.cpp | 110 + thirdparty/eigen3/test/integer_types.cpp | 169 + thirdparty/eigen3/test/inverse.cpp | 119 + thirdparty/eigen3/test/is_same_dense.cpp | 33 + thirdparty/eigen3/test/jacobi.cpp | 81 + thirdparty/eigen3/test/jacobisvd.cpp | 126 + thirdparty/eigen3/test/linearstructure.cpp | 149 + thirdparty/eigen3/test/lscg.cpp | 37 + thirdparty/eigen3/test/lu.cpp | 281 + thirdparty/eigen3/test/main.h | 803 + thirdparty/eigen3/test/mapped_matrix.cpp | 212 + thirdparty/eigen3/test/mapstaticmethods.cpp | 175 + thirdparty/eigen3/test/mapstride.cpp | 236 + thirdparty/eigen3/test/meta.cpp | 97 + thirdparty/eigen3/test/metis_support.cpp | 25 + thirdparty/eigen3/test/miscmatrices.cpp | 47 + thirdparty/eigen3/test/mixingtypes.cpp | 300 + thirdparty/eigen3/test/mpl2only.cpp | 22 + thirdparty/eigen3/test/nesting_ops.cpp | 107 + thirdparty/eigen3/test/nomalloc.cpp | 229 + thirdparty/eigen3/test/nullary.cpp | 304 + thirdparty/eigen3/test/numext.cpp | 53 + thirdparty/eigen3/test/packetmath.cpp | 641 + thirdparty/eigen3/test/pardiso_support.cpp | 29 + thirdparty/eigen3/test/pastix_support.cpp | 54 + .../eigen3/test/permutationmatrices.cpp | 168 + thirdparty/eigen3/test/prec_inverse_4x4.cpp | 83 + thirdparty/eigen3/test/product.h | 231 + thirdparty/eigen3/test/product_extra.cpp | 375 + thirdparty/eigen3/test/product_large.cpp | 107 + thirdparty/eigen3/test/product_mmtr.cpp | 96 + .../eigen3/test/product_notemporary.cpp | 160 + .../eigen3/test/product_selfadjoint.cpp | 87 + thirdparty/eigen3/test/product_small.cpp | 293 + thirdparty/eigen3/test/product_symm.cpp | 112 + thirdparty/eigen3/test/product_syrk.cpp | 136 + thirdparty/eigen3/test/product_trmm.cpp | 127 + thirdparty/eigen3/test/product_trmv.cpp | 91 + thirdparty/eigen3/test/product_trsolve.cpp | 101 + thirdparty/eigen3/test/qr.cpp | 132 + thirdparty/eigen3/test/qr_colpivoting.cpp | 342 + thirdparty/eigen3/test/qr_fullpivoting.cpp | 159 + thirdparty/eigen3/test/qtvector.cpp | 158 + thirdparty/eigen3/test/rand.cpp | 118 + thirdparty/eigen3/test/real_qz.cpp | 95 + thirdparty/eigen3/test/redux.cpp | 180 + thirdparty/eigen3/test/ref.cpp | 292 + thirdparty/eigen3/test/resize.cpp | 41 + thirdparty/eigen3/test/rvalue_types.cpp | 64 + thirdparty/eigen3/test/schur_complex.cpp | 91 + thirdparty/eigen3/test/schur_real.cpp | 112 + thirdparty/eigen3/test/selfadjoint.cpp | 76 + .../eigen3/test/simplicial_cholesky.cpp | 47 + thirdparty/eigen3/test/sizeof.cpp | 47 + thirdparty/eigen3/test/sizeoverflow.cpp | 64 + thirdparty/eigen3/test/smallvectors.cpp | 67 + thirdparty/eigen3/test/sparse.h | 210 + thirdparty/eigen3/test/sparseLM.cpp | 176 + thirdparty/eigen3/test/sparse_basic.cpp | 688 + thirdparty/eigen3/test/sparse_block.cpp | 317 + .../eigen3/test/sparse_permutations.cpp | 236 + thirdparty/eigen3/test/sparse_product.cpp | 475 + thirdparty/eigen3/test/sparse_ref.cpp | 139 + thirdparty/eigen3/test/sparse_solver.h | 565 + thirdparty/eigen3/test/sparse_solvers.cpp | 112 + thirdparty/eigen3/test/sparse_vector.cpp | 163 + thirdparty/eigen3/test/sparselu.cpp | 45 + thirdparty/eigen3/test/sparseqr.cpp | 128 + thirdparty/eigen3/test/special_numbers.cpp | 58 + thirdparty/eigen3/test/spqr_support.cpp | 64 + thirdparty/eigen3/test/stable_norm.cpp | 202 + thirdparty/eigen3/test/stddeque.cpp | 132 + thirdparty/eigen3/test/stddeque_overload.cpp | 158 + thirdparty/eigen3/test/stdlist.cpp | 132 + thirdparty/eigen3/test/stdlist_overload.cpp | 192 + thirdparty/eigen3/test/stdvector.cpp | 148 + thirdparty/eigen3/test/stdvector_overload.cpp | 161 + thirdparty/eigen3/test/superlu_support.cpp | 23 + thirdparty/eigen3/test/svd_common.h | 483 + thirdparty/eigen3/test/svd_fill.h | 119 + thirdparty/eigen3/test/swap.cpp | 94 + thirdparty/eigen3/test/triangular.cpp | 247 + thirdparty/eigen3/test/umeyama.cpp | 183 + thirdparty/eigen3/test/umfpack_support.cpp | 32 + thirdparty/eigen3/test/unalignedassert.cpp | 180 + thirdparty/eigen3/test/unalignedcount.cpp | 53 + .../eigen3/test/upperbidiagonalization.cpp | 43 + .../eigen3/test/vectorization_logic.cpp | 425 + thirdparty/eigen3/test/vectorwiseop.cpp | 252 + thirdparty/eigen3/test/visitor.cpp | 135 + thirdparty/eigen3/test/zerosized.cpp | 102 + thirdparty/eigen3/unsupported/CMakeLists.txt | 9 + .../eigen3/unsupported/Eigen/AdolcForward | 156 + .../eigen3/unsupported/Eigen/AlignedVector3 | 224 + .../eigen3/unsupported/Eigen/ArpackSupport | 31 + thirdparty/eigen3/unsupported/Eigen/AutoDiff | 40 + thirdparty/eigen3/unsupported/Eigen/BVH | 95 + .../eigen3/unsupported/Eigen/CMakeLists.txt | 32 + .../unsupported/Eigen/CXX11/CMakeLists.txt | 8 + .../eigen3/unsupported/Eigen/CXX11/Tensor | 152 + .../unsupported/Eigen/CXX11/TensorSymmetry | 42 + .../eigen3/unsupported/Eigen/CXX11/ThreadPool | 65 + .../Eigen/CXX11/src/Tensor/README.md | 1757 ++ .../Eigen/CXX11/src/Tensor/Tensor.h | 527 + .../Eigen/CXX11/src/Tensor/TensorArgMax.h | 299 + .../Eigen/CXX11/src/Tensor/TensorAssign.h | 181 + .../Eigen/CXX11/src/Tensor/TensorBase.h | 1010 + .../CXX11/src/Tensor/TensorBroadcasting.h | 392 + .../Eigen/CXX11/src/Tensor/TensorChipping.h | 384 + .../CXX11/src/Tensor/TensorConcatenation.h | 361 + .../CXX11/src/Tensor/TensorContraction.h | 628 + .../src/Tensor/TensorContractionBlocking.h | 56 + .../CXX11/src/Tensor/TensorContractionCuda.h | 1391 ++ .../src/Tensor/TensorContractionMapper.h | 467 + .../src/Tensor/TensorContractionThreadPool.h | 1052 + .../Eigen/CXX11/src/Tensor/TensorConversion.h | 279 + .../CXX11/src/Tensor/TensorConvolution.h | 1104 ++ .../Eigen/CXX11/src/Tensor/TensorCostModel.h | 212 + .../Eigen/CXX11/src/Tensor/TensorCustomOp.h | 313 + .../Eigen/CXX11/src/Tensor/TensorDevice.h | 68 + .../Eigen/CXX11/src/Tensor/TensorDeviceCuda.h | 337 + .../CXX11/src/Tensor/TensorDeviceDefault.h | 81 + .../Eigen/CXX11/src/Tensor/TensorDeviceSycl.h | 122 + .../CXX11/src/Tensor/TensorDeviceThreadPool.h | 282 + .../CXX11/src/Tensor/TensorDimensionList.h | 236 + .../Eigen/CXX11/src/Tensor/TensorDimensions.h | 428 + .../Eigen/CXX11/src/Tensor/TensorEvalTo.h | 181 + .../Eigen/CXX11/src/Tensor/TensorEvaluator.h | 633 + .../Eigen/CXX11/src/Tensor/TensorExecutor.h | 288 + .../Eigen/CXX11/src/Tensor/TensorExpr.h | 371 + .../Eigen/CXX11/src/Tensor/TensorFFT.h | 651 + .../Eigen/CXX11/src/Tensor/TensorFixedSize.h | 389 + .../Eigen/CXX11/src/Tensor/TensorForcedEval.h | 167 + .../src/Tensor/TensorForwardDeclarations.h | 109 + .../Eigen/CXX11/src/Tensor/TensorFunctors.h | 489 + .../Eigen/CXX11/src/Tensor/TensorGenerator.h | 185 + .../CXX11/src/Tensor/TensorGlobalFunctions.h | 33 + .../Eigen/CXX11/src/Tensor/TensorIO.h | 79 + .../Eigen/CXX11/src/Tensor/TensorImagePatch.h | 509 + .../Eigen/CXX11/src/Tensor/TensorIndexList.h | 725 + .../Eigen/CXX11/src/Tensor/TensorInflation.h | 229 + .../CXX11/src/Tensor/TensorInitializer.h | 82 + .../Eigen/CXX11/src/Tensor/TensorIntDiv.h | 253 + .../Eigen/CXX11/src/Tensor/TensorLayoutSwap.h | 209 + .../Eigen/CXX11/src/Tensor/TensorMacros.h | 54 + .../Eigen/CXX11/src/Tensor/TensorMap.h | 321 + .../Eigen/CXX11/src/Tensor/TensorMeta.h | 218 + .../Eigen/CXX11/src/Tensor/TensorMorphing.h | 888 + .../Eigen/CXX11/src/Tensor/TensorPadding.h | 397 + .../Eigen/CXX11/src/Tensor/TensorPatch.h | 269 + .../Eigen/CXX11/src/Tensor/TensorRandom.h | 276 + .../Eigen/CXX11/src/Tensor/TensorReduction.h | 781 + .../CXX11/src/Tensor/TensorReductionCuda.h | 750 + .../CXX11/src/Tensor/TensorReductionSycl.h | 242 + .../Eigen/CXX11/src/Tensor/TensorRef.h | 429 + .../Eigen/CXX11/src/Tensor/TensorReverse.h | 288 + .../Eigen/CXX11/src/Tensor/TensorScan.h | 287 + .../Eigen/CXX11/src/Tensor/TensorShuffling.h | 264 + .../Eigen/CXX11/src/Tensor/TensorStorage.h | 146 + .../Eigen/CXX11/src/Tensor/TensorStriding.h | 338 + .../Eigen/CXX11/src/Tensor/TensorSycl.h | 82 + .../TensorSyclConvertToDeviceExpression.h | 121 + .../src/Tensor/TensorSyclExprConstructor.h | 239 + .../src/Tensor/TensorSyclExtractAccessor.h | 204 + .../src/Tensor/TensorSyclExtractFunctors.h | 177 + .../CXX11/src/Tensor/TensorSyclLeafCount.h | 114 + .../src/Tensor/TensorSyclPlaceHolderExpr.h | 181 + .../Eigen/CXX11/src/Tensor/TensorSyclRun.h | 70 + .../Eigen/CXX11/src/Tensor/TensorSyclTuple.h | 234 + .../Eigen/CXX11/src/Tensor/TensorTraits.h | 272 + .../Eigen/CXX11/src/Tensor/TensorUInt128.h | 248 + .../CXX11/src/Tensor/TensorVolumePatch.h | 608 + .../src/TensorSymmetry/DynamicSymmetry.h | 293 + .../CXX11/src/TensorSymmetry/StaticSymmetry.h | 236 + .../Eigen/CXX11/src/TensorSymmetry/Symmetry.h | 338 + .../TensorSymmetry/util/TemplateGroupTheory.h | 666 + .../Eigen/CXX11/src/ThreadPool/EventCount.h | 233 + .../src/ThreadPool/NonBlockingThreadPool.h | 274 + .../Eigen/CXX11/src/ThreadPool/RunQueue.h | 210 + .../CXX11/src/ThreadPool/SimpleThreadPool.h | 154 + .../CXX11/src/ThreadPool/ThreadEnvironment.h | 38 + .../Eigen/CXX11/src/ThreadPool/ThreadLocal.h | 22 + .../src/ThreadPool/ThreadPoolInterface.h | 33 + .../Eigen/CXX11/src/ThreadPool/ThreadYield.h | 20 + .../Eigen/CXX11/src/util/CXX11Meta.h | 542 + .../Eigen/CXX11/src/util/CXX11Workarounds.h | 88 + .../Eigen/CXX11/src/util/EmulateArray.h | 267 + .../Eigen/CXX11/src/util/EmulateCXX11Meta.h | 311 + .../Eigen/CXX11/src/util/MaxSizeVector.h | 141 + .../eigen3/unsupported/Eigen/EulerAngles | 43 + thirdparty/eigen3/unsupported/Eigen/FFT | 418 + .../eigen3/unsupported/Eigen/IterativeSolvers | 42 + .../eigen3/unsupported/Eigen/KroneckerProduct | 36 + .../unsupported/Eigen/LevenbergMarquardt | 45 + .../eigen3/unsupported/Eigen/MPRealSupport | 209 + .../eigen3/unsupported/Eigen/MatrixFunctions | 501 + .../unsupported/Eigen/MoreVectorization | 24 + .../unsupported/Eigen/NonLinearOptimization | 134 + .../eigen3/unsupported/Eigen/NumericalDiff | 56 + .../eigen3/unsupported/Eigen/OpenGLSupport | 322 + .../eigen3/unsupported/Eigen/Polynomials | 138 + thirdparty/eigen3/unsupported/Eigen/Skyline | 39 + .../eigen3/unsupported/Eigen/SparseExtra | 53 + .../eigen3/unsupported/Eigen/SpecialFunctions | 63 + thirdparty/eigen3/unsupported/Eigen/Splines | 31 + .../Eigen/src/AutoDiff/AutoDiffJacobian.h | 108 + .../Eigen/src/AutoDiff/AutoDiffScalar.h | 693 + .../Eigen/src/AutoDiff/AutoDiffVector.h | 220 + .../unsupported/Eigen/src/BVH/BVAlgorithms.h | 293 + .../eigen3/unsupported/Eigen/src/BVH/KdBVH.h | 222 + .../ArpackSelfAdjointEigenSolver.h | 805 + .../Eigen/src/EulerAngles/CMakeLists.txt | 6 + .../Eigen/src/EulerAngles/EulerAngles.h | 386 + .../Eigen/src/EulerAngles/EulerSystem.h | 326 + .../unsupported/Eigen/src/FFT/ei_fftw_impl.h | 261 + .../Eigen/src/FFT/ei_kissfft_impl.h | 420 + .../IterativeSolvers/ConstrainedConjGrad.h | 189 + .../Eigen/src/IterativeSolvers/DGMRES.h | 511 + .../Eigen/src/IterativeSolvers/GMRES.h | 343 + .../Eigen/src/IterativeSolvers/IncompleteLU.h | 90 + .../IterativeSolvers/IterationController.h | 154 + .../Eigen/src/IterativeSolvers/MINRES.h | 289 + .../Eigen/src/IterativeSolvers/Scaling.h | 187 + .../KroneckerProduct/KroneckerTensorProduct.h | 305 + .../LevenbergMarquardt/CopyrightMINPACK.txt | 52 + .../Eigen/src/LevenbergMarquardt/LMcovar.h | 84 + .../Eigen/src/LevenbergMarquardt/LMonestep.h | 202 + .../Eigen/src/LevenbergMarquardt/LMpar.h | 160 + .../Eigen/src/LevenbergMarquardt/LMqrsolv.h | 188 + .../LevenbergMarquardt/LevenbergMarquardt.h | 396 + .../src/MatrixFunctions/MatrixExponential.h | 441 + .../src/MatrixFunctions/MatrixFunction.h | 580 + .../src/MatrixFunctions/MatrixLogarithm.h | 373 + .../Eigen/src/MatrixFunctions/MatrixPower.h | 709 + .../src/MatrixFunctions/MatrixSquareRoot.h | 370 + .../Eigen/src/MatrixFunctions/StemFunction.h | 117 + .../src/MoreVectorization/MathFunctions.h | 95 + .../HybridNonLinearSolver.h | 601 + .../LevenbergMarquardt.h | 657 + .../Eigen/src/NonLinearOptimization/chkder.h | 66 + .../Eigen/src/NonLinearOptimization/covar.h | 70 + .../Eigen/src/NonLinearOptimization/dogleg.h | 107 + .../Eigen/src/NonLinearOptimization/fdjac1.h | 79 + .../Eigen/src/NonLinearOptimization/lmpar.h | 298 + .../Eigen/src/NonLinearOptimization/qrsolv.h | 91 + .../Eigen/src/NonLinearOptimization/r1mpyq.h | 30 + .../Eigen/src/NonLinearOptimization/r1updt.h | 99 + .../Eigen/src/NonLinearOptimization/rwupdt.h | 49 + .../Eigen/src/NumericalDiff/NumericalDiff.h | 130 + .../Eigen/src/Polynomials/Companion.h | 276 + .../Eigen/src/Polynomials/PolynomialSolver.h | 406 + .../Eigen/src/Polynomials/PolynomialUtils.h | 143 + .../Eigen/src/Skyline/SkylineInplaceLU.h | 352 + .../Eigen/src/Skyline/SkylineMatrix.h | 862 + .../Eigen/src/Skyline/SkylineMatrixBase.h | 212 + .../Eigen/src/Skyline/SkylineProduct.h | 295 + .../Eigen/src/Skyline/SkylineStorage.h | 259 + .../Eigen/src/Skyline/SkylineUtil.h | 89 + .../SparseExtra/BlockOfDynamicSparseMatrix.h | 122 + .../Eigen/src/SparseExtra/BlockSparseMatrix.h | 1079 + .../src/SparseExtra/DynamicSparseMatrix.h | 392 + .../Eigen/src/SparseExtra/MarketIO.h | 275 + .../src/SparseExtra/MatrixMarketIterator.h | 247 + .../Eigen/src/SparseExtra/RandomSetter.h | 327 + .../SpecialFunctionsArrayAPI.h | 124 + .../SpecialFunctionsFunctors.h | 236 + .../SpecialFunctions/SpecialFunctionsHalf.h | 47 + .../SpecialFunctions/SpecialFunctionsImpl.h | 1565 ++ .../SpecialFunctionsPacketMath.h | 58 + .../arch/CUDA/CudaSpecialFunctions.h | 165 + .../unsupported/Eigen/src/Splines/Spline.h | 512 + .../Eigen/src/Splines/SplineFitting.h | 430 + .../unsupported/Eigen/src/Splines/SplineFwd.h | 93 + thirdparty/eigen3/unsupported/README.txt | 50 + .../eigen3/unsupported/bench/bench_svd.cpp | 123 + .../eigen3/unsupported/doc/CMakeLists.txt | 4 + .../eigen3/unsupported/doc/Overview.dox | 28 + .../unsupported/doc/eigendoxy_layout.xml.in | 177 + .../unsupported/doc/examples/BVH_Example.cpp | 50 + .../unsupported/doc/examples/CMakeLists.txt | 20 + .../unsupported/doc/examples/EulerAngles.cpp | 46 + .../eigen3/unsupported/doc/examples/FFT.cpp | 118 + .../doc/examples/MatrixExponential.cpp | 16 + .../doc/examples/MatrixFunction.cpp | 23 + .../doc/examples/MatrixLogarithm.cpp | 15 + .../unsupported/doc/examples/MatrixPower.cpp | 16 + .../doc/examples/MatrixPower_optimal.cpp | 17 + .../unsupported/doc/examples/MatrixSine.cpp | 20 + .../unsupported/doc/examples/MatrixSinh.cpp | 20 + .../doc/examples/MatrixSquareRoot.cpp | 16 + .../doc/examples/PolynomialSolver1.cpp | 53 + .../doc/examples/PolynomialUtils1.cpp | 20 + .../unsupported/doc/snippets/CMakeLists.txt | 26 + thirdparty/eigen3/unsupported/test/BVH.cpp | 222 + .../eigen3/unsupported/test/CMakeLists.txt | 262 + .../eigen3/unsupported/test/EulerAngles.cpp | 208 + thirdparty/eigen3/unsupported/test/FFT.cpp | 2 + thirdparty/eigen3/unsupported/test/FFTW.cpp | 262 + .../test/NonLinearOptimization.cpp | 1878 ++ .../eigen3/unsupported/test/NumericalDiff.cpp | 114 + .../unsupported/test/alignedvector3.cpp | 84 + .../eigen3/unsupported/test/autodiff.cpp | 371 + .../unsupported/test/autodiff_scalar.cpp | 101 + .../unsupported/test/cxx11_eventcount.cpp | 142 + .../eigen3/unsupported/test/cxx11_meta.cpp | 357 + .../test/cxx11_non_blocking_thread_pool.cpp | 107 + .../unsupported/test/cxx11_runqueue.cpp | 235 + .../unsupported/test/cxx11_tensor_argmax.cpp | 294 + .../test/cxx11_tensor_argmax_cuda.cu | 251 + .../unsupported/test/cxx11_tensor_assign.cpp | 370 + .../test/cxx11_tensor_broadcast_sycl.cpp | 74 + .../test/cxx11_tensor_broadcasting.cpp | 194 + .../test/cxx11_tensor_cast_float16_cuda.cu | 79 + .../unsupported/test/cxx11_tensor_casts.cpp | 115 + .../test/cxx11_tensor_chipping.cpp | 425 + .../test/cxx11_tensor_comparisons.cpp | 84 + .../test/cxx11_tensor_complex_cuda.cu | 150 + .../cxx11_tensor_complex_cwise_ops_cuda.cu | 94 + .../test/cxx11_tensor_concatenation.cpp | 137 + .../unsupported/test/cxx11_tensor_const.cpp | 62 + .../test/cxx11_tensor_contract_cuda.cu | 213 + .../test/cxx11_tensor_contraction.cpp | 545 + .../test/cxx11_tensor_convolution.cpp | 149 + .../unsupported/test/cxx11_tensor_cuda.cu | 1284 ++ .../test/cxx11_tensor_custom_index.cpp | 100 + .../test/cxx11_tensor_custom_op.cpp | 111 + .../unsupported/test/cxx11_tensor_device.cu | 387 + .../test/cxx11_tensor_device_sycl.cpp | 31 + .../test/cxx11_tensor_dimension.cpp | 69 + .../unsupported/test/cxx11_tensor_empty.cpp | 40 + .../unsupported/test/cxx11_tensor_expr.cpp | 314 + .../unsupported/test/cxx11_tensor_fft.cpp | 273 + .../test/cxx11_tensor_fixed_size.cpp | 261 + .../test/cxx11_tensor_forced_eval.cpp | 79 + .../test/cxx11_tensor_forced_eval_sycl.cpp | 70 + .../test/cxx11_tensor_generator.cpp | 91 + .../unsupported/test/cxx11_tensor_ifft.cpp | 154 + .../test/cxx11_tensor_image_patch.cpp | 757 + .../test/cxx11_tensor_index_list.cpp | 386 + .../test/cxx11_tensor_inflation.cpp | 81 + .../unsupported/test/cxx11_tensor_intdiv.cpp | 147 + .../unsupported/test/cxx11_tensor_io.cpp | 136 + .../test/cxx11_tensor_layout_swap.cpp | 61 + .../unsupported/test/cxx11_tensor_lvalue.cpp | 42 + .../unsupported/test/cxx11_tensor_map.cpp | 277 + .../unsupported/test/cxx11_tensor_math.cpp | 46 + .../test/cxx11_tensor_mixed_indices.cpp | 53 + .../test/cxx11_tensor_morphing.cpp | 485 + .../test/cxx11_tensor_notification.cpp | 81 + .../test/cxx11_tensor_of_complex.cpp | 103 + .../test/cxx11_tensor_of_const_values.cpp | 105 + .../test/cxx11_tensor_of_float16_cuda.cu | 491 + .../test/cxx11_tensor_of_strings.cpp | 152 + .../unsupported/test/cxx11_tensor_padding.cpp | 93 + .../unsupported/test/cxx11_tensor_patch.cpp | 172 + .../unsupported/test/cxx11_tensor_random.cpp | 78 + .../test/cxx11_tensor_random_cuda.cu | 85 + .../test/cxx11_tensor_reduction.cpp | 508 + .../test/cxx11_tensor_reduction_cuda.cu | 154 + .../test/cxx11_tensor_reduction_sycl.cpp | 138 + .../unsupported/test/cxx11_tensor_ref.cpp | 248 + .../unsupported/test/cxx11_tensor_reverse.cpp | 190 + .../test/cxx11_tensor_roundings.cpp | 62 + .../unsupported/test/cxx11_tensor_scan.cpp | 110 + .../test/cxx11_tensor_scan_cuda.cu | 76 + .../test/cxx11_tensor_shuffling.cpp | 228 + .../unsupported/test/cxx11_tensor_simple.cpp | 327 + .../test/cxx11_tensor_striding.cpp | 119 + .../unsupported/test/cxx11_tensor_sugar.cpp | 81 + .../unsupported/test/cxx11_tensor_sycl.cpp | 159 + .../test/cxx11_tensor_symmetry.cpp | 818 + .../test/cxx11_tensor_thread_pool.cpp | 373 + .../unsupported/test/cxx11_tensor_uint128.cpp | 160 + .../test/cxx11_tensor_volume_patch.cpp | 112 + thirdparty/eigen3/unsupported/test/dgmres.cpp | 31 + .../eigen3/unsupported/test/forward_adolc.cpp | 141 + thirdparty/eigen3/unsupported/test/gmres.cpp | 31 + .../unsupported/test/kronecker_product.cpp | 252 + .../unsupported/test/levenberg_marquardt.cpp | 1477 ++ .../unsupported/test/matrix_exponential.cpp | 141 + .../unsupported/test/matrix_function.cpp | 193 + .../unsupported/test/matrix_functions.h | 67 + .../eigen3/unsupported/test/matrix_power.cpp | 204 + .../unsupported/test/matrix_square_root.cpp | 31 + thirdparty/eigen3/unsupported/test/minres.cpp | 44 + .../eigen3/unsupported/test/mpreal/mpreal.h | 3104 +++ .../unsupported/test/mpreal_support.cpp | 65 + .../eigen3/unsupported/test/openglsupport.cpp | 337 + .../unsupported/test/polynomialsolver.cpp | 218 + .../unsupported/test/polynomialutils.cpp | 113 + .../eigen3/unsupported/test/sparse_extra.cpp | 147 + .../unsupported/test/special_functions.cpp | 345 + .../eigen3/unsupported/test/splines.cpp | 281 + thirdparty/gflags/.gitattributes | 3 + thirdparty/gflags/.gitignore | 25 + thirdparty/gflags/.gitmodules | 4 + thirdparty/gflags/.travis.yml | 20 + thirdparty/gflags/AUTHORS.txt | 2 + thirdparty/gflags/BUILD | 18 + thirdparty/gflags/CMakeLists.txt | 741 + thirdparty/gflags/COPYING.txt | 28 + thirdparty/gflags/ChangeLog.txt | 254 + thirdparty/gflags/INSTALL.md | 83 + thirdparty/gflags/README.md | 305 + thirdparty/gflags/WORKSPACE | 6 + thirdparty/gflags/appveyor.yml | 68 + thirdparty/gflags/bazel/gflags.bzl | 103 + thirdparty/gflags/cmake/README_runtime.txt | 4 + .../gflags/cmake/cmake_uninstall.cmake.in | 26 + thirdparty/gflags/cmake/config.cmake.in | 183 + thirdparty/gflags/cmake/execute_test.cmake | 53 + thirdparty/gflags/cmake/package.cmake.in | 49 + thirdparty/gflags/cmake/package.pc.in | 14 + thirdparty/gflags/cmake/utils.cmake | 205 + thirdparty/gflags/cmake/version.cmake.in | 21 + thirdparty/gflags/src/config.h | 57 + thirdparty/gflags/src/defines.h.in | 48 + thirdparty/gflags/src/gflags.cc | 2013 ++ thirdparty/gflags/src/gflags.h.in | 626 + thirdparty/gflags/src/gflags_completions.cc | 772 + thirdparty/gflags/src/gflags_completions.h.in | 121 + thirdparty/gflags/src/gflags_completions.sh | 117 + thirdparty/gflags/src/gflags_declare.h.in | 152 + thirdparty/gflags/src/gflags_ns.h.in | 102 + thirdparty/gflags/src/gflags_reporting.cc | 442 + thirdparty/gflags/src/mutex.h | 348 + thirdparty/gflags/src/util.h | 373 + thirdparty/gflags/src/windows_port.cc | 73 + thirdparty/gflags/src/windows_port.h | 133 + thirdparty/gflags/test/CMakeLists.txt | 209 + thirdparty/gflags/test/config/CMakeLists.txt | 10 + thirdparty/gflags/test/config/main.cc | 20 + thirdparty/gflags/test/flagfile.1 | 1 + thirdparty/gflags/test/flagfile.2 | 2 + thirdparty/gflags/test/flagfile.3 | 1 + thirdparty/gflags/test/gflags_build.py.in | 43 + .../gflags/test/gflags_declare_flags.cc | 12 + thirdparty/gflags/test/gflags_declare_test.cc | 12 + .../gflags/test/gflags_strip_flags_test.cc | 60 + .../gflags/test/gflags_strip_flags_test.cmake | 7 + thirdparty/gflags/test/gflags_unittest.cc | 1572 ++ .../gflags/test/gflags_unittest_flagfile | 2 + thirdparty/gflags/test/nc/CMakeLists.txt | 16 + thirdparty/gflags/test/nc/gflags_nc.cc | 73 + thirdparty/glog/.bazelci/presubmit.yml | 17 + thirdparty/glog/.gitignore | 12 + thirdparty/glog/AUTHORS | 24 + thirdparty/glog/BUILD | 5 + thirdparty/glog/CMakeLists.txt | 675 + thirdparty/glog/CONTRIBUTING.md | 58 + thirdparty/glog/CONTRIBUTORS | 44 + thirdparty/glog/COPYING | 65 + thirdparty/glog/ChangeLog | 84 + thirdparty/glog/INSTALL | 297 + thirdparty/glog/Makefile.am | 260 + thirdparty/glog/README | 5 + thirdparty/glog/README.windows | 17 + thirdparty/glog/WORKSPACE | 9 + thirdparty/glog/autogen.sh | 6 + thirdparty/glog/bazel/example/BUILD | 8 + thirdparty/glog/bazel/example/main.cc | 22 + thirdparty/glog/bazel/glog.bzl | 138 + thirdparty/glog/cmake/INSTALL.md | 81 + thirdparty/glog/configure.ac | 237 + thirdparty/glog/doc/designstyle.css | 115 + thirdparty/glog/doc/glog.html | 613 + thirdparty/glog/glog-config.cmake.in | 11 + thirdparty/glog/libglog.pc.in | 10 + thirdparty/glog/ltmain.sh | 9661 +++++++++ thirdparty/glog/m4/ac_have_attribute.m4 | 16 + thirdparty/glog/m4/ac_have_builtin_expect.m4 | 14 + .../m4/ac_have_sync_val_compare_and_swap.m4 | 14 + thirdparty/glog/m4/ac_rwlock.m4 | 31 + thirdparty/glog/m4/acx_pthread.m4 | 363 + thirdparty/glog/m4/google_namespace.m4 | 36 + thirdparty/glog/m4/libtool.m4 | 8001 ++++++++ thirdparty/glog/m4/ltoptions.m4 | 384 + thirdparty/glog/m4/ltsugar.m4 | 123 + thirdparty/glog/m4/ltversion.m4 | 23 + thirdparty/glog/m4/lt~obsolete.m4 | 98 + thirdparty/glog/m4/namespaces.m4 | 15 + thirdparty/glog/m4/pc_from_ucontext.m4 | 71 + thirdparty/glog/m4/stl_namespace.m4 | 25 + thirdparty/glog/m4/using_operator.m4 | 15 + thirdparty/glog/packages/deb.sh | 73 + thirdparty/glog/packages/deb/README | 7 + thirdparty/glog/packages/deb/changelog | 65 + thirdparty/glog/packages/deb/compat | 1 + thirdparty/glog/packages/deb/control | 23 + thirdparty/glog/packages/deb/copyright | 35 + thirdparty/glog/packages/deb/docs | 8 + .../glog/packages/deb/libgoogle-glog-dev.dirs | 4 + .../packages/deb/libgoogle-glog-dev.install | 10 + .../glog/packages/deb/libgoogle-glog0.dirs | 1 + .../glog/packages/deb/libgoogle-glog0.install | 2 + thirdparty/glog/packages/deb/rules | 117 + thirdparty/glog/packages/rpm.sh | 75 + thirdparty/glog/packages/rpm/rpm.spec | 72 + thirdparty/glog/src/base/commandlineflags.h | 133 + thirdparty/glog/src/base/googleinit.h | 51 + thirdparty/glog/src/base/mutex.h | 333 + thirdparty/glog/src/config.h.cmake.in | 210 + thirdparty/glog/src/config.h.in | 180 + thirdparty/glog/src/config_for_unittests.h | 66 + thirdparty/glog/src/demangle.cc | 1336 ++ thirdparty/glog/src/demangle.h | 85 + thirdparty/glog/src/demangle_unittest.cc | 168 + thirdparty/glog/src/demangle_unittest.sh | 95 + thirdparty/glog/src/demangle_unittest.txt | 137 + thirdparty/glog/src/glog/log_severity.h | 92 + thirdparty/glog/src/glog/logging.h.in | 1658 ++ thirdparty/glog/src/glog/raw_logging.h.in | 185 + thirdparty/glog/src/glog/stl_logging.h.in | 220 + thirdparty/glog/src/glog/vlog_is_on.h.in | 129 + thirdparty/glog/src/googletest.h | 606 + thirdparty/glog/src/logging.cc | 2161 ++ thirdparty/glog/src/logging_striplog_test.sh | 79 + thirdparty/glog/src/logging_striptest10.cc | 35 + thirdparty/glog/src/logging_striptest2.cc | 35 + thirdparty/glog/src/logging_striptest_main.cc | 73 + thirdparty/glog/src/logging_unittest.cc | 1226 ++ thirdparty/glog/src/logging_unittest.err | 307 + thirdparty/glog/src/mock-log.h | 156 + thirdparty/glog/src/mock-log_test.cc | 106 + thirdparty/glog/src/raw_logging.cc | 172 + thirdparty/glog/src/signalhandler.cc | 403 + thirdparty/glog/src/signalhandler_unittest.cc | 112 + thirdparty/glog/src/signalhandler_unittest.sh | 131 + thirdparty/glog/src/stacktrace.h | 61 + thirdparty/glog/src/stacktrace_generic-inl.h | 59 + .../glog/src/stacktrace_libunwind-inl.h | 87 + thirdparty/glog/src/stacktrace_powerpc-inl.h | 130 + thirdparty/glog/src/stacktrace_unittest.cc | 208 + thirdparty/glog/src/stacktrace_windows-inl.h | 50 + thirdparty/glog/src/stacktrace_x86-inl.h | 146 + thirdparty/glog/src/stacktrace_x86_64-inl.h | 105 + thirdparty/glog/src/stl_logging_unittest.cc | 197 + thirdparty/glog/src/symbolize.cc | 947 + thirdparty/glog/src/symbolize.h | 155 + thirdparty/glog/src/symbolize_unittest.cc | 425 + thirdparty/glog/src/utilities.cc | 384 + thirdparty/glog/src/utilities.h | 240 + thirdparty/glog/src/utilities_unittest.cc | 58 + thirdparty/glog/src/vlog_is_on.cc | 257 + .../glog/src/windows/glog/log_severity.h | 96 + thirdparty/glog/src/windows/glog/logging.h | 1666 ++ .../glog/src/windows/glog/raw_logging.h | 189 + .../glog/src/windows/glog/stl_logging.h | 224 + thirdparty/glog/src/windows/glog/vlog_is_on.h | 133 + thirdparty/glog/src/windows/port.cc | 65 + thirdparty/glog/src/windows/port.h | 174 + thirdparty/glog/src/windows/preprocess.sh | 119 + thirdparty/googletest/.clang-format | 4 + thirdparty/googletest/.gitignore | 56 + thirdparty/googletest/.travis.yml | 71 + thirdparty/googletest/BUILD.bazel | 180 + thirdparty/googletest/CMakeLists.txt | 24 + thirdparty/googletest/CONTRIBUTING.md | 161 + thirdparty/googletest/LICENSE | 28 + thirdparty/googletest/Makefile.am | 14 + thirdparty/googletest/README.md | 128 + thirdparty/googletest/WORKSPACE | 8 + thirdparty/googletest/appveyor.yml | 103 + .../googletest/ci/build-linux-autotools.sh | 44 + thirdparty/googletest/ci/build-linux-bazel.sh | 36 + thirdparty/googletest/ci/env-linux.sh | 41 + thirdparty/googletest/ci/env-osx.sh | 41 + thirdparty/googletest/ci/get-nprocessors.sh | 48 + thirdparty/googletest/ci/install-linux.sh | 49 + thirdparty/googletest/ci/install-osx.sh | 39 + thirdparty/googletest/ci/log-config.sh | 51 + thirdparty/googletest/ci/travis.sh | 44 + thirdparty/googletest/configure.ac | 16 + .../googletest/googlemock/CMakeLists.txt | 225 + thirdparty/googletest/googlemock/CONTRIBUTORS | 40 + thirdparty/googletest/googlemock/LICENSE | 28 + thirdparty/googletest/googlemock/Makefile.am | 224 + thirdparty/googletest/googlemock/README.md | 293 + .../googletest/googlemock/cmake/gmock.pc.in | 10 + .../googlemock/cmake/gmock_main.pc.in | 10 + thirdparty/googletest/googlemock/configure.ac | 146 + .../googletest/googlemock/docs/CheatSheet.md | 588 + .../googletest/googlemock/docs/CookBook.md | 3660 ++++ .../googletest/googlemock/docs/DesignDoc.md | 282 + .../googlemock/docs/Documentation.md | 15 + .../googletest/googlemock/docs/ForDummies.md | 447 + .../docs/FrequentlyAskedQuestions.md | 627 + .../googletest/googlemock/docs/KnownIssues.md | 19 + .../googlemock/include/gmock/gmock-actions.h | 1262 ++ .../include/gmock/gmock-cardinalities.h | 153 + .../include/gmock/gmock-generated-actions.h | 2579 +++ .../gmock/gmock-generated-actions.h.pump | 833 + .../gmock/gmock-generated-function-mockers.h | 1333 ++ .../gmock-generated-function-mockers.h.pump | 348 + .../include/gmock/gmock-generated-matchers.h | 1486 ++ .../gmock/gmock-generated-matchers.h.pump | 511 + .../gmock/gmock-generated-nice-strict.h | 459 + .../gmock/gmock-generated-nice-strict.h.pump | 179 + .../googlemock/include/gmock/gmock-matchers.h | 5207 +++++ .../include/gmock/gmock-more-actions.h | 247 + .../include/gmock/gmock-more-matchers.h | 92 + .../include/gmock/gmock-spec-builders.h | 1919 ++ .../googlemock/include/gmock/gmock.h | 96 + .../include/gmock/internal/custom/README.md | 16 + .../internal/custom/gmock-generated-actions.h | 10 + .../custom/gmock-generated-actions.h.pump | 12 + .../gmock/internal/custom/gmock-matchers.h | 36 + .../gmock/internal/custom/gmock-port.h | 39 + .../internal/gmock-generated-internal-utils.h | 278 + .../gmock-generated-internal-utils.h.pump | 137 + .../gmock/internal/gmock-internal-utils.h | 576 + .../include/gmock/internal/gmock-port.h | 88 + .../googletest/googlemock/msvc/2005/gmock.sln | 32 + .../googlemock/msvc/2005/gmock.vcproj | 191 + .../googlemock/msvc/2005/gmock_config.vsprops | 15 + .../googlemock/msvc/2005/gmock_main.vcproj | 187 + .../googlemock/msvc/2005/gmock_test.vcproj | 201 + .../googletest/googlemock/msvc/2010/gmock.sln | 46 + .../googlemock/msvc/2010/gmock.vcxproj | 145 + .../googlemock/msvc/2010/gmock_config.props | 19 + .../googlemock/msvc/2010/gmock_main.vcxproj | 151 + .../googlemock/msvc/2010/gmock_test.vcxproj | 176 + .../googletest/googlemock/msvc/2015/gmock.sln | 46 + .../googlemock/msvc/2015/gmock.vcxproj | 145 + .../googlemock/msvc/2015/gmock_config.props | 19 + .../googlemock/msvc/2015/gmock_main.vcxproj | 151 + .../googlemock/msvc/2015/gmock_test.vcxproj | 176 + .../googlemock/scripts/fuse_gmock_files.py | 240 + .../googlemock/scripts/generator/LICENSE | 203 + .../googlemock/scripts/generator/README | 34 + .../scripts/generator/README.cppclean | 115 + .../scripts/generator/cpp/__init__.py | 0 .../googlemock/scripts/generator/cpp/ast.py | 1736 ++ .../scripts/generator/cpp/gmock_class.py | 227 + .../scripts/generator/cpp/gmock_class_test.py | 466 + .../scripts/generator/cpp/keywords.py | 59 + .../scripts/generator/cpp/tokenize.py | 287 + .../googlemock/scripts/generator/cpp/utils.py | 41 + .../googlemock/scripts/generator/gmock_gen.py | 31 + .../googlemock/scripts/gmock-config.in | 303 + .../googlemock/scripts/gmock_doctor.py | 640 + .../googletest/googlemock/scripts/upload.py | 1387 ++ .../googlemock/scripts/upload_gmock.py | 78 + .../googletest/googlemock/src/gmock-all.cc | 46 + .../googlemock/src/gmock-cardinalities.cc | 155 + .../googlemock/src/gmock-internal-utils.cc | 203 + .../googlemock/src/gmock-matchers.cc | 572 + .../googlemock/src/gmock-spec-builders.cc | 879 + thirdparty/googletest/googlemock/src/gmock.cc | 204 + .../googletest/googlemock/src/gmock_main.cc | 54 + .../googletest/googlemock/test/BUILD.bazel | 123 + .../googlemock/test/gmock-actions_test.cc | 1372 ++ .../test/gmock-cardinalities_test.cc | 427 + .../test/gmock-generated-actions_test.cc | 1228 ++ .../gmock-generated-function-mockers_test.cc | 657 + .../gmock-generated-internal-utils_test.cc | 130 + .../test/gmock-generated-matchers_test.cc | 1339 ++ .../test/gmock-internal-utils_test.cc | 718 + .../googlemock/test/gmock-matchers_test.cc | 6790 +++++++ .../test/gmock-more-actions_test.cc | 708 + .../googlemock/test/gmock-nice-strict_test.cc | 510 + .../googlemock/test/gmock-port_test.cc | 42 + .../test/gmock-spec-builders_test.cc | 2770 +++ .../googlemock/test/gmock_all_test.cc | 50 + .../googlemock/test/gmock_ex_test.cc | 80 + .../googlemock/test/gmock_leak_test.py | 104 + .../googlemock/test/gmock_leak_test_.cc | 99 + .../googlemock/test/gmock_link2_test.cc | 39 + .../googlemock/test/gmock_link_test.cc | 39 + .../googlemock/test/gmock_link_test.h | 690 + .../googlemock/test/gmock_output_test.py | 181 + .../googlemock/test/gmock_output_test_.cc | 309 + .../test/gmock_output_test_golden.txt | 317 + .../googlemock/test/gmock_stress_test.cc | 321 + .../googletest/googlemock/test/gmock_test.cc | 181 + .../googlemock/test/gmock_test_utils.py | 108 + .../googletest/googletest/CMakeLists.txt | 319 + thirdparty/googletest/googletest/CONTRIBUTORS | 37 + thirdparty/googletest/googletest/LICENSE | 28 + thirdparty/googletest/googletest/Makefile.am | 336 + thirdparty/googletest/googletest/README.md | 318 + .../googletest/cmake/Config.cmake.in | 9 + .../googletest/googletest/cmake/gtest.pc.in | 9 + .../googletest/cmake/gtest_main.pc.in | 10 + .../googletest/cmake/internal_utils.cmake | 369 + .../googletest/codegear/gtest.cbproj | 138 + .../googletest/codegear/gtest.groupproj | 54 + .../googletest/codegear/gtest_all.cc | 38 + .../googletest/codegear/gtest_link.cc | 40 + .../googletest/codegear/gtest_main.cbproj | 82 + .../googletest/codegear/gtest_unittest.cbproj | 88 + thirdparty/googletest/googletest/configure.ac | 68 + .../googletest/googletest/docs/Pkgconfig.md | 146 + .../googletest/googletest/docs/PumpManual.md | 177 + .../googletest/googletest/docs/XcodeGuide.md | 93 + .../googletest/googletest/docs/advanced.md | 2520 +++ thirdparty/googletest/googletest/docs/faq.md | 770 + .../googletest/googletest/docs/primer.md | 566 + .../googletest/googletest/docs/samples.md | 22 + .../include/gtest/gtest-death-test.h | 344 + .../googletest/include/gtest/gtest-message.h | 255 + .../include/gtest/gtest-param-test.h | 1430 ++ .../include/gtest/gtest-param-test.h.pump | 496 + .../googletest/include/gtest/gtest-printers.h | 953 + .../googletest/include/gtest/gtest-spi.h | 237 + .../include/gtest/gtest-test-part.h | 184 + .../include/gtest/gtest-typed-test.h | 306 + .../googletest/include/gtest/gtest.h | 2366 +++ .../include/gtest/gtest_pred_impl.h | 359 + .../googletest/include/gtest/gtest_prod.h | 61 + .../include/gtest/internal/custom/README.md | 56 + .../gtest/internal/custom/gtest-port.h | 37 + .../gtest/internal/custom/gtest-printers.h | 42 + .../include/gtest/internal/custom/gtest.h | 37 + .../internal/gtest-death-test-internal.h | 280 + .../include/gtest/internal/gtest-filepath.h | 211 + .../include/gtest/internal/gtest-internal.h | 1320 ++ .../include/gtest/internal/gtest-linked_ptr.h | 243 + .../internal/gtest-param-util-generated.h | 5546 ++++++ .../gtest-param-util-generated.h.pump | 279 + .../include/gtest/internal/gtest-param-util.h | 720 + .../include/gtest/internal/gtest-port-arch.h | 103 + .../include/gtest/internal/gtest-port.h | 2528 +++ .../include/gtest/internal/gtest-string.h | 167 + .../include/gtest/internal/gtest-type-util.h | 3348 ++++ .../gtest/internal/gtest-type-util.h.pump | 314 + .../googletest/googletest/m4/acx_pthread.m4 | 363 + thirdparty/googletest/googletest/m4/gtest.m4 | 74 + .../googletest/msvc/2010/gtest-md.sln | 55 + .../googletest/msvc/2010/gtest-md.vcxproj | 149 + .../msvc/2010/gtest-md.vcxproj.filters | 18 + .../googletest/googletest/msvc/2010/gtest.sln | 55 + .../googletest/msvc/2010/gtest.vcxproj | 149 + .../msvc/2010/gtest.vcxproj.filters | 18 + .../msvc/2010/gtest_main-md.vcxproj | 154 + .../msvc/2010/gtest_main-md.vcxproj.filters | 18 + .../googletest/msvc/2010/gtest_main.vcxproj | 162 + .../msvc/2010/gtest_main.vcxproj.filters | 18 + .../msvc/2010/gtest_prod_test-md.vcxproj | 199 + .../2010/gtest_prod_test-md.vcxproj.filters | 26 + .../msvc/2010/gtest_prod_test.vcxproj | 191 + .../msvc/2010/gtest_prod_test.vcxproj.filters | 26 + .../msvc/2010/gtest_unittest-md.vcxproj | 188 + .../2010/gtest_unittest-md.vcxproj.filters | 18 + .../msvc/2010/gtest_unittest.vcxproj | 180 + .../msvc/2010/gtest_unittest.vcxproj.filters | 18 + .../googletest/samples/prime_tables.h | 126 + .../googletest/googletest/samples/sample1.cc | 66 + .../googletest/googletest/samples/sample1.h | 41 + .../googletest/samples/sample10_unittest.cc | 139 + .../googletest/samples/sample1_unittest.cc | 151 + .../googletest/googletest/samples/sample2.cc | 54 + .../googletest/googletest/samples/sample2.h | 81 + .../googletest/samples/sample2_unittest.cc | 107 + .../googletest/samples/sample3-inl.h | 172 + .../googletest/samples/sample3_unittest.cc | 149 + .../googletest/googletest/samples/sample4.cc | 54 + .../googletest/googletest/samples/sample4.h | 53 + .../googletest/samples/sample4_unittest.cc | 53 + .../googletest/samples/sample5_unittest.cc | 196 + .../googletest/samples/sample6_unittest.cc | 224 + .../googletest/samples/sample7_unittest.cc | 117 + .../googletest/samples/sample8_unittest.cc | 155 + .../googletest/samples/sample9_unittest.cc | 156 + .../googletest/googletest/scripts/common.py | 83 + .../googletest/scripts/fuse_gtest_files.py | 253 + .../googletest/scripts/gen_gtest_pred_impl.py | 730 + .../googletest/scripts/gtest-config.in | 274 + .../googletest/googletest/scripts/pump.py | 855 + .../googletest/scripts/release_docs.py | 158 + .../googletest/googletest/scripts/upload.py | 1387 ++ .../googletest/scripts/upload_gtest.py | 78 + .../googletest/googletest/src/gtest-all.cc | 47 + .../googletest/src/gtest-death-test.cc | 1573 ++ .../googletest/src/gtest-filepath.cc | 385 + .../googletest/src/gtest-internal-inl.h | 1189 ++ .../googletest/googletest/src/gtest-port.cc | 1322 ++ .../googletest/src/gtest-printers.cc | 457 + .../googletest/src/gtest-test-part.cc | 104 + .../googletest/src/gtest-typed-test.cc | 118 + thirdparty/googletest/googletest/src/gtest.cc | 6061 ++++++ .../googletest/googletest/src/gtest_main.cc | 37 + .../googletest/googletest/test/BUILD.bazel | 524 + .../googletest-break-on-failure-unittest.py | 208 + .../googletest-break-on-failure-unittest_.cc | 86 + .../test/googletest-catch-exceptions-test.py | 233 + .../test/googletest-catch-exceptions-test_.cc | 292 + .../googletest/test/googletest-color-test.py | 127 + .../googletest/test/googletest-color-test_.cc | 62 + .../test/googletest-death-test-test.cc | 1422 ++ .../test/googletest-death-test_ex_test.cc | 92 + .../test/googletest-env-var-test.py | 117 + .../test/googletest-env-var-test_.cc | 122 + .../test/googletest-filepath-test.cc | 651 + .../test/googletest-filter-unittest.py | 636 + .../test/googletest-filter-unittest_.cc | 137 + .../test/googletest-json-outfiles-test.py | 162 + .../test/googletest-json-output-unittest.py | 618 + .../test/googletest-linked-ptr-test.cc | 151 + .../test/googletest-list-tests-unittest.py | 205 + .../test/googletest-list-tests-unittest_.cc | 156 + .../test/googletest-listener-test.cc | 311 + .../test/googletest-message-test.cc | 158 + .../test/googletest-options-test.cc | 217 + .../googletest-output-test-golden-lin.txt | 1047 + .../googletest/test/googletest-output-test.py | 347 + .../test/googletest-output-test_.cc | 1108 ++ ...oogletest-param-test-invalid-name1-test.py | 63 + ...ogletest-param-test-invalid-name1-test_.cc | 50 + ...oogletest-param-test-invalid-name2-test.py | 62 + ...ogletest-param-test-invalid-name2-test_.cc | 55 + .../test/googletest-param-test-test.cc | 1050 + .../test/googletest-param-test-test.h | 51 + .../test/googletest-param-test2-test.cc | 61 + .../googletest/test/googletest-port-test.cc | 1300 ++ .../test/googletest-printers-test.cc | 1637 ++ .../test/googletest-shuffle-test.py | 323 + .../test/googletest-shuffle-test_.cc | 102 + .../test/googletest-test-part-test.cc | 232 + .../googletest/test/googletest-test2_test.cc | 61 + .../test/googletest-throw-on-failure-test.py | 169 + .../test/googletest-throw-on-failure-test_.cc | 71 + .../test/googletest-uninitialized-test.py | 67 + .../test/googletest-uninitialized-test_.cc | 42 + .../googletest/test/gtest-typed-test2_test.cc | 44 + .../googletest/test/gtest-typed-test_test.cc | 461 + .../googletest/test/gtest-typed-test_test.h | 65 + .../test/gtest-unittest-api_test.cc | 340 + .../googletest/test/gtest_all_test.cc | 47 + .../test/gtest_assert_by_exception_test.cc | 117 + .../googletest/test/gtest_environment_test.cc | 188 + .../googletest/test/gtest_help_test.py | 170 + .../googletest/test/gtest_help_test_.cc | 45 + .../googletest/test/gtest_json_test_utils.py | 60 + .../test/gtest_list_output_unittest.py | 141 + .../test/gtest_list_output_unittest_.cc | 51 + .../googletest/test/gtest_main_unittest.cc | 44 + .../googletest/test/gtest_no_test_unittest.cc | 54 + .../test/gtest_pred_impl_unittest.cc | 2427 +++ .../test/gtest_premature_exit_test.cc | 126 + .../googletest/test/gtest_prod_test.cc | 56 + .../googletest/test/gtest_repeat_test.cc | 234 + .../googletest/test/gtest_skip_test.cc | 38 + .../googletest/test/gtest_sole_header_test.cc | 56 + .../googletest/test/gtest_stress_test.cc | 249 + .../gtest_test_macro_stack_footprint_test.cc | 89 + .../googletest/test/gtest_test_utils.py | 315 + .../googletest/test/gtest_testbridge_test.py | 63 + .../googletest/test/gtest_testbridge_test_.cc | 43 + .../test/gtest_throw_on_failure_ex_test.cc | 90 + .../googletest/test/gtest_unittest.cc | 7499 +++++++ .../test/gtest_xml_outfile1_test_.cc | 47 + .../test/gtest_xml_outfile2_test_.cc | 47 + .../test/gtest_xml_outfiles_test.py | 140 + .../test/gtest_xml_output_unittest.py | 383 + .../test/gtest_xml_output_unittest_.cc | 179 + .../googletest/test/gtest_xml_test_utils.py | 196 + .../googletest/googletest/test/production.cc | 35 + .../googletest/googletest/test/production.h | 54 + .../xcode/Config/DebugProject.xcconfig | 30 + .../xcode/Config/FrameworkTarget.xcconfig | 17 + .../googletest/xcode/Config/General.xcconfig | 41 + .../xcode/Config/ReleaseProject.xcconfig | 32 + .../xcode/Config/StaticLibraryTarget.xcconfig | 18 + .../xcode/Config/TestTarget.xcconfig | 8 + .../googletest/xcode/Resources/Info.plist | 30 + .../xcode/Samples/FrameworkSample/Info.plist | 28 + .../WidgetFramework.xcodeproj/project.pbxproj | 457 + .../xcode/Samples/FrameworkSample/runtests.sh | 62 + .../xcode/Samples/FrameworkSample/widget.cc | 63 + .../xcode/Samples/FrameworkSample/widget.h | 59 + .../Samples/FrameworkSample/widget_test.cc | 68 + .../googletest/xcode/Scripts/runtests.sh | 65 + .../xcode/Scripts/versiongenerate.py | 100 + .../xcode/gtest.xcodeproj/project.pbxproj | 1182 ++ thirdparty/gperftools/.gitignore | 146 + thirdparty/gperftools/.travis.yml | 4 + thirdparty/gperftools/AUTHORS | 2 + thirdparty/gperftools/COPYING | 28 + thirdparty/gperftools/ChangeLog | 2 + thirdparty/gperftools/ChangeLog.old | 646 + thirdparty/gperftools/INSTALL | 563 + thirdparty/gperftools/Makefile.am | 1503 ++ thirdparty/gperftools/NEWS | 1003 + thirdparty/gperftools/README | 284 + thirdparty/gperftools/README_windows.txt | 120 + thirdparty/gperftools/TODO | 47 + thirdparty/gperftools/autogen.sh | 3 + .../gperftools/benchmark/binary_trees.cc | 108 + .../gperftools/benchmark/malloc_bench.cc | 293 + .../gperftools/benchmark/run_benchmark.c | 112 + .../gperftools/benchmark/run_benchmark.h | 43 + thirdparty/gperftools/configure.ac | 671 + .../docs/cpuprofile-fileformat.html | 264 + thirdparty/gperftools/docs/cpuprofile.html | 536 + thirdparty/gperftools/docs/designstyle.css | 109 + thirdparty/gperftools/docs/heap-example1.png | Bin 0 -> 37619 bytes thirdparty/gperftools/docs/heap_checker.html | 534 + thirdparty/gperftools/docs/heapprofile.html | 391 + thirdparty/gperftools/docs/index.html | 20 + thirdparty/gperftools/docs/overview.dot | 15 + thirdparty/gperftools/docs/overview.gif | Bin 0 -> 6472 bytes thirdparty/gperftools/docs/pageheap.dot | 25 + thirdparty/gperftools/docs/pageheap.gif | Bin 0 -> 5942 bytes thirdparty/gperftools/docs/pprof-test-big.gif | Bin 0 -> 111566 bytes thirdparty/gperftools/docs/pprof-test.gif | Bin 0 -> 56995 bytes .../gperftools/docs/pprof-vsnprintf-big.gif | Bin 0 -> 100721 bytes .../gperftools/docs/pprof-vsnprintf.gif | Bin 0 -> 31054 bytes thirdparty/gperftools/docs/pprof.1 | 131 + thirdparty/gperftools/docs/pprof.see_also | 11 + .../gperftools/docs/pprof_remote_servers.html | 260 + thirdparty/gperftools/docs/spanmap.dot | 22 + thirdparty/gperftools/docs/spanmap.gif | Bin 0 -> 8482 bytes thirdparty/gperftools/docs/t-test1.times.txt | 480 + ...loc-opspercpusec.vs.threads.1024.bytes.png | Bin 0 -> 1882 bytes ...lloc-opspercpusec.vs.threads.128.bytes.png | Bin 0 -> 1731 bytes ...c-opspercpusec.vs.threads.131072.bytes.png | Bin 0 -> 1314 bytes ...oc-opspercpusec.vs.threads.16384.bytes.png | Bin 0 -> 1815 bytes ...loc-opspercpusec.vs.threads.2048.bytes.png | Bin 0 -> 1877 bytes ...lloc-opspercpusec.vs.threads.256.bytes.png | Bin 0 -> 1838 bytes ...oc-opspercpusec.vs.threads.32768.bytes.png | Bin 0 -> 1516 bytes ...loc-opspercpusec.vs.threads.4096.bytes.png | Bin 0 -> 2005 bytes ...lloc-opspercpusec.vs.threads.512.bytes.png | Bin 0 -> 1683 bytes ...alloc-opspercpusec.vs.threads.64.bytes.png | Bin 0 -> 1656 bytes ...oc-opspercpusec.vs.threads.65536.bytes.png | Bin 0 -> 1498 bytes ...loc-opspercpusec.vs.threads.8192.bytes.png | Bin 0 -> 1912 bytes .../tcmalloc-opspersec.vs.size.1.threads.png | Bin 0 -> 1689 bytes .../tcmalloc-opspersec.vs.size.12.threads.png | Bin 0 -> 2216 bytes .../tcmalloc-opspersec.vs.size.16.threads.png | Bin 0 -> 2010 bytes .../tcmalloc-opspersec.vs.size.2.threads.png | Bin 0 -> 2163 bytes .../tcmalloc-opspersec.vs.size.20.threads.png | Bin 0 -> 2147 bytes .../tcmalloc-opspersec.vs.size.3.threads.png | Bin 0 -> 2270 bytes .../tcmalloc-opspersec.vs.size.4.threads.png | Bin 0 -> 2174 bytes .../tcmalloc-opspersec.vs.size.5.threads.png | Bin 0 -> 1995 bytes .../tcmalloc-opspersec.vs.size.8.threads.png | Bin 0 -> 2156 bytes thirdparty/gperftools/docs/tcmalloc.html | 778 + thirdparty/gperftools/docs/threadheap.dot | 21 + thirdparty/gperftools/docs/threadheap.gif | Bin 0 -> 7571 bytes thirdparty/gperftools/gperftools.sln | 307 + thirdparty/gperftools/m4/ac_have_attribute.m4 | 16 + thirdparty/gperftools/m4/acx_nanosleep.m4 | 35 + thirdparty/gperftools/m4/acx_pthread.m4 | 397 + .../gperftools/m4/ax_cxx_compile_stdcxx.m4 | 948 + .../gperftools/m4/ax_generate_changelog.m4 | 99 + .../gperftools/m4/compiler_characteristics.m4 | 24 + thirdparty/gperftools/m4/install_prefix.m4 | 8 + thirdparty/gperftools/m4/namespaces.m4 | 15 + thirdparty/gperftools/m4/pc_from_ucontext.m4 | 109 + .../gperftools/m4/program_invocation_name.m4 | 19 + thirdparty/gperftools/m4/stl_namespace.m4 | 25 + thirdparty/gperftools/packages/deb.sh | 74 + thirdparty/gperftools/packages/deb/README | 7 + thirdparty/gperftools/packages/deb/changelog | 208 + thirdparty/gperftools/packages/deb/compat | 1 + thirdparty/gperftools/packages/deb/control | 25 + thirdparty/gperftools/packages/deb/copyright | 38 + thirdparty/gperftools/packages/deb/docs | 47 + .../packages/deb/libgperftools-dev.dirs | 5 + .../packages/deb/libgperftools-dev.install | 12 + .../packages/deb/libgperftools0.dirs | 2 + .../packages/deb/libgperftools0.install | 4 + .../packages/deb/libgperftools0.manpages | 1 + thirdparty/gperftools/packages/deb/rules | 117 + thirdparty/gperftools/packages/rpm.sh | 86 + thirdparty/gperftools/packages/rpm/rpm.spec | 77 + thirdparty/gperftools/src/addressmap-inl.h | 422 + .../src/base/arm_instruction_set_select.h | 84 + .../base/atomicops-internals-arm-generic.h | 228 + .../src/base/atomicops-internals-arm-v6plus.h | 330 + .../src/base/atomicops-internals-gcc.h | 203 + .../src/base/atomicops-internals-linuxppc.h | 437 + .../src/base/atomicops-internals-macosx.h | 370 + .../src/base/atomicops-internals-mips.h | 323 + .../src/base/atomicops-internals-windows.h | 457 + .../src/base/atomicops-internals-x86.cc | 112 + .../src/base/atomicops-internals-x86.h | 391 + thirdparty/gperftools/src/base/atomicops.h | 399 + thirdparty/gperftools/src/base/basictypes.h | 436 + .../gperftools/src/base/commandlineflags.h | 175 + .../gperftools/src/base/dynamic_annotations.c | 179 + .../gperftools/src/base/dynamic_annotations.h | 627 + .../gperftools/src/base/elf_mem_image.cc | 434 + .../gperftools/src/base/elf_mem_image.h | 135 + thirdparty/gperftools/src/base/elfcore.h | 401 + thirdparty/gperftools/src/base/googleinit.h | 74 + .../src/base/linux_syscall_support.h | 2913 +++ .../gperftools/src/base/linuxthreads.cc | 707 + thirdparty/gperftools/src/base/linuxthreads.h | 54 + thirdparty/gperftools/src/base/logging.cc | 108 + thirdparty/gperftools/src/base/logging.h | 259 + .../gperftools/src/base/low_level_alloc.cc | 582 + .../gperftools/src/base/low_level_alloc.h | 120 + thirdparty/gperftools/src/base/simple_mutex.h | 332 + thirdparty/gperftools/src/base/spinlock.cc | 129 + thirdparty/gperftools/src/base/spinlock.h | 143 + .../gperftools/src/base/spinlock_internal.cc | 102 + .../gperftools/src/base/spinlock_internal.h | 51 + .../gperftools/src/base/spinlock_linux-inl.h | 102 + .../gperftools/src/base/spinlock_posix-inl.h | 63 + .../gperftools/src/base/spinlock_win32-inl.h | 54 + .../gperftools/src/base/stl_allocator.h | 98 + thirdparty/gperftools/src/base/sysinfo.cc | 891 + thirdparty/gperftools/src/base/sysinfo.h | 232 + .../gperftools/src/base/thread_annotations.h | 134 + .../gperftools/src/base/thread_lister.c | 83 + .../gperftools/src/base/thread_lister.h | 83 + .../gperftools/src/base/vdso_support.cc | 142 + thirdparty/gperftools/src/base/vdso_support.h | 136 + thirdparty/gperftools/src/central_freelist.cc | 387 + thirdparty/gperftools/src/central_freelist.h | 211 + thirdparty/gperftools/src/common.cc | 291 + thirdparty/gperftools/src/common.h | 311 + .../gperftools/src/config_for_unittests.h | 65 + thirdparty/gperftools/src/debugallocation.cc | 1583 ++ thirdparty/gperftools/src/emergency_malloc.cc | 169 + thirdparty/gperftools/src/emergency_malloc.h | 60 + .../src/emergency_malloc_for_stacktrace.cc | 48 + .../gperftools/src/fake_stacktrace_scope.cc | 39 + thirdparty/gperftools/src/getenv_safe.h | 63 + thirdparty/gperftools/src/getpc.h | 195 + .../gperftools/src/google/heap-checker.h | 36 + .../gperftools/src/google/heap-profiler.h | 37 + .../gperftools/src/google/malloc_extension.h | 36 + .../src/google/malloc_extension_c.h | 37 + .../gperftools/src/google/malloc_hook.h | 36 + .../gperftools/src/google/malloc_hook_c.h | 37 + thirdparty/gperftools/src/google/profiler.h | 37 + thirdparty/gperftools/src/google/stacktrace.h | 36 + thirdparty/gperftools/src/google/tcmalloc.h | 37 + .../gperftools/src/gperftools/heap-checker.h | 422 + .../gperftools/src/gperftools/heap-profiler.h | 105 + .../src/gperftools/malloc_extension.h | 446 + .../src/gperftools/malloc_extension_c.h | 101 + .../gperftools/src/gperftools/malloc_hook.h | 359 + .../gperftools/src/gperftools/malloc_hook_c.h | 173 + .../gperftools/src/gperftools/nallocx.h | 37 + .../gperftools/src/gperftools/profiler.h | 169 + .../gperftools/src/gperftools/stacktrace.h | 117 + .../gperftools/src/gperftools/tcmalloc.h.in | 163 + .../gperftools/src/heap-checker-bcad.cc | 93 + thirdparty/gperftools/src/heap-checker.cc | 2388 +++ .../gperftools/src/heap-profile-stats.h | 78 + .../gperftools/src/heap-profile-table.cc | 629 + .../gperftools/src/heap-profile-table.h | 399 + thirdparty/gperftools/src/heap-profiler.cc | 622 + thirdparty/gperftools/src/internal_logging.cc | 192 + thirdparty/gperftools/src/internal_logging.h | 144 + thirdparty/gperftools/src/libc_override.h | 99 + .../src/libc_override_gcc_and_weak.h | 244 + .../gperftools/src/libc_override_glibc.h | 92 + thirdparty/gperftools/src/libc_override_osx.h | 308 + .../gperftools/src/libc_override_redefine.h | 131 + thirdparty/gperftools/src/linked_list.h | 115 + thirdparty/gperftools/src/malloc_extension.cc | 388 + thirdparty/gperftools/src/malloc_hook-inl.h | 249 + thirdparty/gperftools/src/malloc_hook.cc | 711 + .../gperftools/src/malloc_hook_mmap_freebsd.h | 135 + .../gperftools/src/malloc_hook_mmap_linux.h | 244 + .../gperftools/src/maybe_emergency_malloc.h | 55 + thirdparty/gperftools/src/maybe_threads.cc | 177 + thirdparty/gperftools/src/maybe_threads.h | 61 + thirdparty/gperftools/src/memfs_malloc.cc | 272 + .../gperftools/src/memory_region_map.cc | 838 + thirdparty/gperftools/src/memory_region_map.h | 416 + thirdparty/gperftools/src/packed-cache-inl.h | 216 + thirdparty/gperftools/src/page_heap.cc | 726 + thirdparty/gperftools/src/page_heap.h | 358 + .../gperftools/src/page_heap_allocator.h | 179 + thirdparty/gperftools/src/pagemap.h | 328 + thirdparty/gperftools/src/pprof | 5580 ++++++ thirdparty/gperftools/src/profile-handler.cc | 584 + thirdparty/gperftools/src/profile-handler.h | 142 + thirdparty/gperftools/src/profiledata.cc | 332 + thirdparty/gperftools/src/profiledata.h | 184 + thirdparty/gperftools/src/profiler.cc | 428 + thirdparty/gperftools/src/raw_printer.cc | 72 + thirdparty/gperftools/src/raw_printer.h | 90 + thirdparty/gperftools/src/sampler.cc | 133 + thirdparty/gperftools/src/sampler.h | 232 + thirdparty/gperftools/src/span.cc | 102 + thirdparty/gperftools/src/span.h | 175 + .../gperftools/src/stack_trace_table.cc | 123 + thirdparty/gperftools/src/stack_trace_table.h | 85 + thirdparty/gperftools/src/stacktrace.cc | 340 + .../gperftools/src/stacktrace_arm-inl.h | 148 + .../gperftools/src/stacktrace_generic-inl.h | 84 + .../src/stacktrace_impl_setup-inl.h | 94 + .../src/stacktrace_instrument-inl.h | 155 + .../gperftools/src/stacktrace_libgcc-inl.h | 111 + .../gperftools/src/stacktrace_libunwind-inl.h | 152 + .../src/stacktrace_powerpc-darwin-inl.h | 162 + .../gperftools/src/stacktrace_powerpc-inl.h | 176 + .../src/stacktrace_powerpc-linux-inl.h | 231 + .../gperftools/src/stacktrace_win32-inl.h | 107 + .../gperftools/src/stacktrace_x86-inl.h | 354 + thirdparty/gperftools/src/static_vars.cc | 152 + thirdparty/gperftools/src/static_vars.h | 126 + thirdparty/gperftools/src/symbolize.cc | 298 + thirdparty/gperftools/src/symbolize.h | 84 + thirdparty/gperftools/src/system-alloc.cc | 555 + thirdparty/gperftools/src/system-alloc.h | 92 + thirdparty/gperftools/src/tcmalloc.cc | 2194 +++ thirdparty/gperftools/src/tcmalloc.h | 70 + thirdparty/gperftools/src/tcmalloc_guard.h | 49 + .../src/tests/addressmap_unittest.cc | 171 + .../src/tests/atomicops_unittest.cc | 162 + .../src/tests/current_allocated_bytes_test.cc | 64 + .../src/tests/debugallocation_test.cc | 332 + .../src/tests/debugallocation_test.sh | 98 + .../gperftools/src/tests/frag_unittest.cc | 133 + thirdparty/gperftools/src/tests/getpc_test.cc | 123 + .../src/tests/heap-checker-death_unittest.sh | 176 + .../src/tests/heap-checker_unittest.cc | 1538 ++ .../src/tests/heap-checker_unittest.sh | 89 + .../src/tests/heap-profiler_unittest.cc | 168 + .../src/tests/heap-profiler_unittest.sh | 147 + .../large_heap_fragmentation_unittest.cc | 62 + .../src/tests/low_level_alloc_unittest.cc | 197 + .../src/tests/malloc_extension_c_test.c | 182 + .../src/tests/malloc_extension_test.cc | 98 + .../gperftools/src/tests/malloc_hook_test.cc | 367 + .../gperftools/src/tests/markidle_unittest.cc | 127 + .../src/tests/maybe_threads_unittest.sh | 79 + .../gperftools/src/tests/memalign_unittest.cc | 221 + .../gperftools/src/tests/packed-cache_test.cc | 82 + .../gperftools/src/tests/page_heap_test.cc | 202 + .../gperftools/src/tests/pagemap_unittest.cc | 178 + .../src/tests/profile-handler_unittest.cc | 398 + .../src/tests/profiledata_unittest.cc | 612 + .../gperftools/src/tests/profiler_unittest.cc | 147 + .../gperftools/src/tests/profiler_unittest.sh | 269 + .../gperftools/src/tests/raw_printer_test.cc | 64 + .../gperftools/src/tests/realloc_unittest.cc | 125 + .../gperftools/src/tests/sampler_test.cc | 631 + .../gperftools/src/tests/sampling_test.cc | 83 + .../gperftools/src/tests/sampling_test.sh | 94 + .../src/tests/simple_compat_test.cc | 71 + .../src/tests/stack_trace_table_test.cc | 93 + .../src/tests/stacktrace_unittest.cc | 194 + .../src/tests/system-alloc_unittest.cc | 155 + .../src/tests/tcmalloc_large_unittest.cc | 138 + .../gperftools/src/tests/tcmalloc_unittest.cc | 1645 ++ .../gperftools/src/tests/tcmalloc_unittest.sh | 84 + thirdparty/gperftools/src/tests/testutil.cc | 224 + thirdparty/gperftools/src/tests/testutil.h | 62 + .../src/tests/thread_dealloc_unittest.cc | 84 + .../gperftools/src/third_party/valgrind.h | 3924 ++++ thirdparty/gperftools/src/thread_cache.cc | 529 + thirdparty/gperftools/src/thread_cache.h | 510 + thirdparty/gperftools/src/windows/TODO | 86 + .../gperftools/src/windows/addr2line-pdb.c | 182 + .../src/windows/auto_testing_hook.h | 156 + thirdparty/gperftools/src/windows/config.h | 363 + .../src/windows/get_mangled_names.cc | 65 + .../gperftools/src/windows/google/tcmalloc.h | 34 + .../src/windows/gperftools/tcmalloc.h | 155 + .../src/windows/gperftools/tcmalloc.h.in | 155 + .../gperftools/src/windows/ia32_modrm_map.cc | 121 + .../gperftools/src/windows/ia32_opcode_map.cc | 1219 ++ thirdparty/gperftools/src/windows/mingw.h | 74 + .../src/windows/mini_disassembler.cc | 432 + .../src/windows/mini_disassembler.h | 198 + .../src/windows/mini_disassembler_types.h | 237 + thirdparty/gperftools/src/windows/nm-pdb.c | 273 + .../src/windows/override_functions.cc | 173 + .../gperftools/src/windows/patch_functions.cc | 1097 ++ thirdparty/gperftools/src/windows/port.cc | 249 + thirdparty/gperftools/src/windows/port.h | 499 + .../src/windows/preamble_patcher.cc | 736 + .../gperftools/src/windows/preamble_patcher.h | 620 + .../src/windows/preamble_patcher_test.cc | 368 + .../src/windows/preamble_patcher_with_stub.cc | 302 + .../gperftools/src/windows/shortproc.asm | 169 + .../gperftools/src/windows/system-alloc.cc | 204 + .../addr2line-pdb/addr2line-pdb.vcxproj | 191 + .../addr2line-pdb.vcxproj.filters | 18 + .../addressmap_unittest.vcxproj | 229 + .../addressmap_unittest.vcxproj.filters | 95 + .../current_allocated_bytes_test.vcxproj | 215 + ...rrent_allocated_bytes_test.vcxproj.filters | 35 + .../frag_unittest/frag_unittest.vcxproj | 213 + .../frag_unittest.vcxproj.filters | 29 + .../libtcmalloc_minimal.vcxproj | 297 + .../libtcmalloc_minimal.vcxproj.filters | 275 + .../low_level_alloc_unittest.vcxproj | 238 + .../low_level_alloc_unittest.vcxproj.filters | 122 + .../malloc_extension_test.vcxproj | 216 + .../malloc_extension_test.vcxproj.filters | 38 + .../malloc_hook_test/malloc_hook_test.vcxproj | 217 + .../malloc_hook_test.vcxproj.filters | 41 + .../markidle_unittest.vcxproj | 215 + .../markidle_unittest.vcxproj.filters | 35 + .../vsprojects/nm-pdb/nm-pdb.vcxproj | 191 + .../vsprojects/nm-pdb/nm-pdb.vcxproj.filters | 18 + .../packed-cache_test.vcxproj | 229 + .../packed-cache_test.vcxproj.filters | 77 + .../page_heap_test/page_heap_test.vcxproj | 216 + .../page_heap_test.vcxproj.filters | 38 + .../pagemap_unittest/pagemap_unittest.vcxproj | 215 + .../pagemap_unittest.vcxproj.filters | 35 + .../preamble_patcher_test.vcxproj | 234 + .../preamble_patcher_test.vcxproj.filters | 49 + .../realloc_unittest/realloc_unittest.vcxproj | 214 + .../realloc_unittest.vcxproj.filters | 32 + .../sampler_test/sampler_test.vcxproj | 215 + .../sampler_test/sampler_test.vcxproj.filters | 35 + .../stack_trace_table_test.vcxproj | 214 + .../stack_trace_table_test.vcxproj.filters | 32 + .../system-alloc_unittest.vcxproj | 215 + .../system-alloc_unittest.vcxproj.filters | 35 + .../tcmalloc_minimal_large_unittest.vcxproj | 213 + ...loc_minimal_large_unittest.vcxproj.filters | 29 + .../tcmalloc_minimal_unittest.vcxproj | 215 + .../tcmalloc_minimal_unittest.vcxproj.filters | 35 + .../thread_dealloc_unittest.vcxproj | 215 + .../thread_dealloc_unittest.vcxproj.filters | 35 + thirdparty/jsoncpp/.clang-format | 47 + thirdparty/jsoncpp/.gitattributes | 11 + thirdparty/jsoncpp/.gitignore | 55 + thirdparty/jsoncpp/.travis.yml | 42 + thirdparty/jsoncpp/AUTHORS | 111 + thirdparty/jsoncpp/CMakeLists.txt | 159 + thirdparty/jsoncpp/LICENSE | 55 + thirdparty/jsoncpp/README.md | 137 + thirdparty/jsoncpp/amalgamate.py | 155 + thirdparty/jsoncpp/appveyor.yml | 22 + thirdparty/jsoncpp/dev.makefile | 35 + thirdparty/jsoncpp/devtools/__init__.py | 6 + thirdparty/jsoncpp/devtools/agent_vmw7.json | 33 + thirdparty/jsoncpp/devtools/agent_vmxp.json | 26 + thirdparty/jsoncpp/devtools/antglob.py | 205 + thirdparty/jsoncpp/devtools/batchbuild.py | 278 + thirdparty/jsoncpp/devtools/fixeol.py | 70 + thirdparty/jsoncpp/devtools/licenseupdater.py | 94 + thirdparty/jsoncpp/devtools/tarball.py | 52 + thirdparty/jsoncpp/doc/doxyfile.in | 2302 +++ thirdparty/jsoncpp/doc/footer.html | 21 + thirdparty/jsoncpp/doc/header.html | 64 + thirdparty/jsoncpp/doc/jsoncpp.dox | 164 + thirdparty/jsoncpp/doc/readme.txt | 1 + thirdparty/jsoncpp/doc/roadmap.dox | 3 + thirdparty/jsoncpp/doc/web_doxyfile.in | 2290 +++ thirdparty/jsoncpp/doxybuild.py | 189 + thirdparty/jsoncpp/include/CMakeLists.txt | 2 + thirdparty/jsoncpp/include/json/allocator.h | 89 + thirdparty/jsoncpp/include/json/assertions.h | 59 + thirdparty/jsoncpp/include/json/autolink.h | 25 + thirdparty/jsoncpp/include/json/config.h | 200 + thirdparty/jsoncpp/include/json/features.h | 61 + thirdparty/jsoncpp/include/json/forwards.h | 37 + thirdparty/jsoncpp/include/json/json.h | 15 + thirdparty/jsoncpp/include/json/reader.h | 420 + thirdparty/jsoncpp/include/json/value.h | 909 + thirdparty/jsoncpp/include/json/version.h | 22 + thirdparty/jsoncpp/include/json/writer.h | 368 + .../jsoncpp/makefiles/vs71/jsontest.vcproj | 119 + .../jsoncpp/makefiles/vs71/lib_json.vcproj | 205 + .../makefiles/vs71/test_lib_json.vcproj | 130 + thirdparty/jsoncpp/makerelease.py | 390 + thirdparty/jsoncpp/meson.build | 115 + thirdparty/jsoncpp/pkg-config/jsoncpp.pc.in | 9 + thirdparty/jsoncpp/src/CMakeLists.txt | 5 + .../jsoncpp/src/jsontestrunner/CMakeLists.txt | 25 + .../jsoncpp/src/jsontestrunner/main.cpp | 311 + .../jsoncpp/src/lib_json/CMakeLists.txt | 118 + .../jsoncpp/src/lib_json/json_reader.cpp | 2032 ++ thirdparty/jsoncpp/src/lib_json/json_tool.h | 134 + .../jsoncpp/src/lib_json/json_value.cpp | 1697 ++ .../src/lib_json/json_valueiterator.inl | 167 + .../jsoncpp/src/lib_json/json_writer.cpp | 1263 ++ thirdparty/jsoncpp/src/lib_json/version.h.in | 20 + .../jsoncpp/src/test_lib_json/CMakeLists.txt | 38 + .../jsoncpp/src/test_lib_json/jsontest.cpp | 442 + .../jsoncpp/src/test_lib_json/jsontest.h | 279 + thirdparty/jsoncpp/src/test_lib_json/main.cpp | 2586 +++ thirdparty/jsoncpp/test/cleantests.py | 16 + .../jsoncpp/test/data/fail_test_array_01.json | 1 + .../test/data/fail_test_stack_limit.json | 1 + .../jsoncpp/test/data/test_array_01.expected | 1 + .../jsoncpp/test/data/test_array_01.json | 1 + .../jsoncpp/test/data/test_array_02.expected | 2 + .../jsoncpp/test/data/test_array_02.json | 1 + .../jsoncpp/test/data/test_array_03.expected | 6 + .../jsoncpp/test/data/test_array_03.json | 1 + .../jsoncpp/test/data/test_array_04.expected | 5 + .../jsoncpp/test/data/test_array_04.json | 1 + .../jsoncpp/test/data/test_array_05.expected | 100 + .../jsoncpp/test/data/test_array_05.json | 1 + .../jsoncpp/test/data/test_array_06.expected | 5 + .../jsoncpp/test/data/test_array_06.json | 4 + .../jsoncpp/test/data/test_array_07.expected | 2122 ++ .../jsoncpp/test/data/test_array_07.json | 2 + .../jsoncpp/test/data/test_basic_01.expected | 1 + .../jsoncpp/test/data/test_basic_01.json | 1 + .../jsoncpp/test/data/test_basic_02.expected | 1 + .../jsoncpp/test/data/test_basic_02.json | 1 + .../jsoncpp/test/data/test_basic_03.expected | 3 + .../jsoncpp/test/data/test_basic_03.json | 3 + .../jsoncpp/test/data/test_basic_04.expected | 2 + .../jsoncpp/test/data/test_basic_04.json | 2 + .../jsoncpp/test/data/test_basic_05.expected | 2 + .../jsoncpp/test/data/test_basic_05.json | 2 + .../jsoncpp/test/data/test_basic_06.expected | 2 + .../jsoncpp/test/data/test_basic_06.json | 2 + .../jsoncpp/test/data/test_basic_07.expected | 2 + .../jsoncpp/test/data/test_basic_07.json | 2 + .../jsoncpp/test/data/test_basic_08.expected | 3 + .../jsoncpp/test/data/test_basic_08.json | 3 + .../jsoncpp/test/data/test_basic_09.expected | 4 + .../jsoncpp/test/data/test_basic_09.json | 4 + .../test/data/test_comment_00.expected | 4 + .../jsoncpp/test/data/test_comment_00.json | 5 + .../test/data/test_comment_01.expected | 10 + .../jsoncpp/test/data/test_comment_01.json | 10 + .../test/data/test_comment_02.expected | 23 + .../jsoncpp/test/data/test_comment_02.json | 26 + .../test/data/test_complex_01.expected | 20 + .../jsoncpp/test/data/test_complex_01.json | 17 + .../test/data/test_integer_01.expected | 2 + .../jsoncpp/test/data/test_integer_01.json | 2 + .../test/data/test_integer_02.expected | 2 + .../jsoncpp/test/data/test_integer_02.json | 2 + .../test/data/test_integer_03.expected | 2 + .../jsoncpp/test/data/test_integer_03.json | 2 + .../test/data/test_integer_04.expected | 3 + .../jsoncpp/test/data/test_integer_04.json | 3 + .../test/data/test_integer_05.expected | 2 + .../jsoncpp/test/data/test_integer_05.json | 2 + .../test/data/test_integer_06_64bits.expected | 1 + .../test/data/test_integer_06_64bits.json | 2 + .../test/data/test_integer_07_64bits.expected | 1 + .../test/data/test_integer_07_64bits.json | 2 + .../test/data/test_integer_08_64bits.expected | 1 + .../test/data/test_integer_08_64bits.json | 2 + .../jsoncpp/test/data/test_large_01.expected | 2122 ++ .../jsoncpp/test/data/test_large_01.json | 2 + .../jsoncpp/test/data/test_object_01.expected | 1 + .../jsoncpp/test/data/test_object_01.json | 1 + .../jsoncpp/test/data/test_object_02.expected | 2 + .../jsoncpp/test/data/test_object_02.json | 1 + .../jsoncpp/test/data/test_object_03.expected | 4 + .../jsoncpp/test/data/test_object_03.json | 5 + .../jsoncpp/test/data/test_object_04.expected | 2 + .../jsoncpp/test/data/test_object_04.json | 3 + .../data/test_preserve_comment_01.expected | 11 + .../test/data/test_preserve_comment_01.json | 14 + .../jsoncpp/test/data/test_real_01.expected | 3 + .../jsoncpp/test/data/test_real_01.json | 3 + .../jsoncpp/test/data/test_real_02.expected | 3 + .../jsoncpp/test/data/test_real_02.json | 3 + .../jsoncpp/test/data/test_real_03.expected | 3 + .../jsoncpp/test/data/test_real_03.json | 3 + .../jsoncpp/test/data/test_real_04.expected | 3 + .../jsoncpp/test/data/test_real_04.json | 3 + .../jsoncpp/test/data/test_real_05.expected | 4 + .../jsoncpp/test/data/test_real_05.json | 3 + .../jsoncpp/test/data/test_real_06.expected | 4 + .../jsoncpp/test/data/test_real_06.json | 3 + .../jsoncpp/test/data/test_real_07.expected | 4 + .../jsoncpp/test/data/test_real_07.json | 3 + .../jsoncpp/test/data/test_real_08.expected | 4 + .../jsoncpp/test/data/test_real_08.json | 4 + .../jsoncpp/test/data/test_real_09.expected | 4 + .../jsoncpp/test/data/test_real_09.json | 4 + .../jsoncpp/test/data/test_real_10.expected | 4 + .../jsoncpp/test/data/test_real_10.json | 4 + .../jsoncpp/test/data/test_real_11.expected | 4 + .../jsoncpp/test/data/test_real_11.json | 4 + .../jsoncpp/test/data/test_real_12.expected | 2 + .../jsoncpp/test/data/test_real_12.json | 2 + .../jsoncpp/test/data/test_string_01.expected | 1 + .../jsoncpp/test/data/test_string_01.json | 1 + .../jsoncpp/test/data/test_string_02.expected | 1 + .../jsoncpp/test/data/test_string_02.json | 1 + .../jsoncpp/test/data/test_string_03.expected | 1 + .../jsoncpp/test/data/test_string_03.json | 1 + .../jsoncpp/test/data/test_string_04.expected | 2 + .../jsoncpp/test/data/test_string_04.json | 2 + .../jsoncpp/test/data/test_string_05.expected | 2 + .../jsoncpp/test/data/test_string_05.json | 2 + .../test/data/test_string_unicode_01.expected | 1 + .../test/data/test_string_unicode_01.json | 1 + .../test/data/test_string_unicode_02.expected | 1 + .../test/data/test_string_unicode_02.json | 1 + .../test/data/test_string_unicode_03.expected | 1 + .../test/data/test_string_unicode_03.json | 1 + .../test/data/test_string_unicode_04.expected | 1 + .../test/data/test_string_unicode_04.json | 1 + .../test/data/test_string_unicode_05.expected | 2 + .../test/data/test_string_unicode_05.json | 1 + thirdparty/jsoncpp/test/generate_expected.py | 17 + .../jsoncpp/test/jsonchecker/fail1.json | 1 + .../jsoncpp/test/jsonchecker/fail10.json | 1 + .../jsoncpp/test/jsonchecker/fail11.json | 1 + .../jsoncpp/test/jsonchecker/fail12.json | 1 + .../jsoncpp/test/jsonchecker/fail13.json | 1 + .../jsoncpp/test/jsonchecker/fail14.json | 1 + .../jsoncpp/test/jsonchecker/fail15.json | 1 + .../jsoncpp/test/jsonchecker/fail16.json | 1 + .../jsoncpp/test/jsonchecker/fail17.json | 1 + .../jsoncpp/test/jsonchecker/fail18.json | 1 + .../jsoncpp/test/jsonchecker/fail19.json | 1 + .../jsoncpp/test/jsonchecker/fail2.json | 1 + .../jsoncpp/test/jsonchecker/fail20.json | 1 + .../jsoncpp/test/jsonchecker/fail21.json | 1 + .../jsoncpp/test/jsonchecker/fail22.json | 1 + .../jsoncpp/test/jsonchecker/fail23.json | 1 + .../jsoncpp/test/jsonchecker/fail24.json | 1 + .../jsoncpp/test/jsonchecker/fail25.json | 1 + .../jsoncpp/test/jsonchecker/fail26.json | 1 + .../jsoncpp/test/jsonchecker/fail27.json | 2 + .../jsoncpp/test/jsonchecker/fail28.json | 2 + .../jsoncpp/test/jsonchecker/fail29.json | 1 + .../jsoncpp/test/jsonchecker/fail3.json | 1 + .../jsoncpp/test/jsonchecker/fail30.json | 1 + .../jsoncpp/test/jsonchecker/fail31.json | 1 + .../jsoncpp/test/jsonchecker/fail32.json | 1 + .../jsoncpp/test/jsonchecker/fail33.json | 1 + .../jsoncpp/test/jsonchecker/fail4.json | 1 + .../jsoncpp/test/jsonchecker/fail5.json | 1 + .../jsoncpp/test/jsonchecker/fail6.json | 1 + .../jsoncpp/test/jsonchecker/fail7.json | 1 + .../jsoncpp/test/jsonchecker/fail8.json | 1 + .../jsoncpp/test/jsonchecker/fail9.json | 1 + .../jsoncpp/test/jsonchecker/pass1.json | 58 + .../jsoncpp/test/jsonchecker/pass2.json | 1 + .../jsoncpp/test/jsonchecker/pass3.json | 6 + .../jsoncpp/test/jsonchecker/readme.txt | 3 + thirdparty/jsoncpp/test/pyjsontestrunner.py | 71 + thirdparty/jsoncpp/test/runjsontests.py | 174 + thirdparty/jsoncpp/test/rununittests.py | 84 + .../jsoncpp/travis.before_install.linux.sh | 7 + .../jsoncpp/travis.before_install.osx.sh | 3 + thirdparty/jsoncpp/travis.install.linux.sh | 14 + thirdparty/jsoncpp/travis.install.osx.sh | 12 + thirdparty/jsoncpp/travis.sh | 31 + thirdparty/jsoncpp/version | 1 + thirdparty/jsoncpp/version.in | 1 + thirdparty/pybind11/.appveyor.yml | 70 + thirdparty/pybind11/.gitignore | 38 + thirdparty/pybind11/.gitmodules | 3 + thirdparty/pybind11/.readthedocs.yml | 3 + thirdparty/pybind11/.travis.yml | 280 + thirdparty/pybind11/CMakeLists.txt | 157 + thirdparty/pybind11/CONTRIBUTING.md | 49 + thirdparty/pybind11/ISSUE_TEMPLATE.md | 17 + thirdparty/pybind11/LICENSE | 29 + thirdparty/pybind11/MANIFEST.in | 2 + thirdparty/pybind11/README.md | 129 + thirdparty/pybind11/docs/Doxyfile | 20 + .../pybind11/docs/_static/theme_overrides.css | 11 + .../pybind11/docs/advanced/cast/chrono.rst | 81 + .../pybind11/docs/advanced/cast/custom.rst | 91 + .../pybind11/docs/advanced/cast/eigen.rst | 310 + .../docs/advanced/cast/functional.rst | 109 + .../pybind11/docs/advanced/cast/index.rst | 42 + .../pybind11/docs/advanced/cast/overview.rst | 165 + .../pybind11/docs/advanced/cast/stl.rst | 240 + .../pybind11/docs/advanced/cast/strings.rst | 305 + thirdparty/pybind11/docs/advanced/classes.rst | 1126 ++ .../pybind11/docs/advanced/embedding.rst | 261 + .../pybind11/docs/advanced/exceptions.rst | 142 + .../pybind11/docs/advanced/functions.rst | 507 + thirdparty/pybind11/docs/advanced/misc.rst | 306 + .../pybind11/docs/advanced/pycpp/index.rst | 13 + .../pybind11/docs/advanced/pycpp/numpy.rst | 386 + .../pybind11/docs/advanced/pycpp/object.rst | 170 + .../docs/advanced/pycpp/utilities.rst | 144 + .../pybind11/docs/advanced/smart_ptrs.rst | 173 + thirdparty/pybind11/docs/basics.rst | 293 + thirdparty/pybind11/docs/benchmark.py | 88 + thirdparty/pybind11/docs/benchmark.rst | 97 + thirdparty/pybind11/docs/changelog.rst | 1158 ++ thirdparty/pybind11/docs/classes.rst | 521 + thirdparty/pybind11/docs/compiling.rst | 289 + thirdparty/pybind11/docs/conf.py | 332 + thirdparty/pybind11/docs/faq.rst | 297 + thirdparty/pybind11/docs/index.rst | 47 + thirdparty/pybind11/docs/intro.rst | 93 + thirdparty/pybind11/docs/limitations.rst | 20 + thirdparty/pybind11/docs/pybind11-logo.png | Bin 0 -> 58510 bytes .../docs/pybind11_vs_boost_python1.png | Bin 0 -> 44653 bytes .../docs/pybind11_vs_boost_python1.svg | 427 + .../docs/pybind11_vs_boost_python2.png | Bin 0 -> 41121 bytes .../docs/pybind11_vs_boost_python2.svg | 427 + thirdparty/pybind11/docs/reference.rst | 117 + thirdparty/pybind11/docs/release.rst | 25 + thirdparty/pybind11/docs/requirements.txt | 1 + thirdparty/pybind11/docs/upgrade.rst | 404 + thirdparty/pybind11/include/pybind11/attr.h | 493 + .../pybind11/include/pybind11/buffer_info.h | 108 + thirdparty/pybind11/include/pybind11/cast.h | 2128 ++ thirdparty/pybind11/include/pybind11/chrono.h | 162 + thirdparty/pybind11/include/pybind11/common.h | 2 + .../pybind11/include/pybind11/complex.h | 65 + .../pybind11/include/pybind11/detail/class.h | 623 + .../pybind11/include/pybind11/detail/common.h | 807 + .../pybind11/include/pybind11/detail/descr.h | 100 + .../pybind11/include/pybind11/detail/init.h | 335 + .../include/pybind11/detail/internals.h | 291 + .../pybind11/include/pybind11/detail/typeid.h | 55 + thirdparty/pybind11/include/pybind11/eigen.h | 607 + thirdparty/pybind11/include/pybind11/embed.h | 200 + thirdparty/pybind11/include/pybind11/eval.h | 117 + .../pybind11/include/pybind11/functional.h | 94 + .../pybind11/include/pybind11/iostream.h | 207 + thirdparty/pybind11/include/pybind11/numpy.h | 1610 ++ .../pybind11/include/pybind11/operators.h | 168 + .../pybind11/include/pybind11/options.h | 65 + .../pybind11/include/pybind11/pybind11.h | 2161 ++ .../pybind11/include/pybind11/pytypes.h | 1471 ++ thirdparty/pybind11/include/pybind11/stl.h | 386 + .../pybind11/include/pybind11/stl_bind.h | 630 + thirdparty/pybind11/pybind11/__init__.py | 28 + thirdparty/pybind11/pybind11/__main__.py | 37 + thirdparty/pybind11/pybind11/_version.py | 2 + thirdparty/pybind11/setup.cfg | 12 + thirdparty/pybind11/setup.py | 108 + thirdparty/pybind11/tests/CMakeLists.txt | 239 + thirdparty/pybind11/tests/conftest.py | 239 + thirdparty/pybind11/tests/constructor_stats.h | 276 + thirdparty/pybind11/tests/local_bindings.h | 64 + thirdparty/pybind11/tests/object.h | 175 + .../tests/pybind11_cross_module_tests.cpp | 123 + thirdparty/pybind11/tests/pybind11_tests.cpp | 93 + thirdparty/pybind11/tests/pybind11_tests.h | 65 + thirdparty/pybind11/tests/pytest.ini | 16 + thirdparty/pybind11/tests/test_buffers.cpp | 169 + thirdparty/pybind11/tests/test_buffers.py | 87 + .../pybind11/tests/test_builtin_casters.cpp | 170 + .../pybind11/tests/test_builtin_casters.py | 342 + .../pybind11/tests/test_call_policies.cpp | 100 + .../pybind11/tests/test_call_policies.py | 187 + thirdparty/pybind11/tests/test_callbacks.cpp | 168 + thirdparty/pybind11/tests/test_callbacks.py | 136 + thirdparty/pybind11/tests/test_chrono.cpp | 55 + thirdparty/pybind11/tests/test_chrono.py | 107 + thirdparty/pybind11/tests/test_class.cpp | 422 + thirdparty/pybind11/tests/test_class.py | 281 + .../tests/test_cmake_build/CMakeLists.txt | 58 + .../pybind11/tests/test_cmake_build/embed.cpp | 21 + .../installed_embed/CMakeLists.txt | 15 + .../installed_function/CMakeLists.txt | 12 + .../installed_target/CMakeLists.txt | 22 + .../pybind11/tests/test_cmake_build/main.cpp | 6 + .../subdirectory_embed/CMakeLists.txt | 25 + .../subdirectory_function/CMakeLists.txt | 8 + .../subdirectory_target/CMakeLists.txt | 15 + .../pybind11/tests/test_cmake_build/test.py | 5 + .../tests/test_constants_and_functions.cpp | 127 + .../tests/test_constants_and_functions.py | 39 + thirdparty/pybind11/tests/test_copy_move.cpp | 213 + thirdparty/pybind11/tests/test_copy_move.py | 112 + .../pybind11/tests/test_docstring_options.cpp | 61 + .../pybind11/tests/test_docstring_options.py | 38 + thirdparty/pybind11/tests/test_eigen.cpp | 329 + thirdparty/pybind11/tests/test_eigen.py | 694 + .../pybind11/tests/test_embed/CMakeLists.txt | 41 + .../pybind11/tests/test_embed/catch.cpp | 22 + .../tests/test_embed/external_module.cpp | 23 + .../tests/test_embed/test_interpreter.cpp | 284 + .../tests/test_embed/test_interpreter.py | 9 + thirdparty/pybind11/tests/test_enum.cpp | 85 + thirdparty/pybind11/tests/test_enum.py | 167 + thirdparty/pybind11/tests/test_eval.cpp | 91 + thirdparty/pybind11/tests/test_eval.py | 17 + thirdparty/pybind11/tests/test_eval_call.py | 4 + thirdparty/pybind11/tests/test_exceptions.cpp | 196 + thirdparty/pybind11/tests/test_exceptions.py | 146 + .../tests/test_factory_constructors.cpp | 338 + .../tests/test_factory_constructors.py | 459 + thirdparty/pybind11/tests/test_gil_scoped.cpp | 44 + thirdparty/pybind11/tests/test_gil_scoped.py | 80 + thirdparty/pybind11/tests/test_iostream.cpp | 73 + thirdparty/pybind11/tests/test_iostream.py | 214 + .../tests/test_kwargs_and_defaults.cpp | 102 + .../tests/test_kwargs_and_defaults.py | 147 + .../pybind11/tests/test_local_bindings.cpp | 101 + .../pybind11/tests/test_local_bindings.py | 226 + .../tests/test_methods_and_attributes.cpp | 454 + .../tests/test_methods_and_attributes.py | 512 + thirdparty/pybind11/tests/test_modules.cpp | 98 + thirdparty/pybind11/tests/test_modules.py | 72 + .../tests/test_multiple_inheritance.cpp | 220 + .../tests/test_multiple_inheritance.py | 349 + .../pybind11/tests/test_numpy_array.cpp | 309 + thirdparty/pybind11/tests/test_numpy_array.py | 421 + .../pybind11/tests/test_numpy_dtypes.cpp | 466 + .../pybind11/tests/test_numpy_dtypes.py | 310 + .../pybind11/tests/test_numpy_vectorize.cpp | 89 + .../pybind11/tests/test_numpy_vectorize.py | 196 + .../pybind11/tests/test_opaque_types.cpp | 67 + .../pybind11/tests/test_opaque_types.py | 46 + .../tests/test_operator_overloading.cpp | 171 + .../tests/test_operator_overloading.py | 108 + thirdparty/pybind11/tests/test_pickling.cpp | 130 + thirdparty/pybind11/tests/test_pickling.py | 42 + thirdparty/pybind11/tests/test_pytypes.cpp | 296 + thirdparty/pybind11/tests/test_pytypes.py | 253 + .../tests/test_sequences_and_iterators.cpp | 353 + .../tests/test_sequences_and_iterators.py | 171 + thirdparty/pybind11/tests/test_smart_ptr.cpp | 366 + thirdparty/pybind11/tests/test_smart_ptr.py | 285 + thirdparty/pybind11/tests/test_stl.cpp | 284 + thirdparty/pybind11/tests/test_stl.py | 241 + .../pybind11/tests/test_stl_binders.cpp | 107 + thirdparty/pybind11/tests/test_stl_binders.py | 225 + .../tests/test_tagbased_polymorphic.cpp | 136 + .../tests/test_tagbased_polymorphic.py | 20 + thirdparty/pybind11/tests/test_union.cpp | 22 + thirdparty/pybind11/tests/test_union.py | 8 + .../pybind11/tests/test_virtual_functions.cpp | 479 + .../pybind11/tests/test_virtual_functions.py | 377 + thirdparty/pybind11/tools/FindCatch.cmake | 57 + thirdparty/pybind11/tools/FindEigen3.cmake | 81 + .../pybind11/tools/FindPythonLibsNew.cmake | 202 + thirdparty/pybind11/tools/check-style.sh | 70 + thirdparty/pybind11/tools/libsize.py | 38 + thirdparty/pybind11/tools/mkdoc.py | 379 + .../pybind11/tools/pybind11Config.cmake.in | 104 + thirdparty/pybind11/tools/pybind11Tools.cmake | 227 + 4409 files changed, 871182 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.md create mode 100755 build.sh create mode 100644 cfg/atan.json create mode 100644 cfg/equidistant.json create mode 100644 cfg/estimator.json create mode 100644 cfg/estimator_latex.json create mode 100644 cfg/estimator_scenenet.json create mode 100644 cfg/estimator_sim.json create mode 100644 cfg/lyapunov_baseline.json create mode 100644 cfg/pointgrey_xsens.json create mode 100644 cfg/pointgrey_xsens_viewer.json create mode 100644 cfg/simulation.json create mode 100644 cfg/simulator.json create mode 100644 cfg/tuning.json create mode 100644 cfg/viewer.json create mode 100644 cfg/viewer_scenenet.json create mode 100644 cfg/vio.json create mode 100644 common/CMakeLists.txt create mode 100644 common/ProducerConsumerQueue.h create mode 100644 common/alias.h create mode 100644 common/atan.h create mode 100644 common/camera.h create mode 100644 common/component.h create mode 100644 common/equidist.h create mode 100644 common/example_process.cpp create mode 100644 common/pinhole.h create mode 100644 common/process.h create mode 100644 common/radtan.h create mode 100644 common/rodrigues.h create mode 100644 common/se3.h create mode 100644 common/test/test_rodrigues.cpp create mode 100644 common/test/test_se3.cpp create mode 100644 common/utils.cpp create mode 100644 common/utils.h create mode 100644 experimental/CMakeLists.txt create mode 100644 experimental/async_dataloader.cpp create mode 100644 experimental/camera_factory.h create mode 100644 experimental/inproc_communication_zmq.cpp create mode 100644 experimental/test_camera_factory.cpp create mode 100755 format_all.sh create mode 100644 misc/tumvi_calib/pinhole-equi-512/camchain-imucam-imucalib.yaml create mode 100644 misc/tumvi_calib/pinhole-equi-512/imu-imucalib.yaml create mode 100644 misc/tumvi_calib/pinhole-equi-512/imucalib-command.txt create mode 100644 misc/tumvi_calib/pinhole-equi-512/imucalib.log create mode 100644 misc/tumvi_calib/pinhole-equi-512/results-imucam-imucalib.txt create mode 100644 node/CMakeLists.txt create mode 100644 node/launch/sensors.launch create mode 100644 node/launch/tumvi.launch create mode 100644 node/launch/tumvi.xml create mode 100644 node/launch/xivo.launch create mode 100644 node/launch/xivo.xml create mode 100644 node/main.cpp create mode 100644 node/package.xml create mode 100644 node/ros_setup.h create mode 100644 node/simple_node.cpp create mode 100644 node/simple_node.h create mode 100755 print_stats.sh create mode 100644 pybind11/pyxivo.cpp create mode 100644 requirements.txt create mode 100755 run_all.sh create mode 100644 scripts/compareTraj.py create mode 100644 scripts/plot_state.py create mode 100644 scripts/pyxivo.py create mode 100644 scripts/run_and_eval_pyxivo.py create mode 100644 scripts/run_and_eval_xivo.py create mode 100644 scripts/scenenet_demo.py create mode 100644 scripts/tum_rgbd_benchmark_tools/associate.py create mode 100644 scripts/tum_rgbd_benchmark_tools/evaluate_ate.py create mode 100644 scripts/tum_rgbd_benchmark_tools/evaluate_rpe.py create mode 100644 src/CMakeLists.txt create mode 100644 src/adjustable_cameras.h create mode 100644 src/app/evaluate.cpp create mode 100644 src/app/simulation.cpp create mode 100644 src/app/singlethread_vio.cpp create mode 100644 src/app/vio.cpp create mode 100644 src/camera_manager.cpp create mode 100644 src/camera_manager.h create mode 100644 src/core.cpp create mode 100644 src/core.h create mode 100644 src/estimator.cpp create mode 100644 src/estimator.h create mode 100644 src/estimator_process.cpp create mode 100644 src/estimator_process.h create mode 100644 src/feature.cpp create mode 100644 src/feature.h create mode 100644 src/geometry.cpp create mode 100644 src/geometry.h create mode 100644 src/graph.cpp create mode 100644 src/graph.h create mode 100644 src/group.cpp create mode 100644 src/group.h create mode 100644 src/helpers.cpp create mode 100644 src/helpers.h create mode 100644 src/imu.cpp create mode 100644 src/imu.h create mode 100644 src/jac.h create mode 100644 src/manager.cpp create mode 100644 src/message_types.h create mode 100644 src/metrics.cpp create mode 100644 src/metrics.h create mode 100644 src/mm.cpp create mode 100644 src/mm.h create mode 100644 src/options.cpp create mode 100644 src/options.h create mode 100644 src/param.cpp create mode 100644 src/param.h create mode 100644 src/princedormand.cpp create mode 100644 src/project.h create mode 100644 src/publisher.cpp create mode 100644 src/publisher.h create mode 100644 src/rk4.cpp create mode 100644 src/simulator.cpp create mode 100644 src/simulator.h create mode 100644 src/test/test_estimator.cpp create mode 100644 src/test/test_geometry.cpp create mode 100644 src/test/test_givens.cpp create mode 100644 src/test/test_matcher.cpp create mode 100644 src/test/test_qr.cpp create mode 100644 src/test/test_simulator.cpp create mode 100644 src/test/test_tracker.cpp create mode 100644 src/test/test_tumvi.cpp create mode 100644 src/test/test_viewer.cpp create mode 100644 src/tracker.cpp create mode 100644 src/tracker.h create mode 100644 src/tumvi.cpp create mode 100644 src/tumvi.h create mode 100644 src/update.cpp create mode 100644 src/viewer.cpp create mode 100644 src/viewer.h create mode 100644 src/visualize.cpp create mode 100644 src/visualize.h create mode 100644 thirdparty/Pangolin/.clang-format create mode 100644 thirdparty/Pangolin/.gitignore create mode 100644 thirdparty/Pangolin/.gitmodules create mode 100644 thirdparty/Pangolin/.travis.yml create mode 100644 thirdparty/Pangolin/CMakeLists.txt create mode 100644 thirdparty/Pangolin/CMakeModules/AndroidUtils.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/CreateMethodCallFile.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/EmbedBinaryFiles.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindDC1394.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindDepthSense.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindEigen.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindFFMPEG.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindFREEGLUT.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindGLEW.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindGLUES.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindLibRealSense.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindLibRealSense2.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindLz4.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindMediaFoundation.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindOculus.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindOpenEXR.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindOpenNI.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindOpenNI2.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindPleora.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindROBOTVISION.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindTeliCam.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindTooN.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindWayland.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/FindXrandr.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/Findlibusb1.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/Findpthread.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/Finduvc.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/Findzstd.cmake create mode 100644 thirdparty/Pangolin/CMakeModules/SetPlatformVars.cmake create mode 100644 thirdparty/Pangolin/LICENCE create mode 100644 thirdparty/Pangolin/README.md create mode 100644 thirdparty/Pangolin/appveyor.yml create mode 100644 thirdparty/Pangolin/cmake_uninstall.cmake.in create mode 100644 thirdparty/Pangolin/examples/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/HelloPangolin/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/HelloPangolin/main.cpp create mode 100644 thirdparty/Pangolin/examples/HelloPangolinOffscreen/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/HelloPangolinOffscreen/main.cpp create mode 100644 thirdparty/Pangolin/examples/HelloPangolinThreads/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/HelloPangolinThreads/main.cpp create mode 100644 thirdparty/Pangolin/examples/SharedMemoryCamera/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SharedMemoryCamera/main.cpp create mode 100644 thirdparty/Pangolin/examples/SimpleDisplay/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SimpleDisplay/app.cfg create mode 100644 thirdparty/Pangolin/examples/SimpleDisplay/main.cpp create mode 100644 thirdparty/Pangolin/examples/SimpleDisplayImage/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SimpleDisplayImage/main.cpp create mode 100644 thirdparty/Pangolin/examples/SimpleMultiDisplay/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SimpleMultiDisplay/app.cfg create mode 100644 thirdparty/Pangolin/examples/SimpleMultiDisplay/main.cpp create mode 100644 thirdparty/Pangolin/examples/SimplePlot/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SimplePlot/main.cpp create mode 100644 thirdparty/Pangolin/examples/SimpleRecord/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SimpleRecord/main.cpp create mode 100644 thirdparty/Pangolin/examples/SimpleScene/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SimpleScene/main.cpp create mode 100644 thirdparty/Pangolin/examples/SimpleVideo/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/SimpleVideo/main.cpp create mode 100644 thirdparty/Pangolin/examples/VBODisplay/CMakeLists.txt create mode 100644 thirdparty/Pangolin/examples/VBODisplay/kernal.cu create mode 100644 thirdparty/Pangolin/examples/VBODisplay/main.cpp create mode 100644 thirdparty/Pangolin/external/CMakeLists.txt create mode 100644 thirdparty/Pangolin/include/experimental/optional.hpp create mode 100644 thirdparty/Pangolin/include/mpark/variant.hpp create mode 100644 thirdparty/Pangolin/include/pangolin/compat/glutbitmap.h create mode 100644 thirdparty/Pangolin/include/pangolin/compat/optional.h create mode 100644 thirdparty/Pangolin/include/pangolin/compat/type_traits.h create mode 100644 thirdparty/Pangolin/include/pangolin/compat/variant.h create mode 100644 thirdparty/Pangolin/include/pangolin/console/ConsoleInterpreter.h create mode 100644 thirdparty/Pangolin/include/pangolin/console/ConsoleView.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/attach.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/device/OsxWindow.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/device/PangolinNSApplication.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/device/PangolinNSGLView.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/device/WinWindow.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/device/X11GlContext.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/device/X11Window.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/device/display_android.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/display.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/display_internal.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/image_view.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/opengl_render_state.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/user_app.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/view.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/viewport.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/widgets/widgets.h create mode 100644 thirdparty/Pangolin/include/pangolin/display/window.h create mode 100644 thirdparty/Pangolin/include/pangolin/factory/factory_registry.h create mode 100644 thirdparty/Pangolin/include/pangolin/geometry/geometry.h create mode 100644 thirdparty/Pangolin/include/pangolin/geometry/geometry_obj.h create mode 100644 thirdparty/Pangolin/include/pangolin/geometry/geometry_ply.h create mode 100644 thirdparty/Pangolin/include/pangolin/geometry/glgeometry.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/cg.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/colour.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/compat/gl2engine.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/compat/gl_es_compat.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/gl.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/gl.hpp create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glchar.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glcuda.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/gldraw.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glfont.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glformattraits.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glinclude.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glpangoglu.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glpixformat.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glplatform.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glsl.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glstate.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/gltext.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/gltexturecache.h create mode 100644 thirdparty/Pangolin/include/pangolin/gl/glvbo.h create mode 100644 thirdparty/Pangolin/include/pangolin/handler/handler.h create mode 100644 thirdparty/Pangolin/include/pangolin/handler/handler_enums.h create mode 100644 thirdparty/Pangolin/include/pangolin/handler/handler_glbuffer.h create mode 100644 thirdparty/Pangolin/include/pangolin/handler/handler_image.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/copy.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/image.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/image_convert.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/image_io.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/image_utils.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/managed_image.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/memcpy.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/pixel_format.h create mode 100644 thirdparty/Pangolin/include/pangolin/image/typed_image.h create mode 100644 thirdparty/Pangolin/include/pangolin/ios/PangolinAppDelegate.h create mode 100644 thirdparty/Pangolin/include/pangolin/ios/PangolinUIView.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/packet.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/packetstream.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/packetstream_reader.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/packetstream_source.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/packetstream_tags.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/packetstream_writer.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/playback_session.h create mode 100644 thirdparty/Pangolin/include/pangolin/log/sync_time.h create mode 100644 thirdparty/Pangolin/include/pangolin/pangolin.h create mode 100644 thirdparty/Pangolin/include/pangolin/platform.h create mode 100644 thirdparty/Pangolin/include/pangolin/plot/datalog.h create mode 100644 thirdparty/Pangolin/include/pangolin/plot/plotter.h create mode 100644 thirdparty/Pangolin/include/pangolin/plot/range.h create mode 100644 thirdparty/Pangolin/include/pangolin/python/pyinterpreter.h create mode 100644 thirdparty/Pangolin/include/pangolin/python/pypangoio.h create mode 100644 thirdparty/Pangolin/include/pangolin/python/pypangolin_init.h create mode 100644 thirdparty/Pangolin/include/pangolin/python/pyuniqueobj.h create mode 100644 thirdparty/Pangolin/include/pangolin/python/pyvar.h create mode 100644 thirdparty/Pangolin/include/pangolin/scene/axis.h create mode 100644 thirdparty/Pangolin/include/pangolin/scene/interactive.h create mode 100644 thirdparty/Pangolin/include/pangolin/scene/interactive_index.h create mode 100644 thirdparty/Pangolin/include/pangolin/scene/renderable.h create mode 100644 thirdparty/Pangolin/include/pangolin/scene/scenehandler.h create mode 100644 thirdparty/Pangolin/include/pangolin/scene/tree.h create mode 100644 thirdparty/Pangolin/include/pangolin/tools/video_viewer.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/argagg.hpp create mode 100644 thirdparty/Pangolin/include/pangolin/utils/assert.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/compontent_cast.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/file_extension.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/file_utils.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/fix_size_buffer_queue.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/format_string.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/log.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/memstreambuf.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/params.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/parse.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/picojson.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/posix/condition_variable.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/posix/semaphore.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/posix/shared_memory_buffer.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/registration.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/signal_slot.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/sigstate.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/simple_math.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/threadedfilebuf.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/timer.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/transform.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/type_convert.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/uri.h create mode 100644 thirdparty/Pangolin/include/pangolin/utils/variadic_all.h create mode 100755 thirdparty/Pangolin/include/pangolin/utils/xml/license.txt create mode 100755 thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml.hpp create mode 100755 thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_iterators.hpp create mode 100755 thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_print.hpp create mode 100755 thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_utils.hpp create mode 100644 thirdparty/Pangolin/include/pangolin/var/input_record_repeat.h create mode 100644 thirdparty/Pangolin/include/pangolin/var/var.h create mode 100644 thirdparty/Pangolin/include/pangolin/var/varextra.h create mode 100644 thirdparty/Pangolin/include/pangolin/var/varstate.h create mode 100644 thirdparty/Pangolin/include/pangolin/var/varvalue.h create mode 100644 thirdparty/Pangolin/include/pangolin/var/varvaluegeneric.h create mode 100644 thirdparty/Pangolin/include/pangolin/var/varvaluet.h create mode 100644 thirdparty/Pangolin/include/pangolin/var/varwrapper.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/debayer.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/deinterlace.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/depthsense.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/ffmpeg.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/firewire.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/images.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/images_out.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/join.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/merge.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/mirror.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/openni.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/openni2.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/openni_common.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/pack.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/pango.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/pango_video_output.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/pleora.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/pvn.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/realsense.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/realsense2.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/shared_memory.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/shift.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/split.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/teli.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/test.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/thread.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/truncate.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/unpack.h create mode 100755 thirdparty/Pangolin/include/pangolin/video/drivers/uvc.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/drivers/uvc_mediafoundation.h create mode 100755 thirdparty/Pangolin/include/pangolin/video/drivers/v4l.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/iostream_operators.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/stream_encoder_factory.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/stream_info.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/video.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/video_exception.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/video_input.h create mode 100755 thirdparty/Pangolin/include/pangolin/video/video_interface.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/video_output.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/video_output_interface.h create mode 100644 thirdparty/Pangolin/include/pangolin/video/video_record_repeat.h create mode 100644 thirdparty/Pangolin/include/tinyobj/tiny_obj_loader.h create mode 100644 thirdparty/Pangolin/package.xml create mode 100644 thirdparty/Pangolin/pyexamples/SimpleDisplay.py create mode 100644 thirdparty/Pangolin/pyexamples/SimplePlot.py create mode 100644 thirdparty/Pangolin/pyexamples/SimpleVideo.py create mode 100644 thirdparty/Pangolin/src/CMakeLists.txt create mode 100644 thirdparty/Pangolin/src/Doxyfile.in create mode 100644 thirdparty/Pangolin/src/PangolinConfig.cmake.in create mode 100644 thirdparty/Pangolin/src/PangolinConfigVersion.cmake.in create mode 100644 thirdparty/Pangolin/src/_embed_/fonts/AnonymousPro.ttf create mode 100644 thirdparty/Pangolin/src/_embed_/fonts/AnonymousPro.txt create mode 100644 thirdparty/Pangolin/src/config.h.in create mode 100644 thirdparty/Pangolin/src/console/ConsoleView.cpp create mode 100644 thirdparty/Pangolin/src/display/device/PangolinNSApplication.mm create mode 100644 thirdparty/Pangolin/src/display/device/PangolinNSGLView.mm create mode 100644 thirdparty/Pangolin/src/display/device/display_android.cpp create mode 100755 thirdparty/Pangolin/src/display/device/display_headless.cpp create mode 100644 thirdparty/Pangolin/src/display/device/display_osx.mm create mode 100755 thirdparty/Pangolin/src/display/device/display_wayland.cpp create mode 100644 thirdparty/Pangolin/src/display/device/display_win.cpp create mode 100644 thirdparty/Pangolin/src/display/device/display_x11.cpp create mode 100644 thirdparty/Pangolin/src/display/display.cpp create mode 100644 thirdparty/Pangolin/src/display/image_view.cpp create mode 100644 thirdparty/Pangolin/src/display/opengl_render_state.cpp create mode 100644 thirdparty/Pangolin/src/display/view.cpp create mode 100644 thirdparty/Pangolin/src/display/viewport.cpp create mode 100644 thirdparty/Pangolin/src/display/widgets/widgets.cpp create mode 100644 thirdparty/Pangolin/src/display/window_factory.cpp create mode 100644 thirdparty/Pangolin/src/geometry/geometry.cpp create mode 100644 thirdparty/Pangolin/src/geometry/geometry_obj.cpp create mode 100644 thirdparty/Pangolin/src/geometry/geometry_ply.cpp create mode 100644 thirdparty/Pangolin/src/geometry/glgeometry.cpp create mode 100644 thirdparty/Pangolin/src/geometry/tinyobj.cpp create mode 100644 thirdparty/Pangolin/src/gl/compat/gl2engine.cpp create mode 100644 thirdparty/Pangolin/src/gl/glchar.cpp create mode 100644 thirdparty/Pangolin/src/gl/gldraw.cpp create mode 100644 thirdparty/Pangolin/src/gl/glfont.cpp create mode 100644 thirdparty/Pangolin/src/gl/glpangoglu.cpp create mode 100644 thirdparty/Pangolin/src/gl/gltext.cpp create mode 100644 thirdparty/Pangolin/src/gl/gltexturecache.cpp create mode 100644 thirdparty/Pangolin/src/gl/stb_truetype.h create mode 100644 thirdparty/Pangolin/src/handler/handler.cpp create mode 100644 thirdparty/Pangolin/src/handler/handler_glbuffer.cpp create mode 100644 thirdparty/Pangolin/src/handler/handler_image.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_exr.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_jpg.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_lz4.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_packed12bit.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_pango.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_png.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_ppm.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_raw.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_tga.cpp create mode 100644 thirdparty/Pangolin/src/image/image_io_zstd.cpp create mode 100644 thirdparty/Pangolin/src/image/pixel_format.cpp create mode 100644 thirdparty/Pangolin/src/ios/PangolinAppDelegate.mm create mode 100644 thirdparty/Pangolin/src/ios/PangolinUIView.mm create mode 100644 thirdparty/Pangolin/src/log/packet.cpp create mode 100644 thirdparty/Pangolin/src/log/packetstream.cpp create mode 100644 thirdparty/Pangolin/src/log/packetstream_reader.cpp create mode 100644 thirdparty/Pangolin/src/log/packetstream_writer.cpp create mode 100644 thirdparty/Pangolin/src/log/playback_session.cpp create mode 100644 thirdparty/Pangolin/src/plot/datalog.cpp create mode 100644 thirdparty/Pangolin/src/plot/plotter.cpp create mode 100644 thirdparty/Pangolin/src/python/pyinterpreter.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/attach.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/attach.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/colour.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/colour.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/datalog.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/datalog.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/display.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/display.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/gl_draw.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/gl_draw.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/handler.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/handler.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/image.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/image.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/image_view.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/image_view.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/opengl_render_state.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/opengl_render_state.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/params.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/params.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/pixel_format.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/pixel_format.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/plotter.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/plotter.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/pypangolin.h create mode 100644 thirdparty/Pangolin/src/python/pypangolin/var.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/var.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/video.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/video.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/view.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/view.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/viewport.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/viewport.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/widget.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/widget.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/window.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin/window.hpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin_init.cpp create mode 100644 thirdparty/Pangolin/src/python/pypangolin_module.cpp create mode 100644 thirdparty/Pangolin/src/tools/video_viewer.cpp create mode 100644 thirdparty/Pangolin/src/utils/file_extension.cpp create mode 100644 thirdparty/Pangolin/src/utils/file_utils.cpp create mode 100644 thirdparty/Pangolin/src/utils/posix/condition_variable.cpp create mode 100644 thirdparty/Pangolin/src/utils/posix/semaphore.cpp create mode 100644 thirdparty/Pangolin/src/utils/posix/shared_memory_buffer.cpp create mode 100644 thirdparty/Pangolin/src/utils/sigstate.cpp create mode 100644 thirdparty/Pangolin/src/utils/threadedfilebuf.cpp create mode 100644 thirdparty/Pangolin/src/utils/timer.cpp create mode 100644 thirdparty/Pangolin/src/utils/uri.cpp create mode 100644 thirdparty/Pangolin/src/var/input_record_repeat.cpp create mode 100644 thirdparty/Pangolin/src/var/vars.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/debayer.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/deinterlace.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/depthsense.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/ffmpeg.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/firewire.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/images.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/images_out.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/join.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/json.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/merge.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/mirror.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/openni.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/openni2.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/pack.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/pango.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/pango_video_output.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/pleora.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/pvn.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/realsense.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/realsense2.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/shared_memory.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/shift.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/split.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/teli.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/test.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/thread.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/truncate.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/unpack.cpp create mode 100755 thirdparty/Pangolin/src/video/drivers/uvc.cpp create mode 100644 thirdparty/Pangolin/src/video/drivers/uvc_mediafoundation.cpp create mode 100755 thirdparty/Pangolin/src/video/drivers/v4l.cpp create mode 100644 thirdparty/Pangolin/src/video/stream_encoder_factory.cpp create mode 100644 thirdparty/Pangolin/src/video/video.cpp create mode 100644 thirdparty/Pangolin/src/video/video_input.cpp create mode 100644 thirdparty/Pangolin/src/video/video_interface_factory.cpp create mode 100644 thirdparty/Pangolin/src/video/video_output.cpp create mode 100644 thirdparty/Pangolin/src/video/video_output_interface_factory.cpp create mode 100644 thirdparty/Pangolin/test/CMakeLists.txt create mode 100644 thirdparty/Pangolin/test/log/CMakeLists.txt create mode 100644 thirdparty/Pangolin/test/log/testlog.cpp create mode 100644 thirdparty/Pangolin/tools/CMakeLists.txt create mode 100644 thirdparty/Pangolin/tools/ModelViewer/CMakeLists.txt create mode 100644 thirdparty/Pangolin/tools/ModelViewer/main.cpp create mode 100644 thirdparty/Pangolin/tools/ModelViewer/rendertree.h create mode 100644 thirdparty/Pangolin/tools/ModelViewer/shader.h create mode 100644 thirdparty/Pangolin/tools/ModelViewer/util.h create mode 100644 thirdparty/Pangolin/tools/Plotter/CMakeLists.txt create mode 100644 thirdparty/Pangolin/tools/Plotter/application-x-pangoplot.xml create mode 100644 thirdparty/Pangolin/tools/Plotter/csv_data_loader.h create mode 100644 thirdparty/Pangolin/tools/Plotter/main.cpp create mode 100644 thirdparty/Pangolin/tools/VideoConvert/CMakeLists.txt create mode 100644 thirdparty/Pangolin/tools/VideoConvert/main.cpp create mode 100644 thirdparty/Pangolin/tools/VideoJson/CMakeLists.txt create mode 100644 thirdparty/Pangolin/tools/VideoJson/main-print.cpp create mode 100644 thirdparty/Pangolin/tools/VideoJson/main-transform.cpp create mode 100644 thirdparty/Pangolin/tools/VideoViewer/CMakeLists.txt create mode 100644 thirdparty/Pangolin/tools/VideoViewer/application-x-pango.svg create mode 100644 thirdparty/Pangolin/tools/VideoViewer/application-x-pango.xml create mode 100644 thirdparty/Pangolin/tools/VideoViewer/main.cpp create mode 100644 thirdparty/abseil-cpp/.clang-format create mode 100644 thirdparty/abseil-cpp/.gitignore create mode 100644 thirdparty/abseil-cpp/ABSEIL_ISSUE_TEMPLATE.md create mode 100644 thirdparty/abseil-cpp/AUTHORS create mode 100644 thirdparty/abseil-cpp/CMake/AbseilHelpers.cmake create mode 100644 thirdparty/abseil-cpp/CMake/CMakeLists.txt.in create mode 100644 thirdparty/abseil-cpp/CMake/DownloadGTest.cmake create mode 100644 thirdparty/abseil-cpp/CMake/README.md create mode 100644 thirdparty/abseil-cpp/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/CONTRIBUTING.md create mode 100644 thirdparty/abseil-cpp/LICENSE create mode 100644 thirdparty/abseil-cpp/LTS.md create mode 100644 thirdparty/abseil-cpp/README.md create mode 100644 thirdparty/abseil-cpp/WORKSPACE create mode 100644 thirdparty/abseil-cpp/absl/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/algorithm/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/algorithm/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/algorithm/algorithm.h create mode 100644 thirdparty/abseil-cpp/absl/algorithm/algorithm_test.cc create mode 100644 thirdparty/abseil-cpp/absl/algorithm/container.h create mode 100644 thirdparty/abseil-cpp/absl/algorithm/container_test.cc create mode 100644 thirdparty/abseil-cpp/absl/algorithm/equal_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/base/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/base/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/base/attributes.h create mode 100644 thirdparty/abseil-cpp/absl/base/bit_cast_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/call_once.h create mode 100644 thirdparty/abseil-cpp/absl/base/call_once_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/casts.h create mode 100644 thirdparty/abseil-cpp/absl/base/config.h create mode 100644 thirdparty/abseil-cpp/absl/base/config_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/dynamic_annotations.cc create mode 100644 thirdparty/abseil-cpp/absl/base/dynamic_annotations.h create mode 100644 thirdparty/abseil-cpp/absl/base/exception_safety_testing_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/inline_variable_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/inline_variable_test_a.cc create mode 100644 thirdparty/abseil-cpp/absl/base/inline_variable_test_b.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/atomic_hook.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/atomic_hook_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/bits.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/bits_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/cycleclock.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/cycleclock.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/direct_mmap.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/endian.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/endian_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/exception_safety_testing.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/exception_safety_testing.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/exception_testing.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/hide_ptr.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/identity.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/inline_variable.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/inline_variable_testing.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/invoke.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/low_level_alloc.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/low_level_alloc.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/low_level_alloc_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/low_level_scheduling.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/per_thread_tls.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/pretty_function.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/raw_logging.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/raw_logging.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/scheduling_mode.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock_akaros.inc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock_linux.inc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock_posix.inc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock_wait.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock_wait.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/spinlock_win32.inc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/sysinfo.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/sysinfo.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/sysinfo_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/thread_identity.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/thread_identity.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/thread_identity_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/throw_delegate.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/throw_delegate.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/tsan_mutex_interface.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/unaligned_access.h create mode 100644 thirdparty/abseil-cpp/absl/base/internal/unscaledcycleclock.cc create mode 100644 thirdparty/abseil-cpp/absl/base/internal/unscaledcycleclock.h create mode 100644 thirdparty/abseil-cpp/absl/base/invoke_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/log_severity.h create mode 100644 thirdparty/abseil-cpp/absl/base/macros.h create mode 100644 thirdparty/abseil-cpp/absl/base/optimization.h create mode 100644 thirdparty/abseil-cpp/absl/base/policy_checks.h create mode 100644 thirdparty/abseil-cpp/absl/base/port.h create mode 100644 thirdparty/abseil-cpp/absl/base/raw_logging_test.cc create mode 100644 thirdparty/abseil-cpp/absl/base/spinlock_test_common.cc create mode 100644 thirdparty/abseil-cpp/absl/base/thread_annotations.h create mode 100644 thirdparty/abseil-cpp/absl/base/throw_delegate_test.cc create mode 100644 thirdparty/abseil-cpp/absl/compiler_config_setting.bzl create mode 100644 thirdparty/abseil-cpp/absl/container/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/container/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/container/fixed_array.h create mode 100644 thirdparty/abseil-cpp/absl/container/fixed_array_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/fixed_array_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/flat_hash_map.h create mode 100644 thirdparty/abseil-cpp/absl/container/flat_hash_map_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/flat_hash_set.h create mode 100644 thirdparty/abseil-cpp/absl/container/flat_hash_set_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/inlined_vector.h create mode 100644 thirdparty/abseil-cpp/absl/container/inlined_vector_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/container/inlined_vector_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/compressed_tuple.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/compressed_tuple_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/container_memory.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/container_memory_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_function_defaults.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_generator_testing.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_generator_testing.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_policy_testing.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_policy_traits.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hashtable_debug.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/layout.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/layout_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/node_hash_policy.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/node_hash_policy_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/raw_hash_map.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/raw_hash_set.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/raw_hash_set.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/raw_hash_set_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/test_instance_tracker.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/test_instance_tracker.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/tracked.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_map_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h create mode 100644 thirdparty/abseil-cpp/absl/container/internal/unordered_set_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/node_hash_map.h create mode 100644 thirdparty/abseil-cpp/absl/container/node_hash_map_test.cc create mode 100644 thirdparty/abseil-cpp/absl/container/node_hash_set.h create mode 100644 thirdparty/abseil-cpp/absl/container/node_hash_set_test.cc create mode 100644 thirdparty/abseil-cpp/absl/copts.bzl create mode 100644 thirdparty/abseil-cpp/absl/debugging/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/debugging/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/debugging/failure_signal_handler.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/failure_signal_handler.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/failure_signal_handler_test.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/address_is_readable.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/address_is_readable.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/demangle.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/demangle.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/demangle_test.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/elf_mem_image.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/elf_mem_image.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/examine_stack.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/examine_stack.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stack_consumption.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stack_consumption.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_config.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/symbolize.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/vdso_support.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/internal/vdso_support.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/leak_check.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/leak_check.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/leak_check_disable.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/leak_check_fail_test.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/leak_check_test.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/stacktrace.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/stacktrace.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/symbolize.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/symbolize.h create mode 100644 thirdparty/abseil-cpp/absl/debugging/symbolize_elf.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/symbolize_test.cc create mode 100644 thirdparty/abseil-cpp/absl/debugging/symbolize_unimplemented.inc create mode 100644 thirdparty/abseil-cpp/absl/debugging/symbolize_win32.inc create mode 100644 thirdparty/abseil-cpp/absl/hash/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/hash/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/hash/hash.h create mode 100644 thirdparty/abseil-cpp/absl/hash/hash_test.cc create mode 100644 thirdparty/abseil-cpp/absl/hash/hash_testing.h create mode 100644 thirdparty/abseil-cpp/absl/hash/internal/city.cc create mode 100644 thirdparty/abseil-cpp/absl/hash/internal/city.h create mode 100644 thirdparty/abseil-cpp/absl/hash/internal/city_test.cc create mode 100644 thirdparty/abseil-cpp/absl/hash/internal/hash.cc create mode 100644 thirdparty/abseil-cpp/absl/hash/internal/hash.h create mode 100644 thirdparty/abseil-cpp/absl/hash/internal/print_hash_of.cc create mode 100644 thirdparty/abseil-cpp/absl/hash/internal/spy_hash_state.h create mode 100644 thirdparty/abseil-cpp/absl/memory/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/memory/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/memory/memory.h create mode 100644 thirdparty/abseil-cpp/absl/memory/memory_exception_safety_test.cc create mode 100644 thirdparty/abseil-cpp/absl/memory/memory_test.cc create mode 100644 thirdparty/abseil-cpp/absl/meta/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/meta/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/meta/type_traits.h create mode 100644 thirdparty/abseil-cpp/absl/meta/type_traits_test.cc create mode 100644 thirdparty/abseil-cpp/absl/numeric/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/numeric/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/numeric/int128.cc create mode 100644 thirdparty/abseil-cpp/absl/numeric/int128.h create mode 100644 thirdparty/abseil-cpp/absl/numeric/int128_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/numeric/int128_have_intrinsic.inc create mode 100644 thirdparty/abseil-cpp/absl/numeric/int128_no_intrinsic.inc create mode 100644 thirdparty/abseil-cpp/absl/numeric/int128_stream_test.cc create mode 100644 thirdparty/abseil-cpp/absl/numeric/int128_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/strings/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/strings/ascii.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/ascii.h create mode 100644 thirdparty/abseil-cpp/absl/strings/ascii_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/ascii_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/charconv.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/charconv.h create mode 100644 thirdparty/abseil-cpp/absl/strings/charconv_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/charconv_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/escaping.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/escaping.h create mode 100644 thirdparty/abseil-cpp/absl/strings/escaping_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/escaping_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/char_map.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/char_map_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/char_map_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/charconv_bigint.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/charconv_bigint.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/charconv_parse.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/charconv_parse.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/charconv_parse_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/escaping_test_common.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/memutil.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/memutil.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/memutil_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/memutil_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/numbers_test_common.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/ostringstream.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/ostringstream.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/ostringstream_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/resize_uninitialized.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/stl_type_traits.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/arg.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/arg.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/arg_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/bind.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/bind.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/bind_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/checker.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/checker_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/convert_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/extension.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/extension.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/extension_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/float_conversion.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/output.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/output.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/output_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/parser.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/parser.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_format/parser_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_join_internal.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/str_split_internal.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/utf8.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/utf8.h create mode 100644 thirdparty/abseil-cpp/absl/strings/internal/utf8_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/match.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/match.h create mode 100644 thirdparty/abseil-cpp/absl/strings/match_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/numbers.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/numbers.h create mode 100644 thirdparty/abseil-cpp/absl/strings/numbers_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/numbers_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_cat.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_cat.h create mode 100644 thirdparty/abseil-cpp/absl/strings/str_cat_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_cat_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_format.h create mode 100644 thirdparty/abseil-cpp/absl/strings/str_format_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_join.h create mode 100644 thirdparty/abseil-cpp/absl/strings/str_join_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_join_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_replace.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_replace.h create mode 100644 thirdparty/abseil-cpp/absl/strings/str_replace_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_replace_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_split.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_split.h create mode 100644 thirdparty/abseil-cpp/absl/strings/str_split_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/str_split_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/string_view.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/string_view.h create mode 100644 thirdparty/abseil-cpp/absl/strings/string_view_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/string_view_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/strip.h create mode 100644 thirdparty/abseil-cpp/absl/strings/strip_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/substitute.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/substitute.h create mode 100644 thirdparty/abseil-cpp/absl/strings/substitute_test.cc create mode 100644 thirdparty/abseil-cpp/absl/strings/testdata/getline-1.txt create mode 100644 thirdparty/abseil-cpp/absl/strings/testdata/getline-2.txt create mode 100644 thirdparty/abseil-cpp/absl/synchronization/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/synchronization/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/synchronization/barrier.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/barrier.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/barrier_test.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/blocking_counter.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/blocking_counter.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/blocking_counter_test.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/create_thread_identity.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/graphcycles.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/graphcycles.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/kernel_timeout.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/mutex_nonprod.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/mutex_nonprod.inc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/per_thread_sem.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/thread_pool.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/waiter.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/internal/waiter.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/lifetime_test.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/mutex.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/mutex.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/mutex_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/mutex_test.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/notification.cc create mode 100644 thirdparty/abseil-cpp/absl/synchronization/notification.h create mode 100644 thirdparty/abseil-cpp/absl/synchronization/notification_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/time/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/time/civil_time.cc create mode 100644 thirdparty/abseil-cpp/absl/time/civil_time.h create mode 100644 thirdparty/abseil-cpp/absl/time/civil_time_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/time/civil_time_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/clock.cc create mode 100644 thirdparty/abseil-cpp/absl/time/clock.h create mode 100644 thirdparty/abseil-cpp/absl/time/clock_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/time/clock_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/duration.cc create mode 100644 thirdparty/abseil-cpp/absl/time/duration_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/time/duration_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/format.cc create mode 100644 thirdparty/abseil-cpp/absl/time/format_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/time/format_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/civil_time_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/tzfile.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/README.zoneinfo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/version create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Adak create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Atka create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Belem create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Belize create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Boise create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Creston create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Denver create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Havana create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Lima create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Managua create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Merida create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/New_York create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Nome create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Panama create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Recife create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Regina create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Thule create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/North create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/South create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/West create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/CET create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Cuba create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EET create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EST create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Egypt create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Eire create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/London create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Factory create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GB create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/GMT0 create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Greenwich create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/HST create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Hongkong create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Iceland create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Iran create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Israel create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Jamaica create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Japan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Libya create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MET create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MST create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/NZ create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Navajo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/PRC create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Poland create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Portugal create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/ROC create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/ROK create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Singapore create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Turkey create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/UCT create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Central create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/UTC create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Universal create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/W-SU create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/WET create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Zulu create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/localtime create mode 100644 thirdparty/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab create mode 100644 thirdparty/abseil-cpp/absl/time/internal/get_current_time_chrono.inc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/get_current_time_posix.inc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/test_util.cc create mode 100644 thirdparty/abseil-cpp/absl/time/internal/test_util.h create mode 100644 thirdparty/abseil-cpp/absl/time/internal/zoneinfo.inc create mode 100644 thirdparty/abseil-cpp/absl/time/time.cc create mode 100644 thirdparty/abseil-cpp/absl/time/time.h create mode 100644 thirdparty/abseil-cpp/absl/time/time_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/time/time_test.cc create mode 100644 thirdparty/abseil-cpp/absl/time/time_zone_test.cc create mode 100644 thirdparty/abseil-cpp/absl/types/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/types/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/types/any.h create mode 100644 thirdparty/abseil-cpp/absl/types/any_exception_safety_test.cc create mode 100644 thirdparty/abseil-cpp/absl/types/any_test.cc create mode 100644 thirdparty/abseil-cpp/absl/types/bad_any_cast.cc create mode 100644 thirdparty/abseil-cpp/absl/types/bad_any_cast.h create mode 100644 thirdparty/abseil-cpp/absl/types/bad_optional_access.cc create mode 100644 thirdparty/abseil-cpp/absl/types/bad_optional_access.h create mode 100644 thirdparty/abseil-cpp/absl/types/bad_variant_access.cc create mode 100644 thirdparty/abseil-cpp/absl/types/bad_variant_access.h create mode 100644 thirdparty/abseil-cpp/absl/types/internal/variant.h create mode 100644 thirdparty/abseil-cpp/absl/types/optional.cc create mode 100644 thirdparty/abseil-cpp/absl/types/optional.h create mode 100644 thirdparty/abseil-cpp/absl/types/optional_exception_safety_test.cc create mode 100644 thirdparty/abseil-cpp/absl/types/optional_test.cc create mode 100644 thirdparty/abseil-cpp/absl/types/span.h create mode 100644 thirdparty/abseil-cpp/absl/types/span_test.cc create mode 100644 thirdparty/abseil-cpp/absl/types/variant.h create mode 100644 thirdparty/abseil-cpp/absl/types/variant_benchmark.cc create mode 100644 thirdparty/abseil-cpp/absl/types/variant_exception_safety_test.cc create mode 100644 thirdparty/abseil-cpp/absl/types/variant_test.cc create mode 100644 thirdparty/abseil-cpp/absl/utility/BUILD.bazel create mode 100644 thirdparty/abseil-cpp/absl/utility/CMakeLists.txt create mode 100644 thirdparty/abseil-cpp/absl/utility/utility.h create mode 100644 thirdparty/abseil-cpp/absl/utility/utility_test.cc create mode 100644 thirdparty/eigen3/.hg_archival.txt create mode 100644 thirdparty/eigen3/.hgeol create mode 100644 thirdparty/eigen3/.hgignore create mode 100644 thirdparty/eigen3/.hgtags create mode 100644 thirdparty/eigen3/CMakeLists.txt create mode 100644 thirdparty/eigen3/COPYING.BSD create mode 100644 thirdparty/eigen3/COPYING.GPL create mode 100644 thirdparty/eigen3/COPYING.LGPL create mode 100644 thirdparty/eigen3/COPYING.MINPACK create mode 100644 thirdparty/eigen3/COPYING.MPL2 create mode 100644 thirdparty/eigen3/COPYING.README create mode 100644 thirdparty/eigen3/CTestConfig.cmake create mode 100644 thirdparty/eigen3/CTestCustom.cmake.in create mode 100644 thirdparty/eigen3/Eigen/CMakeLists.txt create mode 100644 thirdparty/eigen3/Eigen/Cholesky create mode 100644 thirdparty/eigen3/Eigen/CholmodSupport create mode 100644 thirdparty/eigen3/Eigen/Core create mode 100644 thirdparty/eigen3/Eigen/Dense create mode 100644 thirdparty/eigen3/Eigen/Eigen create mode 100644 thirdparty/eigen3/Eigen/Eigenvalues create mode 100644 thirdparty/eigen3/Eigen/Geometry create mode 100644 thirdparty/eigen3/Eigen/Householder create mode 100644 thirdparty/eigen3/Eigen/IterativeLinearSolvers create mode 100644 thirdparty/eigen3/Eigen/Jacobi create mode 100644 thirdparty/eigen3/Eigen/LU create mode 100644 thirdparty/eigen3/Eigen/MetisSupport create mode 100644 thirdparty/eigen3/Eigen/OrderingMethods create mode 100644 thirdparty/eigen3/Eigen/PaStiXSupport create mode 100755 thirdparty/eigen3/Eigen/PardisoSupport create mode 100644 thirdparty/eigen3/Eigen/QR create mode 100644 thirdparty/eigen3/Eigen/QtAlignedMalloc create mode 100644 thirdparty/eigen3/Eigen/SPQRSupport create mode 100644 thirdparty/eigen3/Eigen/SVD create mode 100644 thirdparty/eigen3/Eigen/Sparse create mode 100644 thirdparty/eigen3/Eigen/SparseCholesky create mode 100644 thirdparty/eigen3/Eigen/SparseCore create mode 100644 thirdparty/eigen3/Eigen/SparseLU create mode 100644 thirdparty/eigen3/Eigen/SparseQR create mode 100644 thirdparty/eigen3/Eigen/StdDeque create mode 100644 thirdparty/eigen3/Eigen/StdList create mode 100644 thirdparty/eigen3/Eigen/StdVector create mode 100644 thirdparty/eigen3/Eigen/SuperLUSupport create mode 100644 thirdparty/eigen3/Eigen/UmfPackSupport create mode 100644 thirdparty/eigen3/Eigen/src/Cholesky/LDLT.h create mode 100644 thirdparty/eigen3/Eigen/src/Cholesky/LLT.h create mode 100644 thirdparty/eigen3/Eigen/src/Cholesky/LLT_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/CholmodSupport/CholmodSupport.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Array.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/ArrayBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/ArrayWrapper.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Assign.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/AssignEvaluator.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/Assign_MKL.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/BandMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Block.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/BooleanRedux.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CommaInitializer.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/ConditionEstimator.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CoreEvaluators.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CoreIterators.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CwiseBinaryOp.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CwiseNullaryOp.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CwiseTernaryOp.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CwiseUnaryOp.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/CwiseUnaryView.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/DenseBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/DenseCoeffsBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/DenseStorage.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Diagonal.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/DiagonalMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/DiagonalProduct.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Dot.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/EigenBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/ForceAlignedAccess.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Fuzzy.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/GeneralProduct.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/GenericPacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/GlobalFunctions.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/IO.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Inverse.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Map.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/MapBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/MathFunctions.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/MathFunctionsImpl.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Matrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/MatrixBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/NestByValue.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/NoAlias.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/NumTraits.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/PermutationMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/PlainObjectBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Product.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/ProductEvaluators.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Random.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Redux.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Ref.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Replicate.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/ReturnByValue.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Reverse.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Select.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/SelfAdjointView.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Solve.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/SolveTriangular.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/SolverBase.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/StableNorm.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Stride.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Swap.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Transpose.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Transpositions.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/TriangularMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/VectorBlock.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/VectorwiseOp.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/Visitor.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AVX/Complex.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AVX/MathFunctions.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AVX/PacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AVX/TypeCasting.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AVX512/MathFunctions.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AVX512/PacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AltiVec/Complex.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/AltiVec/MathFunctions.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/CUDA/Complex.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/CUDA/Half.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/CUDA/MathFunctions.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/CUDA/PacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/CUDA/PacketMathHalf.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/CUDA/TypeCasting.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/Default/ConjHelper.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/Default/Settings.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/NEON/Complex.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/NEON/MathFunctions.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/NEON/PacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/SSE/Complex.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/SSE/TypeCasting.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/ZVector/Complex.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/arch/ZVector/MathFunctions.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/arch/ZVector/PacketMath.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/functors/AssignmentFunctors.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/functors/BinaryFunctors.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/functors/NullaryFunctors.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/functors/StlFunctors.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/functors/TernaryFunctors.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/functors/UnaryFunctors.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/GeneralMatrixVector.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/Parallelizer.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/SelfadjointProduct.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/TriangularMatrixVector.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/products/TriangularSolverVector.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/util/BlasUtil.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/Constants.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/util/DisableStupidWarnings.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/ForwardDeclarations.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/util/MKL_support.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/Macros.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/Memory.h create mode 100755 thirdparty/eigen3/Eigen/src/Core/util/Meta.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/NonMPL2.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/StaticAssert.h create mode 100644 thirdparty/eigen3/Eigen/src/Core/util/XprHelper.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/ComplexSchur.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/EigenSolver.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/RealQZ.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/RealSchur.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/AlignedBox.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/AngleAxis.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/EulerAngles.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/Homogeneous.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/Hyperplane.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/OrthoMethods.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/ParametrizedLine.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/Quaternion.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/Rotation2D.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/RotationBase.h create mode 100755 thirdparty/eigen3/Eigen/src/Geometry/Scaling.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/Transform.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/Translation.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/Umeyama.h create mode 100644 thirdparty/eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h create mode 100644 thirdparty/eigen3/Eigen/src/Householder/BlockHouseholder.h create mode 100644 thirdparty/eigen3/Eigen/src/Householder/Householder.h create mode 100644 thirdparty/eigen3/Eigen/src/Householder/HouseholderSequence.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h create mode 100644 thirdparty/eigen3/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h create mode 100644 thirdparty/eigen3/Eigen/src/Jacobi/Jacobi.h create mode 100644 thirdparty/eigen3/Eigen/src/LU/Determinant.h create mode 100644 thirdparty/eigen3/Eigen/src/LU/FullPivLU.h create mode 100644 thirdparty/eigen3/Eigen/src/LU/InverseImpl.h create mode 100644 thirdparty/eigen3/Eigen/src/LU/PartialPivLU.h create mode 100644 thirdparty/eigen3/Eigen/src/LU/PartialPivLU_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/LU/arch/Inverse_SSE.h create mode 100644 thirdparty/eigen3/Eigen/src/MetisSupport/MetisSupport.h create mode 100644 thirdparty/eigen3/Eigen/src/OrderingMethods/Amd.h create mode 100644 thirdparty/eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h create mode 100644 thirdparty/eigen3/Eigen/src/OrderingMethods/Ordering.h create mode 100644 thirdparty/eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h create mode 100644 thirdparty/eigen3/Eigen/src/PardisoSupport/PardisoSupport.h create mode 100644 thirdparty/eigen3/Eigen/src/QR/ColPivHouseholderQR.h create mode 100644 thirdparty/eigen3/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/QR/CompleteOrthogonalDecomposition.h create mode 100644 thirdparty/eigen3/Eigen/src/QR/FullPivHouseholderQR.h create mode 100644 thirdparty/eigen3/Eigen/src/QR/HouseholderQR.h create mode 100644 thirdparty/eigen3/Eigen/src/QR/HouseholderQR_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h create mode 100644 thirdparty/eigen3/Eigen/src/SVD/BDCSVD.h create mode 100644 thirdparty/eigen3/Eigen/src/SVD/JacobiSVD.h create mode 100644 thirdparty/eigen3/Eigen/src/SVD/JacobiSVD_LAPACKE.h create mode 100644 thirdparty/eigen3/Eigen/src/SVD/SVDBase.h create mode 100644 thirdparty/eigen3/Eigen/src/SVD/UpperBidiagonalization.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/AmbiVector.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/CompressedStorage.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseAssign.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseBlock.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseColEtree.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseCompressedBase.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseDenseProduct.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseDot.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseFuzzy.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseMap.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseMatrixBase.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparsePermutation.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseProduct.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseRedux.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseRef.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseSolverBase.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseTranspose.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseTriangularView.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseUtil.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseVector.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/SparseView.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseCore/TriangularSolver.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLUImpl.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_Memory.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_Structs.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_Utils.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h create mode 100644 thirdparty/eigen3/Eigen/src/SparseQR/SparseQR.h create mode 100644 thirdparty/eigen3/Eigen/src/StlSupport/StdDeque.h create mode 100644 thirdparty/eigen3/Eigen/src/StlSupport/StdList.h create mode 100644 thirdparty/eigen3/Eigen/src/StlSupport/StdVector.h create mode 100644 thirdparty/eigen3/Eigen/src/StlSupport/details.h create mode 100644 thirdparty/eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h create mode 100644 thirdparty/eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h create mode 100644 thirdparty/eigen3/Eigen/src/misc/Image.h create mode 100644 thirdparty/eigen3/Eigen/src/misc/Kernel.h create mode 100644 thirdparty/eigen3/Eigen/src/misc/RealSvd2x2.h create mode 100644 thirdparty/eigen3/Eigen/src/misc/blas.h create mode 100644 thirdparty/eigen3/Eigen/src/misc/lapack.h create mode 100755 thirdparty/eigen3/Eigen/src/misc/lapacke.h create mode 100644 thirdparty/eigen3/Eigen/src/misc/lapacke_mangling.h create mode 100644 thirdparty/eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h create mode 100644 thirdparty/eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h create mode 100644 thirdparty/eigen3/Eigen/src/plugins/BlockMethods.h create mode 100644 thirdparty/eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h create mode 100644 thirdparty/eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h create mode 100644 thirdparty/eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h create mode 100644 thirdparty/eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h create mode 100644 thirdparty/eigen3/INSTALL create mode 100644 thirdparty/eigen3/README.md create mode 100644 thirdparty/eigen3/bench/BenchSparseUtil.h create mode 100644 thirdparty/eigen3/bench/BenchTimer.h create mode 100644 thirdparty/eigen3/bench/BenchUtil.h create mode 100644 thirdparty/eigen3/bench/README.txt create mode 100644 thirdparty/eigen3/bench/analyze-blocking-sizes.cpp create mode 100644 thirdparty/eigen3/bench/basicbench.cxxlist create mode 100644 thirdparty/eigen3/bench/basicbenchmark.cpp create mode 100644 thirdparty/eigen3/bench/basicbenchmark.h create mode 100644 thirdparty/eigen3/bench/benchBlasGemm.cpp create mode 100644 thirdparty/eigen3/bench/benchCholesky.cpp create mode 100644 thirdparty/eigen3/bench/benchEigenSolver.cpp create mode 100644 thirdparty/eigen3/bench/benchFFT.cpp create mode 100644 thirdparty/eigen3/bench/benchGeometry.cpp create mode 100644 thirdparty/eigen3/bench/benchVecAdd.cpp create mode 100644 thirdparty/eigen3/bench/bench_gemm.cpp create mode 100755 thirdparty/eigen3/bench/bench_multi_compilers.sh create mode 100644 thirdparty/eigen3/bench/bench_norm.cpp create mode 100644 thirdparty/eigen3/bench/bench_reverse.cpp create mode 100644 thirdparty/eigen3/bench/bench_sum.cpp create mode 100755 thirdparty/eigen3/bench/bench_unrolling create mode 100644 thirdparty/eigen3/bench/benchmark-blocking-sizes.cpp create mode 100644 thirdparty/eigen3/bench/benchmark.cpp create mode 100644 thirdparty/eigen3/bench/benchmarkSlice.cpp create mode 100644 thirdparty/eigen3/bench/benchmarkX.cpp create mode 100644 thirdparty/eigen3/bench/benchmarkXcwise.cpp create mode 100755 thirdparty/eigen3/bench/benchmark_suite create mode 100644 thirdparty/eigen3/bench/btl/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/COPYING create mode 100644 thirdparty/eigen3/bench/btl/README create mode 100644 thirdparty/eigen3/bench/btl/actions/action_aat_product.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_ata_product.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_atv_product.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_axpby.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_axpy.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_cholesky.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_ger.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_hessenberg.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_lu_decomp.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_lu_solve.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_matrix_matrix_product.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_matrix_matrix_product_bis.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_matrix_vector_product.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_partial_lu.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_rot.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_symv.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_syr2.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_trisolve.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_trisolve_matrix.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/action_trmm.hh create mode 100644 thirdparty/eigen3/bench/btl/actions/basic_actions.hh create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindACML.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindATLAS.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindBLAZE.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindBlitz.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindCBLAS.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindGMM.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindMKL.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindMTL4.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindOPENBLAS.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindPackageHandleStandardArgs.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/FindTvmet.cmake create mode 100644 thirdparty/eigen3/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake create mode 100644 thirdparty/eigen3/bench/btl/data/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/data/action_settings.txt create mode 100644 thirdparty/eigen3/bench/btl/data/gnuplot_common_settings.hh create mode 100755 thirdparty/eigen3/bench/btl/data/go_mean create mode 100644 thirdparty/eigen3/bench/btl/data/mean.cxx create mode 100644 thirdparty/eigen3/bench/btl/data/mk_gnuplot_script.sh create mode 100644 thirdparty/eigen3/bench/btl/data/mk_mean_script.sh create mode 100755 thirdparty/eigen3/bench/btl/data/mk_new_gnuplot.sh create mode 100644 thirdparty/eigen3/bench/btl/data/perlib_plot_settings.txt create mode 100644 thirdparty/eigen3/bench/btl/data/regularize.cxx create mode 100644 thirdparty/eigen3/bench/btl/data/smooth.cxx create mode 100755 thirdparty/eigen3/bench/btl/data/smooth_all.sh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/bench.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/bench_parameter.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/btl.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/init/init_function.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/init/init_matrix.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/init/init_vector.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/static/bench_static.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/static/intel_bench_fixed_size.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/static/static_size_generator.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/timers/STL_perf_analyzer.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/timers/STL_timer.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh create mode 100755 thirdparty/eigen3/bench/btl/generic_bench/timers/portable_timer.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/timers/x86_perf_analyzer.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/timers/x86_timer.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/utils/size_lin_log.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/utils/size_log.hh create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/utils/utilities.h create mode 100644 thirdparty/eigen3/bench/btl/generic_bench/utils/xy_file.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/BLAS/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/BLAS/blas.h create mode 100644 thirdparty/eigen3/bench/btl/libs/BLAS/blas_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/BLAS/blas_interface_impl.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/BLAS/c_interface_base.h create mode 100644 thirdparty/eigen3/bench/btl/libs/BLAS/main.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/STL/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/STL/STL_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/STL/main.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/blaze/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/blaze/blaze_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/blaze/main.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/blitz/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/blitz/blitz_LU_solve_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/blitz/blitz_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/blitz/btl_blitz.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/blitz/btl_tiny_blitz.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/blitz/tiny_blitz_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen2/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen2/eigen2_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen2/main_adv.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen2/main_linear.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen2/main_matmat.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen2/main_vecmat.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen3/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen3/eigen3_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen3/main_adv.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen3/main_linear.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen3/main_matmat.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/eigen3/main_vecmat.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/gmm/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/gmm/gmm_LU_solve_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/gmm/gmm_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/gmm/main.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/mtl4/.kdbgrc.main create mode 100644 thirdparty/eigen3/bench/btl/libs/mtl4/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/mtl4/main.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/mtl4/mtl4_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/tensors/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/tensors/main_linear.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/tensors/main_matmat.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/tensors/main_vecmat.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/tensors/tensor_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/tvmet/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/tvmet/main.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/tvmet/tvmet_interface.hh create mode 100644 thirdparty/eigen3/bench/btl/libs/ublas/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/btl/libs/ublas/main.cpp create mode 100644 thirdparty/eigen3/bench/btl/libs/ublas/ublas_interface.hh create mode 100644 thirdparty/eigen3/bench/check_cache_queries.cpp create mode 100644 thirdparty/eigen3/bench/dense_solvers.cpp create mode 100644 thirdparty/eigen3/bench/eig33.cpp create mode 100644 thirdparty/eigen3/bench/geometry.cpp create mode 100644 thirdparty/eigen3/bench/perf_monitoring/gemm/changesets.txt create mode 100644 thirdparty/eigen3/bench/perf_monitoring/gemm/gemm.cpp create mode 100644 thirdparty/eigen3/bench/perf_monitoring/gemm/gemm_settings.txt create mode 100644 thirdparty/eigen3/bench/perf_monitoring/gemm/lazy_gemm.cpp create mode 100644 thirdparty/eigen3/bench/perf_monitoring/gemm/lazy_gemm_settings.txt create mode 100755 thirdparty/eigen3/bench/perf_monitoring/gemm/make_plot.sh create mode 100755 thirdparty/eigen3/bench/perf_monitoring/gemm/run.sh create mode 100644 thirdparty/eigen3/bench/product_threshold.cpp create mode 100644 thirdparty/eigen3/bench/quat_slerp.cpp create mode 100644 thirdparty/eigen3/bench/quatmul.cpp create mode 100644 thirdparty/eigen3/bench/sparse_cholesky.cpp create mode 100644 thirdparty/eigen3/bench/sparse_dense_product.cpp create mode 100644 thirdparty/eigen3/bench/sparse_lu.cpp create mode 100644 thirdparty/eigen3/bench/sparse_product.cpp create mode 100644 thirdparty/eigen3/bench/sparse_randomsetter.cpp create mode 100644 thirdparty/eigen3/bench/sparse_setter.cpp create mode 100644 thirdparty/eigen3/bench/sparse_transpose.cpp create mode 100644 thirdparty/eigen3/bench/sparse_trisolver.cpp create mode 100644 thirdparty/eigen3/bench/spbench/CMakeLists.txt create mode 100644 thirdparty/eigen3/bench/spbench/sp_solver.cpp create mode 100644 thirdparty/eigen3/bench/spbench/spbench.dtd create mode 100644 thirdparty/eigen3/bench/spbench/spbenchsolver.cpp create mode 100644 thirdparty/eigen3/bench/spbench/spbenchsolver.h create mode 100644 thirdparty/eigen3/bench/spbench/spbenchstyle.h create mode 100644 thirdparty/eigen3/bench/spbench/test_sparseLU.cpp create mode 100644 thirdparty/eigen3/bench/spmv.cpp create mode 100644 thirdparty/eigen3/bench/tensors/README create mode 100644 thirdparty/eigen3/bench/tensors/benchmark.h create mode 100644 thirdparty/eigen3/bench/tensors/benchmark_main.cc create mode 100644 thirdparty/eigen3/bench/tensors/contraction_benchmarks_cpu.cc create mode 100644 thirdparty/eigen3/bench/tensors/tensor_benchmarks.h create mode 100644 thirdparty/eigen3/bench/tensors/tensor_benchmarks_cpu.cc create mode 100644 thirdparty/eigen3/bench/tensors/tensor_benchmarks_fp16_gpu.cu create mode 100644 thirdparty/eigen3/bench/tensors/tensor_benchmarks_gpu.cu create mode 100644 thirdparty/eigen3/bench/tensors/tensor_benchmarks_sycl.cc create mode 100644 thirdparty/eigen3/bench/vdw_new.cpp create mode 100644 thirdparty/eigen3/blas/BandTriangularSolver.h create mode 100644 thirdparty/eigen3/blas/CMakeLists.txt create mode 100644 thirdparty/eigen3/blas/GeneralRank1Update.h create mode 100644 thirdparty/eigen3/blas/PackedSelfadjointProduct.h create mode 100644 thirdparty/eigen3/blas/PackedTriangularMatrixVector.h create mode 100644 thirdparty/eigen3/blas/PackedTriangularSolverVector.h create mode 100644 thirdparty/eigen3/blas/README.txt create mode 100644 thirdparty/eigen3/blas/Rank2Update.h create mode 100644 thirdparty/eigen3/blas/common.h create mode 100644 thirdparty/eigen3/blas/complex_double.cpp create mode 100644 thirdparty/eigen3/blas/complex_single.cpp create mode 100644 thirdparty/eigen3/blas/double.cpp create mode 100644 thirdparty/eigen3/blas/f2c/chbmv.c create mode 100644 thirdparty/eigen3/blas/f2c/chpmv.c create mode 100644 thirdparty/eigen3/blas/f2c/complexdots.c create mode 100644 thirdparty/eigen3/blas/f2c/ctbmv.c create mode 100644 thirdparty/eigen3/blas/f2c/d_cnjg.c create mode 100644 thirdparty/eigen3/blas/f2c/datatypes.h create mode 100644 thirdparty/eigen3/blas/f2c/drotm.c create mode 100644 thirdparty/eigen3/blas/f2c/drotmg.c create mode 100644 thirdparty/eigen3/blas/f2c/dsbmv.c create mode 100644 thirdparty/eigen3/blas/f2c/dspmv.c create mode 100644 thirdparty/eigen3/blas/f2c/dtbmv.c create mode 100644 thirdparty/eigen3/blas/f2c/lsame.c create mode 100644 thirdparty/eigen3/blas/f2c/r_cnjg.c create mode 100644 thirdparty/eigen3/blas/f2c/srotm.c create mode 100644 thirdparty/eigen3/blas/f2c/srotmg.c create mode 100644 thirdparty/eigen3/blas/f2c/ssbmv.c create mode 100644 thirdparty/eigen3/blas/f2c/sspmv.c create mode 100644 thirdparty/eigen3/blas/f2c/stbmv.c create mode 100644 thirdparty/eigen3/blas/f2c/zhbmv.c create mode 100644 thirdparty/eigen3/blas/f2c/zhpmv.c create mode 100644 thirdparty/eigen3/blas/f2c/ztbmv.c create mode 100644 thirdparty/eigen3/blas/fortran/complexdots.f create mode 100644 thirdparty/eigen3/blas/level1_cplx_impl.h create mode 100644 thirdparty/eigen3/blas/level1_impl.h create mode 100644 thirdparty/eigen3/blas/level1_real_impl.h create mode 100644 thirdparty/eigen3/blas/level2_cplx_impl.h create mode 100644 thirdparty/eigen3/blas/level2_impl.h create mode 100644 thirdparty/eigen3/blas/level2_real_impl.h create mode 100644 thirdparty/eigen3/blas/level3_impl.h create mode 100644 thirdparty/eigen3/blas/single.cpp create mode 100644 thirdparty/eigen3/blas/testing/CMakeLists.txt create mode 100644 thirdparty/eigen3/blas/testing/cblat1.f create mode 100644 thirdparty/eigen3/blas/testing/cblat2.dat create mode 100644 thirdparty/eigen3/blas/testing/cblat2.f create mode 100644 thirdparty/eigen3/blas/testing/cblat3.dat create mode 100644 thirdparty/eigen3/blas/testing/cblat3.f create mode 100644 thirdparty/eigen3/blas/testing/dblat1.f create mode 100644 thirdparty/eigen3/blas/testing/dblat2.dat create mode 100644 thirdparty/eigen3/blas/testing/dblat2.f create mode 100644 thirdparty/eigen3/blas/testing/dblat3.dat create mode 100644 thirdparty/eigen3/blas/testing/dblat3.f create mode 100755 thirdparty/eigen3/blas/testing/runblastest.sh create mode 100644 thirdparty/eigen3/blas/testing/sblat1.f create mode 100644 thirdparty/eigen3/blas/testing/sblat2.dat create mode 100644 thirdparty/eigen3/blas/testing/sblat2.f create mode 100644 thirdparty/eigen3/blas/testing/sblat3.dat create mode 100644 thirdparty/eigen3/blas/testing/sblat3.f create mode 100644 thirdparty/eigen3/blas/testing/zblat1.f create mode 100644 thirdparty/eigen3/blas/testing/zblat2.dat create mode 100644 thirdparty/eigen3/blas/testing/zblat2.f create mode 100644 thirdparty/eigen3/blas/testing/zblat3.dat create mode 100644 thirdparty/eigen3/blas/testing/zblat3.f create mode 100644 thirdparty/eigen3/blas/xerbla.cpp create mode 100644 thirdparty/eigen3/cmake/Eigen3Config.cmake.in create mode 100644 thirdparty/eigen3/cmake/Eigen3ConfigLegacy.cmake.in create mode 100644 thirdparty/eigen3/cmake/EigenConfigureTesting.cmake create mode 100644 thirdparty/eigen3/cmake/EigenDetermineOSVersion.cmake create mode 100644 thirdparty/eigen3/cmake/EigenDetermineVSServicePack.cmake create mode 100644 thirdparty/eigen3/cmake/EigenTesting.cmake create mode 100644 thirdparty/eigen3/cmake/EigenUninstall.cmake create mode 100644 thirdparty/eigen3/cmake/FindAdolc.cmake create mode 100644 thirdparty/eigen3/cmake/FindBLAS.cmake create mode 100644 thirdparty/eigen3/cmake/FindBLASEXT.cmake create mode 100644 thirdparty/eigen3/cmake/FindCholmod.cmake create mode 100644 thirdparty/eigen3/cmake/FindComputeCpp.cmake create mode 100644 thirdparty/eigen3/cmake/FindEigen2.cmake create mode 100644 thirdparty/eigen3/cmake/FindEigen3.cmake create mode 100644 thirdparty/eigen3/cmake/FindFFTW.cmake create mode 100644 thirdparty/eigen3/cmake/FindGLEW.cmake create mode 100644 thirdparty/eigen3/cmake/FindGMP.cmake create mode 100644 thirdparty/eigen3/cmake/FindGSL.cmake create mode 100644 thirdparty/eigen3/cmake/FindGoogleHash.cmake create mode 100644 thirdparty/eigen3/cmake/FindHWLOC.cmake create mode 100644 thirdparty/eigen3/cmake/FindLAPACK.cmake create mode 100644 thirdparty/eigen3/cmake/FindMPFR.cmake create mode 100644 thirdparty/eigen3/cmake/FindMetis.cmake create mode 100644 thirdparty/eigen3/cmake/FindPTSCOTCH.cmake create mode 100644 thirdparty/eigen3/cmake/FindPastix.cmake create mode 100644 thirdparty/eigen3/cmake/FindSPQR.cmake create mode 100644 thirdparty/eigen3/cmake/FindScotch.cmake create mode 100644 thirdparty/eigen3/cmake/FindStandardMathLibrary.cmake create mode 100644 thirdparty/eigen3/cmake/FindSuperLU.cmake create mode 100644 thirdparty/eigen3/cmake/FindUmfpack.cmake create mode 100644 thirdparty/eigen3/cmake/RegexUtils.cmake create mode 100644 thirdparty/eigen3/cmake/UseEigen3.cmake create mode 100644 thirdparty/eigen3/cmake/language_support.cmake create mode 100644 thirdparty/eigen3/debug/gdb/__init__.py create mode 100644 thirdparty/eigen3/debug/gdb/printers.py create mode 100644 thirdparty/eigen3/debug/msvc/eigen.natvis create mode 100644 thirdparty/eigen3/debug/msvc/eigen_autoexp_part.dat create mode 100644 thirdparty/eigen3/demos/CMakeLists.txt create mode 100644 thirdparty/eigen3/demos/mandelbrot/CMakeLists.txt create mode 100644 thirdparty/eigen3/demos/mandelbrot/README create mode 100644 thirdparty/eigen3/demos/mandelbrot/mandelbrot.cpp create mode 100644 thirdparty/eigen3/demos/mandelbrot/mandelbrot.h create mode 100644 thirdparty/eigen3/demos/mix_eigen_and_c/README create mode 100644 thirdparty/eigen3/demos/mix_eigen_and_c/binary_library.cpp create mode 100644 thirdparty/eigen3/demos/mix_eigen_and_c/binary_library.h create mode 100644 thirdparty/eigen3/demos/mix_eigen_and_c/example.c create mode 100644 thirdparty/eigen3/demos/opengl/CMakeLists.txt create mode 100644 thirdparty/eigen3/demos/opengl/README create mode 100644 thirdparty/eigen3/demos/opengl/camera.cpp create mode 100644 thirdparty/eigen3/demos/opengl/camera.h create mode 100644 thirdparty/eigen3/demos/opengl/gpuhelper.cpp create mode 100644 thirdparty/eigen3/demos/opengl/gpuhelper.h create mode 100644 thirdparty/eigen3/demos/opengl/icosphere.cpp create mode 100644 thirdparty/eigen3/demos/opengl/icosphere.h create mode 100644 thirdparty/eigen3/demos/opengl/quaternion_demo.cpp create mode 100644 thirdparty/eigen3/demos/opengl/quaternion_demo.h create mode 100644 thirdparty/eigen3/demos/opengl/trackball.cpp create mode 100644 thirdparty/eigen3/demos/opengl/trackball.h create mode 100644 thirdparty/eigen3/doc/A05_PortingFrom2To3.dox create mode 100644 thirdparty/eigen3/doc/AsciiQuickReference.txt create mode 100644 thirdparty/eigen3/doc/B01_Experimental.dox create mode 100644 thirdparty/eigen3/doc/CMakeLists.txt create mode 100644 thirdparty/eigen3/doc/ClassHierarchy.dox create mode 100644 thirdparty/eigen3/doc/CoeffwiseMathFunctionsTable.dox create mode 100644 thirdparty/eigen3/doc/CustomizingEigen_CustomScalar.dox create mode 100644 thirdparty/eigen3/doc/CustomizingEigen_InheritingMatrix.dox create mode 100644 thirdparty/eigen3/doc/CustomizingEigen_NullaryExpr.dox create mode 100644 thirdparty/eigen3/doc/CustomizingEigen_Plugins.dox create mode 100644 thirdparty/eigen3/doc/DenseDecompositionBenchmark.dox create mode 100644 thirdparty/eigen3/doc/Doxyfile.in create mode 100644 thirdparty/eigen3/doc/Eigen_Silly_Professor_64x64.png create mode 100644 thirdparty/eigen3/doc/FixedSizeVectorizable.dox create mode 100644 thirdparty/eigen3/doc/FunctionsTakingEigenTypes.dox create mode 100644 thirdparty/eigen3/doc/HiPerformance.dox create mode 100644 thirdparty/eigen3/doc/InplaceDecomposition.dox create mode 100644 thirdparty/eigen3/doc/InsideEigenExample.dox create mode 100644 thirdparty/eigen3/doc/LeastSquares.dox create mode 100644 thirdparty/eigen3/doc/Manual.dox create mode 100644 thirdparty/eigen3/doc/MatrixfreeSolverExample.dox create mode 100644 thirdparty/eigen3/doc/NewExpressionType.dox create mode 100644 thirdparty/eigen3/doc/Overview.dox create mode 100644 thirdparty/eigen3/doc/PassingByValue.dox create mode 100644 thirdparty/eigen3/doc/Pitfalls.dox create mode 100644 thirdparty/eigen3/doc/PreprocessorDirectives.dox create mode 100644 thirdparty/eigen3/doc/QuickReference.dox create mode 100644 thirdparty/eigen3/doc/QuickStartGuide.dox create mode 100644 thirdparty/eigen3/doc/SparseLinearSystems.dox create mode 100644 thirdparty/eigen3/doc/SparseQuickReference.dox create mode 100644 thirdparty/eigen3/doc/StlContainers.dox create mode 100644 thirdparty/eigen3/doc/StorageOrders.dox create mode 100644 thirdparty/eigen3/doc/StructHavingEigenMembers.dox create mode 100644 thirdparty/eigen3/doc/TemplateKeyword.dox create mode 100644 thirdparty/eigen3/doc/TopicAliasing.dox create mode 100644 thirdparty/eigen3/doc/TopicAssertions.dox create mode 100644 thirdparty/eigen3/doc/TopicCMakeGuide.dox create mode 100644 thirdparty/eigen3/doc/TopicEigenExpressionTemplates.dox create mode 100644 thirdparty/eigen3/doc/TopicLazyEvaluation.dox create mode 100644 thirdparty/eigen3/doc/TopicLinearAlgebraDecompositions.dox create mode 100644 thirdparty/eigen3/doc/TopicMultithreading.dox create mode 100644 thirdparty/eigen3/doc/TopicResizing.dox create mode 100644 thirdparty/eigen3/doc/TopicScalarTypes.dox create mode 100644 thirdparty/eigen3/doc/TopicVectorization.dox create mode 100644 thirdparty/eigen3/doc/TutorialAdvancedInitialization.dox create mode 100644 thirdparty/eigen3/doc/TutorialArrayClass.dox create mode 100644 thirdparty/eigen3/doc/TutorialBlockOperations.dox create mode 100644 thirdparty/eigen3/doc/TutorialGeometry.dox create mode 100644 thirdparty/eigen3/doc/TutorialLinearAlgebra.dox create mode 100644 thirdparty/eigen3/doc/TutorialMapClass.dox create mode 100644 thirdparty/eigen3/doc/TutorialMatrixArithmetic.dox create mode 100644 thirdparty/eigen3/doc/TutorialMatrixClass.dox create mode 100644 thirdparty/eigen3/doc/TutorialReductionsVisitorsBroadcasting.dox create mode 100644 thirdparty/eigen3/doc/TutorialReshapeSlicing.dox create mode 100644 thirdparty/eigen3/doc/TutorialSparse.dox create mode 100644 thirdparty/eigen3/doc/TutorialSparse_example_details.dox create mode 100644 thirdparty/eigen3/doc/UnalignedArrayAssert.dox create mode 100644 thirdparty/eigen3/doc/UsingBlasLapackBackends.dox create mode 100644 thirdparty/eigen3/doc/UsingIntelMKL.dox create mode 100644 thirdparty/eigen3/doc/UsingNVCC.dox create mode 100644 thirdparty/eigen3/doc/WrongStackAlignment.dox create mode 100644 thirdparty/eigen3/doc/eigen_navtree_hacks.js create mode 100644 thirdparty/eigen3/doc/eigendoxy.css create mode 100644 thirdparty/eigen3/doc/eigendoxy_footer.html.in create mode 100644 thirdparty/eigen3/doc/eigendoxy_header.html.in create mode 100644 thirdparty/eigen3/doc/eigendoxy_layout.xml.in create mode 100644 thirdparty/eigen3/doc/eigendoxy_tabs.css create mode 100644 thirdparty/eigen3/doc/examples/.krazy create mode 100644 thirdparty/eigen3/doc/examples/CMakeLists.txt create mode 100644 thirdparty/eigen3/doc/examples/CustomizingEigen_Inheritance.cpp create mode 100644 thirdparty/eigen3/doc/examples/Cwise_erf.cpp create mode 100644 thirdparty/eigen3/doc/examples/Cwise_erfc.cpp create mode 100644 thirdparty/eigen3/doc/examples/Cwise_lgamma.cpp create mode 100644 thirdparty/eigen3/doc/examples/DenseBase_middleCols_int.cpp create mode 100644 thirdparty/eigen3/doc/examples/DenseBase_middleRows_int.cpp create mode 100644 thirdparty/eigen3/doc/examples/DenseBase_template_int_middleCols.cpp create mode 100644 thirdparty/eigen3/doc/examples/DenseBase_template_int_middleRows.cpp create mode 100644 thirdparty/eigen3/doc/examples/QuickStart_example.cpp create mode 100644 thirdparty/eigen3/doc/examples/QuickStart_example2_dynamic.cpp create mode 100644 thirdparty/eigen3/doc/examples/QuickStart_example2_fixed.cpp create mode 100644 thirdparty/eigen3/doc/examples/TemplateKeyword_flexible.cpp create mode 100644 thirdparty/eigen3/doc/examples/TemplateKeyword_simple.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialInplaceLU.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgComputeTwice.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgExComputeSolveError.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgExSolveColPivHouseholderQR.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgExSolveLDLT.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgInverseDeterminant.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgRankRevealing.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgSVDSolve.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgSelfAdjointEigenSolver.cpp create mode 100644 thirdparty/eigen3/doc/examples/TutorialLinAlgSetThreshold.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ArrayClass_accessors.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ArrayClass_addition.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ArrayClass_cwise_other.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ArrayClass_interop.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ArrayClass_mult.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_BlockOperations_block_assignment.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_BlockOperations_colrow.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_BlockOperations_corner.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_BlockOperations_print_block.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_BlockOperations_vector.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_PartialLU_solve.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_operatornorm.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_simple_example_dynamic_size.cpp create mode 100644 thirdparty/eigen3/doc/examples/Tutorial_simple_example_fixed_size.cpp create mode 100644 thirdparty/eigen3/doc/examples/class_Block.cpp create mode 100644 thirdparty/eigen3/doc/examples/class_CwiseBinaryOp.cpp create mode 100644 thirdparty/eigen3/doc/examples/class_CwiseUnaryOp.cpp create mode 100644 thirdparty/eigen3/doc/examples/class_CwiseUnaryOp_ptrfun.cpp create mode 100644 thirdparty/eigen3/doc/examples/class_FixedBlock.cpp create mode 100644 thirdparty/eigen3/doc/examples/class_FixedVectorBlock.cpp create mode 100644 thirdparty/eigen3/doc/examples/class_VectorBlock.cpp create mode 100644 thirdparty/eigen3/doc/examples/function_taking_eigenbase.cpp create mode 100644 thirdparty/eigen3/doc/examples/function_taking_ref.cpp create mode 100644 thirdparty/eigen3/doc/examples/make_circulant.cpp create mode 100644 thirdparty/eigen3/doc/examples/make_circulant.cpp.entry create mode 100644 thirdparty/eigen3/doc/examples/make_circulant.cpp.evaluator create mode 100644 thirdparty/eigen3/doc/examples/make_circulant.cpp.expression create mode 100644 thirdparty/eigen3/doc/examples/make_circulant.cpp.main create mode 100644 thirdparty/eigen3/doc/examples/make_circulant.cpp.preamble create mode 100644 thirdparty/eigen3/doc/examples/make_circulant.cpp.traits create mode 100644 thirdparty/eigen3/doc/examples/make_circulant2.cpp create mode 100644 thirdparty/eigen3/doc/examples/matrixfree_cg.cpp create mode 100644 thirdparty/eigen3/doc/examples/nullary_indexing.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_arithmetic_add_sub.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_arithmetic_dot_cross.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_arithmetic_matrix_mul.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_arithmetic_redux_basic.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_arithmetic_scalar_mul_div.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_matrix_coefficient_accessors.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_matrix_resize.cpp create mode 100644 thirdparty/eigen3/doc/examples/tut_matrix_resize_fixed_size.cpp create mode 100644 thirdparty/eigen3/doc/ftv2node.png create mode 100644 thirdparty/eigen3/doc/ftv2pnode.png create mode 100644 thirdparty/eigen3/doc/snippets/.krazy create mode 100644 thirdparty/eigen3/doc/snippets/AngleAxis_mimic_euler.cpp create mode 100644 thirdparty/eigen3/doc/snippets/BiCGSTAB_simple.cpp create mode 100644 thirdparty/eigen3/doc/snippets/BiCGSTAB_step_by_step.cpp create mode 100644 thirdparty/eigen3/doc/snippets/CMakeLists.txt create mode 100644 thirdparty/eigen3/doc/snippets/ColPivHouseholderQR_solve.cpp create mode 100644 thirdparty/eigen3/doc/snippets/ComplexEigenSolver_compute.cpp create mode 100644 thirdparty/eigen3/doc/snippets/ComplexEigenSolver_eigenvalues.cpp create mode 100644 thirdparty/eigen3/doc/snippets/ComplexEigenSolver_eigenvectors.cpp create mode 100644 thirdparty/eigen3/doc/snippets/ComplexSchur_compute.cpp create mode 100644 thirdparty/eigen3/doc/snippets/ComplexSchur_matrixT.cpp create mode 100644 thirdparty/eigen3/doc/snippets/ComplexSchur_matrixU.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_abs.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_abs2.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_acos.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_arg.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_array_power_array.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_asin.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_atan.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_boolean_and.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_boolean_not.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_boolean_or.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_boolean_xor.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_ceil.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_cos.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_cosh.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_cube.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_equal_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_exp.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_floor.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_greater.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_greater_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_inverse.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_isFinite.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_isInf.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_isNaN.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_less.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_less_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_log.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_log10.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_max.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_min.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_minus.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_minus_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_not_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_plus.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_plus_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_pow.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_product.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_quotient.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_round.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_scalar_power_array.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_sign.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_sin.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_sinh.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_slash_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_sqrt.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_square.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_tan.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_tanh.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Cwise_times_equal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/DenseBase_LinSpaced.cpp create mode 100644 thirdparty/eigen3/doc/snippets/DenseBase_LinSpacedInt.cpp create mode 100644 thirdparty/eigen3/doc/snippets/DenseBase_LinSpaced_seq.cpp create mode 100644 thirdparty/eigen3/doc/snippets/DenseBase_setLinSpaced.cpp create mode 100644 thirdparty/eigen3/doc/snippets/DirectionWise_hnormalized.cpp create mode 100644 thirdparty/eigen3/doc/snippets/DirectionWise_replicate.cpp create mode 100644 thirdparty/eigen3/doc/snippets/DirectionWise_replicate_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/EigenSolver_EigenSolver_MatrixType.cpp create mode 100644 thirdparty/eigen3/doc/snippets/EigenSolver_compute.cpp create mode 100644 thirdparty/eigen3/doc/snippets/EigenSolver_eigenvalues.cpp create mode 100644 thirdparty/eigen3/doc/snippets/EigenSolver_eigenvectors.cpp create mode 100644 thirdparty/eigen3/doc/snippets/EigenSolver_pseudoEigenvectors.cpp create mode 100644 thirdparty/eigen3/doc/snippets/FullPivHouseholderQR_solve.cpp create mode 100644 thirdparty/eigen3/doc/snippets/FullPivLU_image.cpp create mode 100644 thirdparty/eigen3/doc/snippets/FullPivLU_kernel.cpp create mode 100644 thirdparty/eigen3/doc/snippets/FullPivLU_solve.cpp create mode 100644 thirdparty/eigen3/doc/snippets/GeneralizedEigenSolver.cpp create mode 100644 thirdparty/eigen3/doc/snippets/HessenbergDecomposition_compute.cpp create mode 100644 thirdparty/eigen3/doc/snippets/HessenbergDecomposition_matrixH.cpp create mode 100644 thirdparty/eigen3/doc/snippets/HessenbergDecomposition_packedMatrix.cpp create mode 100644 thirdparty/eigen3/doc/snippets/HouseholderQR_householderQ.cpp create mode 100644 thirdparty/eigen3/doc/snippets/HouseholderQR_solve.cpp create mode 100644 thirdparty/eigen3/doc/snippets/HouseholderSequence_HouseholderSequence.cpp create mode 100644 thirdparty/eigen3/doc/snippets/IOFormat.cpp create mode 100644 thirdparty/eigen3/doc/snippets/JacobiSVD_basic.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Jacobi_makeGivens.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Jacobi_makeJacobi.cpp create mode 100644 thirdparty/eigen3/doc/snippets/LLT_example.cpp create mode 100644 thirdparty/eigen3/doc/snippets/LLT_solve.cpp create mode 100644 thirdparty/eigen3/doc/snippets/LeastSquaresNormalEquations.cpp create mode 100644 thirdparty/eigen3/doc/snippets/LeastSquaresQR.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Map_general_stride.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Map_inner_stride.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Map_outer_stride.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Map_placement_new.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Map_simple.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_adjoint.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_all.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_applyOnTheLeft.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_applyOnTheRight.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_array.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_array_const.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_asDiagonal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_block_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_block_int_int_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_bottomLeftCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_bottomRightCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_bottomRows_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cast.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_col.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_colwise.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_computeInverseAndDetWithCheck.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_computeInverseWithCheck.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseAbs.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseAbs2.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseEqual.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseInverse.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseMax.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseMin.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseNotEqual.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseProduct.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseQuotient.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseSign.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_cwiseSqrt.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_diagonal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_diagonal_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_diagonal_template_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_eigenvalues.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_end_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_eval.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_fixedBlock_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_hnormalized.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_homogeneous.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_identity.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_identity_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_inverse.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_isDiagonal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_isIdentity.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_isOnes.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_isOrthogonal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_isUnitary.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_isZero.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_leftCols_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_noalias.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_ones.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_ones_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_ones_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_operatorNorm.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_prod.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_random.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_random_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_random_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_replicate.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_replicate_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_reverse.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_rightCols_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_row.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_rowwise.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_segment_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_select.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_selfadjointView.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_set.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_setIdentity.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_setOnes.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_setRandom.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_setZero.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_start_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_bottomRows.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_end.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_leftCols.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_rightCols.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_segment.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_start.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_template_int_topRows.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_topLeftCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_topRightCorner_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_topRows_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_transpose.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_triangularView.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_zero.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_zero_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/MatrixBase_zero_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_Map_stride.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_resize_NoChange_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_resize_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_resize_int_NoChange.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_resize_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setConstant_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setConstant_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setIdentity_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setOnes_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setOnes_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setRandom_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setRandom_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setZero_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Matrix_setZero_int_int.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialPivLU_solve.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialRedux_count.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialRedux_maxCoeff.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialRedux_minCoeff.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialRedux_norm.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialRedux_prod.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialRedux_squaredNorm.cpp create mode 100644 thirdparty/eigen3/doc/snippets/PartialRedux_sum.cpp create mode 100644 thirdparty/eigen3/doc/snippets/RealQZ_compute.cpp create mode 100644 thirdparty/eigen3/doc/snippets/RealSchur_RealSchur_MatrixType.cpp create mode 100644 thirdparty/eigen3/doc/snippets/RealSchur_compute.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType2.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvalues.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvectors.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_operatorInverseSqrt.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointEigenSolver_operatorSqrt.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointView_eigenvalues.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SelfAdjointView_operatorNorm.cpp create mode 100644 thirdparty/eigen3/doc/snippets/SparseMatrix_coeffs.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_block.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_block_correct.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_cwise.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_mult1.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_mult2.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_mult3.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_mult4.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicAliasing_mult5.cpp create mode 100644 thirdparty/eigen3/doc/snippets/TopicStorageOrders_example.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Triangular_solve.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tridiagonalization_Tridiagonalization_MatrixType.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tridiagonalization_compute.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tridiagonalization_decomposeInPlace.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tridiagonalization_diagonal.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tridiagonalization_householderCoefficients.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tridiagonalization_packedMatrix.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_AdvancedInitialization_Block.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_AdvancedInitialization_CommaTemporary.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_AdvancedInitialization_Join.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_AdvancedInitialization_LinSpaced.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_AdvancedInitialization_ThreeWays.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_AdvancedInitialization_Zero.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_Map_rowmajor.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_Map_using.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_ReshapeMat2Mat.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_ReshapeMat2Vec.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_SlicingCol.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_SlicingVec.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_commainit_01.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_commainit_01b.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_commainit_02.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_solve_matrix_inverse.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_solve_multiple_rhs.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_solve_reuse_decomposition.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_solve_singular.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_solve_triangular.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Tutorial_solve_triangular_inplace.cpp create mode 100644 thirdparty/eigen3/doc/snippets/VectorwiseOp_homogeneous.cpp create mode 100644 thirdparty/eigen3/doc/snippets/Vectorwise_reverse.cpp create mode 100644 thirdparty/eigen3/doc/snippets/class_FullPivLU.cpp create mode 100644 thirdparty/eigen3/doc/snippets/compile_snippet.cpp.in create mode 100644 thirdparty/eigen3/doc/snippets/tut_arithmetic_redux_minmax.cpp create mode 100644 thirdparty/eigen3/doc/snippets/tut_arithmetic_transpose_aliasing.cpp create mode 100644 thirdparty/eigen3/doc/snippets/tut_arithmetic_transpose_conjugate.cpp create mode 100644 thirdparty/eigen3/doc/snippets/tut_arithmetic_transpose_inplace.cpp create mode 100644 thirdparty/eigen3/doc/snippets/tut_matrix_assignment_resizing.cpp create mode 100644 thirdparty/eigen3/doc/special_examples/CMakeLists.txt create mode 100644 thirdparty/eigen3/doc/special_examples/Tutorial_sparse_example.cpp create mode 100644 thirdparty/eigen3/doc/special_examples/Tutorial_sparse_example_details.cpp create mode 100644 thirdparty/eigen3/doc/special_examples/random_cpp11.cpp create mode 100644 thirdparty/eigen3/doc/tutorial.cpp create mode 100644 thirdparty/eigen3/eigen3.pc.in create mode 100644 thirdparty/eigen3/failtest/CMakeLists.txt create mode 100644 thirdparty/eigen3/failtest/bdcsvd_int.cpp create mode 100644 thirdparty/eigen3/failtest/block_nonconst_ctor_on_const_xpr_0.cpp create mode 100644 thirdparty/eigen3/failtest/block_nonconst_ctor_on_const_xpr_1.cpp create mode 100644 thirdparty/eigen3/failtest/block_nonconst_ctor_on_const_xpr_2.cpp create mode 100644 thirdparty/eigen3/failtest/block_on_const_type_actually_const_0.cpp create mode 100644 thirdparty/eigen3/failtest/block_on_const_type_actually_const_1.cpp create mode 100644 thirdparty/eigen3/failtest/colpivqr_int.cpp create mode 100644 thirdparty/eigen3/failtest/const_qualified_block_method_retval_0.cpp create mode 100644 thirdparty/eigen3/failtest/const_qualified_block_method_retval_1.cpp create mode 100644 thirdparty/eigen3/failtest/const_qualified_diagonal_method_retval.cpp create mode 100644 thirdparty/eigen3/failtest/const_qualified_transpose_method_retval.cpp create mode 100644 thirdparty/eigen3/failtest/cwiseunaryview_nonconst_ctor_on_const_xpr.cpp create mode 100644 thirdparty/eigen3/failtest/cwiseunaryview_on_const_type_actually_const.cpp create mode 100644 thirdparty/eigen3/failtest/diagonal_nonconst_ctor_on_const_xpr.cpp create mode 100644 thirdparty/eigen3/failtest/diagonal_on_const_type_actually_const.cpp create mode 100644 thirdparty/eigen3/failtest/eigensolver_cplx.cpp create mode 100644 thirdparty/eigen3/failtest/eigensolver_int.cpp create mode 100644 thirdparty/eigen3/failtest/failtest_sanity_check.cpp create mode 100644 thirdparty/eigen3/failtest/fullpivlu_int.cpp create mode 100644 thirdparty/eigen3/failtest/fullpivqr_int.cpp create mode 100644 thirdparty/eigen3/failtest/jacobisvd_int.cpp create mode 100644 thirdparty/eigen3/failtest/ldlt_int.cpp create mode 100644 thirdparty/eigen3/failtest/llt_int.cpp create mode 100644 thirdparty/eigen3/failtest/map_nonconst_ctor_on_const_ptr_0.cpp create mode 100644 thirdparty/eigen3/failtest/map_nonconst_ctor_on_const_ptr_1.cpp create mode 100644 thirdparty/eigen3/failtest/map_nonconst_ctor_on_const_ptr_2.cpp create mode 100644 thirdparty/eigen3/failtest/map_nonconst_ctor_on_const_ptr_3.cpp create mode 100644 thirdparty/eigen3/failtest/map_nonconst_ctor_on_const_ptr_4.cpp create mode 100644 thirdparty/eigen3/failtest/map_on_const_type_actually_const_0.cpp create mode 100644 thirdparty/eigen3/failtest/map_on_const_type_actually_const_1.cpp create mode 100644 thirdparty/eigen3/failtest/partialpivlu_int.cpp create mode 100644 thirdparty/eigen3/failtest/qr_int.cpp create mode 100644 thirdparty/eigen3/failtest/ref_1.cpp create mode 100644 thirdparty/eigen3/failtest/ref_2.cpp create mode 100644 thirdparty/eigen3/failtest/ref_3.cpp create mode 100644 thirdparty/eigen3/failtest/ref_4.cpp create mode 100644 thirdparty/eigen3/failtest/ref_5.cpp create mode 100644 thirdparty/eigen3/failtest/selfadjointview_nonconst_ctor_on_const_xpr.cpp create mode 100644 thirdparty/eigen3/failtest/selfadjointview_on_const_type_actually_const.cpp create mode 100644 thirdparty/eigen3/failtest/sparse_ref_1.cpp create mode 100644 thirdparty/eigen3/failtest/sparse_ref_2.cpp create mode 100644 thirdparty/eigen3/failtest/sparse_ref_3.cpp create mode 100644 thirdparty/eigen3/failtest/sparse_ref_4.cpp create mode 100644 thirdparty/eigen3/failtest/sparse_ref_5.cpp create mode 100644 thirdparty/eigen3/failtest/sparse_storage_mismatch.cpp create mode 100644 thirdparty/eigen3/failtest/swap_1.cpp create mode 100644 thirdparty/eigen3/failtest/swap_2.cpp create mode 100644 thirdparty/eigen3/failtest/ternary_1.cpp create mode 100644 thirdparty/eigen3/failtest/ternary_2.cpp create mode 100644 thirdparty/eigen3/failtest/transpose_nonconst_ctor_on_const_xpr.cpp create mode 100644 thirdparty/eigen3/failtest/transpose_on_const_type_actually_const.cpp create mode 100644 thirdparty/eigen3/failtest/triangularview_nonconst_ctor_on_const_xpr.cpp create mode 100644 thirdparty/eigen3/failtest/triangularview_on_const_type_actually_const.cpp create mode 100644 thirdparty/eigen3/lapack/CMakeLists.txt create mode 100644 thirdparty/eigen3/lapack/cholesky.cpp create mode 100644 thirdparty/eigen3/lapack/clacgv.f create mode 100644 thirdparty/eigen3/lapack/cladiv.f create mode 100644 thirdparty/eigen3/lapack/clarf.f create mode 100644 thirdparty/eigen3/lapack/clarfb.f create mode 100644 thirdparty/eigen3/lapack/clarfg.f create mode 100644 thirdparty/eigen3/lapack/clarft.f create mode 100644 thirdparty/eigen3/lapack/complex_double.cpp create mode 100644 thirdparty/eigen3/lapack/complex_single.cpp create mode 100644 thirdparty/eigen3/lapack/dladiv.f create mode 100644 thirdparty/eigen3/lapack/dlamch.f create mode 100644 thirdparty/eigen3/lapack/dlapy2.f create mode 100644 thirdparty/eigen3/lapack/dlapy3.f create mode 100644 thirdparty/eigen3/lapack/dlarf.f create mode 100644 thirdparty/eigen3/lapack/dlarfb.f create mode 100644 thirdparty/eigen3/lapack/dlarfg.f create mode 100644 thirdparty/eigen3/lapack/dlarft.f create mode 100644 thirdparty/eigen3/lapack/double.cpp create mode 100644 thirdparty/eigen3/lapack/dsecnd_NONE.f create mode 100644 thirdparty/eigen3/lapack/eigenvalues.cpp create mode 100644 thirdparty/eigen3/lapack/ilaclc.f create mode 100644 thirdparty/eigen3/lapack/ilaclr.f create mode 100644 thirdparty/eigen3/lapack/iladlc.f create mode 100644 thirdparty/eigen3/lapack/iladlr.f create mode 100644 thirdparty/eigen3/lapack/ilaslc.f create mode 100644 thirdparty/eigen3/lapack/ilaslr.f create mode 100644 thirdparty/eigen3/lapack/ilazlc.f create mode 100644 thirdparty/eigen3/lapack/ilazlr.f create mode 100644 thirdparty/eigen3/lapack/lapack_common.h create mode 100644 thirdparty/eigen3/lapack/lu.cpp create mode 100644 thirdparty/eigen3/lapack/second_NONE.f create mode 100644 thirdparty/eigen3/lapack/single.cpp create mode 100644 thirdparty/eigen3/lapack/sladiv.f create mode 100644 thirdparty/eigen3/lapack/slamch.f create mode 100644 thirdparty/eigen3/lapack/slapy2.f create mode 100644 thirdparty/eigen3/lapack/slapy3.f create mode 100644 thirdparty/eigen3/lapack/slarf.f create mode 100644 thirdparty/eigen3/lapack/slarfb.f create mode 100644 thirdparty/eigen3/lapack/slarfg.f create mode 100644 thirdparty/eigen3/lapack/slarft.f create mode 100644 thirdparty/eigen3/lapack/svd.cpp create mode 100644 thirdparty/eigen3/lapack/zlacgv.f create mode 100644 thirdparty/eigen3/lapack/zladiv.f create mode 100644 thirdparty/eigen3/lapack/zlarf.f create mode 100644 thirdparty/eigen3/lapack/zlarfb.f create mode 100644 thirdparty/eigen3/lapack/zlarfg.f create mode 100644 thirdparty/eigen3/lapack/zlarft.f create mode 100644 thirdparty/eigen3/scripts/CMakeLists.txt create mode 100755 thirdparty/eigen3/scripts/buildtests.in create mode 100644 thirdparty/eigen3/scripts/cdashtesting.cmake.in create mode 100755 thirdparty/eigen3/scripts/check.in create mode 100755 thirdparty/eigen3/scripts/debug.in create mode 100644 thirdparty/eigen3/scripts/eigen_gen_credits.cpp create mode 100644 thirdparty/eigen3/scripts/eigen_gen_docs create mode 100755 thirdparty/eigen3/scripts/release.in create mode 100644 thirdparty/eigen3/scripts/relicense.py create mode 100644 thirdparty/eigen3/signature_of_eigen3_matrix_library create mode 100644 thirdparty/eigen3/test/CMakeLists.txt create mode 100644 thirdparty/eigen3/test/adjoint.cpp create mode 100644 thirdparty/eigen3/test/array.cpp create mode 100644 thirdparty/eigen3/test/array_for_matrix.cpp create mode 100644 thirdparty/eigen3/test/array_of_string.cpp create mode 100644 thirdparty/eigen3/test/array_replicate.cpp create mode 100644 thirdparty/eigen3/test/array_reverse.cpp create mode 100644 thirdparty/eigen3/test/bandmatrix.cpp create mode 100644 thirdparty/eigen3/test/basicstuff.cpp create mode 100644 thirdparty/eigen3/test/bdcsvd.cpp create mode 100644 thirdparty/eigen3/test/bicgstab.cpp create mode 100644 thirdparty/eigen3/test/block.cpp create mode 100644 thirdparty/eigen3/test/boostmultiprec.cpp create mode 100644 thirdparty/eigen3/test/bug1213.cpp create mode 100644 thirdparty/eigen3/test/bug1213.h create mode 100644 thirdparty/eigen3/test/bug1213_main.cpp create mode 100644 thirdparty/eigen3/test/cholesky.cpp create mode 100644 thirdparty/eigen3/test/cholmod_support.cpp create mode 100644 thirdparty/eigen3/test/commainitializer.cpp create mode 100644 thirdparty/eigen3/test/conjugate_gradient.cpp create mode 100644 thirdparty/eigen3/test/conservative_resize.cpp create mode 100644 thirdparty/eigen3/test/constructor.cpp create mode 100644 thirdparty/eigen3/test/corners.cpp create mode 100644 thirdparty/eigen3/test/ctorleak.cpp create mode 100644 thirdparty/eigen3/test/cuda_basic.cu create mode 100644 thirdparty/eigen3/test/cuda_common.h create mode 100644 thirdparty/eigen3/test/denseLM.cpp create mode 100644 thirdparty/eigen3/test/dense_storage.cpp create mode 100644 thirdparty/eigen3/test/determinant.cpp create mode 100644 thirdparty/eigen3/test/diagonal.cpp create mode 100644 thirdparty/eigen3/test/diagonalmatrices.cpp create mode 100644 thirdparty/eigen3/test/dontalign.cpp create mode 100644 thirdparty/eigen3/test/dynalloc.cpp create mode 100644 thirdparty/eigen3/test/eigen2support.cpp create mode 100644 thirdparty/eigen3/test/eigensolver_complex.cpp create mode 100644 thirdparty/eigen3/test/eigensolver_generalized_real.cpp create mode 100644 thirdparty/eigen3/test/eigensolver_generic.cpp create mode 100644 thirdparty/eigen3/test/eigensolver_selfadjoint.cpp create mode 100644 thirdparty/eigen3/test/evaluator_common.h create mode 100644 thirdparty/eigen3/test/evaluators.cpp create mode 100644 thirdparty/eigen3/test/exceptions.cpp create mode 100644 thirdparty/eigen3/test/fastmath.cpp create mode 100644 thirdparty/eigen3/test/first_aligned.cpp create mode 100644 thirdparty/eigen3/test/geo_alignedbox.cpp create mode 100644 thirdparty/eigen3/test/geo_eulerangles.cpp create mode 100644 thirdparty/eigen3/test/geo_homogeneous.cpp create mode 100644 thirdparty/eigen3/test/geo_hyperplane.cpp create mode 100644 thirdparty/eigen3/test/geo_orthomethods.cpp create mode 100644 thirdparty/eigen3/test/geo_parametrizedline.cpp create mode 100644 thirdparty/eigen3/test/geo_quaternion.cpp create mode 100755 thirdparty/eigen3/test/geo_transformations.cpp create mode 100644 thirdparty/eigen3/test/half_float.cpp create mode 100644 thirdparty/eigen3/test/hessenberg.cpp create mode 100644 thirdparty/eigen3/test/householder.cpp create mode 100644 thirdparty/eigen3/test/incomplete_cholesky.cpp create mode 100644 thirdparty/eigen3/test/inplace_decomposition.cpp create mode 100644 thirdparty/eigen3/test/integer_types.cpp create mode 100644 thirdparty/eigen3/test/inverse.cpp create mode 100644 thirdparty/eigen3/test/is_same_dense.cpp create mode 100644 thirdparty/eigen3/test/jacobi.cpp create mode 100644 thirdparty/eigen3/test/jacobisvd.cpp create mode 100644 thirdparty/eigen3/test/linearstructure.cpp create mode 100644 thirdparty/eigen3/test/lscg.cpp create mode 100644 thirdparty/eigen3/test/lu.cpp create mode 100644 thirdparty/eigen3/test/main.h create mode 100644 thirdparty/eigen3/test/mapped_matrix.cpp create mode 100644 thirdparty/eigen3/test/mapstaticmethods.cpp create mode 100644 thirdparty/eigen3/test/mapstride.cpp create mode 100644 thirdparty/eigen3/test/meta.cpp create mode 100644 thirdparty/eigen3/test/metis_support.cpp create mode 100644 thirdparty/eigen3/test/miscmatrices.cpp create mode 100644 thirdparty/eigen3/test/mixingtypes.cpp create mode 100644 thirdparty/eigen3/test/mpl2only.cpp create mode 100644 thirdparty/eigen3/test/nesting_ops.cpp create mode 100644 thirdparty/eigen3/test/nomalloc.cpp create mode 100644 thirdparty/eigen3/test/nullary.cpp create mode 100644 thirdparty/eigen3/test/numext.cpp create mode 100644 thirdparty/eigen3/test/packetmath.cpp create mode 100644 thirdparty/eigen3/test/pardiso_support.cpp create mode 100644 thirdparty/eigen3/test/pastix_support.cpp create mode 100644 thirdparty/eigen3/test/permutationmatrices.cpp create mode 100644 thirdparty/eigen3/test/prec_inverse_4x4.cpp create mode 100644 thirdparty/eigen3/test/product.h create mode 100644 thirdparty/eigen3/test/product_extra.cpp create mode 100644 thirdparty/eigen3/test/product_large.cpp create mode 100644 thirdparty/eigen3/test/product_mmtr.cpp create mode 100644 thirdparty/eigen3/test/product_notemporary.cpp create mode 100644 thirdparty/eigen3/test/product_selfadjoint.cpp create mode 100644 thirdparty/eigen3/test/product_small.cpp create mode 100644 thirdparty/eigen3/test/product_symm.cpp create mode 100644 thirdparty/eigen3/test/product_syrk.cpp create mode 100644 thirdparty/eigen3/test/product_trmm.cpp create mode 100644 thirdparty/eigen3/test/product_trmv.cpp create mode 100644 thirdparty/eigen3/test/product_trsolve.cpp create mode 100644 thirdparty/eigen3/test/qr.cpp create mode 100644 thirdparty/eigen3/test/qr_colpivoting.cpp create mode 100644 thirdparty/eigen3/test/qr_fullpivoting.cpp create mode 100644 thirdparty/eigen3/test/qtvector.cpp create mode 100644 thirdparty/eigen3/test/rand.cpp create mode 100644 thirdparty/eigen3/test/real_qz.cpp create mode 100644 thirdparty/eigen3/test/redux.cpp create mode 100644 thirdparty/eigen3/test/ref.cpp create mode 100644 thirdparty/eigen3/test/resize.cpp create mode 100644 thirdparty/eigen3/test/rvalue_types.cpp create mode 100644 thirdparty/eigen3/test/schur_complex.cpp create mode 100644 thirdparty/eigen3/test/schur_real.cpp create mode 100644 thirdparty/eigen3/test/selfadjoint.cpp create mode 100644 thirdparty/eigen3/test/simplicial_cholesky.cpp create mode 100644 thirdparty/eigen3/test/sizeof.cpp create mode 100644 thirdparty/eigen3/test/sizeoverflow.cpp create mode 100644 thirdparty/eigen3/test/smallvectors.cpp create mode 100644 thirdparty/eigen3/test/sparse.h create mode 100644 thirdparty/eigen3/test/sparseLM.cpp create mode 100644 thirdparty/eigen3/test/sparse_basic.cpp create mode 100644 thirdparty/eigen3/test/sparse_block.cpp create mode 100644 thirdparty/eigen3/test/sparse_permutations.cpp create mode 100644 thirdparty/eigen3/test/sparse_product.cpp create mode 100644 thirdparty/eigen3/test/sparse_ref.cpp create mode 100644 thirdparty/eigen3/test/sparse_solver.h create mode 100644 thirdparty/eigen3/test/sparse_solvers.cpp create mode 100644 thirdparty/eigen3/test/sparse_vector.cpp create mode 100644 thirdparty/eigen3/test/sparselu.cpp create mode 100644 thirdparty/eigen3/test/sparseqr.cpp create mode 100644 thirdparty/eigen3/test/special_numbers.cpp create mode 100644 thirdparty/eigen3/test/spqr_support.cpp create mode 100644 thirdparty/eigen3/test/stable_norm.cpp create mode 100644 thirdparty/eigen3/test/stddeque.cpp create mode 100644 thirdparty/eigen3/test/stddeque_overload.cpp create mode 100644 thirdparty/eigen3/test/stdlist.cpp create mode 100644 thirdparty/eigen3/test/stdlist_overload.cpp create mode 100644 thirdparty/eigen3/test/stdvector.cpp create mode 100644 thirdparty/eigen3/test/stdvector_overload.cpp create mode 100644 thirdparty/eigen3/test/superlu_support.cpp create mode 100644 thirdparty/eigen3/test/svd_common.h create mode 100644 thirdparty/eigen3/test/svd_fill.h create mode 100644 thirdparty/eigen3/test/swap.cpp create mode 100644 thirdparty/eigen3/test/triangular.cpp create mode 100644 thirdparty/eigen3/test/umeyama.cpp create mode 100644 thirdparty/eigen3/test/umfpack_support.cpp create mode 100644 thirdparty/eigen3/test/unalignedassert.cpp create mode 100644 thirdparty/eigen3/test/unalignedcount.cpp create mode 100644 thirdparty/eigen3/test/upperbidiagonalization.cpp create mode 100644 thirdparty/eigen3/test/vectorization_logic.cpp create mode 100644 thirdparty/eigen3/test/vectorwiseop.cpp create mode 100644 thirdparty/eigen3/test/visitor.cpp create mode 100644 thirdparty/eigen3/test/zerosized.cpp create mode 100644 thirdparty/eigen3/unsupported/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/Eigen/AdolcForward create mode 100644 thirdparty/eigen3/unsupported/Eigen/AlignedVector3 create mode 100644 thirdparty/eigen3/unsupported/Eigen/ArpackSupport create mode 100644 thirdparty/eigen3/unsupported/Eigen/AutoDiff create mode 100644 thirdparty/eigen3/unsupported/Eigen/BVH create mode 100644 thirdparty/eigen3/unsupported/Eigen/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/Tensor create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/TensorSymmetry create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/ThreadPool create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/README.md create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/Tensor.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorArgMax.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorAssign.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorCostModel.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorCustomOp.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDevice.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDimensionList.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorExpr.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGenerator.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGlobalFunctions.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorImagePatch.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInflation.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorLayoutSwap.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorPatch.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorRef.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorScan.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSycl.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclConvertToDeviceExpression.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExprConstructor.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractAccessor.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractFunctors.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclLeafCount.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclPlaceHolderExpr.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclRun.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorSyclTuple.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorVolumePatch.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/DynamicSymmetry.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/StaticSymmetry.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/Symmetry.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/EventCount.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadLocal.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadYield.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/util/CXX11Meta.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/util/CXX11Workarounds.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/util/EmulateArray.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/util/EmulateCXX11Meta.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/CXX11/src/util/MaxSizeVector.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/EulerAngles create mode 100644 thirdparty/eigen3/unsupported/Eigen/FFT create mode 100644 thirdparty/eigen3/unsupported/Eigen/IterativeSolvers create mode 100644 thirdparty/eigen3/unsupported/Eigen/KroneckerProduct create mode 100644 thirdparty/eigen3/unsupported/Eigen/LevenbergMarquardt create mode 100644 thirdparty/eigen3/unsupported/Eigen/MPRealSupport create mode 100644 thirdparty/eigen3/unsupported/Eigen/MatrixFunctions create mode 100644 thirdparty/eigen3/unsupported/Eigen/MoreVectorization create mode 100644 thirdparty/eigen3/unsupported/Eigen/NonLinearOptimization create mode 100644 thirdparty/eigen3/unsupported/Eigen/NumericalDiff create mode 100644 thirdparty/eigen3/unsupported/Eigen/OpenGLSupport create mode 100644 thirdparty/eigen3/unsupported/Eigen/Polynomials create mode 100644 thirdparty/eigen3/unsupported/Eigen/Skyline create mode 100644 thirdparty/eigen3/unsupported/Eigen/SparseExtra create mode 100644 thirdparty/eigen3/unsupported/Eigen/SpecialFunctions create mode 100644 thirdparty/eigen3/unsupported/Eigen/Splines create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h create mode 100755 thirdparty/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/BVH/BVAlgorithms.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/BVH/KdBVH.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/EulerAngles/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/EulerAngles/EulerAngles.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/EulerAngles/EulerSystem.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/IterativeSolvers/DGMRES.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/IterativeSolvers/GMRES.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/IterativeSolvers/IterationController.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/IterativeSolvers/MINRES.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/IterativeSolvers/Scaling.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/LevenbergMarquardt/CopyrightMINPACK.txt create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/MatrixFunctions/StemFunction.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/MoreVectorization/MathFunctions.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/chkder.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/covar.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/dogleg.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/lmpar.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/r1updt.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Polynomials/Companion.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Polynomials/PolynomialSolver.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Polynomials/PolynomialUtils.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Skyline/SkylineMatrix.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Skyline/SkylineProduct.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Skyline/SkylineStorage.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Skyline/SkylineUtil.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SparseExtra/MarketIO.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SparseExtra/RandomSetter.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsArrayAPI.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsFunctors.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsHalf.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/CUDA/CudaSpecialFunctions.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Splines/Spline.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Splines/SplineFitting.h create mode 100644 thirdparty/eigen3/unsupported/Eigen/src/Splines/SplineFwd.h create mode 100644 thirdparty/eigen3/unsupported/README.txt create mode 100644 thirdparty/eigen3/unsupported/bench/bench_svd.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/doc/Overview.dox create mode 100644 thirdparty/eigen3/unsupported/doc/eigendoxy_layout.xml.in create mode 100644 thirdparty/eigen3/unsupported/doc/examples/BVH_Example.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/doc/examples/EulerAngles.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/FFT.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixExponential.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixFunction.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixLogarithm.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixPower.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixPower_optimal.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixSine.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixSinh.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/MatrixSquareRoot.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/PolynomialSolver1.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/examples/PolynomialUtils1.cpp create mode 100644 thirdparty/eigen3/unsupported/doc/snippets/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/test/BVH.cpp create mode 100644 thirdparty/eigen3/unsupported/test/CMakeLists.txt create mode 100644 thirdparty/eigen3/unsupported/test/EulerAngles.cpp create mode 100644 thirdparty/eigen3/unsupported/test/FFT.cpp create mode 100644 thirdparty/eigen3/unsupported/test/FFTW.cpp create mode 100644 thirdparty/eigen3/unsupported/test/NonLinearOptimization.cpp create mode 100644 thirdparty/eigen3/unsupported/test/NumericalDiff.cpp create mode 100644 thirdparty/eigen3/unsupported/test/alignedvector3.cpp create mode 100644 thirdparty/eigen3/unsupported/test/autodiff.cpp create mode 100644 thirdparty/eigen3/unsupported/test/autodiff_scalar.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_eventcount.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_meta.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_non_blocking_thread_pool.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_runqueue.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_argmax.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_argmax_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_assign.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_broadcast_sycl.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_broadcasting.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_cast_float16_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_casts.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_chipping.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_comparisons.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_complex_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_complex_cwise_ops_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_concatenation.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_const.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_contract_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_contraction.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_convolution.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_custom_index.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_custom_op.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_device.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_device_sycl.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_dimension.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_empty.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_expr.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_fft.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_fixed_size.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_forced_eval.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_forced_eval_sycl.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_generator.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_ifft.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_image_patch.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_index_list.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_inflation.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_intdiv.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_io.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_layout_swap.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_lvalue.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_map.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_math.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_mixed_indices.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_morphing.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_notification.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_of_complex.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_of_const_values.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_of_float16_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_of_strings.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_padding.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_patch.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_random.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_random_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_reduction.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_reduction_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_reduction_sycl.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_ref.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_reverse.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_roundings.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_scan.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_scan_cuda.cu create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_shuffling.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_simple.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_striding.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_sugar.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_sycl.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_symmetry.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_thread_pool.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_uint128.cpp create mode 100644 thirdparty/eigen3/unsupported/test/cxx11_tensor_volume_patch.cpp create mode 100644 thirdparty/eigen3/unsupported/test/dgmres.cpp create mode 100644 thirdparty/eigen3/unsupported/test/forward_adolc.cpp create mode 100644 thirdparty/eigen3/unsupported/test/gmres.cpp create mode 100644 thirdparty/eigen3/unsupported/test/kronecker_product.cpp create mode 100644 thirdparty/eigen3/unsupported/test/levenberg_marquardt.cpp create mode 100644 thirdparty/eigen3/unsupported/test/matrix_exponential.cpp create mode 100644 thirdparty/eigen3/unsupported/test/matrix_function.cpp create mode 100644 thirdparty/eigen3/unsupported/test/matrix_functions.h create mode 100644 thirdparty/eigen3/unsupported/test/matrix_power.cpp create mode 100644 thirdparty/eigen3/unsupported/test/matrix_square_root.cpp create mode 100644 thirdparty/eigen3/unsupported/test/minres.cpp create mode 100644 thirdparty/eigen3/unsupported/test/mpreal/mpreal.h create mode 100644 thirdparty/eigen3/unsupported/test/mpreal_support.cpp create mode 100644 thirdparty/eigen3/unsupported/test/openglsupport.cpp create mode 100644 thirdparty/eigen3/unsupported/test/polynomialsolver.cpp create mode 100644 thirdparty/eigen3/unsupported/test/polynomialutils.cpp create mode 100644 thirdparty/eigen3/unsupported/test/sparse_extra.cpp create mode 100644 thirdparty/eigen3/unsupported/test/special_functions.cpp create mode 100644 thirdparty/eigen3/unsupported/test/splines.cpp create mode 100644 thirdparty/gflags/.gitattributes create mode 100644 thirdparty/gflags/.gitignore create mode 100644 thirdparty/gflags/.gitmodules create mode 100644 thirdparty/gflags/.travis.yml create mode 100644 thirdparty/gflags/AUTHORS.txt create mode 100644 thirdparty/gflags/BUILD create mode 100644 thirdparty/gflags/CMakeLists.txt create mode 100644 thirdparty/gflags/COPYING.txt create mode 100644 thirdparty/gflags/ChangeLog.txt create mode 100644 thirdparty/gflags/INSTALL.md create mode 100644 thirdparty/gflags/README.md create mode 100644 thirdparty/gflags/WORKSPACE create mode 100644 thirdparty/gflags/appveyor.yml create mode 100644 thirdparty/gflags/bazel/gflags.bzl create mode 100644 thirdparty/gflags/cmake/README_runtime.txt create mode 100644 thirdparty/gflags/cmake/cmake_uninstall.cmake.in create mode 100644 thirdparty/gflags/cmake/config.cmake.in create mode 100644 thirdparty/gflags/cmake/execute_test.cmake create mode 100644 thirdparty/gflags/cmake/package.cmake.in create mode 100644 thirdparty/gflags/cmake/package.pc.in create mode 100644 thirdparty/gflags/cmake/utils.cmake create mode 100644 thirdparty/gflags/cmake/version.cmake.in create mode 100644 thirdparty/gflags/src/config.h create mode 100644 thirdparty/gflags/src/defines.h.in create mode 100644 thirdparty/gflags/src/gflags.cc create mode 100644 thirdparty/gflags/src/gflags.h.in create mode 100644 thirdparty/gflags/src/gflags_completions.cc create mode 100644 thirdparty/gflags/src/gflags_completions.h.in create mode 100755 thirdparty/gflags/src/gflags_completions.sh create mode 100644 thirdparty/gflags/src/gflags_declare.h.in create mode 100644 thirdparty/gflags/src/gflags_ns.h.in create mode 100644 thirdparty/gflags/src/gflags_reporting.cc create mode 100644 thirdparty/gflags/src/mutex.h create mode 100644 thirdparty/gflags/src/util.h create mode 100644 thirdparty/gflags/src/windows_port.cc create mode 100644 thirdparty/gflags/src/windows_port.h create mode 100644 thirdparty/gflags/test/CMakeLists.txt create mode 100644 thirdparty/gflags/test/config/CMakeLists.txt create mode 100644 thirdparty/gflags/test/config/main.cc create mode 100644 thirdparty/gflags/test/flagfile.1 create mode 100644 thirdparty/gflags/test/flagfile.2 create mode 100644 thirdparty/gflags/test/flagfile.3 create mode 100644 thirdparty/gflags/test/gflags_build.py.in create mode 100755 thirdparty/gflags/test/gflags_declare_flags.cc create mode 100644 thirdparty/gflags/test/gflags_declare_test.cc create mode 100755 thirdparty/gflags/test/gflags_strip_flags_test.cc create mode 100644 thirdparty/gflags/test/gflags_strip_flags_test.cmake create mode 100755 thirdparty/gflags/test/gflags_unittest.cc create mode 100644 thirdparty/gflags/test/gflags_unittest_flagfile create mode 100644 thirdparty/gflags/test/nc/CMakeLists.txt create mode 100644 thirdparty/gflags/test/nc/gflags_nc.cc create mode 100644 thirdparty/glog/.bazelci/presubmit.yml create mode 100644 thirdparty/glog/.gitignore create mode 100644 thirdparty/glog/AUTHORS create mode 100644 thirdparty/glog/BUILD create mode 100644 thirdparty/glog/CMakeLists.txt create mode 100644 thirdparty/glog/CONTRIBUTING.md create mode 100644 thirdparty/glog/CONTRIBUTORS create mode 100644 thirdparty/glog/COPYING create mode 100644 thirdparty/glog/ChangeLog create mode 100644 thirdparty/glog/INSTALL create mode 100644 thirdparty/glog/Makefile.am create mode 100644 thirdparty/glog/README create mode 100644 thirdparty/glog/README.windows create mode 100644 thirdparty/glog/WORKSPACE create mode 100755 thirdparty/glog/autogen.sh create mode 100644 thirdparty/glog/bazel/example/BUILD create mode 100644 thirdparty/glog/bazel/example/main.cc create mode 100644 thirdparty/glog/bazel/glog.bzl create mode 100644 thirdparty/glog/cmake/INSTALL.md create mode 100644 thirdparty/glog/configure.ac create mode 100644 thirdparty/glog/doc/designstyle.css create mode 100644 thirdparty/glog/doc/glog.html create mode 100644 thirdparty/glog/glog-config.cmake.in create mode 100644 thirdparty/glog/libglog.pc.in create mode 100644 thirdparty/glog/ltmain.sh create mode 100644 thirdparty/glog/m4/ac_have_attribute.m4 create mode 100644 thirdparty/glog/m4/ac_have_builtin_expect.m4 create mode 100644 thirdparty/glog/m4/ac_have_sync_val_compare_and_swap.m4 create mode 100644 thirdparty/glog/m4/ac_rwlock.m4 create mode 100644 thirdparty/glog/m4/acx_pthread.m4 create mode 100644 thirdparty/glog/m4/google_namespace.m4 create mode 100644 thirdparty/glog/m4/libtool.m4 create mode 100644 thirdparty/glog/m4/ltoptions.m4 create mode 100644 thirdparty/glog/m4/ltsugar.m4 create mode 100644 thirdparty/glog/m4/ltversion.m4 create mode 100644 thirdparty/glog/m4/lt~obsolete.m4 create mode 100644 thirdparty/glog/m4/namespaces.m4 create mode 100644 thirdparty/glog/m4/pc_from_ucontext.m4 create mode 100644 thirdparty/glog/m4/stl_namespace.m4 create mode 100644 thirdparty/glog/m4/using_operator.m4 create mode 100755 thirdparty/glog/packages/deb.sh create mode 100644 thirdparty/glog/packages/deb/README create mode 100644 thirdparty/glog/packages/deb/changelog create mode 100644 thirdparty/glog/packages/deb/compat create mode 100644 thirdparty/glog/packages/deb/control create mode 100644 thirdparty/glog/packages/deb/copyright create mode 100644 thirdparty/glog/packages/deb/docs create mode 100644 thirdparty/glog/packages/deb/libgoogle-glog-dev.dirs create mode 100644 thirdparty/glog/packages/deb/libgoogle-glog-dev.install create mode 100644 thirdparty/glog/packages/deb/libgoogle-glog0.dirs create mode 100644 thirdparty/glog/packages/deb/libgoogle-glog0.install create mode 100755 thirdparty/glog/packages/deb/rules create mode 100755 thirdparty/glog/packages/rpm.sh create mode 100644 thirdparty/glog/packages/rpm/rpm.spec create mode 100644 thirdparty/glog/src/base/commandlineflags.h create mode 100644 thirdparty/glog/src/base/googleinit.h create mode 100644 thirdparty/glog/src/base/mutex.h create mode 100644 thirdparty/glog/src/config.h.cmake.in create mode 100644 thirdparty/glog/src/config.h.in create mode 100644 thirdparty/glog/src/config_for_unittests.h create mode 100644 thirdparty/glog/src/demangle.cc create mode 100644 thirdparty/glog/src/demangle.h create mode 100644 thirdparty/glog/src/demangle_unittest.cc create mode 100755 thirdparty/glog/src/demangle_unittest.sh create mode 100644 thirdparty/glog/src/demangle_unittest.txt create mode 100644 thirdparty/glog/src/glog/log_severity.h create mode 100644 thirdparty/glog/src/glog/logging.h.in create mode 100644 thirdparty/glog/src/glog/raw_logging.h.in create mode 100644 thirdparty/glog/src/glog/stl_logging.h.in create mode 100644 thirdparty/glog/src/glog/vlog_is_on.h.in create mode 100644 thirdparty/glog/src/googletest.h create mode 100644 thirdparty/glog/src/logging.cc create mode 100755 thirdparty/glog/src/logging_striplog_test.sh create mode 100644 thirdparty/glog/src/logging_striptest10.cc create mode 100644 thirdparty/glog/src/logging_striptest2.cc create mode 100644 thirdparty/glog/src/logging_striptest_main.cc create mode 100644 thirdparty/glog/src/logging_unittest.cc create mode 100644 thirdparty/glog/src/logging_unittest.err create mode 100644 thirdparty/glog/src/mock-log.h create mode 100644 thirdparty/glog/src/mock-log_test.cc create mode 100644 thirdparty/glog/src/raw_logging.cc create mode 100644 thirdparty/glog/src/signalhandler.cc create mode 100644 thirdparty/glog/src/signalhandler_unittest.cc create mode 100755 thirdparty/glog/src/signalhandler_unittest.sh create mode 100644 thirdparty/glog/src/stacktrace.h create mode 100644 thirdparty/glog/src/stacktrace_generic-inl.h create mode 100644 thirdparty/glog/src/stacktrace_libunwind-inl.h create mode 100644 thirdparty/glog/src/stacktrace_powerpc-inl.h create mode 100644 thirdparty/glog/src/stacktrace_unittest.cc create mode 100644 thirdparty/glog/src/stacktrace_windows-inl.h create mode 100644 thirdparty/glog/src/stacktrace_x86-inl.h create mode 100644 thirdparty/glog/src/stacktrace_x86_64-inl.h create mode 100644 thirdparty/glog/src/stl_logging_unittest.cc create mode 100644 thirdparty/glog/src/symbolize.cc create mode 100644 thirdparty/glog/src/symbolize.h create mode 100644 thirdparty/glog/src/symbolize_unittest.cc create mode 100644 thirdparty/glog/src/utilities.cc create mode 100644 thirdparty/glog/src/utilities.h create mode 100644 thirdparty/glog/src/utilities_unittest.cc create mode 100644 thirdparty/glog/src/vlog_is_on.cc create mode 100644 thirdparty/glog/src/windows/glog/log_severity.h create mode 100755 thirdparty/glog/src/windows/glog/logging.h create mode 100755 thirdparty/glog/src/windows/glog/raw_logging.h create mode 100755 thirdparty/glog/src/windows/glog/stl_logging.h create mode 100755 thirdparty/glog/src/windows/glog/vlog_is_on.h create mode 100755 thirdparty/glog/src/windows/port.cc create mode 100755 thirdparty/glog/src/windows/port.h create mode 100755 thirdparty/glog/src/windows/preprocess.sh create mode 100644 thirdparty/googletest/.clang-format create mode 100644 thirdparty/googletest/.gitignore create mode 100644 thirdparty/googletest/.travis.yml create mode 100644 thirdparty/googletest/BUILD.bazel create mode 100644 thirdparty/googletest/CMakeLists.txt create mode 100644 thirdparty/googletest/CONTRIBUTING.md create mode 100644 thirdparty/googletest/LICENSE create mode 100644 thirdparty/googletest/Makefile.am create mode 100644 thirdparty/googletest/README.md create mode 100644 thirdparty/googletest/WORKSPACE create mode 100644 thirdparty/googletest/appveyor.yml create mode 100755 thirdparty/googletest/ci/build-linux-autotools.sh create mode 100755 thirdparty/googletest/ci/build-linux-bazel.sh create mode 100755 thirdparty/googletest/ci/env-linux.sh create mode 100755 thirdparty/googletest/ci/env-osx.sh create mode 100755 thirdparty/googletest/ci/get-nprocessors.sh create mode 100755 thirdparty/googletest/ci/install-linux.sh create mode 100755 thirdparty/googletest/ci/install-osx.sh create mode 100755 thirdparty/googletest/ci/log-config.sh create mode 100755 thirdparty/googletest/ci/travis.sh create mode 100644 thirdparty/googletest/configure.ac create mode 100644 thirdparty/googletest/googlemock/CMakeLists.txt create mode 100644 thirdparty/googletest/googlemock/CONTRIBUTORS create mode 100644 thirdparty/googletest/googlemock/LICENSE create mode 100644 thirdparty/googletest/googlemock/Makefile.am create mode 100644 thirdparty/googletest/googlemock/README.md create mode 100644 thirdparty/googletest/googlemock/cmake/gmock.pc.in create mode 100644 thirdparty/googletest/googlemock/cmake/gmock_main.pc.in create mode 100644 thirdparty/googletest/googlemock/configure.ac create mode 100644 thirdparty/googletest/googlemock/docs/CheatSheet.md create mode 100644 thirdparty/googletest/googlemock/docs/CookBook.md create mode 100644 thirdparty/googletest/googlemock/docs/DesignDoc.md create mode 100644 thirdparty/googletest/googlemock/docs/Documentation.md create mode 100644 thirdparty/googletest/googlemock/docs/ForDummies.md create mode 100644 thirdparty/googletest/googlemock/docs/FrequentlyAskedQuestions.md create mode 100644 thirdparty/googletest/googlemock/docs/KnownIssues.md create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-actions.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-cardinalities.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-actions.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-actions.h.pump create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-matchers.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-matchers.h.pump create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h.pump create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-matchers.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-more-actions.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-more-matchers.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock-spec-builders.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/gmock.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/custom/README.md create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/custom/gmock-port.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h create mode 100644 thirdparty/googletest/googlemock/include/gmock/internal/gmock-port.h create mode 100644 thirdparty/googletest/googlemock/msvc/2005/gmock.sln create mode 100644 thirdparty/googletest/googlemock/msvc/2005/gmock.vcproj create mode 100644 thirdparty/googletest/googlemock/msvc/2005/gmock_config.vsprops create mode 100644 thirdparty/googletest/googlemock/msvc/2005/gmock_main.vcproj create mode 100644 thirdparty/googletest/googlemock/msvc/2005/gmock_test.vcproj create mode 100644 thirdparty/googletest/googlemock/msvc/2010/gmock.sln create mode 100644 thirdparty/googletest/googlemock/msvc/2010/gmock.vcxproj create mode 100644 thirdparty/googletest/googlemock/msvc/2010/gmock_config.props create mode 100644 thirdparty/googletest/googlemock/msvc/2010/gmock_main.vcxproj create mode 100644 thirdparty/googletest/googlemock/msvc/2010/gmock_test.vcxproj create mode 100644 thirdparty/googletest/googlemock/msvc/2015/gmock.sln create mode 100644 thirdparty/googletest/googlemock/msvc/2015/gmock.vcxproj create mode 100644 thirdparty/googletest/googlemock/msvc/2015/gmock_config.props create mode 100644 thirdparty/googletest/googlemock/msvc/2015/gmock_main.vcxproj create mode 100644 thirdparty/googletest/googlemock/msvc/2015/gmock_test.vcxproj create mode 100755 thirdparty/googletest/googlemock/scripts/fuse_gmock_files.py create mode 100644 thirdparty/googletest/googlemock/scripts/generator/LICENSE create mode 100644 thirdparty/googletest/googlemock/scripts/generator/README create mode 100644 thirdparty/googletest/googlemock/scripts/generator/README.cppclean create mode 100755 thirdparty/googletest/googlemock/scripts/generator/cpp/__init__.py create mode 100755 thirdparty/googletest/googlemock/scripts/generator/cpp/ast.py create mode 100755 thirdparty/googletest/googlemock/scripts/generator/cpp/gmock_class.py create mode 100755 thirdparty/googletest/googlemock/scripts/generator/cpp/gmock_class_test.py create mode 100755 thirdparty/googletest/googlemock/scripts/generator/cpp/keywords.py create mode 100755 thirdparty/googletest/googlemock/scripts/generator/cpp/tokenize.py create mode 100755 thirdparty/googletest/googlemock/scripts/generator/cpp/utils.py create mode 100755 thirdparty/googletest/googlemock/scripts/generator/gmock_gen.py create mode 100755 thirdparty/googletest/googlemock/scripts/gmock-config.in create mode 100755 thirdparty/googletest/googlemock/scripts/gmock_doctor.py create mode 100755 thirdparty/googletest/googlemock/scripts/upload.py create mode 100755 thirdparty/googletest/googlemock/scripts/upload_gmock.py create mode 100644 thirdparty/googletest/googlemock/src/gmock-all.cc create mode 100644 thirdparty/googletest/googlemock/src/gmock-cardinalities.cc create mode 100644 thirdparty/googletest/googlemock/src/gmock-internal-utils.cc create mode 100644 thirdparty/googletest/googlemock/src/gmock-matchers.cc create mode 100644 thirdparty/googletest/googlemock/src/gmock-spec-builders.cc create mode 100644 thirdparty/googletest/googlemock/src/gmock.cc create mode 100644 thirdparty/googletest/googlemock/src/gmock_main.cc create mode 100644 thirdparty/googletest/googlemock/test/BUILD.bazel create mode 100644 thirdparty/googletest/googlemock/test/gmock-actions_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-cardinalities_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-generated-actions_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-generated-function-mockers_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-generated-internal-utils_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-generated-matchers_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-internal-utils_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-matchers_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-more-actions_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-nice-strict_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-port_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock-spec-builders_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock_all_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock_ex_test.cc create mode 100755 thirdparty/googletest/googlemock/test/gmock_leak_test.py create mode 100644 thirdparty/googletest/googlemock/test/gmock_leak_test_.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock_link2_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock_link_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock_link_test.h create mode 100755 thirdparty/googletest/googlemock/test/gmock_output_test.py create mode 100644 thirdparty/googletest/googlemock/test/gmock_output_test_.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock_output_test_golden.txt create mode 100644 thirdparty/googletest/googlemock/test/gmock_stress_test.cc create mode 100644 thirdparty/googletest/googlemock/test/gmock_test.cc create mode 100755 thirdparty/googletest/googlemock/test/gmock_test_utils.py create mode 100644 thirdparty/googletest/googletest/CMakeLists.txt create mode 100644 thirdparty/googletest/googletest/CONTRIBUTORS create mode 100644 thirdparty/googletest/googletest/LICENSE create mode 100644 thirdparty/googletest/googletest/Makefile.am create mode 100644 thirdparty/googletest/googletest/README.md create mode 100644 thirdparty/googletest/googletest/cmake/Config.cmake.in create mode 100644 thirdparty/googletest/googletest/cmake/gtest.pc.in create mode 100644 thirdparty/googletest/googletest/cmake/gtest_main.pc.in create mode 100644 thirdparty/googletest/googletest/cmake/internal_utils.cmake create mode 100644 thirdparty/googletest/googletest/codegear/gtest.cbproj create mode 100644 thirdparty/googletest/googletest/codegear/gtest.groupproj create mode 100644 thirdparty/googletest/googletest/codegear/gtest_all.cc create mode 100644 thirdparty/googletest/googletest/codegear/gtest_link.cc create mode 100644 thirdparty/googletest/googletest/codegear/gtest_main.cbproj create mode 100644 thirdparty/googletest/googletest/codegear/gtest_unittest.cbproj create mode 100644 thirdparty/googletest/googletest/configure.ac create mode 100644 thirdparty/googletest/googletest/docs/Pkgconfig.md create mode 100644 thirdparty/googletest/googletest/docs/PumpManual.md create mode 100644 thirdparty/googletest/googletest/docs/XcodeGuide.md create mode 100644 thirdparty/googletest/googletest/docs/advanced.md create mode 100644 thirdparty/googletest/googletest/docs/faq.md create mode 100644 thirdparty/googletest/googletest/docs/primer.md create mode 100644 thirdparty/googletest/googletest/docs/samples.md create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-death-test.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-message.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-param-test.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-param-test.h.pump create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-printers.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-spi.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-test-part.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest-typed-test.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest_pred_impl.h create mode 100644 thirdparty/googletest/googletest/include/gtest/gtest_prod.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/custom/README.md create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/custom/gtest-port.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/custom/gtest-printers.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/custom/gtest.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-filepath.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-internal.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-param-util-generated.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-param-util-generated.h.pump create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-param-util.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-port-arch.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-port.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-string.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-type-util.h create mode 100644 thirdparty/googletest/googletest/include/gtest/internal/gtest-type-util.h.pump create mode 100644 thirdparty/googletest/googletest/m4/acx_pthread.m4 create mode 100644 thirdparty/googletest/googletest/m4/gtest.m4 create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest-md.sln create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest-md.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest-md.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest.sln create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_main-md.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_main-md.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_main.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_main.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_prod_test-md.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_prod_test-md.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_prod_test.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_prod_test.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_unittest-md.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_unittest-md.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_unittest.vcxproj create mode 100644 thirdparty/googletest/googletest/msvc/2010/gtest_unittest.vcxproj.filters create mode 100644 thirdparty/googletest/googletest/samples/prime_tables.h create mode 100644 thirdparty/googletest/googletest/samples/sample1.cc create mode 100644 thirdparty/googletest/googletest/samples/sample1.h create mode 100644 thirdparty/googletest/googletest/samples/sample10_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample1_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample2.cc create mode 100644 thirdparty/googletest/googletest/samples/sample2.h create mode 100644 thirdparty/googletest/googletest/samples/sample2_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample3-inl.h create mode 100644 thirdparty/googletest/googletest/samples/sample3_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample4.cc create mode 100644 thirdparty/googletest/googletest/samples/sample4.h create mode 100644 thirdparty/googletest/googletest/samples/sample4_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample5_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample6_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample7_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample8_unittest.cc create mode 100644 thirdparty/googletest/googletest/samples/sample9_unittest.cc create mode 100644 thirdparty/googletest/googletest/scripts/common.py create mode 100755 thirdparty/googletest/googletest/scripts/fuse_gtest_files.py create mode 100755 thirdparty/googletest/googletest/scripts/gen_gtest_pred_impl.py create mode 100755 thirdparty/googletest/googletest/scripts/gtest-config.in create mode 100755 thirdparty/googletest/googletest/scripts/pump.py create mode 100755 thirdparty/googletest/googletest/scripts/release_docs.py create mode 100755 thirdparty/googletest/googletest/scripts/upload.py create mode 100755 thirdparty/googletest/googletest/scripts/upload_gtest.py create mode 100644 thirdparty/googletest/googletest/src/gtest-all.cc create mode 100644 thirdparty/googletest/googletest/src/gtest-death-test.cc create mode 100644 thirdparty/googletest/googletest/src/gtest-filepath.cc create mode 100644 thirdparty/googletest/googletest/src/gtest-internal-inl.h create mode 100644 thirdparty/googletest/googletest/src/gtest-port.cc create mode 100644 thirdparty/googletest/googletest/src/gtest-printers.cc create mode 100644 thirdparty/googletest/googletest/src/gtest-test-part.cc create mode 100644 thirdparty/googletest/googletest/src/gtest-typed-test.cc create mode 100644 thirdparty/googletest/googletest/src/gtest.cc create mode 100644 thirdparty/googletest/googletest/src/gtest_main.cc create mode 100644 thirdparty/googletest/googletest/test/BUILD.bazel create mode 100755 thirdparty/googletest/googletest/test/googletest-break-on-failure-unittest.py create mode 100644 thirdparty/googletest/googletest/test/googletest-break-on-failure-unittest_.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-catch-exceptions-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-catch-exceptions-test_.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-color-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-color-test_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-death-test-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-death-test_ex_test.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-env-var-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-env-var-test_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-filepath-test.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-filter-unittest.py create mode 100644 thirdparty/googletest/googletest/test/googletest-filter-unittest_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-json-outfiles-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-json-output-unittest.py create mode 100644 thirdparty/googletest/googletest/test/googletest-linked-ptr-test.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-list-tests-unittest.py create mode 100644 thirdparty/googletest/googletest/test/googletest-list-tests-unittest_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-listener-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-message-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-options-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-output-test-golden-lin.txt create mode 100755 thirdparty/googletest/googletest/test/googletest-output-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-output-test_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-param-test-invalid-name1-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-param-test-invalid-name1-test_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-param-test-invalid-name2-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-param-test-invalid-name2-test_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-param-test-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-param-test-test.h create mode 100644 thirdparty/googletest/googletest/test/googletest-param-test2-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-port-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-printers-test.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-shuffle-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-shuffle-test_.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-test-part-test.cc create mode 100644 thirdparty/googletest/googletest/test/googletest-test2_test.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-throw-on-failure-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-throw-on-failure-test_.cc create mode 100755 thirdparty/googletest/googletest/test/googletest-uninitialized-test.py create mode 100644 thirdparty/googletest/googletest/test/googletest-uninitialized-test_.cc create mode 100644 thirdparty/googletest/googletest/test/gtest-typed-test2_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest-typed-test_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest-typed-test_test.h create mode 100644 thirdparty/googletest/googletest/test/gtest-unittest-api_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_all_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_assert_by_exception_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_environment_test.cc create mode 100755 thirdparty/googletest/googletest/test/gtest_help_test.py create mode 100644 thirdparty/googletest/googletest/test/gtest_help_test_.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_json_test_utils.py create mode 100644 thirdparty/googletest/googletest/test/gtest_list_output_unittest.py create mode 100644 thirdparty/googletest/googletest/test/gtest_list_output_unittest_.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_main_unittest.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_no_test_unittest.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_pred_impl_unittest.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_premature_exit_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_prod_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_repeat_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_skip_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_sole_header_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_stress_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_test_macro_stack_footprint_test.cc create mode 100755 thirdparty/googletest/googletest/test/gtest_test_utils.py create mode 100755 thirdparty/googletest/googletest/test/gtest_testbridge_test.py create mode 100644 thirdparty/googletest/googletest/test/gtest_testbridge_test_.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_throw_on_failure_ex_test.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_unittest.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_xml_outfile1_test_.cc create mode 100644 thirdparty/googletest/googletest/test/gtest_xml_outfile2_test_.cc create mode 100755 thirdparty/googletest/googletest/test/gtest_xml_outfiles_test.py create mode 100755 thirdparty/googletest/googletest/test/gtest_xml_output_unittest.py create mode 100644 thirdparty/googletest/googletest/test/gtest_xml_output_unittest_.cc create mode 100755 thirdparty/googletest/googletest/test/gtest_xml_test_utils.py create mode 100644 thirdparty/googletest/googletest/test/production.cc create mode 100644 thirdparty/googletest/googletest/test/production.h create mode 100644 thirdparty/googletest/googletest/xcode/Config/DebugProject.xcconfig create mode 100644 thirdparty/googletest/googletest/xcode/Config/FrameworkTarget.xcconfig create mode 100644 thirdparty/googletest/googletest/xcode/Config/General.xcconfig create mode 100644 thirdparty/googletest/googletest/xcode/Config/ReleaseProject.xcconfig create mode 100644 thirdparty/googletest/googletest/xcode/Config/StaticLibraryTarget.xcconfig create mode 100644 thirdparty/googletest/googletest/xcode/Config/TestTarget.xcconfig create mode 100644 thirdparty/googletest/googletest/xcode/Resources/Info.plist create mode 100644 thirdparty/googletest/googletest/xcode/Samples/FrameworkSample/Info.plist create mode 100644 thirdparty/googletest/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj create mode 100644 thirdparty/googletest/googletest/xcode/Samples/FrameworkSample/runtests.sh create mode 100644 thirdparty/googletest/googletest/xcode/Samples/FrameworkSample/widget.cc create mode 100644 thirdparty/googletest/googletest/xcode/Samples/FrameworkSample/widget.h create mode 100644 thirdparty/googletest/googletest/xcode/Samples/FrameworkSample/widget_test.cc create mode 100644 thirdparty/googletest/googletest/xcode/Scripts/runtests.sh create mode 100755 thirdparty/googletest/googletest/xcode/Scripts/versiongenerate.py create mode 100644 thirdparty/googletest/googletest/xcode/gtest.xcodeproj/project.pbxproj create mode 100644 thirdparty/gperftools/.gitignore create mode 100644 thirdparty/gperftools/.travis.yml create mode 100644 thirdparty/gperftools/AUTHORS create mode 100644 thirdparty/gperftools/COPYING create mode 100644 thirdparty/gperftools/ChangeLog create mode 100644 thirdparty/gperftools/ChangeLog.old create mode 100644 thirdparty/gperftools/INSTALL create mode 100755 thirdparty/gperftools/Makefile.am create mode 100644 thirdparty/gperftools/NEWS create mode 100644 thirdparty/gperftools/README create mode 100644 thirdparty/gperftools/README_windows.txt create mode 100644 thirdparty/gperftools/TODO create mode 100755 thirdparty/gperftools/autogen.sh create mode 100644 thirdparty/gperftools/benchmark/binary_trees.cc create mode 100644 thirdparty/gperftools/benchmark/malloc_bench.cc create mode 100644 thirdparty/gperftools/benchmark/run_benchmark.c create mode 100644 thirdparty/gperftools/benchmark/run_benchmark.h create mode 100644 thirdparty/gperftools/configure.ac create mode 100644 thirdparty/gperftools/docs/cpuprofile-fileformat.html create mode 100644 thirdparty/gperftools/docs/cpuprofile.html create mode 100644 thirdparty/gperftools/docs/designstyle.css create mode 100644 thirdparty/gperftools/docs/heap-example1.png create mode 100644 thirdparty/gperftools/docs/heap_checker.html create mode 100644 thirdparty/gperftools/docs/heapprofile.html create mode 100644 thirdparty/gperftools/docs/index.html create mode 100644 thirdparty/gperftools/docs/overview.dot create mode 100644 thirdparty/gperftools/docs/overview.gif create mode 100644 thirdparty/gperftools/docs/pageheap.dot create mode 100644 thirdparty/gperftools/docs/pageheap.gif create mode 100644 thirdparty/gperftools/docs/pprof-test-big.gif create mode 100644 thirdparty/gperftools/docs/pprof-test.gif create mode 100644 thirdparty/gperftools/docs/pprof-vsnprintf-big.gif create mode 100644 thirdparty/gperftools/docs/pprof-vsnprintf.gif create mode 100644 thirdparty/gperftools/docs/pprof.1 create mode 100644 thirdparty/gperftools/docs/pprof.see_also create mode 100644 thirdparty/gperftools/docs/pprof_remote_servers.html create mode 100644 thirdparty/gperftools/docs/spanmap.dot create mode 100644 thirdparty/gperftools/docs/spanmap.gif create mode 100644 thirdparty/gperftools/docs/t-test1.times.txt create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.1.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.12.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.16.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.2.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.20.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.3.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.4.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.5.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc-opspersec.vs.size.8.threads.png create mode 100644 thirdparty/gperftools/docs/tcmalloc.html create mode 100644 thirdparty/gperftools/docs/threadheap.dot create mode 100644 thirdparty/gperftools/docs/threadheap.gif create mode 100755 thirdparty/gperftools/gperftools.sln create mode 100644 thirdparty/gperftools/m4/ac_have_attribute.m4 create mode 100644 thirdparty/gperftools/m4/acx_nanosleep.m4 create mode 100644 thirdparty/gperftools/m4/acx_pthread.m4 create mode 100644 thirdparty/gperftools/m4/ax_cxx_compile_stdcxx.m4 create mode 100644 thirdparty/gperftools/m4/ax_generate_changelog.m4 create mode 100644 thirdparty/gperftools/m4/compiler_characteristics.m4 create mode 100644 thirdparty/gperftools/m4/install_prefix.m4 create mode 100644 thirdparty/gperftools/m4/namespaces.m4 create mode 100644 thirdparty/gperftools/m4/pc_from_ucontext.m4 create mode 100644 thirdparty/gperftools/m4/program_invocation_name.m4 create mode 100644 thirdparty/gperftools/m4/stl_namespace.m4 create mode 100755 thirdparty/gperftools/packages/deb.sh create mode 100644 thirdparty/gperftools/packages/deb/README create mode 100644 thirdparty/gperftools/packages/deb/changelog create mode 100644 thirdparty/gperftools/packages/deb/compat create mode 100644 thirdparty/gperftools/packages/deb/control create mode 100644 thirdparty/gperftools/packages/deb/copyright create mode 100644 thirdparty/gperftools/packages/deb/docs create mode 100644 thirdparty/gperftools/packages/deb/libgperftools-dev.dirs create mode 100644 thirdparty/gperftools/packages/deb/libgperftools-dev.install create mode 100644 thirdparty/gperftools/packages/deb/libgperftools0.dirs create mode 100644 thirdparty/gperftools/packages/deb/libgperftools0.install create mode 100644 thirdparty/gperftools/packages/deb/libgperftools0.manpages create mode 100755 thirdparty/gperftools/packages/deb/rules create mode 100755 thirdparty/gperftools/packages/rpm.sh create mode 100644 thirdparty/gperftools/packages/rpm/rpm.spec create mode 100644 thirdparty/gperftools/src/addressmap-inl.h create mode 100644 thirdparty/gperftools/src/base/arm_instruction_set_select.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-arm-generic.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-arm-v6plus.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-gcc.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-linuxppc.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-macosx.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-mips.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-windows.h create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-x86.cc create mode 100644 thirdparty/gperftools/src/base/atomicops-internals-x86.h create mode 100644 thirdparty/gperftools/src/base/atomicops.h create mode 100644 thirdparty/gperftools/src/base/basictypes.h create mode 100644 thirdparty/gperftools/src/base/commandlineflags.h create mode 100644 thirdparty/gperftools/src/base/dynamic_annotations.c create mode 100644 thirdparty/gperftools/src/base/dynamic_annotations.h create mode 100644 thirdparty/gperftools/src/base/elf_mem_image.cc create mode 100644 thirdparty/gperftools/src/base/elf_mem_image.h create mode 100644 thirdparty/gperftools/src/base/elfcore.h create mode 100644 thirdparty/gperftools/src/base/googleinit.h create mode 100644 thirdparty/gperftools/src/base/linux_syscall_support.h create mode 100644 thirdparty/gperftools/src/base/linuxthreads.cc create mode 100644 thirdparty/gperftools/src/base/linuxthreads.h create mode 100644 thirdparty/gperftools/src/base/logging.cc create mode 100644 thirdparty/gperftools/src/base/logging.h create mode 100644 thirdparty/gperftools/src/base/low_level_alloc.cc create mode 100644 thirdparty/gperftools/src/base/low_level_alloc.h create mode 100644 thirdparty/gperftools/src/base/simple_mutex.h create mode 100644 thirdparty/gperftools/src/base/spinlock.cc create mode 100644 thirdparty/gperftools/src/base/spinlock.h create mode 100644 thirdparty/gperftools/src/base/spinlock_internal.cc create mode 100644 thirdparty/gperftools/src/base/spinlock_internal.h create mode 100644 thirdparty/gperftools/src/base/spinlock_linux-inl.h create mode 100644 thirdparty/gperftools/src/base/spinlock_posix-inl.h create mode 100644 thirdparty/gperftools/src/base/spinlock_win32-inl.h create mode 100644 thirdparty/gperftools/src/base/stl_allocator.h create mode 100644 thirdparty/gperftools/src/base/sysinfo.cc create mode 100644 thirdparty/gperftools/src/base/sysinfo.h create mode 100644 thirdparty/gperftools/src/base/thread_annotations.h create mode 100644 thirdparty/gperftools/src/base/thread_lister.c create mode 100644 thirdparty/gperftools/src/base/thread_lister.h create mode 100644 thirdparty/gperftools/src/base/vdso_support.cc create mode 100644 thirdparty/gperftools/src/base/vdso_support.h create mode 100644 thirdparty/gperftools/src/central_freelist.cc create mode 100644 thirdparty/gperftools/src/central_freelist.h create mode 100644 thirdparty/gperftools/src/common.cc create mode 100644 thirdparty/gperftools/src/common.h create mode 100644 thirdparty/gperftools/src/config_for_unittests.h create mode 100644 thirdparty/gperftools/src/debugallocation.cc create mode 100644 thirdparty/gperftools/src/emergency_malloc.cc create mode 100644 thirdparty/gperftools/src/emergency_malloc.h create mode 100644 thirdparty/gperftools/src/emergency_malloc_for_stacktrace.cc create mode 100644 thirdparty/gperftools/src/fake_stacktrace_scope.cc create mode 100644 thirdparty/gperftools/src/getenv_safe.h create mode 100644 thirdparty/gperftools/src/getpc.h create mode 100644 thirdparty/gperftools/src/google/heap-checker.h create mode 100644 thirdparty/gperftools/src/google/heap-profiler.h create mode 100644 thirdparty/gperftools/src/google/malloc_extension.h create mode 100644 thirdparty/gperftools/src/google/malloc_extension_c.h create mode 100644 thirdparty/gperftools/src/google/malloc_hook.h create mode 100644 thirdparty/gperftools/src/google/malloc_hook_c.h create mode 100644 thirdparty/gperftools/src/google/profiler.h create mode 100644 thirdparty/gperftools/src/google/stacktrace.h create mode 100644 thirdparty/gperftools/src/google/tcmalloc.h create mode 100644 thirdparty/gperftools/src/gperftools/heap-checker.h create mode 100644 thirdparty/gperftools/src/gperftools/heap-profiler.h create mode 100644 thirdparty/gperftools/src/gperftools/malloc_extension.h create mode 100644 thirdparty/gperftools/src/gperftools/malloc_extension_c.h create mode 100644 thirdparty/gperftools/src/gperftools/malloc_hook.h create mode 100644 thirdparty/gperftools/src/gperftools/malloc_hook_c.h create mode 100644 thirdparty/gperftools/src/gperftools/nallocx.h create mode 100644 thirdparty/gperftools/src/gperftools/profiler.h create mode 100644 thirdparty/gperftools/src/gperftools/stacktrace.h create mode 100644 thirdparty/gperftools/src/gperftools/tcmalloc.h.in create mode 100644 thirdparty/gperftools/src/heap-checker-bcad.cc create mode 100755 thirdparty/gperftools/src/heap-checker.cc create mode 100644 thirdparty/gperftools/src/heap-profile-stats.h create mode 100644 thirdparty/gperftools/src/heap-profile-table.cc create mode 100644 thirdparty/gperftools/src/heap-profile-table.h create mode 100755 thirdparty/gperftools/src/heap-profiler.cc create mode 100644 thirdparty/gperftools/src/internal_logging.cc create mode 100644 thirdparty/gperftools/src/internal_logging.h create mode 100644 thirdparty/gperftools/src/libc_override.h create mode 100644 thirdparty/gperftools/src/libc_override_gcc_and_weak.h create mode 100644 thirdparty/gperftools/src/libc_override_glibc.h create mode 100644 thirdparty/gperftools/src/libc_override_osx.h create mode 100644 thirdparty/gperftools/src/libc_override_redefine.h create mode 100644 thirdparty/gperftools/src/linked_list.h create mode 100644 thirdparty/gperftools/src/malloc_extension.cc create mode 100644 thirdparty/gperftools/src/malloc_hook-inl.h create mode 100644 thirdparty/gperftools/src/malloc_hook.cc create mode 100644 thirdparty/gperftools/src/malloc_hook_mmap_freebsd.h create mode 100644 thirdparty/gperftools/src/malloc_hook_mmap_linux.h create mode 100644 thirdparty/gperftools/src/maybe_emergency_malloc.h create mode 100644 thirdparty/gperftools/src/maybe_threads.cc create mode 100644 thirdparty/gperftools/src/maybe_threads.h create mode 100644 thirdparty/gperftools/src/memfs_malloc.cc create mode 100644 thirdparty/gperftools/src/memory_region_map.cc create mode 100644 thirdparty/gperftools/src/memory_region_map.h create mode 100644 thirdparty/gperftools/src/packed-cache-inl.h create mode 100644 thirdparty/gperftools/src/page_heap.cc create mode 100644 thirdparty/gperftools/src/page_heap.h create mode 100644 thirdparty/gperftools/src/page_heap_allocator.h create mode 100644 thirdparty/gperftools/src/pagemap.h create mode 100755 thirdparty/gperftools/src/pprof create mode 100644 thirdparty/gperftools/src/profile-handler.cc create mode 100644 thirdparty/gperftools/src/profile-handler.h create mode 100644 thirdparty/gperftools/src/profiledata.cc create mode 100644 thirdparty/gperftools/src/profiledata.h create mode 100644 thirdparty/gperftools/src/profiler.cc create mode 100644 thirdparty/gperftools/src/raw_printer.cc create mode 100644 thirdparty/gperftools/src/raw_printer.h create mode 100644 thirdparty/gperftools/src/sampler.cc create mode 100644 thirdparty/gperftools/src/sampler.h create mode 100644 thirdparty/gperftools/src/span.cc create mode 100644 thirdparty/gperftools/src/span.h create mode 100644 thirdparty/gperftools/src/stack_trace_table.cc create mode 100644 thirdparty/gperftools/src/stack_trace_table.h create mode 100644 thirdparty/gperftools/src/stacktrace.cc create mode 100644 thirdparty/gperftools/src/stacktrace_arm-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_generic-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_impl_setup-inl.h create mode 100755 thirdparty/gperftools/src/stacktrace_instrument-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_libgcc-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_libunwind-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_powerpc-darwin-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_powerpc-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_powerpc-linux-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_win32-inl.h create mode 100644 thirdparty/gperftools/src/stacktrace_x86-inl.h create mode 100644 thirdparty/gperftools/src/static_vars.cc create mode 100644 thirdparty/gperftools/src/static_vars.h create mode 100755 thirdparty/gperftools/src/symbolize.cc create mode 100644 thirdparty/gperftools/src/symbolize.h create mode 100755 thirdparty/gperftools/src/system-alloc.cc create mode 100644 thirdparty/gperftools/src/system-alloc.h create mode 100644 thirdparty/gperftools/src/tcmalloc.cc create mode 100644 thirdparty/gperftools/src/tcmalloc.h create mode 100644 thirdparty/gperftools/src/tcmalloc_guard.h create mode 100644 thirdparty/gperftools/src/tests/addressmap_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/atomicops_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/current_allocated_bytes_test.cc create mode 100644 thirdparty/gperftools/src/tests/debugallocation_test.cc create mode 100755 thirdparty/gperftools/src/tests/debugallocation_test.sh create mode 100644 thirdparty/gperftools/src/tests/frag_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/getpc_test.cc create mode 100755 thirdparty/gperftools/src/tests/heap-checker-death_unittest.sh create mode 100644 thirdparty/gperftools/src/tests/heap-checker_unittest.cc create mode 100755 thirdparty/gperftools/src/tests/heap-checker_unittest.sh create mode 100644 thirdparty/gperftools/src/tests/heap-profiler_unittest.cc create mode 100755 thirdparty/gperftools/src/tests/heap-profiler_unittest.sh create mode 100644 thirdparty/gperftools/src/tests/large_heap_fragmentation_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/low_level_alloc_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/malloc_extension_c_test.c create mode 100644 thirdparty/gperftools/src/tests/malloc_extension_test.cc create mode 100644 thirdparty/gperftools/src/tests/malloc_hook_test.cc create mode 100644 thirdparty/gperftools/src/tests/markidle_unittest.cc create mode 100755 thirdparty/gperftools/src/tests/maybe_threads_unittest.sh create mode 100644 thirdparty/gperftools/src/tests/memalign_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/packed-cache_test.cc create mode 100644 thirdparty/gperftools/src/tests/page_heap_test.cc create mode 100644 thirdparty/gperftools/src/tests/pagemap_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/profile-handler_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/profiledata_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/profiler_unittest.cc create mode 100755 thirdparty/gperftools/src/tests/profiler_unittest.sh create mode 100644 thirdparty/gperftools/src/tests/raw_printer_test.cc create mode 100644 thirdparty/gperftools/src/tests/realloc_unittest.cc create mode 100755 thirdparty/gperftools/src/tests/sampler_test.cc create mode 100644 thirdparty/gperftools/src/tests/sampling_test.cc create mode 100755 thirdparty/gperftools/src/tests/sampling_test.sh create mode 100644 thirdparty/gperftools/src/tests/simple_compat_test.cc create mode 100644 thirdparty/gperftools/src/tests/stack_trace_table_test.cc create mode 100644 thirdparty/gperftools/src/tests/stacktrace_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/system-alloc_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/tcmalloc_large_unittest.cc create mode 100644 thirdparty/gperftools/src/tests/tcmalloc_unittest.cc create mode 100755 thirdparty/gperftools/src/tests/tcmalloc_unittest.sh create mode 100644 thirdparty/gperftools/src/tests/testutil.cc create mode 100644 thirdparty/gperftools/src/tests/testutil.h create mode 100644 thirdparty/gperftools/src/tests/thread_dealloc_unittest.cc create mode 100644 thirdparty/gperftools/src/third_party/valgrind.h create mode 100644 thirdparty/gperftools/src/thread_cache.cc create mode 100644 thirdparty/gperftools/src/thread_cache.h create mode 100644 thirdparty/gperftools/src/windows/TODO create mode 100644 thirdparty/gperftools/src/windows/addr2line-pdb.c create mode 100644 thirdparty/gperftools/src/windows/auto_testing_hook.h create mode 100644 thirdparty/gperftools/src/windows/config.h create mode 100644 thirdparty/gperftools/src/windows/get_mangled_names.cc create mode 100644 thirdparty/gperftools/src/windows/google/tcmalloc.h create mode 100644 thirdparty/gperftools/src/windows/gperftools/tcmalloc.h create mode 100644 thirdparty/gperftools/src/windows/gperftools/tcmalloc.h.in create mode 100644 thirdparty/gperftools/src/windows/ia32_modrm_map.cc create mode 100644 thirdparty/gperftools/src/windows/ia32_opcode_map.cc create mode 100644 thirdparty/gperftools/src/windows/mingw.h create mode 100644 thirdparty/gperftools/src/windows/mini_disassembler.cc create mode 100644 thirdparty/gperftools/src/windows/mini_disassembler.h create mode 100644 thirdparty/gperftools/src/windows/mini_disassembler_types.h create mode 100644 thirdparty/gperftools/src/windows/nm-pdb.c create mode 100644 thirdparty/gperftools/src/windows/override_functions.cc create mode 100644 thirdparty/gperftools/src/windows/patch_functions.cc create mode 100644 thirdparty/gperftools/src/windows/port.cc create mode 100644 thirdparty/gperftools/src/windows/port.h create mode 100644 thirdparty/gperftools/src/windows/preamble_patcher.cc create mode 100644 thirdparty/gperftools/src/windows/preamble_patcher.h create mode 100644 thirdparty/gperftools/src/windows/preamble_patcher_test.cc create mode 100644 thirdparty/gperftools/src/windows/preamble_patcher_with_stub.cc create mode 100644 thirdparty/gperftools/src/windows/shortproc.asm create mode 100644 thirdparty/gperftools/src/windows/system-alloc.cc create mode 100644 thirdparty/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/sampler_test/sampler_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/sampler_test/sampler_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj.filters create mode 100644 thirdparty/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj create mode 100644 thirdparty/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj.filters create mode 100644 thirdparty/jsoncpp/.clang-format create mode 100644 thirdparty/jsoncpp/.gitattributes create mode 100644 thirdparty/jsoncpp/.gitignore create mode 100644 thirdparty/jsoncpp/.travis.yml create mode 100644 thirdparty/jsoncpp/AUTHORS create mode 100644 thirdparty/jsoncpp/CMakeLists.txt create mode 100644 thirdparty/jsoncpp/LICENSE create mode 100644 thirdparty/jsoncpp/README.md create mode 100644 thirdparty/jsoncpp/amalgamate.py create mode 100644 thirdparty/jsoncpp/appveyor.yml create mode 100644 thirdparty/jsoncpp/dev.makefile create mode 100644 thirdparty/jsoncpp/devtools/__init__.py create mode 100644 thirdparty/jsoncpp/devtools/agent_vmw7.json create mode 100644 thirdparty/jsoncpp/devtools/agent_vmxp.json create mode 100644 thirdparty/jsoncpp/devtools/antglob.py create mode 100644 thirdparty/jsoncpp/devtools/batchbuild.py create mode 100644 thirdparty/jsoncpp/devtools/fixeol.py create mode 100644 thirdparty/jsoncpp/devtools/licenseupdater.py create mode 100644 thirdparty/jsoncpp/devtools/tarball.py create mode 100644 thirdparty/jsoncpp/doc/doxyfile.in create mode 100644 thirdparty/jsoncpp/doc/footer.html create mode 100644 thirdparty/jsoncpp/doc/header.html create mode 100644 thirdparty/jsoncpp/doc/jsoncpp.dox create mode 100644 thirdparty/jsoncpp/doc/readme.txt create mode 100644 thirdparty/jsoncpp/doc/roadmap.dox create mode 100644 thirdparty/jsoncpp/doc/web_doxyfile.in create mode 100644 thirdparty/jsoncpp/doxybuild.py create mode 100644 thirdparty/jsoncpp/include/CMakeLists.txt create mode 100644 thirdparty/jsoncpp/include/json/allocator.h create mode 100644 thirdparty/jsoncpp/include/json/assertions.h create mode 100644 thirdparty/jsoncpp/include/json/autolink.h create mode 100644 thirdparty/jsoncpp/include/json/config.h create mode 100644 thirdparty/jsoncpp/include/json/features.h create mode 100644 thirdparty/jsoncpp/include/json/forwards.h create mode 100644 thirdparty/jsoncpp/include/json/json.h create mode 100644 thirdparty/jsoncpp/include/json/reader.h create mode 100644 thirdparty/jsoncpp/include/json/value.h create mode 100644 thirdparty/jsoncpp/include/json/version.h create mode 100644 thirdparty/jsoncpp/include/json/writer.h create mode 100644 thirdparty/jsoncpp/makefiles/vs71/jsontest.vcproj create mode 100644 thirdparty/jsoncpp/makefiles/vs71/lib_json.vcproj create mode 100644 thirdparty/jsoncpp/makefiles/vs71/test_lib_json.vcproj create mode 100644 thirdparty/jsoncpp/makerelease.py create mode 100644 thirdparty/jsoncpp/meson.build create mode 100644 thirdparty/jsoncpp/pkg-config/jsoncpp.pc.in create mode 100644 thirdparty/jsoncpp/src/CMakeLists.txt create mode 100644 thirdparty/jsoncpp/src/jsontestrunner/CMakeLists.txt create mode 100644 thirdparty/jsoncpp/src/jsontestrunner/main.cpp create mode 100644 thirdparty/jsoncpp/src/lib_json/CMakeLists.txt create mode 100644 thirdparty/jsoncpp/src/lib_json/json_reader.cpp create mode 100644 thirdparty/jsoncpp/src/lib_json/json_tool.h create mode 100644 thirdparty/jsoncpp/src/lib_json/json_value.cpp create mode 100644 thirdparty/jsoncpp/src/lib_json/json_valueiterator.inl create mode 100644 thirdparty/jsoncpp/src/lib_json/json_writer.cpp create mode 100644 thirdparty/jsoncpp/src/lib_json/version.h.in create mode 100644 thirdparty/jsoncpp/src/test_lib_json/CMakeLists.txt create mode 100644 thirdparty/jsoncpp/src/test_lib_json/jsontest.cpp create mode 100644 thirdparty/jsoncpp/src/test_lib_json/jsontest.h create mode 100644 thirdparty/jsoncpp/src/test_lib_json/main.cpp create mode 100644 thirdparty/jsoncpp/test/cleantests.py create mode 100644 thirdparty/jsoncpp/test/data/fail_test_array_01.json create mode 100644 thirdparty/jsoncpp/test/data/fail_test_stack_limit.json create mode 100644 thirdparty/jsoncpp/test/data/test_array_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_array_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_array_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_array_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_array_03.expected create mode 100644 thirdparty/jsoncpp/test/data/test_array_03.json create mode 100644 thirdparty/jsoncpp/test/data/test_array_04.expected create mode 100644 thirdparty/jsoncpp/test/data/test_array_04.json create mode 100644 thirdparty/jsoncpp/test/data/test_array_05.expected create mode 100644 thirdparty/jsoncpp/test/data/test_array_05.json create mode 100644 thirdparty/jsoncpp/test/data/test_array_06.expected create mode 100644 thirdparty/jsoncpp/test/data/test_array_06.json create mode 100644 thirdparty/jsoncpp/test/data/test_array_07.expected create mode 100644 thirdparty/jsoncpp/test/data/test_array_07.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_03.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_03.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_04.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_04.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_05.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_05.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_06.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_06.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_07.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_07.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_08.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_08.json create mode 100644 thirdparty/jsoncpp/test/data/test_basic_09.expected create mode 100644 thirdparty/jsoncpp/test/data/test_basic_09.json create mode 100644 thirdparty/jsoncpp/test/data/test_comment_00.expected create mode 100644 thirdparty/jsoncpp/test/data/test_comment_00.json create mode 100644 thirdparty/jsoncpp/test/data/test_comment_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_comment_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_comment_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_comment_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_complex_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_complex_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_03.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_03.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_04.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_04.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_05.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_05.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_06_64bits.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_06_64bits.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_07_64bits.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_07_64bits.json create mode 100644 thirdparty/jsoncpp/test/data/test_integer_08_64bits.expected create mode 100644 thirdparty/jsoncpp/test/data/test_integer_08_64bits.json create mode 100644 thirdparty/jsoncpp/test/data/test_large_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_large_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_object_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_object_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_object_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_object_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_object_03.expected create mode 100644 thirdparty/jsoncpp/test/data/test_object_03.json create mode 100644 thirdparty/jsoncpp/test/data/test_object_04.expected create mode 100644 thirdparty/jsoncpp/test/data/test_object_04.json create mode 100644 thirdparty/jsoncpp/test/data/test_preserve_comment_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_preserve_comment_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_03.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_03.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_04.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_04.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_05.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_05.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_06.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_06.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_07.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_07.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_08.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_08.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_09.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_09.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_10.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_10.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_11.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_11.json create mode 100644 thirdparty/jsoncpp/test/data/test_real_12.expected create mode 100644 thirdparty/jsoncpp/test/data/test_real_12.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_03.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_03.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_04.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_04.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_05.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_05.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_01.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_01.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_02.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_02.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_03.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_03.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_04.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_04.json create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_05.expected create mode 100644 thirdparty/jsoncpp/test/data/test_string_unicode_05.json create mode 100644 thirdparty/jsoncpp/test/generate_expected.py create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail1.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail10.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail11.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail12.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail13.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail14.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail15.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail16.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail17.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail18.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail19.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail2.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail20.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail21.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail22.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail23.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail24.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail25.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail26.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail27.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail28.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail29.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail3.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail30.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail31.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail32.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail33.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail4.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail5.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail6.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail7.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail8.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/fail9.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/pass1.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/pass2.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/pass3.json create mode 100644 thirdparty/jsoncpp/test/jsonchecker/readme.txt create mode 100644 thirdparty/jsoncpp/test/pyjsontestrunner.py create mode 100644 thirdparty/jsoncpp/test/runjsontests.py create mode 100644 thirdparty/jsoncpp/test/rununittests.py create mode 100644 thirdparty/jsoncpp/travis.before_install.linux.sh create mode 100644 thirdparty/jsoncpp/travis.before_install.osx.sh create mode 100644 thirdparty/jsoncpp/travis.install.linux.sh create mode 100644 thirdparty/jsoncpp/travis.install.osx.sh create mode 100755 thirdparty/jsoncpp/travis.sh create mode 100644 thirdparty/jsoncpp/version create mode 100644 thirdparty/jsoncpp/version.in create mode 100644 thirdparty/pybind11/.appveyor.yml create mode 100644 thirdparty/pybind11/.gitignore create mode 100644 thirdparty/pybind11/.gitmodules create mode 100644 thirdparty/pybind11/.readthedocs.yml create mode 100644 thirdparty/pybind11/.travis.yml create mode 100644 thirdparty/pybind11/CMakeLists.txt create mode 100644 thirdparty/pybind11/CONTRIBUTING.md create mode 100644 thirdparty/pybind11/ISSUE_TEMPLATE.md create mode 100644 thirdparty/pybind11/LICENSE create mode 100644 thirdparty/pybind11/MANIFEST.in create mode 100644 thirdparty/pybind11/README.md create mode 100644 thirdparty/pybind11/docs/Doxyfile create mode 100644 thirdparty/pybind11/docs/_static/theme_overrides.css create mode 100644 thirdparty/pybind11/docs/advanced/cast/chrono.rst create mode 100644 thirdparty/pybind11/docs/advanced/cast/custom.rst create mode 100644 thirdparty/pybind11/docs/advanced/cast/eigen.rst create mode 100644 thirdparty/pybind11/docs/advanced/cast/functional.rst create mode 100644 thirdparty/pybind11/docs/advanced/cast/index.rst create mode 100644 thirdparty/pybind11/docs/advanced/cast/overview.rst create mode 100644 thirdparty/pybind11/docs/advanced/cast/stl.rst create mode 100644 thirdparty/pybind11/docs/advanced/cast/strings.rst create mode 100644 thirdparty/pybind11/docs/advanced/classes.rst create mode 100644 thirdparty/pybind11/docs/advanced/embedding.rst create mode 100644 thirdparty/pybind11/docs/advanced/exceptions.rst create mode 100644 thirdparty/pybind11/docs/advanced/functions.rst create mode 100644 thirdparty/pybind11/docs/advanced/misc.rst create mode 100644 thirdparty/pybind11/docs/advanced/pycpp/index.rst create mode 100644 thirdparty/pybind11/docs/advanced/pycpp/numpy.rst create mode 100644 thirdparty/pybind11/docs/advanced/pycpp/object.rst create mode 100644 thirdparty/pybind11/docs/advanced/pycpp/utilities.rst create mode 100644 thirdparty/pybind11/docs/advanced/smart_ptrs.rst create mode 100644 thirdparty/pybind11/docs/basics.rst create mode 100644 thirdparty/pybind11/docs/benchmark.py create mode 100644 thirdparty/pybind11/docs/benchmark.rst create mode 100644 thirdparty/pybind11/docs/changelog.rst create mode 100644 thirdparty/pybind11/docs/classes.rst create mode 100644 thirdparty/pybind11/docs/compiling.rst create mode 100644 thirdparty/pybind11/docs/conf.py create mode 100644 thirdparty/pybind11/docs/faq.rst create mode 100644 thirdparty/pybind11/docs/index.rst create mode 100644 thirdparty/pybind11/docs/intro.rst create mode 100644 thirdparty/pybind11/docs/limitations.rst create mode 100644 thirdparty/pybind11/docs/pybind11-logo.png create mode 100644 thirdparty/pybind11/docs/pybind11_vs_boost_python1.png create mode 100644 thirdparty/pybind11/docs/pybind11_vs_boost_python1.svg create mode 100644 thirdparty/pybind11/docs/pybind11_vs_boost_python2.png create mode 100644 thirdparty/pybind11/docs/pybind11_vs_boost_python2.svg create mode 100644 thirdparty/pybind11/docs/reference.rst create mode 100644 thirdparty/pybind11/docs/release.rst create mode 100644 thirdparty/pybind11/docs/requirements.txt create mode 100644 thirdparty/pybind11/docs/upgrade.rst create mode 100644 thirdparty/pybind11/include/pybind11/attr.h create mode 100644 thirdparty/pybind11/include/pybind11/buffer_info.h create mode 100644 thirdparty/pybind11/include/pybind11/cast.h create mode 100644 thirdparty/pybind11/include/pybind11/chrono.h create mode 100644 thirdparty/pybind11/include/pybind11/common.h create mode 100644 thirdparty/pybind11/include/pybind11/complex.h create mode 100644 thirdparty/pybind11/include/pybind11/detail/class.h create mode 100644 thirdparty/pybind11/include/pybind11/detail/common.h create mode 100644 thirdparty/pybind11/include/pybind11/detail/descr.h create mode 100644 thirdparty/pybind11/include/pybind11/detail/init.h create mode 100644 thirdparty/pybind11/include/pybind11/detail/internals.h create mode 100644 thirdparty/pybind11/include/pybind11/detail/typeid.h create mode 100644 thirdparty/pybind11/include/pybind11/eigen.h create mode 100644 thirdparty/pybind11/include/pybind11/embed.h create mode 100644 thirdparty/pybind11/include/pybind11/eval.h create mode 100644 thirdparty/pybind11/include/pybind11/functional.h create mode 100644 thirdparty/pybind11/include/pybind11/iostream.h create mode 100644 thirdparty/pybind11/include/pybind11/numpy.h create mode 100644 thirdparty/pybind11/include/pybind11/operators.h create mode 100644 thirdparty/pybind11/include/pybind11/options.h create mode 100644 thirdparty/pybind11/include/pybind11/pybind11.h create mode 100644 thirdparty/pybind11/include/pybind11/pytypes.h create mode 100644 thirdparty/pybind11/include/pybind11/stl.h create mode 100644 thirdparty/pybind11/include/pybind11/stl_bind.h create mode 100644 thirdparty/pybind11/pybind11/__init__.py create mode 100644 thirdparty/pybind11/pybind11/__main__.py create mode 100644 thirdparty/pybind11/pybind11/_version.py create mode 100644 thirdparty/pybind11/setup.cfg create mode 100644 thirdparty/pybind11/setup.py create mode 100644 thirdparty/pybind11/tests/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/conftest.py create mode 100644 thirdparty/pybind11/tests/constructor_stats.h create mode 100644 thirdparty/pybind11/tests/local_bindings.h create mode 100644 thirdparty/pybind11/tests/object.h create mode 100644 thirdparty/pybind11/tests/pybind11_cross_module_tests.cpp create mode 100644 thirdparty/pybind11/tests/pybind11_tests.cpp create mode 100644 thirdparty/pybind11/tests/pybind11_tests.h create mode 100644 thirdparty/pybind11/tests/pytest.ini create mode 100644 thirdparty/pybind11/tests/test_buffers.cpp create mode 100644 thirdparty/pybind11/tests/test_buffers.py create mode 100644 thirdparty/pybind11/tests/test_builtin_casters.cpp create mode 100644 thirdparty/pybind11/tests/test_builtin_casters.py create mode 100644 thirdparty/pybind11/tests/test_call_policies.cpp create mode 100644 thirdparty/pybind11/tests/test_call_policies.py create mode 100644 thirdparty/pybind11/tests/test_callbacks.cpp create mode 100644 thirdparty/pybind11/tests/test_callbacks.py create mode 100644 thirdparty/pybind11/tests/test_chrono.cpp create mode 100644 thirdparty/pybind11/tests/test_chrono.py create mode 100644 thirdparty/pybind11/tests/test_class.cpp create mode 100644 thirdparty/pybind11/tests/test_class.py create mode 100644 thirdparty/pybind11/tests/test_cmake_build/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_cmake_build/embed.cpp create mode 100644 thirdparty/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_cmake_build/main.cpp create mode 100644 thirdparty/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_cmake_build/test.py create mode 100644 thirdparty/pybind11/tests/test_constants_and_functions.cpp create mode 100644 thirdparty/pybind11/tests/test_constants_and_functions.py create mode 100644 thirdparty/pybind11/tests/test_copy_move.cpp create mode 100644 thirdparty/pybind11/tests/test_copy_move.py create mode 100644 thirdparty/pybind11/tests/test_docstring_options.cpp create mode 100644 thirdparty/pybind11/tests/test_docstring_options.py create mode 100644 thirdparty/pybind11/tests/test_eigen.cpp create mode 100644 thirdparty/pybind11/tests/test_eigen.py create mode 100644 thirdparty/pybind11/tests/test_embed/CMakeLists.txt create mode 100644 thirdparty/pybind11/tests/test_embed/catch.cpp create mode 100644 thirdparty/pybind11/tests/test_embed/external_module.cpp create mode 100644 thirdparty/pybind11/tests/test_embed/test_interpreter.cpp create mode 100644 thirdparty/pybind11/tests/test_embed/test_interpreter.py create mode 100644 thirdparty/pybind11/tests/test_enum.cpp create mode 100644 thirdparty/pybind11/tests/test_enum.py create mode 100644 thirdparty/pybind11/tests/test_eval.cpp create mode 100644 thirdparty/pybind11/tests/test_eval.py create mode 100644 thirdparty/pybind11/tests/test_eval_call.py create mode 100644 thirdparty/pybind11/tests/test_exceptions.cpp create mode 100644 thirdparty/pybind11/tests/test_exceptions.py create mode 100644 thirdparty/pybind11/tests/test_factory_constructors.cpp create mode 100644 thirdparty/pybind11/tests/test_factory_constructors.py create mode 100644 thirdparty/pybind11/tests/test_gil_scoped.cpp create mode 100644 thirdparty/pybind11/tests/test_gil_scoped.py create mode 100644 thirdparty/pybind11/tests/test_iostream.cpp create mode 100644 thirdparty/pybind11/tests/test_iostream.py create mode 100644 thirdparty/pybind11/tests/test_kwargs_and_defaults.cpp create mode 100644 thirdparty/pybind11/tests/test_kwargs_and_defaults.py create mode 100644 thirdparty/pybind11/tests/test_local_bindings.cpp create mode 100644 thirdparty/pybind11/tests/test_local_bindings.py create mode 100644 thirdparty/pybind11/tests/test_methods_and_attributes.cpp create mode 100644 thirdparty/pybind11/tests/test_methods_and_attributes.py create mode 100644 thirdparty/pybind11/tests/test_modules.cpp create mode 100644 thirdparty/pybind11/tests/test_modules.py create mode 100644 thirdparty/pybind11/tests/test_multiple_inheritance.cpp create mode 100644 thirdparty/pybind11/tests/test_multiple_inheritance.py create mode 100644 thirdparty/pybind11/tests/test_numpy_array.cpp create mode 100644 thirdparty/pybind11/tests/test_numpy_array.py create mode 100644 thirdparty/pybind11/tests/test_numpy_dtypes.cpp create mode 100644 thirdparty/pybind11/tests/test_numpy_dtypes.py create mode 100644 thirdparty/pybind11/tests/test_numpy_vectorize.cpp create mode 100644 thirdparty/pybind11/tests/test_numpy_vectorize.py create mode 100644 thirdparty/pybind11/tests/test_opaque_types.cpp create mode 100644 thirdparty/pybind11/tests/test_opaque_types.py create mode 100644 thirdparty/pybind11/tests/test_operator_overloading.cpp create mode 100644 thirdparty/pybind11/tests/test_operator_overloading.py create mode 100644 thirdparty/pybind11/tests/test_pickling.cpp create mode 100644 thirdparty/pybind11/tests/test_pickling.py create mode 100644 thirdparty/pybind11/tests/test_pytypes.cpp create mode 100644 thirdparty/pybind11/tests/test_pytypes.py create mode 100644 thirdparty/pybind11/tests/test_sequences_and_iterators.cpp create mode 100644 thirdparty/pybind11/tests/test_sequences_and_iterators.py create mode 100644 thirdparty/pybind11/tests/test_smart_ptr.cpp create mode 100644 thirdparty/pybind11/tests/test_smart_ptr.py create mode 100644 thirdparty/pybind11/tests/test_stl.cpp create mode 100644 thirdparty/pybind11/tests/test_stl.py create mode 100644 thirdparty/pybind11/tests/test_stl_binders.cpp create mode 100644 thirdparty/pybind11/tests/test_stl_binders.py create mode 100644 thirdparty/pybind11/tests/test_tagbased_polymorphic.cpp create mode 100644 thirdparty/pybind11/tests/test_tagbased_polymorphic.py create mode 100644 thirdparty/pybind11/tests/test_union.cpp create mode 100644 thirdparty/pybind11/tests/test_union.py create mode 100644 thirdparty/pybind11/tests/test_virtual_functions.cpp create mode 100644 thirdparty/pybind11/tests/test_virtual_functions.py create mode 100644 thirdparty/pybind11/tools/FindCatch.cmake create mode 100644 thirdparty/pybind11/tools/FindEigen3.cmake create mode 100644 thirdparty/pybind11/tools/FindPythonLibsNew.cmake create mode 100755 thirdparty/pybind11/tools/check-style.sh create mode 100644 thirdparty/pybind11/tools/libsize.py create mode 100755 thirdparty/pybind11/tools/mkdoc.py create mode 100644 thirdparty/pybind11/tools/pybind11Config.cmake.in create mode 100644 thirdparty/pybind11/tools/pybind11Tools.cmake diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d1122334 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +build +.idea +*.pyc +estimator/*json +tmp.* +test_cfg/ +bin/ +lib/ +!thirdparty +src/src/ +src/Makefile +back_results/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..cefec4cf --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,79 @@ +cmake_minimum_required(VERSION 3.5) +project(feh) + +option(BUILD_ROSNODE "wrap the system in a rosnode" OFF) + +# set(CMAKE_CC_COMPILER "/usr/bin/gcc-7") +# set(CMAKE_CXX_COMPILER "/usr/bin/g++-7") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -std=c++17 -Wno-narrowing -Wno-register -g -fPIC") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=native -march=native") +set(CMAKE_BUILD_TYPE "Release") +add_definitions(-DNDEBUG) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) + +# add_definitions(-DEIGEN_DEFAULT_TO_ROW_MAJOR) +add_definitions(-DEIGEN_INITIALIZE_MATRICES_BY_ZERO) + +# comment out the following line to disable NaN checks on Jacobians +find_package(OpenCV REQUIRED) + +link_directories( + ${PROJECT_SOURCE_DIR}/lib + ${PROJECT_SOURCE_DIR}/thirdparty/gflags/lib + ${PROJECT_SOURCE_DIR}/thirdparty/glog/lib + ${PROJECT_SOURCE_DIR}/thirdparty/Pangolin/lib + ${PROJECT_SOURCE_DIR}/thirdparty/jsoncpp/lib + # ${PROJECT_SOURCE_DIR}/thirdparty/gperftools/lib + /usr/local/lib + # /opt/ros/kinetic/lib/x86_64-linux-gnu + # /usr/lib + # /usr/lib/x86_64-linux-gnu +) + +include_directories( + ${PROJECT_SOURCE_DIR}/common + ${PROJECT_SOURCE_DIR}/src + ${PROJECT_SOURCE_DIR}/thirdparty/gflags/include + ${PROJECT_SOURCE_DIR}/thirdparty/glog/include + ${PROJECT_SOURCE_DIR}/thirdparty/Pangolin/include + ${PROJECT_SOURCE_DIR}/thirdparty/jsoncpp/include + ${PROJECT_SOURCE_DIR}/thirdparty/eigen3/include/eigen3 + ${PROJECT_SOURCE_DIR}/thirdparty/pybind11/include + ${JSONCPP_INCLUDE_DIRS} + /usr/local/include/opencv2 + # /opt/ros/kinetic/include/opencv-3.3.1-dev + # ${PROJECT_SOURCE_DIR}/thirdparty/libigl/include + # ${PROJECT_SOURCE_DIR}/thirdparty/gperftools/include +) + + + +enable_testing() +add_subdirectory(thirdparty/googletest) +add_subdirectory(thirdparty/gflags) +add_subdirectory(thirdparty/abseil-cpp) +# add_subdirectory(thirdparty/xfeatures2d) + +# feh +add_subdirectory(common) +add_subdirectory(src) +if (BUILD_ROSNODE) + add_subdirectory(node) +endif(BUILD_ROSNODE) +# add_subdirectory(experimental) + +######################################## +# PYTHON BINDING +######################################## +# NOTE: to build with a specific python version +# cmake -DPYTHON_EXECUTABLE=path/to/python .. +# By default, the python binding generated is only compatible with +# your default python interpreter, which you can check by typing +# "which python" in your terminal. +set(PYBIND11_CPP_STANDARD -std=c++17) +add_subdirectory(thirdparty/pybind11) +pybind11_add_module(pyxivo MODULE pybind11/pyxivo.cpp) +target_link_libraries(pyxivo PRIVATE common estimator application) diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..dcd450ba --- /dev/null +++ b/LICENSE @@ -0,0 +1,31 @@ +Academic Software License + +XIVO + +No Commercial Use + +This License governs use of the accompanying Software, and your use of the Software constitutes acceptance of this license. + +You may use this Software for any non-commercial purpose, subject to the restrictions in this license. Uses which are non-commercial include teaching, academic research, and personal experimentation. + +You may not use or distribute this Software or any derivative works in any form for any commercial purpose. Examples of commercial purposes would be running business operations, licensing, leasing, or selling the Software, or distributing the Software for use with commercial products. + +You may modify this Software and distribute the modified Software for non-commercial purposes; however, you may not grant rights to the Software or derivative works that are broader than those provided by this License. For example, you may not distribute modifications of the Software under terms that would permit commercial use, or under terms that purport to require the Software or derivative works to be sublicensed to others. + +You agree: + +Not remove any copyright or other notices from the Software. + +That if you distribute the Software in source or object form, you will include a verbatim copy of this license. + +That if you distribute derivative works of the Software in source code form you do so only under a license that includes all of the provisions of this License, and if you distribute derivative works of the Software solely in object form you do so only under a license that complies with this License. + +That if you have modified the Software or created derivative works, and distribute such modifications or derivative works, you will cause the modified files to carry prominent notices so that recipients know that they are not receiving the original Software. Such notices must state: (i) that you have changed the Software; and (ii) the date of any changes. + +THAT THIS PRODUCT IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. YOU MUST PASS THIS LIMITATION OF LIABILITY ON WHENEVER YOU DISTRIBUTE THE SOFTWARE OR DERIVATIVE WORKS. + +That if you sue anyone over patents that you think may apply to the Software or anyone's use of the Software, your license to the Software ends automatically. + +That your rights under the License end automatically if you breach it in any way. + +UCLA reserves all rights not expressly granted to you in this license. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..73ca955c --- /dev/null +++ b/README.md @@ -0,0 +1,215 @@ +# X Inertial-aided Visual Odometry + +I started writing this software as a hobby project in winter 2018. The motivation behind this is in part that I want to have a (hopefully) minimal implementation of EKF-based Visual-Inertial Odometry and to play with some new C++ language features (C++ 14/17) and coding techniques (templates, design patterns, etc.). The project was paused for months due to job hunting, paper submission, defense and vacation, etc. Fortunately, I was able to spend more time on it before I leave UCLA. + +This is still work in progress, and under no circumstances, it can be considered as done. However, with readability and maintainability in mind when writing this piece of software, I believe it still has some value for people who want to dive into the world of VIO. Besides, the performance of the system in terms of ATE (Absolute Trajectory Error) and RPE (Relative Pose Error) is comparable to other open-source VIO systems (see the performance section). + + +A detailed technical report of the implementation will follow. Stay tuned. + +Have fun! + +## Install + +To install the state estiamtor and dependencies, execute the `build.sh` script in the root directory of the project. + +## Usage + +The current implementation supports two executation modes: Either run on a folder of image sequences and a text file of inertial measurements (like what provided by the EuRoC and TUM-VI datasets), or a rosbag (TUM-VI also provides rosbags). + +### Dataset + +Assume the environment variable `$TUMVIROOT` has been set to the root directory of your [TUMVI](https://vision.in.tum.de/data/datasets/visual-inertial-dataset) dataset. For example, + +``` +export TUMVIROOT=/home/Data/tumvi/exported/euroc/512_16 +``` + +where on my machine `/home/Data/tumvi/exported/euroc/512_16` hosts folders of data, such as `dataset-room1_512_16`, `dataset-corridor1_512_16`, etc. + +### Run + +In the project root directory, you can run the estimator with configuration specified by the `-cfg cfg/vio.json` option on images captured by camera 0 (`-cam_id 0`) of 6-th room sequence (`-seq room6`) of the TUMVI dataset (`-dataset tumvi`) which resides in `$TUMVIROOT` (option `-root $TUMVIROOT`) as follows: + +``` +bin/st_vio -cfg cfg/vio.json -root $TUMVIROOT -dataset tumvi -seq room6 -cam_id 0 -out out_state +``` + +where estimated states are saved to the output file `out_state`. + +For detailed usage of the application, see the flags defined at the begining of the application source file `src/app/singlethread_vio.cpp`. + + +### Evaluation + + + +We provide a python script `scripts/run_and_eval_pyxivo.py` to run the estimator on a specified TUM-VI sequence and benchmark the performance in terms ATE (Absolute Trajectory Error) and RPE (Relative Pose Error). To use it, execute the following in the project root directory: + +``` +python scripts/run_and_eval_pyxivo.py -root $TUMVIROOT -seq room6 -stdout -out_dir tmp -use_viewer +``` +the `-seq` and `-root` options are the same as explained above. If the `-stdout` option is on, the script will print out the benchmarked performance to the terminal; `-out_dir` specifies the directory to save state estimates; `-use_viewer` option will turn on a 3D visualization. For detailed usage about the script, see the options defined at the begining of the script. + +### Log to file for debugging + +We use [glog](https://github.com/google/glog) for system logging. If you want to log debug information to a file for inspection later, + +``` +GLOG_log_dir=log GLOG_v=0 bin/st_vio -cfg cfg/vio.json -root $TUMVIROOT +``` + +Note, the directory `log`, which is where the logs are kept, should be created first (simply `mkdir log`). + +By default, log is suppressed by setting `add_definitions(-DGOOGLE_STRIP_LOG=1)` in `src/CMakeLists.txt`. To enable log, simply comment out that line and re-build. + +For more details on how to use glog, see [the tutorial here](http://rpg.ifi.uzh.ch/docs/glog.html). + + + +## Rosbag mode + +### Build + +By default the ROS wrapper of the system will not be built, to build the ROS support, you need to turn on the `BUILD_ROSNODE` option when generating the makefile: In `build` directory of the project root, do the following: + +``` +cmake .. -DBUILD_ROSNODE=ON +``` + +followed by `make` to build with ROS support. + +### Run + +1. In the project root directory, `source build/devel/setup.zsh`. If another shell, such as bash/sh, is used, please source the corresponding shell script (`setup.bash`/`setup.sh`) respectively. +2. `roslaunch node/launch/xivo.launch` to launch the ros node, which subscribes to `/imu0` and `/cam0/image_raw` topics. +3. In antoher terminal, playback rosbags from the TUM-VI dataset, e.g., `rosbag play PATH/TO/YOUR/ROSBAG` . + + + + +## Python binding + +A simple python binding is provided by wrapping some public interfaces of the estimator via [`pybind11`](https://github.com/pybind/pybind11). Check out `pybind11/pyxivo.cpp` for the available interfaces in python. With pybind11, it is relatively easy if you want to expose more interfaces of the C++ implementation to python. + +An example of using the python binding is available in `scripts/pyxivo.py`, which demonstrates estimator creation, data loading, and visualization in python. + +To run the demo, simply execute: + +``` +python scripts/pyxivo.py -root $TUMVIROOT -seq room6 -cam_id 0 +``` + +in the project root directory. The command line options are more or less same as the C++ executable. For detailed usage, you can look at the options defined at the begining of the script `scripts/pyxivo.py`. Note you might need to install some python dependencies: + +``` +pip install -r requirements.txt +``` + +executed in the project root directory. + +## Performance + +The benchmark performance of this software on TUM-VI dataset is comparable to other open-source VIO systems (slightly worse than optimization-based OKVIS and VINS-Mono and on par with EKF-based ROVIO). Also, our system runs at more than 100 Hz on a desktop PC with a Core i7 6th gen CPU at very low CPU consumption rate. The runtime can be further improved by utilizing CPU cache and memory better. The following table shows the performance on 6 indoor sequences where ground-truth poses are available. The numbers for OKVIS, VINS-Mono and ROVIO are taken from the TUM-VI benchmark paper. Ours XIVO is obtained by using the aforementioned evaluation script. + + +| Sequence | length | OKVIS | VINS-Mono | ROVIO | Ours-XIVO | +|:--- | :--- | :---: | :---: | :---: | :---: | +|room1 | 156m | **0.06m** | 0.07m | 0.16m | 0.22m | +|room2 | 142m | 0.11m | **0.07m** | 0.33m | 0.08m | +|room3 | 135m | **0.7m** | 0.11m | 0.15m | 0.11m | +|room4 | 68m | **0.03m** | 0.04m | 0.09m | 0.08m | +|room5 | 131m | **0.07m** | 0.20m | 0.12m | 0.11m | +|room6 | 67m | **0.04m** | 0.08m | 0.05m | 0.12m | + +*Table 1. RMSE ATE* in meters. OKVIS and VINS-Mono are optimization-based, whereas ROVIO and Ours-XIVO are EKF-based. + + +| Sequence | OKVIS | VINS-Mono | ROVIO | Ours-XIVO | +|:--- | :---: | :---: | :---: | :---: | +|room1 | **0.013**m/**0.43**o | 0.015m/0.44o | 0.029m/0.53o | 0.031m/0.59o | +|room2 | **0.015**m/**0.62**o | 0.017m/0.63o | 0.030m/0.67o | 0.023m/0.75o | +|room3 | **0.012**m/0.64o | 0.023m/**0.63**o | 0.027m/0.66o | 0.027m/0.73o | +|room4 | **0.012**m/0.57o | 0.015m/**0.41**o | 0.022m/0.61o | 0.023m/0.62o | +|room5 | **0.012**m/**0.47**o | 0.026m/**0.47**o | 0.031m/0.60o | 0.023m/0.65o | +|room6| **0.012**m/0.49o | 0.014m/**0.44**o | 0.019m/0.50o | 0.031m/0.53o | + +*Table 2. RMSE RPE* in meters (translation) and degrees (rotation). + + +--- + +## Reference + +If you find this software useful and use it in your work, please cite: + +``` +@misc{feiS19xivo, + author = {Xiaohan Fei, and Stefano Soatto}, + title = {XIVO: X Inertial-aided Visual Odometry}, + howpublished = "\url{https://github.com/feixh/xivo}", +} +``` + + \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..ba6c064e --- /dev/null +++ b/build.sh @@ -0,0 +1,58 @@ +#!/bin/sh +PROJECT_DIR=$(pwd) +echo $PROJECT_DIR + +cd $PROJECT_DIR/thirdparty/googletest +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=.. +make install -j + +cd $PROJECT_DIR/thirdparty/gflags +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=.. +make install -j + +cd $PROJECT_DIR/thirdparty/glog +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=.. +make install -j + +cd $PROJECT_DIR/thirdparty/eigen3 +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=.. +make install -j + +cd $PROJECT_DIR/thirdparty/Sophus +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=.. +make install -j + +cd $PROJECT_DIR/thirdparty/Pangolin +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=.. +make install -j + +cd $PROJECT_DIR/thirdparty/jsoncpp +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=.. -DBUILD_SHARED_LIBS=TRUE +make install -j + +# to build gperftools, need to install autoconf and libtool first +# sudo apt-get install autoconf libtool +cd $PROJECT_DIR/thirdparty/gperftools +./autogen.sh +./configure --prefix=$PROJECT_DIR/thirdparty/gperftools +make install + + +mkdir ${PROJECT_DIR}/build +cd ${PROJECT_DIR}/build +cmake .. +make -j diff --git a/cfg/atan.json b/cfg/atan.json new file mode 100644 index 00000000..c094d8b5 --- /dev/null +++ b/cfg/atan.json @@ -0,0 +1,10 @@ +{ +"model": "atan", +"rows": 320, +"cols": 480, +"fx": 0.425881, +"fy": 0.639873, +"cx": 0.504153, +"cy": 0.525719, +"w": 0.857591 +} diff --git a/cfg/equidistant.json b/cfg/equidistant.json new file mode 100644 index 00000000..7d8ed7a6 --- /dev/null +++ b/cfg/equidistant.json @@ -0,0 +1,13 @@ +{ +"model": "equidistant", +"rows": 512, +"cols": 512, +"fx": 190.97847715128717, +"fy": 190.9733070521226, +"cx": 254.93170605935475, +"cy": 256.8974428996504, +"k0123": [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, 0.00020293673591811182], +"max_iter": 15, +"comment": "512-cam0" +} + diff --git a/cfg/estimator.json b/cfg/estimator.json new file mode 100644 index 00000000..1bca2572 --- /dev/null +++ b/cfg/estimator.json @@ -0,0 +1,271 @@ +{ + // verbose + "simulation": false, + "print_timing": false, + "use_canvas": true, + "async_run": false, // turn this off in benchmarking + + // algorithmic-level knobs + "integration_method": "PrinceDormand", // "PrinceDormand", "RK4", //, Fehlberg + "use_OOS": false, // update with Out-Of-State features + "use_depth_opt": true, // depth optimization + "use_MH_gating": true, + "use_1pt_RANSAC": false, + "use_compression": true, // measurement compression + "triangulate_pre_subfilter": true, + "compression_trigger_ratio": 1.5, + "max_group_lifetime": 30, + + "PrinceDormand": { + "control_stepsize": false, + "tolerance": 1e-15, + "attempts": 12, + "min_scale_factor": 0.125, + "max_scale_factor": 4.0, + "stepsize": 0.002 + }, + + "RK4": { + "stepsize": 0.002 + }, + + // memory + "memory": { + "max_features": 256, + "max_groups": 256 // max groups should increase as allowed group lifetime increases + }, + + + // gravity constant + "gravity": [0, 0, -9.8], + // Initial State + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + "bg" : [0, 0, 0], + "ba" : [0, 0, 0], + "Wbc" : [[-0.99952504, 0.00750192, -0.02989013], + [0.02961534, -0.03439736, -0.99896935], + [-0.00852233, -0.99938008, 0.03415885]], + // Wbc in tangent space: [-0.0418, -2.172, 2.248] + "Tbc": [0.04557484, -0.0711618, -0.04468125], + "Wg" : [0, 0, 0], + "td" : 0 + }, + + "P" : { + "W" : 0.0001, + "T" : 0.001, + "V" : 0.5, + "bg" : 0.0001, + "ba" : 0.001, + "Wbc" : 0.0001, + "Tbc" : 0.001, + "Wg" : 0.01, + "td" : 1e-5, // 1ms + "Cg" : 1e-5, + "Ca" : 1e-5, + "FC" : 50, + "distortion": 1e-3 + }, + + "Qmodel" : { + "W" : 0.000, + "T" : 0.0, + "V" : 0.0, + "wb" : 0.0000, + "ab" : 0.000, + "Wbc" : 0.000, + "Tbc" : 0.0, + "Wg" : 0.000 + }, + + // // exact densities provided by TUM-VI dataset + // // https://vision.in.tum.de/data/datasets/visual-inertial-dataset + // "Qimu": { + // "gyro": 8.0e-5, + // "gyro_bias": 2.2e-6, + // "accel":1.4e-3, + // "accel_bias": 8.6e-5 + // }, + + // // inflated by sqrt(3) times + // "Qimu": { + // "gyro": 14.0e-5, + // "gyro_bias": 3.8e-6, + // "accel": 2.4e-3, + // "accel_bias": 14.9e-5 + // }, + + // // doubled + // "Qimu": { + // "gyro": 16.0e-5, + // "gyro_bias": 4.4e-6, + // "accel":2.8e-3, + // "accel_bias": 17.2e-5 + // }, + + // inflated by 3 times + "Qimu": { + "gyro": 24.0e-5, + "gyro_bias": 6.6e-6, + "accel": 4.2e-3, + "accel_bias": 25.8e-5 + }, + + + // initial std on feature state + "initial_z": 2.5, // meter + "initial_std_x": 3.5, // pixel + "initial_std_y": 3.5, // pixel + "initial_std_z": 1.0, // meter + + // std of visuale measurement, in pixels + "visual_meas_std": 1.5, + "outlier_thresh": 1.1, + "oos_meas_std": 3.5, + "max_depth": 5.0, + "min_depth": 0.05, + + + // depth sub-filter setting + "subfilter": { + "visual_meas_std": 3.5, + "ready_steps": 2, + "MH_thresh": 8.991 + }, + + // pre-subfilter triangulation options + "triangulation": { + "method": 1, + "zmin": 0.05, + "zmax": 5.0 + }, + + "depth_opt": { + "two_view": false, + "max_iters": 5, + "eps": 1e-3, + "damping": 1e-3, + "max_res_norm": 2.0 // maximal norm of per observation residuals + }, + + "feature_P0_damping": 10.0, // 10.0 seems most appropriate + + "imu_calib": { + "Cas": [1, 1, 1], + "Car": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]], + "Cgs": [1, 1, 1], + "Cgr": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]] + }, + "gravity_init_counter": 20, + + "camera_cfg": { + "model": "equidistant", + "rows": 512, + "cols": 512, + "fx": 190.97847715128717, + "fy": 190.9733070521226, + "cx": 254.93170605935475, + "cy": 256.8974428996504, + "k0123": [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, 0.00020293673591811182], + "max_iter": 15, + "comment": "512-cam0" + }, + + "min_inliers": 5, // minimum number of inlier measurements + + "MH_thresh": 5.991, // 8.991 + "MH_adjust_factor": 1.15, + + "1pt_RANSAC_thresh": 1.5, + "1pt_RANSAC_prob": 0.95, + "1pt_RANSAC_Chi2": 5.89, + + "tracker_cfg": { + "use_prediction": true, + "mask_size": 15, + "margin": 8, // image boundary to mask out + "num_features_min": 90, + "num_features_max": 120, + "max_pixel_displacement": 64, + "normalize": false, + + "KLT": { + "win_size": 15, + "max_level": 5, + "max_iter": 30, + "eps": 0.01 + }, + + "extract_descriptor": false, + "descriptor_distance_thresh": -1, // -1 to disable descriptor check + "default_descriptor": "BRIEF", + + // "detector": "BRISK", + "detector": "FAST", + // "detector": "ORB", + // "detector": "AGAST", + // "detector": "GFTT", + + "FAST": { + // https://docs.opencv.org/3.4/df/d74/classcv_1_1FastFeatureDetector.html + "threshold": 20, + "nonmaxSuppression": true + }, + + "BRISK": { + // https://docs.opencv.org/3.4/de/dbf/classcv_1_1BRISK.html + "thresh": 25, + "octaves": 3, + "patternScale": 1.0 + }, + + "ORB": { + // https://docs.opencv.org/3.3.0/db/d95/classcv_1_1ORB.html + "nfeatures": 500, + "scaleFactor": 1.2, + "nlevels": 4, + "edgeThreshold": 31, + "firstLevel": 0, + "WTA_K": 2, + "patchSize": 31, + "fastThreshold": 20 + }, + + "AGAST": { + // https://docs.opencv.org/3.4/d7/d19/classcv_1_1AgastFeatureDetector.html + "threshold": 10, + "nonmaxSuppression": true + }, + + "GFTT": { + // Good Feature To Track + // https://docs.opencv.org/3.3.0/df/d21/classcv_1_1GFTTDetector.html + "maxCorners": 1000, + "qualityLevel": 0.01, + "minDistance": 1.0, + "blockSize": 3, + "useHarrisDetector": false, + "k": 0.04 + }, + + "BRIEF": { + "bytes": 64, + "use_orientation": false + }, + + "FREAK": { + "orientationNormalized": true, + "scaleNormalized": true, + "patternScale": 22.0, + "nOctaves": 4 + } + } + +} diff --git a/cfg/estimator_latex.json b/cfg/estimator_latex.json new file mode 100644 index 00000000..e2c56900 --- /dev/null +++ b/cfg/estimator_latex.json @@ -0,0 +1,122 @@ +{ + // This particular configuration is used to generate the results in + // the latex manuscript. + "simulation": false, + "update_method": "ekf", + "gravity": [0, 0, -9.8], + // Initial State + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + "bg" : [0, 0, 0], + "ba" : [0, 0, 0], + "Wbc" : [[-0.99952504, 0.00750192, -0.02989013], + [0.02961534, -0.03439736, -0.99896935], + [-0.00852233, -0.99938008, 0.03415885]], + "Tbc": [0.04557484, -0.0711618, -0.04468125], + "Wg" : [0, 0] + }, + + "P" : { + "W" : 0.0001, + "T" : 0.001, + "V" : 0.5, + "bg" : 0.0001, + "ba" : 0.001, + "Wbc" : 0.0001, + "Tbc" : 0.001, + "Wg" : 0.01 + }, + + "Qmodel" : { + "W" : 0.000, + "T" : 0.0, + "V" : 0.0, + "wb" : 0.0000, + "ab" : 0.000, + "Wbc" : 0.000, + "Tbc" : 0.0, + "Wg" : 0.000 + }, + + "Qimu": { + "gyro": 1e-3, + "gyro_bias": 1e-4, + "accel":1e-2, + "accel_bias": 1e-1 + }, + + // initial std on feature state + "initial_z": 2.5, // meter + "initial_std_x": 3.5, // pixel + "initial_std_y": 3.5, // pixel + "initial_std_z": 1.0, // meter + + // std of visuale measurement, in pixels + "visual_meas_std": 1.5, + "subfilter_visual_meas_std": 3.5, + "max_depth": 5.0, + "min_depth": 0.05, + "max_depth_init_steps": 5, + "depth_opt_iters": 5, + "depth_opt_eps": 0.001, + "depth_opt_damping": 1e-3, + "inn_thresh": 64, + "MH_thresh": 6, + + "imu_calib": { + "Cas": [1, 1, 1], + "Car": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]], + "Cgs": [1, 1, 1], + "Cgr": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]] + }, + "imu_init_counter": 20, + "RK4": true, + + "camera_cfg": { + "model": "equidistant", + "rows": 512, + "cols": 512, + "fx": 190.97847715128717, + "fy": 190.9733070521226, + "cx": 254.93170605935475, + "cy": 256.8974428996504, + "k0123": [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, 0.00020293673591811182], + "max_iter": 15, + "comment": "512-cam0" + }, + + "tracker_cfg": { + "mask_size": 15, + "num_features_min": 90, + "num_features_max": 120, + "normalize": true, + + "OpticalFlow": { + "win_size": 15, + "max_level": 5, + "max_iter": 15, + "eps": 1e-4, + "threshold": 20 + }, + + // somehow, only BRISK and FAST work well with the generic FeatureDetector interface (Version 2.4.9) + "DetectorType": "FAST", + + "FAST": { + "threshold": 20, + "nonmaxSuppression": true + }, + + "GridAdapter": { + "grid_rows": 4, + "grid_cols": 4 + } + } + +} diff --git a/cfg/estimator_scenenet.json b/cfg/estimator_scenenet.json new file mode 100644 index 00000000..5efe4954 --- /dev/null +++ b/cfg/estimator_scenenet.json @@ -0,0 +1,154 @@ +{ + // verbose + "simulation": false, + "print_timer": false, + + // algorithmic-level knobs + "integration_method": "PrinceDormand", // "PrinceDormand", "RK4", //, Fehlberg + "use_OOS": false, // update with Out-Of-State features + "use_depth_opt": true, // depth optimization + "use_MH_gating": true, + "use_1pt_RANSAC": false, + "use_compression": true, // measurement compression + "compression_trigger_ratio": 1.5, + + "PrinceDormand": { + "control_stepsize": false, + "tolerance": 1e-15, + "attempts": 12, + "min_scale_factor": 0.125, + "max_scale_factor": 4.0, + "stepsize": 0.002 + }, + + "RK4": { + "stepsize": 0.002 + }, + + // memory + "max_features": 256, + "max_groups": 256, // max groups should increase as allowed group lifetime increases + + "gravity": [0, 0, -9.8], + "timing": false, + + // Initial State + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + "bg" : [0, 0, 0], + "ba" : [0, 0, 0], + "Wbc" : [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]], + "Tbc": [0, 0, 0], + "Wg" : [0, 0] + }, + + "P" : { + "W" : 0.001, + "T" : 0.01, + "V" : 0.5, + "bg" : 0.000, + "ba" : 0.00, + "Wbc" : 0.00001, + "Tbc" : 0.0001, + "Wg" : 0.01 + }, + + "Qmodel" : { + "W" : 0.000, + "T" : 0.0, + "V" : 0.0, + "wb" : 0.0000, + "ab" : 0.000, + "Wbc" : 0.000, + "Tbc" : 0.0, + "Wg" : 0.000 + }, + + // // exact densities provided by TUM-VI dataset + // // https://vision.in.tum.de/data/datasets/visual-inertial-dataset + "Qimu": { + "gyro": 8.0e-5, + "gyro_bias": 2.2e-6, + "accel":1.4e-3, + "accel_bias": 8.6e-5 + }, + + // initial std on feature state + "initial_z": 5.5, // meter + "initial_std_x": 0.5, // pixel + "initial_std_y": 0.5, // pixel + "initial_std_z": 2.0, // meter + + // std of visuale measurement, in pixels + "visual_meas_std": 1.5, + "subfilter_visual_meas_std": 1.5, + "max_depth": 10.0, + "min_depth": 0.05, + "max_depth_init_steps": 5, + + "use_depth_opt": true, + "depth_opt_iters": 5, + "depth_opt_eps": 0.001, + "depth_opt_damping": 1e-3, + + "feature_P0_damping": 10.0, + "inn_thresh": 64, + "MH_thresh": 8.991, + + "imu_calib": { + "Cas": [1, 1, 1], + "Car": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]], + "Cgs": [1, 1, 1], + "Cgr": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]] + }, + "imu_init_counter": 5, + + "camera_cfg": { + "model": "pinhole", + "rows": 240, + "cols": 320, + "fx": 277.12812921, + "fy": 289.70562748, + "cx": 160, + "cy": 120, + "comment": "pinhole" + }, + + "tracker_cfg": { + "use_prediction": true, + "mask_size": 15, + "num_features_min": 60, + "num_features_max": 90, + "normalize": false, + + "OpticalFlow": { + "win_size": 7, + "max_level": 5, + "max_iter": 15, + "eps": 1e-4, + "threshold": 20 + }, + + // somehow, only BRISK and FAST work well with the generic FeatureDetector interface (Version 2.4.9) + "DetectorType": "FAST", + + "FAST": { + "threshold": 20, + "nonmaxSuppression": true + }, + + "GridAdapter": { + "grid_rows": 4, + "grid_cols": 4 + } + } + +} diff --git a/cfg/estimator_sim.json b/cfg/estimator_sim.json new file mode 100644 index 00000000..c4473710 --- /dev/null +++ b/cfg/estimator_sim.json @@ -0,0 +1,77 @@ +{ + "simulation": true, + "gravity": [0, 0, -9.8], + // Initial State + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + "bg" : [0, 0, 0], + "ba" : [0, 0, 0], + "Wbc" : [[-0.99952504, 0.00750192, -0.02989013], + [0.02961534, -0.03439736, -0.99896935], + [-0.00852233, -0.99938008, 0.03415885]], + "Tbc": [0.04557484, -0.0711618, -0.04468125], + "Wg" : [0, 0] + }, + + "P" : { + "W" : 0.0000, + "T" : 0.000, + "V" : 0.0, + "bg" : 0.005, + "ba" : 0.05, + "Wbc" : 0.005, + "Tbc" : 0.05, + "Wg" : 0.0 + }, + + "Qmodel" : { + "W" : 0.000, + "T" : 0.0, + "V" : 0.0, + "wb" : 0.0000, + "ab" : 0.000, + "Wbc" : 0.000, + "Tbc" : 0.0, + "Wg" : 0.000 + }, + + "Qimu": { + "gyro": 3e-3, + "accel":3e-2 + }, + + // initial std on feature state + "initial_z": 2.0, // meter + "initial_std_x": 0.1, // pixel + "initial_std_y": 0.1, // pixel + "initial_std_z": 1.0, // meter + + // std of visuale measurement, in pixels + "visual_meas_std": 1.5, + "subfilter_visual_meas_std": 1.5, + "max_depth": 5.0, + "min_depth": 0.05, + "max_depth_init_steps": 2, + "depth_opt_iters": 10, + "depth_opt_eps": 0.001, + "depth_opt_damping": 1e-4, + "inn_thresh": 20, + + + "imu_calib": { + "Cas": [1, 1, 1], + "Car": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]], + "Cgs": [1, 1, 1], + "Cgr": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]] + }, + "imu_init_counter": 10, + + "camera_cfg": "../cfg/equidistant.json", // atan + "tracker_cfg": "../cfg/tracker.json" +} diff --git a/cfg/lyapunov_baseline.json b/cfg/lyapunov_baseline.json new file mode 100644 index 00000000..da685893 --- /dev/null +++ b/cfg/lyapunov_baseline.json @@ -0,0 +1,156 @@ +{ + // verbose + "simulation": false, + "print_timer": false, + + // algorithmic-level knobs + "update_method": "ekf", + "integration_method": "RK4", // RK4, ForwardEuler + "RK4_stepsize": 0.002, + "use_OOS": false, // update with Out-Of-State features + "use_depth_opt": true, // depth optimization + "use_MH_gating": true, + "use_1pt_RANSAC": false, + "use_compression": true, // measurement compression + "compression_trigger_ratio": 1.5, + "use_discrete_covariance_propagation": true, + + // memory + "max_features": 256, + "max_groups": 256, // max groups should increase as allowed group lifetime increases + "max_group_lifetime": 120, + + // gravity constant + "gravity": [0, 0, -9.8], + // Initial State + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + "bg" : [0, 0, 0], + "ba" : [0, 0, 0], + "Wbc" : [[-0.99952504, 0.00750192, -0.02989013], + [0.02961534, -0.03439736, -0.99896935], + [-0.00852233, -0.99938008, 0.03415885]], + "Tbc": [0.04557484, -0.0711618, -0.04468125], + "Wg" : [0, 0, 0] + }, + + "P" : { + "W" : 0.0001, + "T" : 0.001, + "V" : 0.5, + "bg" : 0.0001, + "ba" : 0.001, + "Wbc" : 0.00001, + "Tbc" : 0.001, + "Wg" : 0.01 + }, + + "Qmodel" : { + "W" : 0.000, + "T" : 0.0, + "V" : 0.0, + "wb" : 0.0000, + "ab" : 0.000, + "Wbc" : 0.000, + "Tbc" : 0.0, + "Wg" : 0.000 + }, + + // original block without numerical integration of Lyapunov + "Qimu": { + "gyro": 0.5e-3, + "gyro_bias": 1e-4, + "accel":1e-2, + "accel_bias": 1e-1 + }, + + // initial std on feature state + "initial_z": 2.5, // meter + "initial_std_x": 0.5, // pixel + "initial_std_y": 0.5, // pixel + "initial_std_z": 2.0, // meter + + // std of visuale measurement, in pixels + "visual_meas_std": 1.5, + "oos_meas_std": 3.5, + "subfilter_visual_meas_std": 3.5, + "max_depth": 5.0, + "min_depth": 0.05, + + + // depth sub-filter setting + "subfilter_ready_steps": 5, + "subfilter_MH_thresh": 8.991, + + "depth_opt_iters": 5, + "depth_opt_eps": 0.001, + "depth_opt_damping": 1e-3, + + "feature_P0_damping": 1000.0, + + "imu_calib": { + "Cas": [1, 1, 1], + "Car": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]], + "Cgs": [1, 1, 1], + "Cgr": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]] + }, + "imu_init_counter": 20, + + "camera_cfg": { + "model": "equidistant", + "rows": 512, + "cols": 512, + "fx": 190.97847715128717, + "fy": 190.9733070521226, + "cx": 254.93170605935475, + "cy": 256.8974428996504, + "k0123": [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, 0.00020293673591811182], + "max_iter": 25, + "comment": "512-cam0" + }, + + "min_inliers": 5, // minimum number of inlier measurements + + "MH_thresh": 8.991, // 8.991 + "MH_adjust_factor": 1.5, + + "1pt_RANSAC_thresh": 1.5, + "1pt_RANSAC_prob": 0.95, + "1pt_RANSAC_Chi2": 5.89, + + "tracker_cfg": { + "use_prediction": true, + "mask_size": 15, + "num_features_min": 60, + "num_features_max": 90, + "normalize": true, + + "OpticalFlow": { + "win_size": 15, + "max_level": 5, + "max_iter": 15, + "eps": 1e-4, + "threshold": 20 + }, + + // somehow, only BRISK and FAST work well with the generic FeatureDetector interface (Version 2.4.9) + "DetectorType": "FAST", + + "FAST": { + "threshold": 20, + "nonmaxSuppression": true + }, + + "GridAdapter": { + "grid_rows": 4, + "grid_cols": 4 + } + } + +} diff --git a/cfg/pointgrey_xsens.json b/cfg/pointgrey_xsens.json new file mode 100644 index 00000000..5131dc03 --- /dev/null +++ b/cfg/pointgrey_xsens.json @@ -0,0 +1,228 @@ +{ + // verbose + "simulation": false, + "print_timer": false, + "use_canvas": true, + + // algorithmic-level knobs + "integration_method": "PrinceDormand", // "PrinceDormand", "RK4", //, Fehlberg + "use_OOS": false, // update with Out-Of-State features + "use_depth_opt": true, // depth optimization + "use_MH_gating": true, + "use_1pt_RANSAC": false, + "use_compression": true, // measurement compression + "compression_trigger_ratio": 1.5, + "max_group_lifetime": 6, + + "PrinceDormand": { + "control_stepsize": false, + "tolerance": 1e-15, + "attempts": 12, + "min_scale_factor": 0.125, + "max_scale_factor": 4.0, + "stepsize": 0.002 + }, + + "RK4": { + "stepsize": 0.002 + }, + + // memory + "memory": { + "max_features": 256, + "max_groups": 256 // max groups should increase as allowed group lifetime increases + }, + + + // gravity constant + "gravity": [0, 0, -9.8], + // Initial State + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + + "bg" : [-0.05163, 0.0108186, 0.0188156], + "ba" : [-0.00342173, -0.00861755, 0.0218768], + "Wbc" : [[4.01e-02, -4.24e-02, 9.98e-01], + [-9.99e-01, -2.05e-03, 4.00e-02], + [3.50e-04, -9.99e-01, -4.25e-02]], + "Tbc": [0.0737, -0.00977, -0.1088], + "Wg" : [0, 0, 0] + }, + + "P" : { + "W" : 0.0001, + "T" : 0.001, + "V" : 0.5, + "bg" : 0.001, + "ba" : 0.01, + "Wbc" : 0.001, + "Tbc" : 0.01, + "Wg" : 0.01 + }, + + "Qmodel" : { + "W" : 0.000, + "T" : 0.0, + "V" : 0.0, + "wb" : 0.0000, + "ab" : 0.000, + "Wbc" : 0.000, + "Tbc" : 0.0, + "Wg" : 0.000 + }, + + "Qimu": { + "gyro": 24.0e-4, + "gyro_bias": 6.6e-5, + "accel": 4.2e-2, + "accel_bias": 25.8e-4 + }, + + + // initial std on feature state + "initial_z": 3.5, // meter + "initial_std_x": 1.5, // pixel + "initial_std_y": 1.5, // pixel + "initial_std_z": 2.0, // meter + + // std of visuale measurement, in pixels + "visual_meas_std": 3.5, + "subfilter_visual_meas_std": 3.5, + "oos_meas_std": 3.5, + "max_depth": 8.0, + "min_depth": 0.05, + + + // depth sub-filter setting + "subfilter": { + "ready_steps": 5, + "MH_thresh": 8.991 + }, + + "depth_opt": { + "max_iters": 5, + "eps": 1e-5, + "damping_factor": 1e-3, + "adjust_factor": 5.0, + "max_res_norm": 5.0 // maximal norm of per observation residuals + }, + + "feature_P0_damping": 10.0, + + "imu_calib": { + "Cas": [1.00056, 1.00062, 1.00136], + "Car": [[1, -0.000914275, -0.000414882], + [0, 1, -0.0000350183], + [0, 0, 1]], + "Cgs": [0.999823, 1.00412, 0.987355], + "Cgr": [[1, -0.00224194, 0.0120628], + [0.00306442, 1, -0.000998032], + [0.00285738, -0.0154485, 1]] + }, + "imu_init_counter": 20, + + "camera_cfg": { + "model": "atan", + "rows": 500, + "cols": 960, + "fx": 0.561859, + "fy": 1.081848, + "cx": 0.491896, + "cy": 0.5151548, + "w": 0.709402, + "comment": "intrinsics converted from relative to absolute values" + }, + + "min_inliers": 5, // minimum number of inlier measurements + + "MH_thresh": 5.991, // 8.991 + "MH_adjust_factor": 1.5, + + "1pt_RANSAC_thresh": 1.5, + "1pt_RANSAC_prob": 0.95, + "1pt_RANSAC_Chi2": 5.89, + + "tracker_cfg": { + "use_prediction": true, + "mask_size": 15, + "margin": 16, // image boundary to mask out + "num_features_min": 60, + "num_features_max": 90, + "max_pixel_displacement": 128, + "normalize": false, + + "KLT": { + "win_size": 15, + "max_level": 5, + "max_iter": 15, + "eps": 1e-2 + }, + + "extract_descriptor": false, + "descriptor_distance_thresh": -1, // -1 to disable descriptor check + "default_descriptor": "BRIEF", + + // "detector": "BRISK", + "detector": "FAST", + // "detector": "ORB", + // "detector": "AGAST", + // "detector": "GFTT", + + "FAST": { + // https://docs.opencv.org/3.4/df/d74/classcv_1_1FastFeatureDetector.html + "threshold": 5, + "nonmaxSuppression": true + }, + + "BRISK": { + // https://docs.opencv.org/3.4/de/dbf/classcv_1_1BRISK.html + "thresh": 25, + "octaves": 3, + "patternScale": 1.0 + }, + + "ORB": { + // https://docs.opencv.org/3.3.0/db/d95/classcv_1_1ORB.html + "nfeatures": 500, + "scaleFactor": 1.2, + "nlevels": 4, + "edgeThreshold": 31, + "firstLevel": 0, + "WTA_K": 2, + "patchSize": 31, + "fastThreshold": 20 + }, + + "AGAST": { + // https://docs.opencv.org/3.4/d7/d19/classcv_1_1AgastFeatureDetector.html + "threshold": 10, + "nonmaxSuppression": true + }, + + "GFTT": { + // Good Feature To Track + // https://docs.opencv.org/3.3.0/df/d21/classcv_1_1GFTTDetector.html + "maxCorners": 1000, + "qualityLevel": 0.01, + "minDistance": 1.0, + "blockSize": 3, + "useHarrisDetector": false, + "k": 0.04 + }, + + "BRIEF": { + "bytes": 64, + "use_orientation": false + }, + + "FREAK": { + "orientationNormalized": true, + "scaleNormalized": true, + "patternScale": 22.0, + "nOctaves": 4 + } + } + +} diff --git a/cfg/pointgrey_xsens_viewer.json b/cfg/pointgrey_xsens_viewer.json new file mode 100644 index 00000000..b1f63b58 --- /dev/null +++ b/cfg/pointgrey_xsens_viewer.json @@ -0,0 +1,28 @@ +{ + "window": { + "height": 1000, + "width": 960 + }, + + "viewport": { + "height": 500, + "width": 960, + "fx": 800, + "fy": 800, + "cx": 480, + "cy": 250, + "znear": 0.1, + "zfar": 10 + }, + + "bg_color": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + }, + "grid_size": 20, + "draw_trace_as_dots": false + +} + diff --git a/cfg/simulation.json b/cfg/simulation.json new file mode 100644 index 00000000..3d5d6d73 --- /dev/null +++ b/cfg/simulation.json @@ -0,0 +1,8 @@ +{ + "simulator_cfg": "../cfg/simulator.json", + "estimator_cfg": "../cfg/estimator_sim.json", + + "add_noise_to_init_state": true, + "enable_update": true, + "visualize": false +} diff --git a/cfg/simulator.json b/cfg/simulator.json new file mode 100644 index 00000000..f16b2e74 --- /dev/null +++ b/cfg/simulator.json @@ -0,0 +1,60 @@ +{ + // sensor setups + // total simulation time, in seconds + "total_time": 10, + "imu_hz": 200, + "camera_hz": 30, + "num_pts_to_track": 120, + "min_num_pts_to_track": 90, + "motion_type": 2, + "init_static_period": 1, + + "fixed_seed": true, + "seed": 0, + + // measurement noise + "gyro_noise_std": 1e-3, + "accel_noise_std": 1e-2, + "tracking_noise_std": 0.1, // in pixels + "max_track_lifetime": 10, + + // initial standard deviation added to states + "init_noise_std": { + "W": 0.0, + "T": 0.0, + "V": 0.0, + "bg": 0.001, + "ba": 0.01, + "Wbc": 0.001, + "Tbc": 0.01, + "Wg": 0.0 + }, + + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + "wb" : [0, 0, 0], + "ab" : [0, 0, 0], + "Wbc" : [3.1319, 0.00905, 0.00800], + "Tbc": [-0.0162997, -0.00375004, -0.0383651], + "Wg" : [0, 0], + "to" : 0.0 + }, + + // camera latency + "delay_camera_time": 0.00, + + // gravity + "gravity_magnitude": 9.8, + + // camera calibration + // "camera_cfg": "../cfg/atan.json", + "camera_cfg": "../cfg/equidistant.json", + + "z_near": 0.1, + "z_far": 5.0, + "visualize_tracks": false, + "track_drop_probability": 0.005, + "mask_size": 15.0 +} diff --git a/cfg/tuning.json b/cfg/tuning.json new file mode 100644 index 00000000..adeb3d6c --- /dev/null +++ b/cfg/tuning.json @@ -0,0 +1,155 @@ +{ + // verbose + "simulation": false, + "print_timer": false, + + // algorithmic-level knobs + "update_method": "ekf", + "integration_method": "RK4", // RK4, ForwardEuler + "RK4_stepsize": -1, //0.002, + "use_OOS": false, // update with Out-Of-State features + "use_depth_opt": true, // depth optimization + "use_MH_gating": true, + "use_1pt_RANSAC": false, + "use_compression": true, // measurement compression + "compression_trigger_ratio": 1.5, + + // memory + "max_features": 256, + "max_groups": 256, // max groups should increase as allowed group lifetime increases + "max_group_lifetime": 120, + + // gravity constant + "gravity": [0, 0, -9.8], + // Initial State + "X" : { + "W" : [0, 0, 0], + "T" : [0, 0, 0], + "V" : [0, 0, 0], + "bg" : [0, 0, 0], + "ba" : [0, 0, 0], + "Wbc" : [[-0.99952504, 0.00750192, -0.02989013], + [0.02961534, -0.03439736, -0.99896935], + [-0.00852233, -0.99938008, 0.03415885]], + "Tbc": [0.04557484, -0.0711618, -0.04468125], + "Wg" : [0, 0, 0] + }, + + "P" : { + "W" : 0.0001, + "T" : 0.001, + "V" : 0.5, + "bg" : 0.001, + "ba" : 0.001, + "Wbc" : 0.00001, + "Tbc" : 0.001, + "Wg" : 0.01 + }, + + "Qmodel" : { + "W" : 0.000, + "T" : 0.0, + "V" : 0.0, + "wb" : 0.0000, + "ab" : 0.000, + "Wbc" : 0.000, + "Tbc" : 0.0, + "Wg" : 0.000 + }, + + // original block without numerical integration of Lyapunov + "Qimu": { + "gyro": 0.5e-3, + "gyro_bias": 1e-4, + "accel":1e-2, + "accel_bias": 1e-1 + }, + + // initial std on feature state + "initial_z": 2.5, // meter + "initial_std_x": 0.5, // pixel + "initial_std_y": 0.5, // pixel + "initial_std_z": 2.0, // meter + + // std of visuale measurement, in pixels + "visual_meas_std": 1.5, + "oos_meas_std": 3.5, + "subfilter_visual_meas_std": 3.5, + "max_depth": 5.0, + "min_depth": 0.05, + + + // depth sub-filter setting + "subfilter_ready_steps": 5, + "subfilter_MH_thresh": 8.991, + + "depth_opt_iters": 5, + "depth_opt_eps": 0.001, + "depth_opt_damping": 1e-3, + + "feature_P0_damping": 1000.0, + + "imu_calib": { + "Cas": [1, 1, 1], + "Car": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]], + "Cgs": [1, 1, 1], + "Cgr": [[1, 0, 0], + [0, 1, 0], + [0, 0, 1]] + }, + "imu_init_counter": 20, + + "camera_cfg": { + "model": "equidistant", + "rows": 512, + "cols": 512, + "fx": 190.97847715128717, + "fy": 190.9733070521226, + "cx": 254.93170605935475, + "cy": 256.8974428996504, + "k0123": [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, 0.00020293673591811182], + "max_iter": 25, + "comment": "512-cam0" + }, + + "min_inliers": 5, // minimum number of inlier measurements + + "MH_thresh": 8.991, // 8.991 + "MH_adjust_factor": 1.5, + + "1pt_RANSAC_thresh": 1.5, + "1pt_RANSAC_prob": 0.95, + "1pt_RANSAC_Chi2": 5.89, + + "tracker_cfg": { + "use_prediction": true, + "mask_size": 15, + "num_features_min": 60, + "num_features_max": 90, + "normalize": true, + + "OpticalFlow": { + "win_size": 15, + "max_level": 5, + "max_iter": 15, + "eps": 1e-4, + "threshold": 20 + }, + + // somehow, only BRISK and FAST work well with the generic FeatureDetector interface (Version 2.4.9) + "DetectorType": "FAST", + + "FAST": { + "threshold": 20, + "nonmaxSuppression": true + }, + + "GridAdapter": { + "grid_rows": 4, + "grid_cols": 4 + } + } + +} diff --git a/cfg/viewer.json b/cfg/viewer.json new file mode 100644 index 00000000..723aa6b2 --- /dev/null +++ b/cfg/viewer.json @@ -0,0 +1,27 @@ +{ + "window": { + "height": 512, + "width": 1024 + }, + + "viewport": { + "width": 512, + "height": 512, + "fx": 800, + "fy": 800, + "cx": 256, + "cy": 256, + "znear": 0.1, + "zfar": 10 + }, + + "bg_color": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + }, + "grid_size": 20, + "draw_trace_as_dots": false + +} diff --git a/cfg/viewer_scenenet.json b/cfg/viewer_scenenet.json new file mode 100644 index 00000000..ea5d42c3 --- /dev/null +++ b/cfg/viewer_scenenet.json @@ -0,0 +1,27 @@ +{ + "window": { + "height": 240, + "width": 640 + }, + + "viewport": { + "width": 320, + "height": 240, + "fx": 400, + "fy": 400, + "cx": 160, + "cy": 120, + "znear": 0.1, + "zfar": 10 + }, + + "bg_color": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + }, + "grid_size": 20 + +} + diff --git a/cfg/vio.json b/cfg/vio.json new file mode 100644 index 00000000..92d15ad1 --- /dev/null +++ b/cfg/vio.json @@ -0,0 +1,14 @@ +{ + "estimator_cfg": "cfg/estimator.json", + "viewer_cfg": "cfg/viewer.json", + + "visualize": true, + "wait_time": 1, + "verbose": true, + + + "evaluation_cfg": { + "ignore_seconds": 0, // seconds + "RPE_interval": 1.0 // seconds + } +} diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 00000000..b983d3d7 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.5) +project(common) + +# # uncomment to overwrite target destinations +# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) +# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) + +add_library(common STATIC utils.cpp) +target_link_libraries(common absl::str_format pthread) + +# add_executable(example_process example_process.cpp) +# target_link_libraries(example_process glog pthread) +# +# option(BUILD_COMMON_TESTS True) +# if (${BUILD_COMMON_TESTS}) +# add_executable(test_rodrigues test/test_rodrigues.cpp) +# target_link_libraries(test_rodrigues gtest gtest_main) +# # add_executable(test_se3 test_se3.cpp) +# endif(${BUILD_COMMON_TESTS}) diff --git a/common/ProducerConsumerQueue.h b/common/ProducerConsumerQueue.h new file mode 100644 index 00000000..87933a2c --- /dev/null +++ b/common/ProducerConsumerQueue.h @@ -0,0 +1,189 @@ +/* + * Copyright 2012-present Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @author Bo Hu (bhu@fb.com) +// @author Jordan DeLong (delong.j@fb.com) +// +// Doc: +// https://github.com/facebook/folly/blob/master/folly/docs/ProducerConsumerQueue.md +// References on memory_order_relaxed and more: +// https://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +// #include + +namespace folly { + +constexpr size_t hardware_destructive_interference_size = 64; + +/* + * ProducerConsumerQueue is a one producer and one consumer queue + * without locks. + */ +template struct ProducerConsumerQueue { + typedef T value_type; + + ProducerConsumerQueue(const ProducerConsumerQueue &) = delete; + ProducerConsumerQueue &operator=(const ProducerConsumerQueue &) = delete; + + // size must be >= 2. + // + // Also, note that the number of usable slots in the queue at any + // given time is actually (size-1), so if you start with an empty queue, + // isFull() will return true after size-1 insertions. + explicit ProducerConsumerQueue(uint32_t size) + : size_(size), records_(static_cast(std::malloc(sizeof(T) * size))), + readIndex_(0), writeIndex_(0) { + assert(size >= 2); + if (!records_) { + throw std::bad_alloc(); + } + } + + ~ProducerConsumerQueue() { + // We need to destruct anything that may still exist in our queue. + // (No real synchronization needed at destructor time: only one + // thread can be doing this.) + if (!std::is_trivially_destructible::value) { + size_t readIndex = readIndex_; + size_t endIndex = writeIndex_; + while (readIndex != endIndex) { + records_[readIndex].~T(); + if (++readIndex == size_) { + readIndex = 0; + } + } + } + + std::free(records_); + } + + template bool write(Args &&... recordArgs) { + auto const currentWrite = writeIndex_.load(std::memory_order_relaxed); + auto nextRecord = currentWrite + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + if (nextRecord != readIndex_.load(std::memory_order_acquire)) { + new (&records_[currentWrite]) T(std::forward(recordArgs)...); + writeIndex_.store(nextRecord, std::memory_order_release); + return true; + } + + // queue is full + return false; + } + + // move (or copy) the value at the front of the queue to given variable + bool read(T &record) { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + if (currentRead == writeIndex_.load(std::memory_order_acquire)) { + // queue is empty + return false; + } + + auto nextRecord = currentRead + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + record = std::move(records_[currentRead]); + records_[currentRead].~T(); + readIndex_.store(nextRecord, std::memory_order_release); + return true; + } + + // pointer to the value at the front of the queue (for use in-place) or + // nullptr if empty. + T *frontPtr() { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + if (currentRead == writeIndex_.load(std::memory_order_acquire)) { + // queue is empty + return nullptr; + } + return &records_[currentRead]; + } + + // queue must not be empty + void popFront() { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + assert(currentRead != writeIndex_.load(std::memory_order_acquire)); + + auto nextRecord = currentRead + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + records_[currentRead].~T(); + readIndex_.store(nextRecord, std::memory_order_release); + } + + bool isEmpty() const { + return readIndex_.load(std::memory_order_acquire) == + writeIndex_.load(std::memory_order_acquire); + } + + bool isFull() const { + auto nextRecord = writeIndex_.load(std::memory_order_acquire) + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + if (nextRecord != readIndex_.load(std::memory_order_acquire)) { + return false; + } + // queue is full + return true; + } + + // * If called by consumer, then true size may be more (because producer may + // be adding items concurrently). + // * If called by producer, then true size may be less (because consumer may + // be removing items concurrently). + // * It is undefined to call this from any other thread. + size_t sizeGuess() const { + int ret = writeIndex_.load(std::memory_order_acquire) - + readIndex_.load(std::memory_order_acquire); + if (ret < 0) { + ret += size_; + } + return ret; + } + + // maximum number of items in the queue. + size_t capacity() const { return size_ - 1; } + +private: + using AtomicIndex = std::atomic; + + char pad0_[hardware_destructive_interference_size]; + const uint32_t size_; + T *const records_; + + alignas(hardware_destructive_interference_size) AtomicIndex readIndex_; + alignas(hardware_destructive_interference_size) AtomicIndex writeIndex_; + + char pad1_[hardware_destructive_interference_size - sizeof(AtomicIndex)]; +}; + +} // namespace folly diff --git a/common/alias.h b/common/alias.h new file mode 100644 index 00000000..acd65e77 --- /dev/null +++ b/common/alias.h @@ -0,0 +1,70 @@ +#pragma once + +#include "rodrigues.h" +#include "se3.h" + +namespace feh { + +using ftype = double; + +using Mat3 = Eigen::Matrix; +using Vec3 = Eigen::Matrix; +using Mat4 = Eigen::Matrix; +using Vec4 = Eigen::Matrix; +using Mat2 = Eigen::Matrix; +using Vec2 = Eigen::Matrix; +using Vec6 = Eigen::Matrix; +using Vec9 = Eigen::Matrix; +using Mat23 = Eigen::Matrix; +using Mat32 = Eigen::Matrix; +using Mat34 = Eigen::Matrix; +using Mat93 = Eigen::Matrix; +using Mat39 = Eigen::Matrix; +using MatX = Eigen::Matrix; +using VecX = Eigen::Matrix; + +using Mat3f = Eigen::Matrix; +using Mat4f = Eigen::Matrix; +using Mat34f = Eigen::Matrix; +using Mat23f = Eigen::Matrix; +using Mat24f = Eigen::Matrix; +using MatXf = Eigen::Matrix; +using MatX3f = Eigen::Matrix; + +using Mat3d = Eigen::Matrix; +using Mat4d = Eigen::Matrix; +using Mat34d = Eigen::Matrix; +using Mat23d = Eigen::Matrix; +using Mat24d = Eigen::Matrix; +using MatXd = Eigen::Matrix; +using MatX3d = Eigen::Matrix; + +using Vec2f = Eigen::Matrix; +using Vec3f = Eigen::Matrix; +using Vec4f = Eigen::Matrix; +using VecXf = Eigen::Matrix; + +using Vec2d = Eigen::Matrix; +using Vec3d = Eigen::Matrix; +using Vec4d = Eigen::Matrix; +using VecXd = Eigen::Matrix; + +using Vec2i = Eigen::Matrix; +using Vec3i = Eigen::Matrix; +using Vec4i = Eigen::Matrix; +using VecXi = Eigen::Matrix; +using MatXi = Eigen::Matrix; +using MatX3i = Eigen::Matrix; + +using SE3 = SE3Type; +using SO3 = SO3Type; + +using SE3f = SE3Type; +using SO3f = SO3Type; + +using SE3d = SE3Type; +using SO3d = SO3Type; + +static const ftype eps = 1e-4f; + +} // namespace feh diff --git a/common/atan.h b/common/atan.h new file mode 100644 index 00000000..4cf15a91 --- /dev/null +++ b/common/atan.h @@ -0,0 +1,142 @@ +#pragma once +#include "camera.h" + +namespace feh { + +template class ATANCamera : public BaseCamera> { +public: + using MyBase = BaseCamera>; + static constexpr int DIM = 5; // size of intrinsic parameters + + ATANCamera(int rows, int cols, T fx, T fy, T cx, T cy, T w) + : BaseCamera>{rows, cols, fx, fy, cx, cy}, w_(w), + invw_(1.0 / w), w2_(2.0 * std::tan(w * 0.5)) {} + + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + + Eigen::Matrix xp; + + f_t R = xc.norm(); + f_t f{1}; + bool singular = (R < 0.0001 || w_ == 0); + + if (!singular) { + f = invw_ * std::atan(w2_ * R) / R; + } + + // Project through distortion model + xp(0) = fx_ * f * xc(0) + cx_; + xp(1) = fy_ * f * xc(1) + cy_; + + if (jac != nullptr) { + auto &J{*jac}; + // compute jacobians + if (singular) { + J(0, 0) = fx_; + J(1, 1) = fy_; + } else { + // FIXME: optimize computation + f_t df_dx, df_dy, df_dR; + f_t a = w2_ * R; + df_dR = invw_ * (1. / (1 + a * a) * a - std::atan(a)) / R / R; + df_dx = df_dR * xc(0) / R; + df_dy = df_dR * xc(1) / R; + + J << fx_ * f + fx_ * xc(0) * df_dx, fx_ * xc(0) * df_dy, + fy_ * xc(1) * df_dx, fy_ * f + fy_ * xc(1) * df_dy; + } + } + + if (jacc != nullptr) { + auto &J{*jacc}; + J.setZero(2, DIM); // d[x, y]_d[fx, fy, cx, cy, w] + if (singular) { + J << xc(0), 0, 1, 0, 0, 0, xc(1), 0, 1, 0; + } else { + J(0, 0) = f * xc(0); + J(0, 2) = 1; + J(1, 1) = f * xc(1); + J(1, 3) = 1; + // f = inv(w) * atan(w2 * R) / R + // R is constant w.r.t. w + f_t df_dinvw = std::atan(w2_ * R) / R; + f_t dinvw_dw = -invw_ * invw_; + + f_t df_datanw2R = invw_ / R; + // datan(x)_dx = 1 / (1 + x * x) + f_t datanw2R_dw2R = 1 / (1 + (w2_ * R) * (w2_ * R)); + f_t dw2R_dw2 = R; // w2R = w2 * R + // Recall: w2 = 2 * tan(w * 0.5) + // dw2_dw = 2.0 / cos^2(w*0.5) * 0.5 = 1.0 / cos^2(2 * 0.5); + f_t dw2_dw = 1 / std::cos(w_ * 0.5); + dw2_dw *= dw2_dw; + f_t df_dw = df_dinvw * dinvw_dw + + df_datanw2R * datanw2R_dw2R * dw2R_dw2 * dw2_dw; + J(0, 4) = fx_ * xc(0) * df_dw; + J(1, 4) = fy_ * xc(1) * df_dw; + } + } + return xp; + } + + template + Eigen::Matrix UnProject( + const Eigen::MatrixBase &xp, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + + using f_t = typename Derived::Scalar; + Eigen::Matrix xc; + + Eigen::Matrix tmp((xp(0) - cx_) / fx_, (xp(1) - cy_) / fy_); + f_t R = tmp.norm(); + f_t RR{w_ == 0 ? R : std::tan(R * w_) / w2_}; + f_t f{R > 0.01 ? RR / R : 1.0}; + xc = f * tmp; + + if (jac != nullptr) { + if (f == 1) { + (*jac)(0, 0) = 1.0 / fx_; + (*jac)(1, 1) = 1.0 / fy_; + } else { + f_t df_dR; + f_t a = std::tan(R * w_); + df_dR = 1.0 / w2_ * (((1 + a * a) * w_ * R - a) / R / R); + + f_t df_dx, df_dy; + df_dx = df_dR * tmp(0) / R / fx_; + df_dy = df_dR * tmp(1) / R / fy_; + + (*jac) << tmp(0) * df_dx + f / fx_, tmp(0) * df_dy, tmp(1) * df_dx, + tmp(1) * df_dy + f / fy_; + } + } + return xc; + } + + void Print(std::ostream &out) const { + out << "ATAN Camera" << std::endl + << "[rows, cols]=" << rows_ << "," << cols_ << "]" << std::endl + << "[fx, fy, cx, cy, w]=[" << fx_ << "," << fy_ << "," << cx_ << "," + << cy_ << "," << w_ << "]" << std::endl; + } + +protected: + using MyBase::rows_; + using MyBase::cols_; + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; + + T w_, invw_, w2_; +}; + +} // namespace feh diff --git a/common/camera.h b/common/camera.h new file mode 100644 index 00000000..f7db0e1f --- /dev/null +++ b/common/camera.h @@ -0,0 +1,77 @@ +#pragma once + +#include "Eigen/Dense" + +namespace feh { + +template class BaseCamera { +public: + // constructor + BaseCamera(int rows, int cols, T fx, T fy, T cx, T cy) + : rows_{rows}, cols_{cols}, fx_{fx}, fy_{fy}, cx_{cx}, cy_{cy} {} + + // copy constructor & assignment + BaseCamera &operator=(const BaseCamera &) = default; + BaseCamera(const BaseCamera &) = default; + + // move constructor & assignment + BaseCamera &operator=(BaseCamera &&) = default; + BaseCamera(BaseCamera &&) = default; + + // project a point xc in camera coordinates to pixel coordinates. + // xc: camera coordinates of a point. + // jac: jacobian matrix of xp w.r.t. xc, i.e., dxp/dxc + // jacc: jacobian matrix of xp w.r.t. camera intrinsics, for online + // calibration + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + return static_cast(this)->Project(xc, jac); + } + + // un-project a point xp in pixel coordinates to the camera coordinates. + // xp: pixel coordinates of a point. + // jac: jacobian matrix of xc w.r.t. xp, i.e., dxc/dxp + // jacc: jacobian matrix of xc w.r.t. camera intrinsics, for online + // calibration + template + Eigen::Matrix UnProject( + const Eigen::MatrixBase &xp, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + return static_cast(this)->UnProject(xp, jac); + } + + // print intrinsics of the camer amodel + void Print(std::ostream &out) const { static_cast(this)->Print(out); } + + // handy accessors + int rows() const { return rows_; } + int cols() const { return cols_; } + T cx() const { return cx_; } + T cy() const { return cy_; } + T fx() const { return fx_; } + T fy() const { return fy_; } + +protected: + int rows_, cols_; + T fx_, fy_, cx_, cy_; +}; + +// check whether a given point is out of view. +template bool OutOfView(T x, T y, const Cam &cam) { + float margin(0.01f); + return x < cam.cols() * margin || x >= cam.cols() * (1 - margin) || + y < cam.rows() * margin || y >= cam.rows() * (1 - margin); +} + +// Eigen version of the above function. +template +bool OutOfView(const Eigen::MatrixBase &xp, const Cam &cam) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + return OutOfView(xp(0), xp(1), cam); +} + +} // feh diff --git a/common/component.h b/common/component.h new file mode 100644 index 00000000..8dd47020 --- /dev/null +++ b/common/component.h @@ -0,0 +1,52 @@ +// For readability and maintainability, it's better to adopt +// a modular design approach, where componets like groups and features, +// and even IMUs and cameras whose intrinsic parameters can be estimated, +// maintain their own local nominal state. +// The estimator maintains the overall error state, +// and performs state propagation and measurement update. +// When needed, the estimator pulls local nominal states from each module +// to compute Jacobians, and updates the local nominal states +// by injecting the error state back to the nominal state internal to each +// module. +// We abstract as the notion of ''Componet'' all those modules whose +// internal parameters can be estimated. +// +// We adopt the CRTP idiom to ensure a minimal set of local state +// operations are implemented. +// This is more like to impose design requirements rather than to +// enable (static) polymorphism. +// +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once + +namespace feh { + +// helper function to check whehter the given "State" type has a "Tangent" type +// defined. +// referene: +// https://en.cppreference.com/w/cpp/types/void_t +// modified according the has_type_member function +template > struct has_tangent : std::false_type {}; + +template +struct has_tangent> : std::true_type {}; + +// CRTP pattern for static polymorphism +// Derived: Derived class to enforce the implementation of UpdateState +// S: the nominal state for the local parameters. +// Error: the error state for the local parameters. +template struct Component { + std::enable_if_t::value, void> + UpdateState(const typename State::Tangent &dX) { + static_cast(this)->UpdateState(dX); + } + + std::enable_if_t::value, void> + UpdateState(const State &dX) { + static_cast(this)->UpdateState(dX); + } +}; + +// example usage: see src/imu.h + +} // namespace feh diff --git a/common/equidist.h b/common/equidist.h new file mode 100644 index 00000000..5d6f44ff --- /dev/null +++ b/common/equidist.h @@ -0,0 +1,175 @@ +#pragma once +#include "camera.h" + +namespace feh { + +template +class EquidistantCamera : public BaseCamera> { +public: + using MyBase = BaseCamera>; + static constexpr int DIM = 8; // size of intrinsic parameters + + EquidistantCamera(int rows, int cols, T fx, T fy, T cx, T cy, T k0, T k1, + T k2, T k3, int max_iter = 15) + : BaseCamera>{rows, cols, fx, fy, cx, cy}, + k0_{k0}, k1_{k1}, k2_{k2}, k3_{k3}, max_iter_{max_iter} {} + + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + Eigen::Matrix xp; + + f_t xy_norm2 = xc.squaredNorm(); + f_t xy_norm = sqrt(xy_norm2); + f_t xyz_norm2 = xy_norm2 + 1; + + f_t th = std::atan2(xy_norm, 1.0); + + f_t phi = std::atan2(xc[1], xc[0]); + + f_t th2 = th * th; + f_t th3 = th2 * th; + f_t th4 = th3 * th; + f_t th5 = th3 * th2; + f_t th6 = th5 * th; + f_t th7 = th5 * th2; + f_t th8 = th7 * th; + f_t th9 = th7 * th2; + f_t r = th + k0_ * th3 + k1_ * th5 + k2_ * th7 + k3_ * th9; + + f_t cos_phi = std::cos(phi); + f_t sin_phi = std::sin(phi); + + f_t u = fx_ * r * cos_phi + cx_; + f_t v = fy_ * r * sin_phi + cy_; + + // fill in xp + xp[0] = u; + xp[1] = v; + + if (jac != nullptr) { + f_t dphi_dx = -xc[1] / xy_norm2; + f_t dphi_dy = xc[0] / xy_norm2; + + f_t dth_dx = xc[0] / xyz_norm2 / xy_norm; + f_t dth_dy = xc[1] / xyz_norm2 / xy_norm; + + f_t dr_dth = + 1 + k0_ * 3 * th2 + k1_ * 5 * th4 + k2_ * 7 * th6 + k3_ * 9 * th8; + + f_t du_dx = fx_ * cos_phi * dr_dth * dth_dx - fx_ * r * sin_phi * dphi_dx; + f_t du_dy = fx_ * cos_phi * dr_dth * dth_dy - fx_ * r * sin_phi * dphi_dy; + + f_t dv_dx = fy_ * sin_phi * dr_dth * dth_dx + fy_ * r * cos_phi * dphi_dx; + f_t dv_dy = fy_ * sin_phi * dr_dth * dth_dy + fy_ * r * cos_phi * dphi_dy; + + // fill in jacobians + (*jac) << du_dx, du_dy, dv_dx, dv_dy; + } + + if (jacc != nullptr) { + auto &J{*jacc}; + J.setZero(2, 8); // d[x,y]_[fx. fy, cx, cy, k0, k1, k2, k3] + + J(0, 0) = r * cos_phi; // dx_dfx + J(0, 2) = 1; // dx_dcx + J(1, 1) = r * sin_phi; // dy_dfy + J(1, 3) = 1; // dy_dcy + + Eigen::Matrix dr_dk{th3, th5, th7, + th9}; // dr_d[k0, k1, k2, k3] + J.template block<1, 4>(0, 4) = fx_ * cos_phi * dr_dk; + J.template block<1, 4>(1, 4) = fy_ * sin_phi * dr_dk; + } + return xp; + } + + template + Eigen::Matrix UnProject( + const Eigen::MatrixBase &xp, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + using Vec2 = Eigen::Matrix; + Vec2 xc; + + f_t xn = xp[0] - cx_; + f_t yn = xp[1] - cy_; + + f_t b(fx_ * yn), a(fy_ * xn); + f_t phi = std::atan2(b, a); + f_t cos_phi = std::cos(phi); + f_t sin_phi = std::sin(phi); + + f_t rth = xn / (fx_ * cos_phi); + + f_t th = rth; + // solve th: + // th + k0*th**3 + k1*th**5 + k2*th**7 + k3*th**9 = rth + + f_t th2, th3, th4, th6, x0, x1; + for (int i = 0; i < max_iter_; i++) { + // f = (th + k0*th**3 + k1*th**5 + k2*th**7 + k3*th**9 - rth)^2 + th2 = th * th; + th3 = th2 * th; + th4 = th2 * th2; + th6 = th4 * th2; + x0 = k0_ * th3 + k1_ * th4 * th + k2_ * th6 * th + k3_ * th6 * th3 - rth + + th; + x1 = 3 * k0_ * th2 + 5 * k1_ * th4 + 7 * k2_ * th6 + 9 * k3_ * th6 * th2 + + 1; + f_t d = 2 * x0 * x1; + f_t d2 = 4 * th * x0 * (3 * k0_ + 10 * k1_ * th2 + 21 * k2_ * th4 + + 36 * k3_ * th6) + + 2 * x1 * x1; + f_t delta = d / d2; + th -= delta; + } + f_t tan_th = std::tan(th); + xc[0] = tan_th * cos_phi; + xc[1] = tan_th * sin_phi; + + if (jac != nullptr) { + f_t a2b2 = a * a + b * b; + Vec2 dphi_dxy(-b / a2b2 * fy_, a / a2b2 * fx_); + Vec2 dcosphi_dxy(-sin_phi * dphi_dxy); + Vec2 dsinphi_dxy(cos_phi * dphi_dxy); + Vec2 drth_dxy(cos_phi - xn * dcosphi_dxy[0], -xn * dcosphi_dxy[1]); + drth_dxy /= (fx_ * cos_phi * cos_phi); + + f_t cos_th(cos(th)); + Vec2 dtanth_dxy(drth_dxy / x1 / (cos_th * cos_th)); + Vec2 doutx_dxy(cos_phi * dtanth_dxy + tan_th * dcosphi_dxy); + Vec2 douty_dxy(sin_phi * dtanth_dxy + tan_th * dsinphi_dxy); + (*jac) << doutx_dxy[0], doutx_dxy[1], douty_dxy[0], douty_dxy[1]; + } + return xc; + } + + void Print(std::ostream &out) const { + out << "Equidistant Camera" << std::endl + << "[rows, cols]=" << rows_ << "," << cols_ << "]" << std::endl + << "[fx, fy, cx, cy]=[" << fx_ << "," << fy_ << "," << cx_ << "," << cy_ + << "]" << std::endl + << "[k0, k1, k2, k3]=[" << k0_ << "," << k1_ << "," << k2_ << "," << k3_ + << "]" << std::endl; + } + +protected: + using MyBase::rows_; + using MyBase::cols_; + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; + + T k0_, k1_, k2_, k3_; + int max_iter_; +}; + +} // namespace feh diff --git a/common/example_process.cpp b/common/example_process.cpp new file mode 100644 index 00000000..c37e5e4f --- /dev/null +++ b/common/example_process.cpp @@ -0,0 +1,47 @@ +#include "process.h" +#include + +using namespace feh; + +struct ExampleMessage { + virtual ~ExampleMessage() {} +}; + +struct PrintMessage : public ExampleMessage { + PrintMessage(int value) : value_{value} {} + int value_; +}; + +class ExampleProcess : public Process { +public: + using MessageT = ExampleMessage; + ExampleProcess(uint32_t size = 1000) : Process{size}, accumulator_{0} {} + + // Decalre process-specific member variables. + int accumulator_; + +protected: + void Handle(ExampleMessage *message) { + // Define the process-specific handle function. + if (typeid(*message) == typeid(PrintMessage)) { + accumulator_ += dynamic_cast(message)->value_; + delete message; + } + } +}; + +int main() { + ExampleProcess proc{2000}; + proc.Start(); + int accumulator{0}; + for (int i = 0; i < 2000; ++i) { + usleep(10); // sleep for the process to catch up + proc.Enqueue(new PrintMessage(i)); + accumulator += i; + } + proc.Enqueue(nullptr); + std::cout << "process.accumulator=" << proc.accumulator_ << std::endl; + std::cout << "main thread accumulator=" << accumulator << std::endl; + CHECK_EQ(proc.accumulator_, accumulator) + << "main thread and process accumulated different values"; +} diff --git a/common/pinhole.h b/common/pinhole.h new file mode 100644 index 00000000..ebdb7f73 --- /dev/null +++ b/common/pinhole.h @@ -0,0 +1,69 @@ +#pragma once +#include "camera.h" + +namespace feh { + +template +class PinholeCamera : public BaseCamera> { +public: + using MyBase = BaseCamera>; + static constexpr int DIM = 4; // size of intrinsic parameters + + PinholeCamera(int rows, int cols, T fx, T fy, T cx, T cy) + : BaseCamera>{rows, cols, fx, fy, cx, cy} {} + + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + Eigen::Matrix xp{fx_ * xc(0) + cx_, fy_ * xc(1) + cy_}; + + if (jac != nullptr) { + // fill in jacobians + (*jac) << fx_, 0, 0, fy_; + } + + if (jacc != nullptr) { + auto &J{*jacc}; + J.setZero(2, 4); // d[x, y]_d[fx, fy, cx, cy] + J << xc(0), 0, 1, 0, 0, xc(1), 0, 1; + } + return xp; + } + + template + Eigen::Matrix UnProject( + const Eigen::MatrixBase &xp, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + using Vec2 = Eigen::Matrix; + Vec2 xc{(xp(0) - cx_) / fx_, (xp(1) - cy_) / fy_}; + + if (jac != nullptr) { + (*jac) << 1 / fx_, 0, 0, 1 / fy_; + } + return xc; + } + + void Print(std::ostream &out) const { + out << "Pinhole Camera" << std::endl + << "[rows, cols]=" << rows_ << "," << cols_ << "]" << std::endl + << "[fx, fy, cx, cy]=[" << fx_ << "," << fy_ << "," << cx_ << "," << cy_ + << "]" << std::endl; + } + +protected: + using MyBase::rows_; + using MyBase::cols_; + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; +}; + +} // namespace feh diff --git a/common/process.h b/common/process.h new file mode 100644 index 00000000..bda6242b --- /dev/null +++ b/common/process.h @@ -0,0 +1,91 @@ +#pragma once +// stl +#include +#include +#include +// 3rdparty +#include "ProducerConsumerQueue.h" +#include "glog/logging.h" + +// own +#include "utils.h" + +namespace feh { + +// my little process wrapper of +// the single producer single consumer queue +// from facebook's folly library +template class Process { +public: + // struct Block : public MessageT { + // Block() : ready_{false} {} + // std::atomic ready_; + // }; + + Process(uint32_t size = 1000) : worker_{nullptr}, queue_{size} {} + + Process(const Process &) = delete; + Process &operator=(const Process &) = delete; + + virtual void Wait() { + while (!queue_.isEmpty()) { + usleep(1); + } + } + + virtual ~Process() { + if (worker_) { + worker_->join(); + delete worker_; + } + LOG(INFO) << "process stopped"; + } + + void Start() { + worker_ = new std::thread([this]() { + for (;;) { + std::unique_ptr message; + while (!queue_.read(message)) { + continue; + } + if (!this->Handle(message.get())) { + LOG(FATAL) << "cannot handle unknown message type"; + } + } + }); + } + + void Enqueue(std::unique_ptr message) { + // DLOG(INFO) << "enqueueing message ..." << std::endl; + while (!queue_.write(std::move(message))) { + continue; + } + // DLOG(INFO) << "message euqueued" << std::endl; + } + +protected: + // Message handler. Return true if the message is known to this process and + // successfully processed; otherwise return false. + // This is like the "chain of responsibility" design pattern, where the + // message + // will be passed to a child class only if the parent class cannot handle it. + virtual bool Handle(MessageT *message) { + // LOG(INFO) << "Template process; implement actual handle function here"; + // NOTE: Handle function is in charge of destroying the message if needed. + // if (auto msg = dynamic_cast(message)) { + // msg->ready_ = true; + // delete message; + // return true; + // } + return false; + } + +private: + own worker_; + // folly::ProducerConsumerQueue> queue_; // the queue owns the + // pointers and need to delete them after use + folly::ProducerConsumerQueue> + queue_; // the queue owns the pointers and need to delete them after use +}; + +} // namespace feh diff --git a/common/radtan.h b/common/radtan.h new file mode 100644 index 00000000..672019d6 --- /dev/null +++ b/common/radtan.h @@ -0,0 +1,134 @@ +#pragma once +#include "camera.h" + +namespace feh { + +template +class RadialTangentialCamera : public BaseCamera> { +public: + using MyBase = BaseCamera>; + static constexpr int DIM = 9; // size of intrinsic parameters + + RadialTangentialCamera(int rows, int cols, T fx, T fy, T cx, T cy, T p1, T p2, + T k1, T k2, T k3, int max_iter = 15) + : BaseCamera>{rows, cols, fx, fy, cx, cy}, + p1_{p1}, p2_{p2}, k1_{k1}, k2_{k2}, k3_{k3}, max_iter_{max_iter} {} + + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + + using f_t = typename Derived::Scalar; + // intermediate quantities + f_t x2 = xc(0) * xc(0); + f_t y2 = xc(1) * xc(1); + f_t xy = xc(0) * xc(1); + f_t r2{x2 + y2}; + f_t r4{r2 * r2}; + f_t r6{r2 * r4}; + // compute the correction for radial distortion + f_t kr{1.0 + k1_ * r2 + k2_ * r4 + k3_ * r6}; + // compute the correction for tangential distortion + Eigen::Matrix kt{2.0 * p1_ * xy + p2_ * (r2 + 2.0 * x2), + 2.0 * p2_ * xy + p1_ * (r2 + 2.0 * y2)}; + // apply un-distortion + Eigen::Matrix xk{kr * xc + kt}; + // convert to pixels + Eigen::Matrix xp{xk(0) * fx_ + cx_, xk(1) * fy_ + cy_}; + + // optionally compute the jacobian + if (jac != nullptr) { + // fill in jacobians + // dxp_dxc = dxp_dxk * dxk_dxc + // dxk_dxc = dxk_dkr * dkr_dxc + diag([kr, kr]) + dxk_dkt * dkt_dxc + Eigen::Matrix dxp_dxk; + dxp_dxk << fx_, 0, 0, fy_; + Eigen::Matrix dxk_dkr{xc}; + + // dkr_dx = k1_ * 2 * r * dr_dx + k2_ * 4.0 * r3 * dr_dx + k3_ * 6.0 + // * r5 * dr_dx; + // dkr_dy = k1_ * 2 * r * dr_dy + k2_ * 4.0 * r3 * dr_dy + k3_ * 6.0 + // * r5 * dr_dy; + // Since dr_dx = x/r and dr_dy = y / r + // dkr_dx = k1_ * 2 * x + k2_ * 4.0 * r2 * x + k3_ * 6.0 * r4 * x; + // = (k1_ * 2 + k2_ * 4 * r2 + k3_ * 6 * r4) * x; + f_t dkr_dxc_coeff = k1_ * 2 + k2_ * 4 * r2 + k3_ * 6 * r4; + Eigen::Matrix dkr_dxc{dkr_dxc_coeff, dkr_dxc_coeff}; + + // kt = [2.0 * p1_ * xy + p2_ * (r2 + 2.0 * x2), + // 2.0 * p2_ * xy + p1_ * (r2 + 2.0 * y2)] + Eigen::Matrix dkt_dxc; + dkt_dxc << 2.0 * p1_ * xc(1) + p2_ * (2 * xc(0) + 4.0 * xc(0)), + 2.0 * p1_ * xc(0) + p2_ * (2 * xc(1)), + 2.0 * p2_ * xc(1) + p1_ * (2.0 * xc(0)), + 2.0 * p2_ * xc(0) + p1_ * (2 * xc(1) + 4 * xc(1)); + + Eigen::Matrix dxk_dxc{dxk_dkr * dkr_dxc + dkt_dxc}; + dxk_dxc(0, 0) += kr; + dxk_dxc(1, 1) += kr; + *jac = dxp_dxk * dxk_dxc; + } + + if (jacc != nullptr) { + auto &J{*jacc}; + J.setZero(2, DIM); // d[x, y]_d[fx, fy, cx, cy, p1, p2, k1, k2, k3] + J(0, 0) = xk(0); + J(0, 2) = 1; + J(1, 1) = xk(1); + J(1, 3) = 1; + Eigen::Matrix dxk_dp; // d[x, y]_d[p1, p2] + dxk_dp << 2.0 * xy, r2 + 2.0 * x2, r2 + 2.0 * y2, 2.0 * xy; + + Eigen::Matrix dkr_dk{r2, r4, r6}; // dkr_d[k1, k2, k3] + Eigen::Matrix dxk_dk{xc * dkr_dk}; + // dxk_dk << xc(0) * dkr_dk, + // xc(1) * dkr_dk; + + J.template block<1, 5>(0, 4) << fx_ * dxk_dp.row(0), fx_ * dxk_dk.row(0); + J.template block<1, 5>(1, 4) << fy_ * dxk_dp.row(1), fy_ * dxk_dk.row(1); + } + return xp; + } + + template + Eigen::Matrix UnProject( + const Eigen::MatrixBase &xp, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + using Vec2 = Eigen::Matrix; + Vec2 xc{(xp(0) - cx_) / fx_, (xp(1) - cy_) / fy_}; + + if (jac != nullptr) { + (*jac) << 1 / fx_, 0, 0, 1 / fy_; + } + return xc; + } + + void Print(std::ostream &out) const { + out << "RadialTangential Camera" << std::endl + << "[rows, cols]=" << rows_ << "," << cols_ << "]" << std::endl + << "[fx, fy, cx, cy]=[" << fx_ << "," << fy_ << "," << cx_ << "," << cy_ + << "]" + << "[p1, p2]=[" << p1_ << "," << p2_ << "]" + << "[k0, k1, k2]=[" << k1_ << "," << k2_ << "," << k3_ << "]" + << std::endl; + } + +protected: + using MyBase::rows_; + using MyBase::cols_; + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; + T p1_, p2_, k1_, k2_, k3_; + int max_iter_; +}; + +} // namespace feh diff --git a/common/rodrigues.h b/common/rodrigues.h new file mode 100644 index 00000000..f70bc183 --- /dev/null +++ b/common/rodrigues.h @@ -0,0 +1,254 @@ +#pragma once +#include "Eigen/Dense" +#include "math.h" +#include + +namespace feh { + +constexpr int Sum1ToN(int N) { return (N * (N + 1)) >> 1; } + +template +Eigen::Matrix +dA_dAu(const Eigen::MatrixBase &A) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, N, N); + + Eigen::Matrix D; + int idx_u{0}; // indexing to the upper triangular part of the matrix + for (int i = 0; i < N; ++i) { + for (int j = i; j < N; ++j) { + D(i * N + j, idx_u++) = 1; + } + } + return D; +} + +template +Eigen::Matrix +unstack(const Eigen::MatrixBase &u, int major = Eigen::RowMajor) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, M * N, 1); + Eigen::Matrix m; + for (int i = 0; i < M; ++i) + for (int j = 0; j < N; ++j) { + if (major == Eigen::RowMajor) { + m(i, j) = u(i * M + j); + } else { + m(j, i) = u(i * M + j); + } + } + return m; +} + +template +Eigen::Matrix +hat(const Eigen::MatrixBase &u) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + return (Eigen::Matrix{} << 0, -u(2), u(1), + u(2), 0, -u(0), -u(1), u(0), 0) + .finished(); +} + +template Eigen::Matrix dhat() { + return (Eigen::Matrix{} << 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, + 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0) + .finished(); +} + +template +Eigen::Matrix +dhat(const Eigen::MatrixBase &u) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + return dhat(); +} + +template +Eigen::Matrix +vee(const Eigen::MatrixBase &R) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3); + return {R(2, 1) - R(1, 2), R(0, 2) - R(2, 0), R(1, 0) - R(0, 1)}; +} + +template Eigen::Matrix dvee() { + return (Eigen::Matrix{} << 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, + 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0) + .finished(); +} + +template +Eigen::Matrix +dvee(const Eigen::MatrixBase &R) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3); + return dvee(); +} + +template +Eigen::Matrix dAt_dA() { + Eigen::Matrix D; + D.setZero(); + for (int m = 0; m < M; ++m) { + for (int n = 0; n < N; ++n) { + D(m * N + n, n * M + m) = 1; + } + } + return D; +} + +template +Eigen::Matrix +dAt_dA(const Eigen::MatrixBase &A) { + return dAt_dA(); +} + +// Note, by default the Eigen matrices arrange data in RowMajor order. +// This does not affect the way we index the element via () operator. +// But when using Map<> function to map raw internal data to matrices/vectors, +// we need to be careful about the order. +// dC_{n,p}/dA_{n,m}=B_{m,p} +template +Eigen::Matrix +dAB_dA(const Eigen::MatrixBase &A, + const Eigen::MatrixBase &B) { + + using T = typename Derived::Scalar; + constexpr int N = Derived::RowsAtCompileTime; + constexpr int M = Derived::ColsAtCompileTime; + constexpr int P = OtherDerived::ColsAtCompileTime; + + static_assert(std::is_same::value, + "Operands should have same dtype."); + static_assert(M == OtherDerived::RowsAtCompileTime, + "Columns of A should match rows of B."); + + Eigen::Matrix D; + D.setZero(); + for (int n = 0; n < N; ++n) { + for (int p = 0; p < P; ++p) { + for (int m = 0; m < M; ++m) { + D(n * P + p, n * M + m) += B(m, p); + } + } + } + return D; +} + +// dC_{n,p}/dB_{m,p}=A_{n,m} +template +Eigen::Matrix +dAB_dB(const Eigen::MatrixBase &A, + const Eigen::MatrixBase &B) { + + using T = typename Derived::Scalar; + constexpr int N = Derived::RowsAtCompileTime; + constexpr int M = Derived::ColsAtCompileTime; + constexpr int P = OtherDerived::ColsAtCompileTime; + static_assert(std::is_same::value, + "Operands should have same type."); + static_assert(M == OtherDerived::RowsAtCompileTime, + "Columns of A should match rows of B."); + + Eigen::Matrix D; + D.setZero(); + for (int n = 0; n < N; ++n) { + for (int p = 0; p < P; ++p) { + for (int m = 0; m < M; ++m) { + D(n * P + p, m * P + p) += A(n, m); + } + } + } + return D; +} + +template +Eigen::Matrix +rodrigues(const Eigen::MatrixBase &w, + Eigen::Matrix *dR_dw = nullptr) { + + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + using T = typename Derived::Scalar; + Eigen::Matrix R; + + T th = w.norm(); + + if (th < 1e-8) { + // R = I + hat(w) + // std::cout << "small angle approximation" << std::endl; + R = Eigen::Matrix::Identity() + hat(w); + if (dR_dw) { + *dR_dw = dhat(w); + } + return R; + } + T inv_th = 1.0 / th; + Eigen::Matrix u = w * inv_th; + + // R = I + u.hat * sin(th) + (u.hat)^2 * (1-cos(th)) + T sin_th = sin(th); + T cos_th = cos(th); + Eigen::Matrix uhat = hat(u); + Eigen::Matrix uhat2 = uhat * uhat; + R = Eigen::Matrix::Identity() + uhat * sin_th + uhat2 * (1 - cos_th); + if (dR_dw) { + Eigen::Matrix dR_du = + sin_th * dhat(u) + + (1 - cos_th) * (dAB_dA(uhat, uhat) + dAB_dB(uhat, uhat)) * dhat(u); + Eigen::Matrix du_dw = + inv_th * (Eigen::Matrix::Identity() - u * u.transpose()); + Eigen::Matrix dR_dth = Eigen::Map>( + Eigen::Matrix{uhat * cos_th + uhat2 * sin_th}.data()); + // Eigen::Matrix dth_dw = u.transpose(); + *dR_dw = dR_du * du_dw + dR_dth * u.transpose(); + } + return R; +} + +template +Eigen::Matrix +invrodrigues(const Eigen::MatrixBase &R, + Eigen::Matrix *dw_dR = nullptr) { + + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3); + using T = typename Derived::Scalar; + + Eigen::Matrix w; + + T tmp = 0.5 * (R.trace() - 1); + Eigen::Matrix vee_R = vee(R); + if (tmp > 1.0 - 1e-10) { + // std::cout << "small angle approximation" << std::endl; + w = 0.5 * vee_R; + if (dw_dR) { + *dw_dR = 0.5 * dvee(R); + } + return w; + } + + T th = acos(tmp); + T sin_th = sin(th); + T inv_sin_th = 1.0 / sin_th; + Eigen::Matrix u = 0.5 * vee_R * inv_sin_th; + + w = th * u; + + if (dw_dR) { + Eigen::Matrix dth_dR; + T dth_dtmp = -1 / sqrt(1 - tmp * tmp); + Eigen::Matrix dtmp_dR; + dtmp_dR << 1, 0, 0, 0, 1, 0, 0, 0, 1; // d(trace(R)-1)_dR + dtmp_dR *= 0.5; + dth_dR = dth_dtmp * dtmp_dR; + + Eigen::Matrix du_dR; + // u = vee(R) / (2*sin(th)); + du_dR = 0.5 * (dvee(R) * inv_sin_th - + vee(R) * cos(th) * inv_sin_th * inv_sin_th * dth_dR); + *dw_dR = u * dth_dR + th * du_dR; + } + return w; +} +} diff --git a/common/se3.h b/common/se3.h new file mode 100644 index 00000000..fb9da7e8 --- /dev/null +++ b/common/se3.h @@ -0,0 +1,182 @@ +// +// Created by feixh on 10/29/18. +// +#pragma once + +#include "rodrigues.h" + +namespace feh { + +template class SO3Type { +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + using Mat3 = Eigen::Matrix; + using Vec3 = Eigen::Matrix; + + explicit SO3Type() : R_{Mat3::Identity()} {} + + // explicit SO3Type(const Eigen::Matrix &R):R_{R} {} + template + explicit SO3Type(const Eigen::MatrixBase &R) : R_{R} {} + explicit SO3Type(const Vec3 &axis, Type angle) + : R_{rodrigues(Vec3{axis / axis.norm() * angle})} {} + + SO3Type operator*(const SO3Type &other) const { + return SO3Type{R_ * other.matrix()}; + } + SO3Type &operator*=(const SO3Type &other) { + R_ *= other.matrix(); + return *this; + } + + template + Vec3 operator*(const Eigen::MatrixBase &v) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + return Vec3{R_ * v}; + } + + SO3Type inv() const { return SO3Type{R_.transpose()}; } + Mat3 matrix() const { return R_; } + Vec3 log() const { return invrodrigues(R_); } + static Vec3 log(const SO3Type &R) { return R.log(); } + static SO3Type exp(const Vec3 &w) { return SO3Type{rodrigues(w)}; } + + static SO3Type fitToSO3(const Mat3 &R_approx) { + Eigen::JacobiSVD svd(R_approx, + Eigen::ComputeThinU | Eigen::ComputeThinV); + return SO3Type{svd.matrixU() * Mat3::Identity() * + svd.matrixV().transpose()}; + } + + template SO3Type cast() const { + return SO3Type(R_.template cast()); + } + template static SO3Type cast(SO3Type &R) { + return R.cast(); + } + + // factory methods + template + static SO3Type from_matrix(const Eigen::MatrixBase &other) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3); + Eigen::Matrix R = other.template cast(); + return SO3Type(R); + } + + template + static SO3Type project(const Eigen::MatrixBase &R) { + + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3); + using T = typename Derived::Scalar; + Eigen::JacobiSVD> svd(R, Eigen::ComputeFullU | + Eigen::ComputeFullV); + return SO3Type{svd.matrixU() * Eigen::Matrix::Identity() * + svd.matrixV().transpose()}; + } + + // conversion to 3x3 matrix + operator Eigen::Matrix() const { return R_.matrix(); } + +private: + Mat3 R_; +}; + +template class SE3Type { +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + using PointType = Eigen::Matrix; + + explicit SE3Type() : R_{}, T_{0, 0, 0} {} + + template + explicit SE3Type(const Eigen::MatrixBase &RT) + : R_{RT.template block<3, 3>(0, 0)}, T_{RT.template block<3, 1>(0, 3)} {} + + template + explicit SE3Type(const SO3Type &R, const Eigen::MatrixBase &T) + : R_{R}, T_{T} {} + + template + explicit SE3Type(const Eigen::MatrixBase &R, + const Eigen::MatrixBase &T) + : R_{R}, T_{T} {} + + SE3Type operator*(const SE3Type &other) const { + return SE3Type{SO3Type{R_ * other.so3()}, + this->so3() * other.translation() + T_}; + } + SE3Type &operator*=(const SE3Type &other) { + R_ *= other.so3(); + T_ += R_ * other.translation(); + return *this; + } + + template + PointType operator*(const Eigen::MatrixBase &v) const { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + return R_ * v + T_; + }; + + SE3Type inv() const { return SE3Type{R_.inv(), -(R_.inv() * T_)}; } + + SO3Type so3() const { return R_; } + SO3Type R() const { return R_; } + SO3Type rotation() const { return R_; } + + SO3Type &so3() { return R_; } + SO3Type &R() { return R_; } + SO3Type &rotation() { return R_; } + + PointType translation() const { return T_; } + PointType T() const { return T_; } + + PointType &translation() { return T_; } + PointType &T() { return T_; } + + Eigen::Matrix matrix3x4() const { + return (Eigen::Matrix{} << R_.matrix(), T_).finished(); + } + operator Eigen::Matrix() const { return matrix3x4(); } + + Eigen::Matrix matrix() const { + Eigen::Matrix out; + out.setIdentity(); + out.template block<3, 4>(0, 0) = matrix3x4(); + return out; + }; + + Eigen::Matrix matrix4x4() const { return matrix(); } + operator Eigen::Matrix() const { return matrix(); } + + template SE3Type cast() { + return SE3Type{R_.template cast(), T_.template cast()}; + } + + // factory methods + template + static SE3Type from_matrix3x4(const Eigen::MatrixBase &other) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 4); + Eigen::Matrix R = + other.template block<3, 3>(0, 0).template cast(); + Eigen::Matrix T = + other.template block<3, 1>(0, 3).template cast(); + return SE3Type{SO3Type{R}, T}; + } + + template + static SE3Type from_RT(const Eigen::MatrixBase &Rin, + const Eigen::MatrixBase &Tin) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived1, 3, 3); + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived2, 3, 1); + + Eigen::Matrix R = Rin.template cast(); + Eigen::Matrix T = Tin.template cast(); + return SE3Type(R, T); + } + +private: + SO3Type R_; + Eigen::Matrix T_; +}; +} diff --git a/common/test/test_rodrigues.cpp b/common/test/test_rodrigues.cpp new file mode 100644 index 00000000..9d192a9c --- /dev/null +++ b/common/test/test_rodrigues.cpp @@ -0,0 +1,248 @@ +#include + +#include "gtest/gtest.h" +#include "Eigen/Dense" + +#include "rodrigues.h" + +using ftype = double; +const ftype eps = 1e-8; + +using namespace feh; + +class MatrixDifferentialTest : public ::testing::Test { +protected: + MatrixDifferentialTest() { + _A1.setRandom(); + _A2.setRandom(); + _A.setRandom(); + + _B1.setRandom(); + _B2.setRandom(); + _B.setRandom(); + } + ~MatrixDifferentialTest() override {} + void SetUp() override {} + void TearDown() override {} + +public: + Eigen::Matrix _A1; + Eigen::Matrix _A2; + + Eigen::Matrix _B1; + Eigen::Matrix _B2; + + Eigen::Matrix _A; + Eigen::Matrix _B; +}; + + +TEST_F(MatrixDifferentialTest, dAB_dA) { + // setup the differential operator + auto diff = dAB_dA(_A, _B); + + // now let's first compute derivative of C w.r.t. each component of A + auto C = _A * _B; + Eigen::Matrix num_diff; + num_diff.setZero(); + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 4; ++j) { + auto Ap(_A); + Ap(i, j) += eps; + Eigen::Matrix D = (Ap * _B - C) / eps; + num_diff.col(i*4+j) = Eigen::Map>(D.data()); + } + } + ASSERT_LE((diff - num_diff).norm(), 1e-3) << "inconsistent analytical & numerical derivatives"; +} + +// dAB_dA with A and B of expression type +TEST_F(MatrixDifferentialTest, dAB_dA_expression) { + auto A = _A1 * _A2; + auto B = _B1 * _B2; + static_assert(!std::is_same::value, "A and _A should have different types."); + static_assert(!std::is_same::value, "B and _B should have different types."); + dAB_dA(A, B); +} + +TEST_F(MatrixDifferentialTest, dAB_dB) { + // setup the differential operator + auto diff = dAB_dB(_A, _B); + + // now let's first compute derivative of C w.r.t. each component of A + auto C = _A * _B; + Eigen::Matrix num_diff; + num_diff.setZero(); + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 5; ++j) { + auto Bp(_B); + Bp(i, j) += eps; + Eigen::Matrix D = (_A * Bp - C) / eps; + num_diff.col(i*5+j) = Eigen::Map>(D.data()); + } + } + ASSERT_LE((diff - num_diff).norm(), 1e-3) << "inconsistent analytical & numerical derivatives"; +} + +TEST_F(MatrixDifferentialTest, dAB_dB_expression) { + // dAB_dB with A and B of expression type + auto A = _A1 * _A2; + auto B = _B1 * _B2; + static_assert(!std::is_same::value, "A and _A should have different types."); + static_assert(!std::is_same::value, "B and _B should have different types."); + dAB_dB(A, B); +} + +TEST_F(MatrixDifferentialTest, dhat) { + Eigen::Matrix u; + u.setRandom(); + Eigen::Matrix product = dhat(u) * u; + auto a = Eigen::Map>(product.data()); + // c=a.T=-a + auto c = a.transpose(); + auto b = hat(u); + ASSERT_LE((a-b).norm(), 1e-10); + ASSERT_LE((c+b).norm(), 1e-10); +} + +TEST_F(MatrixDifferentialTest, dhat_expression) { + Eigen::Matrix u; + u.setRandom(); + static_assert(!std::is_same()), decltype(u)>::value, "u.head<3>() and u should have different types."); + dhat(u.head<3>()); +} + +TEST_F(MatrixDifferentialTest, dAt_dA) { + Eigen::Matrix A; + A.setRandom(); + auto At = A.transpose(); + Eigen::Matrix D = dAt_dA(A) * Eigen::Map>(A.data()); + auto at = Eigen::Map>(D.data()); + ASSERT_LE((At-at).norm(), 1e-10); +} + +TEST_F(MatrixDifferentialTest, rodrigues) { + Eigen::Matrix w; + w.setRandom(); + Eigen::Matrix dR_dw; + auto R = rodrigues(w, &dR_dw); + auto RRt = R * R.transpose(); + ASSERT_LE((Eigen::Matrix::Identity() - RRt).norm(), 1e-5); + // std::cout << R << std::endl; + // std::cout << "~~~~~~~~~~" << std::endl; + + Eigen::Matrix num_dR_dw; + num_dR_dw.setZero(); + for (int i = 0; i < 3; ++i) { + Eigen::Matrix wp = w; + wp(i) += eps; + num_dR_dw.col(i) = Eigen::Map>( + Eigen::Matrix{(rodrigues(wp) - R) / eps}.data()); + } + // std::cout << dR_dw << std::endl; + // std::cout << "==========" << std::endl; + // std::cout << num_dR_dw << std::endl; + ASSERT_LE((num_dR_dw - dR_dw).norm(), 1e-5); +} + +// make sure rodrigues accepts induced types +TEST_F(MatrixDifferentialTest, rodrigues_expression) { + Eigen::Matrix w; + w.setRandom(); + static_assert(!std::is_same()), decltype(w)>::value, + "w.head<3>() should have type different from Eigen::Matrix."); + rodrigues(w.head<3>()); +} + +TEST_F(MatrixDifferentialTest, rodrigues_small_angle) { + Eigen::Matrix w; + w.setRandom(); + w /= 1e10; + Eigen::Matrix dR_dw; + auto R = rodrigues(w, &dR_dw); + auto RRt = R * R.transpose(); + ASSERT_LE((Eigen::Matrix::Identity() - RRt).norm(), 1e-5); + // std::cout << R << std::endl; + // std::cout << "~~~~~~~~~~" << std::endl; + + Eigen::Matrix num_dR_dw; + num_dR_dw.setZero(); + for (int i = 0; i < 3; ++i) { + Eigen::Matrix wp = w; + wp(i) += eps; + num_dR_dw.col(i) = Eigen::Map>( + Eigen::Matrix{(rodrigues(wp) - R) / eps}.data()); + } + // std::cout << dR_dw << std::endl; + // std::cout << "==========" << std::endl; + // std::cout << num_dR_dw << std::endl; + ASSERT_LE((num_dR_dw - dR_dw).norm(), 1e-5); +} + + +TEST_F(MatrixDifferentialTest, invrodrigues) { + Eigen::Matrix w; + w.setRandom(); + Eigen::Matrix R = rodrigues(w); + + Eigen::Matrix dw_dR; + w = invrodrigues(R, &dw_dR); + + Eigen::Matrix num_dw_dR; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + Eigen::Matrix Rp(R); + // In theory, rotation matrix + delta is not necessarily a rotation matrix. + Rp(i, j) += eps; + Eigen::Matrix wp = invrodrigues(Rp); + num_dw_dR.col(i*3+j) = (wp - w) / eps; + } + } + // std::cout << dw_dR << std::endl; + // std::cout << "==========" << std::endl; + // std::cout << num_dw_dR << std::endl; + ASSERT_LE((dw_dR - num_dw_dR).norm(), 1e-5); +} + +TEST_F(MatrixDifferentialTest, invrodrigues_expression) { + Eigen::Matrix w; + w.setRandom(); + Eigen::Matrix R = rodrigues(w); + static_assert(!std::is_same(0, 0)), decltype(R)>::value, + "R.block<3, 3>(0, 0) and R should have different types."); + invrodrigues(R.block<3, 3>(0, 0)); +} + + +TEST_F(MatrixDifferentialTest, invrodrigues_small_angle) { + Eigen::Matrix w; + w.setIdentity(); + w *= eps; + Eigen::Matrix R = rodrigues(w); + // std::cout << R << std::endl; + // std::cout << "~~~~~~~~~~" << std::endl; + + Eigen::Matrix dw_dR; + w = invrodrigues(R, &dw_dR); + + Eigen::Matrix num_dw_dR; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + Eigen::Matrix Rp(R); + // In theory, rotation matrix + delta is not necessarily a rotation matrix. + Rp(i, j) += eps; + Eigen::Matrix wp = invrodrigues(Rp); + num_dw_dR.col(i*3+j) = (wp - w) / eps; + } + } + // std::cout << dw_dR << std::endl; + // std::cout << "==========" << std::endl; + // std::cout << num_dw_dR << std::endl; + ASSERT_LE((dw_dR - num_dw_dR).norm(), 1e-5); +} + + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/common/test/test_se3.cpp b/common/test/test_se3.cpp new file mode 100644 index 00000000..e69de29b diff --git a/common/utils.cpp b/common/utils.cpp new file mode 100644 index 00000000..7285c555 --- /dev/null +++ b/common/utils.cpp @@ -0,0 +1,149 @@ +// +// Created by feixh on 10/25/17. +// +// unix +#include "dirent.h" +// stl +#include +// I/O +#include "absl/strings/str_format.h" +#include "json/json.h" + +#include "utils.h" + +namespace feh { + +const std::string TermColor::red = "\033[91m"; +const std::string TermColor::green = "\033[92m"; +const std::string TermColor::blue = "\033[94m"; +const std::string TermColor::cyan = "\033[96m"; +const std::string TermColor::yellow = "\033[93m"; +const std::string TermColor::magenta = "\033[95m"; +const std::string TermColor::gray = "\033[90m"; +const std::string TermColor::white = "\033[97m"; +const std::string TermColor::bold = "\033[1m"; +const std::string TermColor::end = "\033[0m"; +const std::string TermColor::endl = "\033[0m\n"; + +std::ostream &operator<<(std::ostream &os, const Timer &obj) { + os << "....." << std::endl; + // write obj to stream + for (auto it = obj.look_up_table_.begin(); it != obj.look_up_table_.end(); + ++it) { + float elapsed = obj.report_average ? it->second / obj.counter_.at(it->first) + : it->second; + os << "[" << TermColor::bold + TermColor::green << obj.module_name_ + << TermColor::end << "]" << TermColor::cyan << it->first + << TermColor::end << ":" << elapsed * 1e-6 << " ms" << std::endl; + } + os << "....." << std::endl; + return os; +} + +bool Glob(const std::string &directory, const std::string &extension, + std::vector &filenames) { + std::string suffix((extension[0] == '.' ? "" : ".") + extension); + std::string path(directory + "/"); + DIR *dir_ptr = opendir(path.c_str()); + struct dirent *entry; + if (dir_ptr) { + while ((entry = readdir(dir_ptr)) != NULL) { + std::string entry_name(entry->d_name); + if (entry_name.length() > suffix.length() && + (entry_name.substr(entry_name.length() - suffix.length()) + .compare(suffix) == 0)) { + filenames.push_back( + entry_name.substr(0, entry_name.length() - suffix.length())); + } + } + try { + std::sort(filenames.begin(), filenames.end(), + [](const std::string &a, const std::string &b) { + return std::stof(a) < std::stof(b); + }); + } catch (const std::invalid_argument &e) { + std::sort(filenames.begin(), filenames.end()); + } + for (auto &filename : filenames) + filename = path + filename + suffix; + closedir(dir_ptr); + return true; + } else { + return false; + } +} + +bool Glob(const std::string &directory, const std::string &extension, + const std::string &prefix, std::vector &filenames) { + std::string suffix((extension[0] == '.' ? "" : ".") + extension); + std::string path(directory + "/"); + DIR *dir_ptr = opendir(path.c_str()); + struct dirent *entry; + if (dir_ptr) { + while ((entry = readdir(dir_ptr)) != NULL) { + std::string entry_name(entry->d_name); + if (entry_name.length() > suffix.length() + prefix.length() && + (entry_name.substr(entry_name.length() - suffix.length()) + .compare(suffix) == 0) && + (entry_name.substr(0, prefix.length()).compare(prefix) == 0)) { + filenames.push_back(entry_name.substr( + prefix.length(), + entry_name.length() - suffix.length() - prefix.length())); + } + } + try { + std::sort(filenames.begin(), filenames.end(), + [](const std::string &a, const std::string &b) { + return std::stof(a) < std::stof(b); + }); + } catch (const std::invalid_argument &e) { + std::sort(filenames.begin(), filenames.end()); + } + for (auto &filename : filenames) + filename = path + prefix + filename + suffix; + closedir(dir_ptr); + return true; + } else { + return false; + } +} + +void MergeJson(Json::Value &a, const Json::Value &b) { + if (!a.isObject() || !b.isObject()) + return; + for (const auto &key : b.getMemberNames()) + if (a[key].isObject()) + MergeJson(a[key], b[key]); + else + a[key] = b[key]; +} + +Json::Value LoadJson(const std::string &filename) { + std::ifstream in(filename, std::ios::in); + if (in.is_open()) { + Json::Value out; + in >> out; + return out; + } else { + throw std::runtime_error( + absl::StrFormat("failed to read file %s", filename)); + } +} + +void SaveJson(const Json::Value &value, const std::string &filename) { + std::ofstream out(filename, std::ios::out); + + if (!out.is_open()) { + throw std::runtime_error("Failed to open output json file @ " + filename); + } + + Json::StreamWriterBuilder builder; + builder["commentStyle"] = "None"; + builder["indentation"] = " "; + + auto writer = builder.newStreamWriter(); + writer->write(value, &out); + out.close(); +} + +} // namespace feh diff --git a/common/utils.h b/common/utils.h new file mode 100644 index 00000000..3f79707a --- /dev/null +++ b/common/utils.h @@ -0,0 +1,358 @@ +// +// Created by feixh on 10/25/17. +// +// Common utilities. +#pragma once +#include "alias.h" + +// stl +#include +#include +#include +#include +#include +#include +#include +// 3rdparty +#include "glog/logging.h" +#include "opencv2/core/core.hpp" +#include "json/json.h" + +namespace feh { + +template using own = T; + +/// \brief colorful texts for terminal +struct TermColor { + static const std::string red; + static const std::string green; + static const std::string blue; + static const std::string cyan; + static const std::string yellow; + static const std::string magenta; + static const std::string gray; + static const std::string white; + static const std::string bold; + static const std::string end; + static const std::string endl; + +private: + TermColor() = delete; +}; + +/// \brief timer +class Timer { +public: + enum Unit { MILLISEC, MICROSEC, NANOSEC }; + +public: + friend std::ostream &operator<<(std::ostream &os, const Timer &obj); + + Timer() : module_name_("default"), report_average(true) {} + + Timer(std::string module_name_) + : module_name_(module_name_), report_average(true) {} + + void Tick() { Tick("anonymous event"); } + + void Tick(const std::string &event) { + start_[event] = std::chrono::high_resolution_clock::now(); + } + + float Tock() { return Tock("anonymous event"); } + + /// \param: Return timing in milliseconds. Also record timing in look up + /// table. + float Tock(const std::string &event) { + float timing(Elapsed(event).count()); + if (look_up_table_.count(event)) { + look_up_table_[event] += timing; + counter_[event] += 1; + } else { + look_up_table_[event] = timing; + counter_[event] = 1; + } + return timing * 1e-6; + } + + void Reset() { + start_.clear(); + look_up_table_.clear(); + counter_.clear(); + } + + float LookUp(const std::string &event, const Unit unit = MILLISEC, + bool average = false) const { + if (!look_up_table_.count(event)) + return -1; + switch (unit) { + case MILLISEC: + return look_up_table_.at(event) * 1e-6 / + (average ? counter_.at(event) + 0.01 : 1.0); + break; + case MICROSEC: + return look_up_table_.at(event) * 1e-3 / + (average ? counter_.at(event) + 0.01 : 1.0); + break; + case NANOSEC: + return look_up_table_.at(event) / + (average ? counter_.at(event) + 0.01 : 1.0); + break; + default: + return -1; + break; + } + } + + std::chrono::nanoseconds Elapsed(std::string event) const { + auto tmp = std::chrono::high_resolution_clock::now(); + assert(start_.count(event) && ("event[" + event + "] not found").c_str()); + return std::chrono::duration_cast( + tmp - start_.at(event)); + } + +private: + std::unordered_map + start_; + std::map look_up_table_; + std::unordered_map counter_; + std::string module_name_; + +public: + bool report_average; +}; + +/// \brief generate a random matrix of dimension N x M +template +Eigen::Matrix +RandomMatrix(ftype meanVal = 0.0, ftype stdVal = 1.0, + std::shared_ptr p_engine = nullptr) { + + using ftype = ftype; + + std::normal_distribution dist(meanVal, stdVal); + Eigen::Matrix v; + if (p_engine == nullptr) { + std::default_random_engine engine; + for (int i = 0; i < N; ++i) + for (int j = 0; j < M; ++j) { + v(i, j) = dist(engine); + } + } else { + for (int i = 0; i < N; ++i) + for (int j = 0; j < M; ++j) { + v(i, j) = dist(*p_engine); + } + } + return v; +}; + +/// \brief generate a random vecotr of dimension N +template +Eigen::Matrix +RandomVector(ftype meanVal = 0.0, ftype stdVal = 1.0, + std::shared_ptr p_engine = nullptr) { + + using ftype = ftype; + + std::normal_distribution dist(meanVal, stdVal); + Eigen::Matrix v; + if (p_engine == nullptr) { + std::default_random_engine engine; + for (int i = 0; i < N; ++i) { + v(i) = dist(engine); + } + } else { + for (int i = 0; i < N; ++i) { + v(i) = dist(*p_engine); + } + } + return v; +}; + +/// \brief detect if any compoennt of a matrix is nan +template bool anynan(const Eigen::MatrixBase &m) { + for (int i = 0; i < m.rows(); ++i) + for (int j = 0; j < m.cols(); ++j) + if (std::isnan(m(i, j))) + return true; + return false; +}; + +/// \brief print enum value as int +template +typename std::underlying_type::type +as_integer(Enumeration const value) { + using type = typename std::underlying_type::type; + return static_cast(value); +} + +/// \brief: Convert from std vector of Eigen vectors to Eigen matrix. +template +Eigen::Matrix StdVectorOfEigenVectorToEigenMatrix( + const std::vector> &v) { + Eigen::Matrix out; + out.resize(v.size(), DIM); + for (int i = 0; i < v.size(); ++i) { + out.row(i) = v[i]; + } + return out; +} + +/// \brief: Convert from an Eigen matrix type to a std vector of Eigen vectors. +template +std::vector> EigenMatrixToStdVectorOfEigenVector( + const Eigen::Matrix &m) { + std::vector> out(m.rows()); + for (int i = 0; i < m.rows(); ++i) + out[i] = m.row(i); + return out; +}; + +/// \brief: Convert from a std vector of Eigen vectors to an Eigen matrix. +template +Eigen::Matrix +StdVectorOfEigenVectorMean(const std::vector> &v) { + return StdVectorOfEigenVectorToEigenMatrix(v).colwise().mean(); +}; + +/// \brief: Compute the rotation matrix to align two vectors. +template +Eigen::Matrix RotationBetweenVectors(Eigen::Matrix u, + Eigen::Matrix v) { + return Eigen::Quaternion::FromTwoVectors(u, v).toRotationMatrix(); +}; + +inline constexpr int cube(int x) { return x * x * x; } +inline constexpr int square(int x) { return x * x; } + +template +std::vector> GenerateRandomColorMap() { + uint8_t q = 255 / L; + std::vector> cm(cube(8)); + auto generator = std::knuth_b(0); + for (int i = 0; i < cube(L); ++i) { + cm[i] = {q * (i % 8u), q * ((i / 8) % 8u), q * ((i / 64) % 8u)}; + std::shuffle(cm[i].begin(), cm[i].end(), generator); + } + std::shuffle(cm.begin() + 1, cm.end(), generator); + return cm; +}; + +/// \brief: List files with the given extension. +/// \param path: Directory of files. +/// \param extension: File extension. +/// \param filenames: List of returned file names. +/// \return: True if reads the file list successfully. +bool Glob(const std::string &path, const std::string &extension, + std::vector &filenames); + +bool Glob(const std::string &path, const std::string &extension, + const std::string &prefix, std::vector &filenames); + +template +T BilinearSample(const cv::Mat &img, const Eigen::Matrix &xy) { + int col{xy(0)}; + int row{xy(1)}; + T v1 = (row + 1 - xy(1)) * (col + 1 - xy(0)) * img.at(row, col); + T v2 = (xy(1) - row) * (col + 1 - xy(0)) * img.at(row + 1, col); + T v3 = (xy(1) - row) * (xy(0) - col) * img.at(row + 1, col + 1); + T v4 = (row + 1 - xy(1)) * (xy(0) - col) * img.at(row, col + 1); + return v1 + v2 + v3 + v4; +} + +//////////////////////////////////////////////////////////////////////////////// +// I/O UTILITIES +//////////////////////////////////////////////////////////////////////////////// + +enum class JsonMatLayout { OneDim, RowMajor, ColMajor }; +/// \brief load NxM double matrix from json file. +/// \param v: json record +/// \param key: the key +/// \param layout: Whether the matrix is arranged as an one-dim array or two-dim +/// matrix. +template +Eigen::Matrix +GetMatrixFromJson(const Json::Value &v, const std::string &key, + JsonMatLayout layout = JsonMatLayout::OneDim) { + + Eigen::Matrix ret; + for (int i = 0; i < N; ++i) + for (int j = 0; j < M; ++j) + if (layout == JsonMatLayout::OneDim) { + ret(i, j) = v[key][i * M + j].asDouble(); + } else if (layout == JsonMatLayout::RowMajor) { + ret(i, j) = v[key][i][j].asDouble(); + } else { + ret(i, j) = v[key][j][i].asDouble(); + } + return ret; +} + +/// \brief load N-dim double vector from json file +template +Eigen::Matrix GetVectorFromJson(const Json::Value &v, + const std::string &key) { + + return GetMatrixFromJson(v, key); +}; + +template +void WriteMatrixToJson(Json::Value &d, const std::string &key, + const Eigen::MatrixBase &m) { + d[key] = Json::Value(Json::arrayValue); + for (int i = 0; i < m.rows(); ++i) + for (int j = 0; j < m.cols(); ++j) + d[key].append(Json::Value(m(i, j))); +} + +/// \brief: Merge json b to json a. +void MergeJson(Json::Value &a, const Json::Value &b); +Json::Value LoadJson(const std::string &filename); +void SaveJson(const Json::Value &j, const std::string &filename); + +template +std::vector +Flatten(const Eigen::MatrixBase &m) { + // Naive implementation of flatten, can use Eigen::Map to simplify code + int rows = m.template rows(); + int cols = m.template cols(); + std::vector out(rows * cols); + for (int i = 0; i < rows; ++i) + for (int j = 0; j < cols; ++j) { + out[i * cols + j] = m(i, j); + } + return out; +} + +template void SaveMat(std::string filename, const cv::Mat &mat) { + std::ofstream out(filename, std::ios::out | std::ios::binary); + if (!out.is_open()) { + LOG(FATAL) << "Failed to open output file"; + } + int rows = mat.rows; + int cols = mat.cols; + out.write((char *)&rows, sizeof rows); + out.write((char *)&cols, sizeof cols); + for (int i = 0; i < rows; ++i) + for (int j = 0; j < cols; ++j) { + T z = mat.at(i, j); + out.write((char *)&z, sizeof z); + } + out.close(); +} + +template +void WriteMatrixToFile(const std::string &filename, + const Eigen::MatrixBase &m) { + LOG(INFO) << "Writing matrix to " << filename; + std::ofstream ostream(filename, std::ios::out); + if (!ostream.is_open()) { + LOG(FATAL) << "Failed to open output file"; + } + ostream << m; + ostream.close(); +} + +} // namespace feh diff --git a/experimental/CMakeLists.txt b/experimental/CMakeLists.txt new file mode 100644 index 00000000..5b87d8bc --- /dev/null +++ b/experimental/CMakeLists.txt @@ -0,0 +1,14 @@ +# TODO (xfei): fill in details +################################################################################ +# EXPERIMENTAL +################################################################################ + +# add_executable(inproc_zmq experimental/inproc_communication_zmq.cpp) +# target_link_libraries(inproc_zmq zmq pthread glog) +# +# add_executable(async_dataloader experimental/async_dataloader.cpp) +# target_link_libraries(async_dataloader zmq pthread glog msckf) + +add_executable(test_camera_factory camera_factory.h test_camera_factory.cpp) + + diff --git a/experimental/async_dataloader.cpp b/experimental/async_dataloader.cpp new file mode 100644 index 00000000..dfc68442 --- /dev/null +++ b/experimental/async_dataloader.cpp @@ -0,0 +1,195 @@ +// Asynchronous dataloader. +// Data acquisition (loader or multiple sensors) lives in its own node (might be multiple nodes), and dispatches messages to the estimator node. This file implements a dataloader node. +// Author: Xiaohan Fei +#include + +#include "zmq.hpp" +#include "glog/logging.h" + +#include "opencv2/core/core.hpp" +#include "opencv2/highgui/highgui.hpp" + +#include "tumvi.h" +#include "helpers.h" + +static std::string tumvi_root = "/home/feixh/Data/tumvi/exported/euroc/512_16/"; +static std::string euroc_root = "/home/feixh/Data/euroc/"; + + +namespace feh { +namespace node { + +// packet for communication +struct Packet { + Packet(): type_{UNINITIALIZED}, image_ptr_{nullptr} {} + + Packet(uint64_t ts, + ftype rx, ftype ry, ftype rz, + ftype tx, ftype ty, ftype tz): + type_{IMU}, ts_{ts}, + rx_{rx}, ry_{ry}, rz_{rz}, + tx_{tx}, ty_{ty}, tz_{tz}, + image_ptr_{nullptr} + {} + + Packet(uint64_t ts, + cv::Mat *ptr): + type_{IMAGE_PTR}, ts_{ts}, + image_ptr_{ptr} + {} + + enum: uint8_t { + UNINITIALIZED = 0, + IMAGE_PTR = 1, + IMU = 2 + } type_; + + uint64_t ts_; + ftype rx_, ry_, rz_, tx_, ty_, tz_; + cv::Mat *image_ptr_; +}; + + +class DataServer { +public: + DataServer(zmq::context_t &context, const std::string &port): + pub_{context, ZMQ_PUB}, + loader_{nullptr} + { + try { + pub_.bind(port); + LOG(INFO) << "Bound to port: " << port; + } catch (const std::exception &e) { + LOG(FATAL) << "Failed to bind to port: " << port; + } + } + + void Initialize(const std::string dataset, + const std::string root, + const std::string seq, + int cam_id) { + std::string image_dir, imu_dir, gt_dir; + std::tie(image_dir, imu_dir, gt_dir) = GetDirs(dataset, root, seq, cam_id); + loader_ = std::unique_ptr(new TUMVILoader{image_dir, imu_dir}); + LOG(INFO) << "#entries=" << loader_->size() << std::endl; + } + + void run() { + if (!loader_) { + LOG(FATAL) << "Empty loader!"; + } + + for (int i = 0; i < loader_->size(); ++i) { + msg::Generic entry = loader_->Get(i); + + // serialize and send the actual message + Packet packet; + if (entry.type_ == msg::Generic::IMAGE) { + cv::Mat *image_ptr = new cv::Mat(cv::imread(entry.image_path_)); + packet = std::move(Packet{entry.ts_, image_ptr}); + } else if (entry.type_ == msg::Generic::IMU) { + packet = std::move(Packet{entry.ts_, + entry.gyro_[0], entry.gyro_[1], entry.gyro_[2], + entry.accel_[0], entry.accel_[1], entry.accel_[2]}); + } + + zmq::message_t msg(sizeof(packet)); + memcpy(msg.data(), &packet, sizeof(packet)); + pub_.send(msg); + LOG(INFO) << "Sent " << i+1 << " messages"; + } + } + +private: + zmq::socket_t pub_; + std::unique_ptr loader_; +}; + +class MessageEchoClient { +public: + + MessageEchoClient(zmq::context_t &context, const std::string &port): + sub_{context, ZMQ_SUB}, + msg_counter_{0} + { + try { + sub_.connect(port); + LOG(INFO) << "Connected to port: " << port; + } catch (const std::exception &e) { + LOG(FATAL) << "Failed to connect to port: " << port; + } + sub_.setsockopt(ZMQ_SUBSCRIBE, "", 0); + // static_cast required due to zmq bug in C++11 + items_.push_back({static_cast(sub_), 0, ZMQ_POLLIN, 0}); + } + + void run() { + while (true) { + zmq::message_t rx_msg; + zmq::poll(&items_[0], 1, -1); // http://api.zeromq.org/2-1:zmq-poll + if (items_[0].revents & ZMQ_POLLIN) { // revents == received events, make sure the revents is ZMQ_POLLIN (read) + sub_.recv(&rx_msg); + + // receive message + Packet packet; + memcpy(&packet, rx_msg.data(), rx_msg.size()); + if (packet.type_ == Packet::IMU) { + std::cout << packet.ts_ << " " << packet.rx_ << " " << packet.ry_ << " " << packet.rz_ << " " + << packet.tx_ << " " << packet.ty_ << " " << packet.tz_ << std::endl; + } else if (packet.type_ == Packet::IMAGE_PTR) { + if (packet.image_ptr_) { + cv::Mat image{packet.image_ptr_->clone()}; + delete packet.image_ptr_; + + cv::imshow("disp", image); + char ckey = cv::waitKey(10); + } else { + LOG(FATAL) << "Empty image pointer"; + } + } else { + LOG(FATAL) << "UN-INITIALIZED PACKET"; + } + + ++msg_counter_; + LOG(INFO) << "Received " << msg_counter_ << " messages"; + } + } + } + + zmq::socket_t sub_; + std::vector items_; + int msg_counter_; + // TODO (xfei): implement a thread-safe message buffer +}; + +} // namespace node + +} // namespace feh + + +// some constants +static const std::string dataset{"tumvi"}; +static const std::string root{"/home/feixh/Data/tumvi/exported/euroc/512_16/"}; +static const std::string seq{"room1"}; +static const int cam_id{0}; + +int main() +{ + zmq::context_t context(0); + std::string port("inproc://7007"); + + // NOTE: launch subscriber first + feh::node::MessageEchoClient client(context, port); + std::thread sub_thread(&feh::node::MessageEchoClient::run, &client); + + feh::node::DataServer loader(context, port); + loader.Initialize(dataset, root, seq, cam_id); + std::thread pub_thread(&feh::node::DataServer::run, &loader); + + // join + pub_thread.join(); + sub_thread.join(); + + + +} diff --git a/experimental/camera_factory.h b/experimental/camera_factory.h new file mode 100644 index 00000000..d903e6ce --- /dev/null +++ b/experimental/camera_factory.h @@ -0,0 +1,438 @@ +/* Curiously Recurring Template Pattern (CRTP) implementation + * of camera models. + * Problem is now we have multiple different base camera classes: + * Each base camera type with a specific derived camera type as + * the template parameter is a different type. + */ +#pragma once +#include +#include +#include "Eigen/Core" + +// TODO (xfei): separate model and factory +#include "json/json.h" +#include "utils.h" + +namespace feh { + +template +class BaseCamera_CRTP { +public: + BaseCamera_CRTP(int rows, int cols, T fx, T fy, T cx, T cy): + rows_{rows}, cols_{cols}, + fx_{fx}, fy_{fy}, cx_{cx}, cy_{cy} + {} + BaseCamera_CRTP& operator=(const BaseCamera_CRTP &) = delete; + BaseCamera_CRTP(const BaseCamera_CRTP &) = delete; + ~BaseCamera_CRTP() { + } + + template + Eigen::Matrix + Project(const Eigen::MatrixBase &xc, + Eigen::Matrix *jac=nullptr) const { + return static_cast(this)->Project(xc, jac); + } + + template + Eigen::Matrix + UnProject(const Eigen::MatrixBase &xp, + Eigen::Matrix *jac=nullptr) const { + return static_cast(this)->UnProject(xp, jac); + } + + virtual void Print(std::ostream &out) const = 0; + + int rows() const { return rows_; } + int cols() const { return cols_; } + T cx() const { return cx_; } + T cy() const { return cy_; } + T fx() const { return fx_; } + T fy() const { return fy_; } + +protected: + int rows_, cols_; + T fx_, fy_, cx_, cy_; +}; + +template +class ATANCamera: public BaseCamera_CRTP> { +public: + ATANCamera(int rows, int cols, T fx, T fy, T cx, T cy, T w): + BaseCamera_CRTP>{rows, cols, fx, fy, cx, cy}, + w_(w), invw_(1.0 / w), tanw2term_(2.0*std::tan(w * 0.5)) + {} + + template + Eigen::Matrix + Project(const Eigen::MatrixBase &xc, + Eigen::Matrix *jac=nullptr) const + { + std::cout << "atan project" << std::endl; + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + + Eigen::Matrix xp; + + f_t R = xc.norm(); + f_t f; + if (R < 0.0001 || w_ == 0) { + f = 1; + } else { + f = invw_ * atan(tanw2term_ * R) / R; + } + + //Project through distortion model + xp(0) = fx_ * f * xc(0) + cx_; + xp(1) = fy_ * f * xc(1) + cy_; + + if (jac != nullptr) { + // compute jacobians + if (R < 0.0001 || w_ == 0) { + (*jac)(0, 0) = fx_; + (*jac)(1, 1) = fy_; + } else { + // FIXME: optimize computation + f_t df_dx, df_dy, df_dR; + f_t a = tanw2term_ * R; + df_dR = invw_ * ( 1./(1+a*a)*a - std::atan(a) ) / R / R; + df_dx = df_dR * xc(0) / R; + df_dy = df_dR * xc(1) / R; + + *jac << fx_ * f + fx_ * xc(0) * df_dx, fx_ * xc(0) * df_dy, + fy_ * xc(1) * df_dx, fy_ * f + fy_ * xc(1) * df_dy; + } + } + return xp; + } + + template + Eigen::Matrix + UnProject(const Eigen::MatrixBase &xp, + Eigen::Matrix *jac=nullptr) const + { + std::cout << "atan un-project" << std::endl; + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + + using f_t = typename Derived::Scalar; + Eigen::Matrix xc; + + Eigen::Matrix tmp((xp(0) - cx_) / fx_, (xp(1) - cy_) / fy_); + f_t R = tmp.norm(); + f_t RR{w_ == 0 ? R : std::tan(R * w_) / tanw2term_}; + f_t f{R > 0.01 ? RR / R : 1.0}; + xc = f * tmp; + + if (jac != nullptr) { + if (f == 1) { + (*jac)(0, 0) = 1.0 / fx_; + (*jac)(1, 1) = 1.0 / fy_; + } else { + f_t df_dR; + f_t a = std::tan(R * w_); + df_dR = 1.0 / tanw2term_ * (((1+a*a)*w_*R - a) / R / R); + + f_t df_dx, df_dy; + df_dx = df_dR * tmp(0) / R / fx_; + df_dy = df_dR * tmp(1) / R / fy_; + + (*jac) << tmp(0) * df_dx + f / fx_, tmp(0) * df_dy, + tmp(1) * df_dx, tmp(1) * df_dy + f / fy_; + } + } + return xc; + } + + void Print(std::ostream &out) const + { + out << "ATAN Camera" << std::endl + << "[rows, cols]=" << rows_ << "," << cols_ << "]" << std::endl + << "[fx, fy, cx, cy, w]=[" + << fx_ << "," << fy_ << "," << cx_ << "," << cy_ << "," << w_ << "]" << std::endl; + } + +private: + using BaseCamera_CRTP>::rows_; + using BaseCamera_CRTP>::cols_; + using BaseCamera_CRTP>::fx_; + using BaseCamera_CRTP>::fy_; + using BaseCamera_CRTP>::cx_; + using BaseCamera_CRTP>::cy_; + + T w_, invw_, tanw2term_; +}; + + + // static + // ATANCamera* Create(const Json::Value &cfg) + // { + // auto cam_model = cfg["model"].asString(); + // int rows = cfg["rows"].asInt(); + // int cols = cfg["cols"].asInt(); + // T fx = cfg["fx"].asDouble(); + // T fy = cfg["fy"].asDouble(); + // T cx = cfg["cx"].asDouble(); + // T cy = cfg["cy"].asDouble(); + // T w = cfg["w"].asDouble(); + // auto cam = new ATANCamera( + // rows, cols, + // cols * fx, rows * fy, cols * cx, rows * cy, w); + // return cam; + // } + + +/* +template +class EquidistantCamera: public BaseCamera_CRTP { +public: + EquidistantCamera( int rows, int cols, + T fx, T fy, T cx, T cy, + T k0, T k1, T k2, T k3, + int max_iter=15): + BaseCamera_CRTP{rows, cols, fx, fy, cx, cy}, + k0_{k0}, k1_{k1}, k2_{k2}, k3_{k3}, + max_iter_{max_iter} {} + + + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac=nullptr) const + { + std::cout << "equidistant project" << std::endl; + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + Eigen::Matrix xp; + + f_t xy_norm2 = xc.squaredNorm(); + f_t xy_norm= sqrt( xy_norm2 ); + f_t xyz_norm2 = xy_norm2 + 1; + + f_t th = atan2( xy_norm, 1.0 ); + + f_t phi = atan2( xc[1], xc[0] ); + + f_t th2 = th * th; + f_t th3 = th2 * th; + f_t th4 = th3 * th; + f_t th5 = th3 * th2; + f_t th6 = th5 * th; + f_t th7 = th5 * th2; + f_t th8 = th7 * th; + f_t th9 = th7 * th2; + f_t r = th + k0_ * th3 + k1_ * th5 + k2_ * th7 + k3_ * th9; + + f_t cos_phi = cos( phi ); + f_t sin_phi = sin( phi ); + + f_t u = fx_ * r * cos_phi + cx_; + f_t v = fy_ * r * sin_phi + cy_; + + // fill in xp + xp[0] = u; + xp[1] = v; + + + if (jac != nullptr) { + f_t dphi_dx = -xc[1] / xy_norm2; + f_t dphi_dy = xc[0] / xy_norm2; + + f_t dth_dx = xc[0] / xyz_norm2 / xy_norm; + f_t dth_dy = xc[1] / xyz_norm2 / xy_norm; + + f_t dr_dth = 1 + k0_ * 3 * th2 + k1_ * 5 * th4 + k2_ * 7 * th6 + k3_ * 9 * th8; + + f_t du_dx = fx_ * cos_phi * dr_dth * dth_dx - fx_ * r * sin_phi * dphi_dx; + f_t du_dy = fx_ * cos_phi * dr_dth * dth_dy - fx_ * r * sin_phi * dphi_dy; + + f_t dv_dx = fy_ * sin_phi * dr_dth * dth_dx + fy_ * r * cos_phi * dphi_dx; + f_t dv_dy = fy_ * sin_phi * dr_dth * dth_dy + fy_ * r * cos_phi * dphi_dy; + + // fill in jacobians + (*jac) << du_dx, du_dy, dv_dx, dv_dy; + } + return xp; + } + + template + Eigen::Matrix + UnProject(const Eigen::MatrixBase &xp, + Eigen::Matrix *jac=nullptr) const + { + std::cout << "equidistant un-project" << std::endl; + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + using Vec2 = Eigen::Matrix; + Vec2 xc; + + f_t xn = xp[0] - cx_; + f_t yn = xp[1] - cy_; + + f_t b(fx_ * yn), a(fy_ * xn); + f_t phi = atan2( b, a ); + f_t cos_phi = cos( phi ); + f_t sin_phi = sin( phi ); + + f_t rth = xn / ( fx_ * cos_phi ); + + f_t th = rth; + // solve th: + // th + k0*th**3 + k1*th**5 + k2*th**7 + k3*th**9 = rth + + f_t th2, th3, th4, th6, x0, x1; + for ( int i = 0; i < max_iter_; i++ ) { + // f = (th + k0*th**3 + k1*th**5 + k2*th**7 + k3*th**9 - rth)^2 + th2 = th * th; + th3 = th2 * th; + th4 = th2 * th2; + th6 = th4 * th2; + x0 = k0_ * th3 + k1_ * th4 * th + k2_ * th6 * th + k3_ * th6 * th3 - rth + th; + x1 = 3 * k0_ * th2 + 5 * k1_ * th4 + 7 * k2_ * th6 + 9 * k3_ * th6 * th2 + 1; + f_t d = 2 * x0 * x1; + f_t d2 = 4 * th * x0 * ( 3 * k0_ + 10 * k1_ * th2 + 21 * k2_ * th4 + 36 * k3_ * th6 ) + 2 * x1 * x1; + f_t delta = d / d2; + th -= delta; + } + f_t tan_th = tan( th ); + xc[0] = tan_th * cos_phi; + xc[1] = tan_th * sin_phi; + + if (jac != nullptr) { + f_t a2b2 = a*a+b*b; + Vec2 dphi_dxy( -b / a2b2 * fy_, a / a2b2 * fx_); + Vec2 dcosphi_dxy(-sin_phi * dphi_dxy); + Vec2 dsinphi_dxy(cos_phi * dphi_dxy); + Vec2 drth_dxy(cos_phi-xn*dcosphi_dxy[0], -xn*dcosphi_dxy[1]); + drth_dxy /= (fx_*cos_phi*cos_phi); + + f_t cos_th(cos(th)); + Vec2 dtanth_dxy(drth_dxy / x1 / (cos_th*cos_th)); + Vec2 doutx_dxy(cos_phi * dtanth_dxy + tan_th * dcosphi_dxy); + Vec2 douty_dxy(sin_phi * dtanth_dxy + tan_th * dsinphi_dxy); + (*jac) << doutx_dxy[0], doutx_dxy[1], + douty_dxy[0], douty_dxy[1]; + } + return xc; + } + + void Print(std::ostream &out) + { + out << "Equidistant Camera" << std::endl + << "[rows, cols]=" << rows_ << "," << cols_ << "]" << std::endl + << "[fx, fy, cx, cy]=[" + << fx_ << "," << fy_ << "," << cx_ << "," << cy_ << "]" << std::endl + << "[k0, k1, k2, k3]=[" + << k0_ << "," << k1_ << "," << k2_ << "," << k3_ << "]" << std::endl; + } + +private: + using BaseCamera_CRTP::rows_; + using BaseCamera_CRTP::cols_; + using BaseCamera_CRTP::fx_; + using BaseCamera_CRTP::fy_; + using BaseCamera_CRTP::cx_; + using BaseCamera_CRTP::cy_; + + T k0_, k1_, k2_, k3_; + int max_iter_; +}; + + // static + // EquidistantCamera* Create(const Json::Value &cfg) + // { + // int rows = cfg["rows"].asInt(); + // int cols = cfg["cols"].asInt(); + // T fx = cfg["fx"].asDouble(); + // T fy = cfg["fy"].asDouble(); + // T cx = cfg["cx"].asDouble(); + // T cy = cfg["cy"].asDouble(); + // auto k0123 = GetVectorFromJson(cfg, "k0123"); + // int max_iter = cfg["max_iter"].asInt(); + + // auto cam = new EquidistantCamera( + // rows, cols, + // fx, fy, cx, cy, + // k0123[0], k0123[1], k0123[2], k0123[3], + // max_iter); + // return cam; + // } + +template +class RadialTangentialCamera: public BaseCamera_CRTP { +public: + RadialTangentialCamera(int rows, int cols, + T fx, T fy, T cx, T cy, + T r0, T r1, + T k0, T k1, T k2, + int max_iter=15): + BaseCamera_CRTP{rows, cols, fx, fy, cx, cy}, + r0_{r0}, r1_{r1}, + k0_{k0}, k1_{k1}, k2_{k2}, + max_iter_{max_iter} {} + + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac=nullptr) const + { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + using Vec2 = Eigen::Matrix; + Vec2 xp; + return xp; + } + + template + Eigen::Matrix + UnProject(const Eigen::MatrixBase &xp, + Eigen::Matrix *jac=nullptr) const + { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + using f_t = typename Derived::Scalar; + using Vec2 = Eigen::Matrix; + Vec2 xc; + // TODO (xfei): implement + return xc; + } + + void Print(std::ostream &out) + { + // TODO (xfei): implement + } + +private: + using BaseCamera_CRTP::rows_; + using BaseCamera_CRTP::cols_; + using BaseCamera_CRTP::fx_; + using BaseCamera_CRTP::fy_; + using BaseCamera_CRTP::cx_; + using BaseCamera_CRTP::cy_; + + T r0_, r1_; + T k0_, k1_, k2_; + int max_iter_; +}; + + +template +bool OutOfView(T x, T y, const Cam &cam) +{ + float margin(0.01f); + return x < cam.cols()*margin + || x >= cam.cols()*(1-margin) + || y < cam.rows()*margin + || y >= cam.rows()*(1-margin); +} + +template +bool OutOfView(const Eigen::MatrixBase &xp, const Cam &cam) +{ + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 2, 1); + return OutOfView(xp(0), xp(1), cam); +} + + +*/ + +} // feh + diff --git a/experimental/inproc_communication_zmq.cpp b/experimental/inproc_communication_zmq.cpp new file mode 100644 index 00000000..a287604a --- /dev/null +++ b/experimental/inproc_communication_zmq.cpp @@ -0,0 +1,76 @@ +// Getting familar with ZeroMQ library. +// Author: Xiaohan Fei +// Reference: +// http://zguide.zeromq.org/page:all#sockets-and-patterns +// Example: +// https://ogbe.net/blog/zmq_helloworld.html +// http://zguide.zeromq.org/cpp:mspoller +#include +#include +#include +#include +#include + +#include "zmq.hpp" +#include "glog/logging.h" + +class Node { +public: + + Node(zmq::context_t &context, const std::string &port): + sub_{context, ZMQ_SUB}, + msg_counter_{0} + { + try { + sub_.connect(port); + LOG(INFO) << "Connected to port: " << port; + } catch (const std::exception &e) { + LOG(FATAL) << "Failed to connect to port: " << port; + } + sub_.setsockopt(ZMQ_SUBSCRIBE, "", 0); + // static_cast required due to zmq bug in C++11 + items_.push_back({static_cast(sub_), 0, ZMQ_POLLIN, 0}); + } + + void run(int max_msg) { + while (true) { + zmq::message_t rx_msg; + zmq::poll(&items_[0], 1, -1); // http://api.zeromq.org/2-1:zmq-poll + if (items_[0].revents & ZMQ_POLLIN) { // revents == received events, make sure the revents is ZMQ_POLLIN (read) + sub_.recv(&rx_msg); + std::string rx_str; + rx_str.assign(static_cast(rx_msg.data()), rx_msg.size()); // assign ? + std::cout << "Received: " << rx_str << std::endl; + if (++msg_counter_ == max_msg) { + break; + } + } + } + } + + zmq::socket_t sub_; + std::vector items_; + int msg_counter_; +}; + +int main() +{ + zmq::context_t context(0); + zmq::socket_t publisher(context, ZMQ_PUB); + std::string port("inproc://5566"); + publisher.bind(port); + + Node node(context, port); + + size_t nmsg = 10; + std::thread subs_thread(&Node::run, &node, nmsg); + + for (size_t i = 0; i < nmsg; ++i) { + std::string content("Hello " + std::to_string(i)); + zmq::message_t msg(content.size()); + std::copy(content.c_str(), content.c_str() + content.size(), static_cast(msg.data())); + publisher.send(msg); + } + + subs_thread.join(); +} diff --git a/experimental/test_camera_factory.cpp b/experimental/test_camera_factory.cpp new file mode 100644 index 00000000..7b4cb590 --- /dev/null +++ b/experimental/test_camera_factory.cpp @@ -0,0 +1,17 @@ +#include "camera_factory.h" +#include "json/json.h" +#include "Eigen/Dense" + +using namespace feh; +using namespace std; + +int main() +{ + ATANCamera *cam = new ATANCamera(480, 640, 400, 400, 320, 240, 1.0); + Eigen::Vector2f xc(100, 100); + std::cout << "rows=" << cam->rows() << "; cols=" << cam->cols() << std::endl; + cam->Project(xc); + + delete cam; +} + diff --git a/format_all.sh b/format_all.sh new file mode 100755 index 00000000..a04a81fb --- /dev/null +++ b/format_all.sh @@ -0,0 +1 @@ +ls pybind11/*.cpp common/*.h common/*.cpp src/*.h src/*.cpp | xargs clang-format -i diff --git a/misc/tumvi_calib/pinhole-equi-512/camchain-imucam-imucalib.yaml b/misc/tumvi_calib/pinhole-equi-512/camchain-imucam-imucalib.yaml new file mode 100644 index 00000000..a336a7c3 --- /dev/null +++ b/misc/tumvi_calib/pinhole-equi-512/camchain-imucam-imucalib.yaml @@ -0,0 +1,33 @@ +cam0: + T_cam_imu: + - [-0.9995250378696743, 0.029615343885863205, -0.008522328211654736, 0.04727988224914392] + - [0.0075019185074052044, -0.03439736061393144, -0.9993800792498829, -0.047443232143367084] + - [-0.02989013031643309, -0.998969345370175, 0.03415885127385616, -0.0681999605066297] + - [0.0, 0.0, 0.0, 1.0] + cam_overlaps: [1] + camera_model: pinhole + distortion_coeffs: [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, + 0.00020293673591811182] + distortion_model: equidistant + intrinsics: [190.97847715128717, 190.9733070521226, 254.93170605935475, 256.8974428996504] + resolution: [512, 512] + rostopic: /cam0/image_raw +cam1: + T_cam_imu: + - [-0.9995110484978581, 0.030299116376600627, -0.0077218830287333565, -0.053697434688869734] + - [0.008104079263822521, 0.012511643720192351, -0.9998888851620987, -0.046131737923635924] + - [-0.030199136245891378, -0.9994625667418545, -0.012751072573940885, -0.07149261284195751] + - [0.0, 0.0, 0.0, 1.0] + T_cn_cnm1: + - [0.9999994457734953, -0.0008233639921576076, -0.0006561436136444361, -0.10106110275180535] + - [0.0007916877528168117, 0.9988994619156757, -0.04689603624058988, -0.0019764575873431013] + - [0.0006940340102242531, 0.04689549078870055, 0.9988995601463054, -0.0011756424802046581] + - [0.0, 0.0, 0.0, 1.0] + cam_overlaps: [0] + camera_model: pinhole + distortion_coeffs: [0.0034003170790442797, 0.001766278153469831, -0.00266312569781606, + 0.0003299517423931039] + distortion_model: equidistant + intrinsics: [190.44236969414825, 190.4344384721956, 252.59949716835982, 254.91723064636983] + resolution: [512, 512] + rostopic: /cam1/image_raw diff --git a/misc/tumvi_calib/pinhole-equi-512/imu-imucalib.yaml b/misc/tumvi_calib/pinhole-equi-512/imu-imucalib.yaml new file mode 100644 index 00000000..d67a1f33 --- /dev/null +++ b/misc/tumvi_calib/pinhole-equi-512/imu-imucalib.yaml @@ -0,0 +1,14 @@ +imu0: + T_i_b: + - [1.0, 0.0, 0.0, 0.0] + - [0.0, 1.0, 0.0, 0.0] + - [0.0, 0.0, 1.0, 0.0] + - [0.0, 0.0, 0.0, 1.0] + accelerometer_noise_density: 0.0028 + accelerometer_random_walk: 0.00086 + gyroscope_noise_density: 0.00016 + gyroscope_random_walk: 2.2e-05 + model: calibrated + rostopic: /imu0 + time_offset: 0.0 + update_rate: 200.0 diff --git a/misc/tumvi_calib/pinhole-equi-512/imucalib-command.txt b/misc/tumvi_calib/pinhole-equi-512/imucalib-command.txt new file mode 100644 index 00000000..0d31e6d5 --- /dev/null +++ b/misc/tumvi_calib/pinhole-equi-512/imucalib-command.txt @@ -0,0 +1 @@ +kalibr_calibrate_imu_camera --target /usr/wiss/demmeln/work/ros_ws/src/tum_stereo_dataset_tools/calibration/april_6x6_80x80cm.yaml --cam /work/ssd/demmeln/tsm-exclude/dataset4/results/kalibr/512_16/dataset-calib-cam8_512_16/pinhole-equi/camchain-camcalib.yaml --imu /usr/wiss/demmeln/work/ros_ws/src/tum_stereo_dataset_tools/calibration/imu_bmi160_tum.yaml --imu-model calibrated --bag imucalib.bag --dont-show-report diff --git a/misc/tumvi_calib/pinhole-equi-512/imucalib.log b/misc/tumvi_calib/pinhole-equi-512/imucalib.log new file mode 100644 index 00000000..59c41690 --- /dev/null +++ b/misc/tumvi_calib/pinhole-equi-512/imucalib.log @@ -0,0 +1,187 @@ +importing libraries +Initializing IMUs: + Update rate: 200.0 + Accelerometer: + Noise density: 0.0028 + Noise density (discrete): 0.0395979797464 + Random walk: 0.00086 + Gyroscope: + Noise density: 0.00016 + Noise density (discrete): 0.0022627416998 + Random walk: 2.2e-05 +Initializing imu rosbag dataset reader: + Dataset: imucalib.bag + Topic: /imu0 + Number of messages: 9694 +Reading IMU data (/imu0) + Progress 1 / 9694 Time remaining: 13s Progress 2 / 9694 Time remaining: 7s Progress 3 / 9694 Time remaining: 5s Progress 4 / 9694 Time remaining: 4s Progress 5 / 9694 Time remaining: 3s Progress 6 / 9694 Time remaining: 3s Progress 7 / 9694 Time remaining: 2s Progress 8 / 9694 Time remaining: 2s Progress 9 / 9694 Time remaining: 2s Progress 10 / 9694 Time remaining: 2s Progress 11 / 9694 Time remaining: 2s Progress 12 / 9694 Time remaining: 2s Progress 13 / 9694 Time remaining: 2s Progress 14 / 9694 Time remaining: 2s Progress 15 / 9694 Time remaining: 1s Progress 16 / 9694 Time remaining: 1s Progress 17 / 9694 Time remaining: 1s Progress 18 / 9694 Time remaining: 1s Progress 19 / 9694 Time remaining: 1s Progress 20 / 9694 Time remaining: 1s Progress 21 / 9694 Time remaining: 1s Progress 22 / 9694 Time remaining: 1s Progress 23 / 9694 Time remaining: 1s Progress 24 / 9694 Time remaining: 1s Progress 25 / 9694 Time remaining: 1s Progress 26 / 9694 Time remaining: 1s Progress 27 / 9694 Time remaining: 1s Progress 28 / 9694 Time remaining: 1s Progress 29 / 9694 Time remaining: 1s Progress 30 / 9694 Time remaining: 1s Progress 31 / 9694 Time remaining: 1s Progress 32 / 9694 Time remaining: 1s Progress 33 / 9694 Time remaining: 1s Progress 34 / 9694 Time remaining: 1s Progress 35 / 9694 Time remaining: 1s Progress 36 / 9694 Time remaining: 1s Progress 37 / 9694 Time remaining: 1s Progress 38 / 9694 Time remaining: 1s Progress 39 / 9694 Time remaining: 1s Progress 40 / 9694 Time remaining: 1s Progress 41 / 9694 Time remaining: 1s Progress 42 / 9694 Time remaining: 1s Progress 43 / 9694 Time remaining: 1s Progress 44 / 9694 Time remaining: 1s Progress 45 / 9694 Time remaining: 1s Progress 46 / 9694 Time remaining: 1s Progress 47 / 9694 Time remaining: 1s Progress 48 / 9694 Time remaining: 1s Progress 49 / 9694 Time remaining: 1s Progress 50 / 9694 Time remaining: 1s Progress 51 / 9694 Time remaining: 1s Progress 52 / 9694 Time remaining: 1s Progress 53 / 9694 Time remaining: 1s Progress 54 / 9694 Time remaining: 1s Progress 55 / 9694 Time remaining: 1s Progress 56 / 9694 Time remaining: 1s Progress 57 / 9694 Time remaining: 1s Progress 58 / 9694 Time remaining: 1s Progress 59 / 9694 Time remaining: 1s Progress 60 / 9694 Time remaining: 1s Progress 61 / 9694 Time remaining: 1s Progress 62 / 9694 Time remaining: 1s Progress 63 / 9694 Time remaining: 1s Progress 64 / 9694 Time remaining: 1s Progress 65 / 9694 Time remaining: 1s Progress 66 / 9694 Time remaining: 1s Progress 67 / 9694 Time remaining: 1s Progress 68 / 9694 Time remaining: 1s Progress 69 / 9694 Time remaining: 1s Progress 70 / 9694 Time remaining: 1s Progress 71 / 9694 Time remaining: 1s Progress 72 / 9694 Time remaining: 1s Progress 73 / 9694 Time remaining: 1s Progress 74 / 9694 Time remaining: 1s Progress 75 / 9694 Time remaining: 1s Progress 76 / 9694 Time remaining: 1s Progress 77 / 9694 Time remaining: 1s Progress 78 / 9694 Time remaining: 1s Progress 79 / 9694 Time remaining: 1s Progress 80 / 9694 Time remaining: 1s Progress 81 / 9694 Time remaining: 1s Progress 82 / 9694 Time remaining: 1s Progress 83 / 9694 Time remaining: 1s Progress 84 / 9694 Time remaining: 1s Progress 85 / 9694 Time remaining: 1s Progress 86 / 9694 Time remaining: 1s Progress 87 / 9694 Time remaining: 1s Progress 88 / 9694 Time remaining: 1s Progress 89 / 9694 Time remaining: 1s Progress 90 / 9694 Time remaining: 1s Progress 91 / 9694 Time remaining: 1s Progress 92 / 9694 Time remaining: 1s Progress 93 / 9694 Time remaining: 1s Progress 94 / 9694 Time remaining: 1s Progress 95 / 9694 Time remaining: 1s Progress 96 / 9694 Time remaining: 1s Progress 97 / 9694 Time remaining: 1s Progress 98 / 9694 Time remaining: 1s Progress 99 / 9694 Time remaining: 1s Progress 100 / 9694 Time remaining: 1s Progress 101 / 9694 Time remaining: 1s Progress 102 / 9694 Time remaining: 1s Progress 103 / 9694 Time remaining: 1s Progress 104 / 9694 Time remaining: 1s Progress 105 / 9694 Time remaining: 1s Progress 106 / 9694 Time remaining: 1s Progress 107 / 9694 Time remaining: 1s Progress 108 / 9694 Time remaining: 1s Progress 109 / 9694 Time remaining: 1s Progress 110 / 9694 Time remaining: 1s Progress 111 / 9694 Time remaining: 1s Progress 112 / 9694 Time remaining: 1s Progress 113 / 9694 Time remaining: 1s Progress 114 / 9694 Time remaining: 1s Progress 115 / 9694 Time remaining: 1s Progress 116 / 9694 Time remaining: 1s Progress 117 / 9694 Time remaining: 1s Progress 118 / 9694 Time remaining: 1s Progress 119 / 9694 Time remaining: 1s Progress 120 / 9694 Time remaining: 1s Progress 121 / 9694 Time remaining: 1s Progress 122 / 9694 Time remaining: 1s Progress 123 / 9694 Time remaining: 1s Progress 124 / 9694 Time remaining: 1s Progress 125 / 9694 Time remaining: 1s Progress 126 / 9694 Time remaining: 1s Progress 127 / 9694 Time remaining: 1s Progress 128 / 9694 Time remaining: 1s Progress 129 / 9694 Time remaining: 1s Progress 130 / 9694 Time remaining: 1s Progress 131 / 9694 Time remaining: 1s Progress 132 / 9694 Time remaining: 1s Progress 133 / 9694 Time remaining: 1s Progress 134 / 9694 Time remaining: 1s Progress 135 / 9694 Time remaining: 1s Progress 136 / 9694 Time remaining: 1s Progress 137 / 9694 Time remaining: 1s Progress 138 / 9694 Time remaining: 1s Progress 139 / 9694 Time remaining: 1s Progress 140 / 9694 Time remaining: 1s Progress 141 / 9694 Time remaining: 1s Progress 142 / 9694 Time remaining: 1s Progress 143 / 9694 Time remaining: 1s Progress 144 / 9694 Time remaining: 1s Progress 145 / 9694 Time remaining: 1s Progress 146 / 9694 Time remaining: 1s Progress 147 / 9694 Time remaining: 1s Progress 148 / 9694 Time remaining: 1s Progress 149 / 9694 Time remaining: 1s Progress 150 / 9694 Time remaining: 1s Progress 151 / 9694 Time remaining: 1s Progress 152 / 9694 Time remaining: 1s Progress 153 / 9694 Time remaining: 1s Progress 154 / 9694 Time remaining: 1s Progress 155 / 9694 Time remaining: 1s Progress 156 / 9694 Time remaining: 1s Progress 157 / 9694 Time remaining: 1s Progress 158 / 9694 Time remaining: 1s Progress 159 / 9694 Time remaining: 1s Progress 160 / 9694 Time remaining: 1s Progress 161 / 9694 Time remaining: 1s Progress 162 / 9694 Time remaining: 1s Progress 163 / 9694 Time remaining: 1s Progress 164 / 9694 Time remaining: 1s Progress 165 / 9694 Time remaining: 1s Progress 166 / 9694 Time remaining: 1s Progress 167 / 9694 Time remaining: 1s Progress 168 / 9694 Time remaining: 1s Progress 169 / 9694 Time remaining: 1s Progress 170 / 9694 Time remaining: 1s Progress 171 / 9694 Time remaining: 1s Progress 172 / 9694 Time remaining: 1s Progress 173 / 9694 Time remaining: 1s Progress 174 / 9694 Time remaining: 1s Progress 175 / 9694 Time remaining: 1s Progress 176 / 9694 Time remaining: 1s Progress 177 / 9694 Time remaining: 1s Progress 178 / 9694 Time remaining: 1s Progress 179 / 9694 Time remaining: 1s Progress 180 / 9694 Time remaining: 1s Progress 181 / 9694 Time remaining: 1s Progress 182 / 9694 Time remaining: 1s Progress 183 / 9694 Time remaining: 1s Progress 184 / 9694 Time remaining: 1s Progress 185 / 9694 Time remaining: 1s Progress 186 / 9694 Time remaining: 1s Progress 187 / 9694 Time remaining: 1s Progress 188 / 9694 Time remaining: 1s Progress 189 / 9694 Time remaining: 1s Progress 190 / 9694 Time remaining: 1s Progress 191 / 9694 Time remaining: 1s Progress 192 / 9694 Time remaining: 1s Progress 193 / 9694 Time remaining: 1s Progress 194 / 9694 Time remaining: 1s Progress 195 / 9694 Time remaining: 1s Progress 196 / 9694 Time remaining: 1s Progress 197 / 9694 Time remaining: 1s Progress 198 / 9694 Time remaining: 1s Progress 199 / 9694 Time remaining: 1s Progress 200 / 9694 Time remaining: 1s Progress 201 / 9694 Time remaining: 1s Progress 202 / 9694 Time remaining: 1s Progress 203 / 9694 Time remaining: 1s Progress 204 / 9694 Time remaining: 1s Progress 205 / 9694 Time remaining: 1s Progress 206 / 9694 Time remaining: 1s Progress 207 / 9694 Time remaining: 1s Progress 208 / 9694 Time remaining: 1s Progress 209 / 9694 Time remaining: 1s Progress 210 / 9694 Time remaining: 1s Progress 211 / 9694 Time remaining: 1s Progress 212 / 9694 Time remaining: 1s Progress 213 / 9694 Time remaining: 1s Progress 214 / 9694 Time remaining: 1s Progress 215 / 9694 Time remaining: 1s Progress 216 / 9694 Time remaining: 1s Progress 217 / 9694 Time remaining: 1s Progress 218 / 9694 Time remaining: 1s Progress 219 / 9694 Time remaining: 1s Progress 220 / 9694 Time remaining: 1s Progress 221 / 9694 Time remaining: 1s Progress 222 / 9694 Time remaining: 1s Progress 223 / 9694 Time remaining: 1s Progress 224 / 9694 Time remaining: 1s Progress 225 / 9694 Time remaining: 1s Progress 226 / 9694 Time remaining: 1s Progress 227 / 9694 Time remaining: 1s Progress 228 / 9694 Time remaining: 1s Progress 229 / 9694 Time remaining: 1s Progress 230 / 9694 Time remaining: 1s Progress 231 / 9694 Time remaining: 1s Progress 232 / 9694 Time remaining: 1s Progress 233 / 9694 Time remaining: 1s Progress 234 / 9694 Time remaining: 1s Progress 235 / 9694 Time remaining: 1s Progress 236 / 9694 Time remaining: 1s Progress 237 / 9694 Time remaining: 1s Progress 238 / 9694 Time remaining: 1s Progress 239 / 9694 Time remaining: 1s Progress 240 / 9694 Time remaining: 1s Progress 241 / 9694 Time remaining: 1s Progress 242 / 9694 Time remaining: 1s Progress 243 / 9694 Time remaining: 1s Progress 244 / 9694 Time remaining: 1s Progress 245 / 9694 Time remaining: 1s Progress 246 / 9694 Time remaining: 1s Progress 247 / 9694 Time remaining: 1s Progress 248 / 9694 Time remaining: 1s Progress 249 / 9694 Time remaining: 1s Progress 250 / 9694 Time remaining: 1s Progress 251 / 9694 Time remaining: 1s Progress 252 / 9694 Time remaining: 1s Progress 253 / 9694 Time remaining: 1s Progress 254 / 9694 Time remaining: 1s Progress 255 / 9694 Time remaining: 1s Progress 256 / 9694 Time remaining: 1s Progress 257 / 9694 Time remaining: 1s Progress 258 / 9694 Time remaining: 1s Progress 259 / 9694 Time remaining: 1s Progress 260 / 9694 Time remaining: 1s Progress 261 / 9694 Time remaining: 1s Progress 262 / 9694 Time remaining: 1s Progress 263 / 9694 Time remaining: 1s Progress 264 / 9694 Time remaining: 1s Progress 265 / 9694 Time remaining: 1s Progress 266 / 9694 Time remaining: 1s Progress 267 / 9694 Time remaining: 1s Progress 268 / 9694 Time remaining: 1s Progress 269 / 9694 Time remaining: 1s Progress 270 / 9694 Time remaining: 1s Progress 271 / 9694 Time remaining: 1s Progress 272 / 9694 Time remaining: 1s Progress 273 / 9694 Time remaining: 1s Progress 274 / 9694 Time remaining: 1s Progress 275 / 9694 Time remaining: 1s Progress 276 / 9694 Time remaining: 1s Progress 277 / 9694 Time remaining: 1s Progress 278 / 9694 Time remaining: 1s Progress 279 / 9694 Time remaining: 1s Progress 280 / 9694 Time remaining: 1s Progress 281 / 9694 Time remaining: 1s Progress 282 / 9694 Time remaining: 1s Progress 283 / 9694 Time remaining: 1s Progress 284 / 9694 Time remaining: 1s Progress 285 / 9694 Time remaining: 1s Progress 286 / 9694 Time remaining: 1s Progress 287 / 9694 Time remaining: 1s Progress 288 / 9694 Time remaining: 1s Progress 289 / 9694 Time remaining: 1s Progress 290 / 9694 Time remaining: 1s Progress 291 / 9694 Time remaining: 1s Progress 292 / 9694 Time remaining: 1s Progress 293 / 9694 Time remaining: 1s Progress 294 / 9694 Time remaining: 1s Progress 295 / 9694 Time remaining: 1s Progress 296 / 9694 Time remaining: 1s Progress 297 / 9694 Time remaining: 1s Progress 298 / 9694 Time remaining: 1s Progress 299 / 9694 Time remaining: 1s Progress 300 / 9694 Time remaining: 1s Progress 301 / 9694 Time remaining: 1s Progress 302 / 9694 Time remaining: 1s Progress 303 / 9694 Time remaining: 1s Progress 304 / 9694 Time remaining: 1s Progress 305 / 9694 Time remaining: 1s Progress 306 / 9694 Time remaining: 1s Progress 307 / 9694 Time remaining: 1s Progress 308 / 9694 Time remaining: 1s Progress 309 / 9694 Time remaining: 1s Progress 310 / 9694 Time remaining: 1s Progress 311 / 9694 Time remaining: 1s Progress 312 / 9694 Time remaining: 1s Progress 313 / 9694 Time remaining: 1s Progress 314 / 9694 Time remaining: 1s Progress 315 / 9694 Time remaining: 1s Progress 316 / 9694 Time remaining: 1s Progress 317 / 9694 Time remaining: 1s Progress 318 / 9694 Time remaining: 1s Progress 319 / 9694 Time remaining: 1s Progress 320 / 9694 Time remaining: 1s Progress 321 / 9694 Time remaining: 1s Progress 322 / 9694 Time remaining: 1s Progress 323 / 9694 Time remaining: 1s Progress 324 / 9694 Time remaining: 1s Progress 325 / 9694 Time remaining: 1s Progress 326 / 9694 Time remaining: 1s Progress 327 / 9694 Time remaining: 1s Progress 328 / 9694 Time remaining: 1s Progress 329 / 9694 Time remaining: 1s Progress 330 / 9694 Time remaining: 1s Progress 331 / 9694 Time remaining: 1s Progress 332 / 9694 Time remaining: 1s Progress 333 / 9694 Time remaining: 1s Progress 334 / 9694 Time remaining: 1s Progress 335 / 9694 Time remaining: 1s Progress 336 / 9694 Time remaining: 1s Progress 337 / 9694 Time remaining: 1s Progress 338 / 9694 Time remaining: 1s Progress 339 / 9694 Time remaining: 1s Progress 340 / 9694 Time remaining: 1s Progress 341 / 9694 Time remaining: 1s Progress 342 / 9694 Time remaining: 1s Progress 343 / 9694 Time remaining: 1s Progress 344 / 9694 Time remaining: 1s Progress 345 / 9694 Time remaining: 1s Progress 346 / 9694 Time remaining: 1s Progress 347 / 9694 Time remaining: 1s Progress 348 / 9694 Time remaining: 1s Progress 349 / 9694 Time remaining: 1s Progress 350 / 9694 Time remaining: 1s Progress 351 / 9694 Time remaining: 1s Progress 352 / 9694 Time remaining: 1s Progress 353 / 9694 Time remaining: 1s Progress 354 / 9694 Time remaining: 1s Progress 355 / 9694 Time remaining: 1s Progress 356 / 9694 Time remaining: 1s Progress 357 / 9694 Time remaining: 1s Progress 358 / 9694 Time remaining: 1s Progress 359 / 9694 Time remaining: 1s Progress 360 / 9694 Time remaining: 1s Progress 361 / 9694 Time remaining: 1s Progress 362 / 9694 Time remaining: 1s Progress 363 / 9694 Time remaining: 1s Progress 364 / 9694 Time remaining: 1s Progress 365 / 9694 Time remaining: 1s Progress 366 / 9694 Time remaining: 1s Progress 367 / 9694 Time remaining: 1s Progress 368 / 9694 Time remaining: 1s Progress 369 / 9694 Time remaining: 1s Progress 370 / 9694 Time remaining: 1s Progress 371 / 9694 Time remaining: 1s Progress 372 / 9694 Time remaining: 1s Progress 373 / 9694 Time remaining: 1s Progress 374 / 9694 Time remaining: 1s Progress 375 / 9694 Time remaining: 1s Progress 376 / 9694 Time remaining: 1s Progress 377 / 9694 Time remaining: 1s Progress 378 / 9694 Time remaining: 1s Progress 379 / 9694 Time remaining: 1s Progress 380 / 9694 Time remaining: 1s Progress 381 / 9694 Time remaining: 1s Progress 382 / 9694 Time remaining: 1s Progress 383 / 9694 Time remaining: 1s Progress 384 / 9694 Time remaining: 1s Progress 385 / 9694 Time remaining: 1s Progress 386 / 9694 Time remaining: 1s Progress 387 / 9694 Time remaining: 1s Progress 388 / 9694 Time remaining: 1s Progress 389 / 9694 Time remaining: 1s Progress 390 / 9694 Time remaining: 1s Progress 391 / 9694 Time remaining: 1s Progress 392 / 9694 Time remaining: 1s Progress 393 / 9694 Time remaining: 1s Progress 394 / 9694 Time remaining: 1s Progress 395 / 9694 Time remaining: 1s Progress 396 / 9694 Time remaining: 1s Progress 397 / 9694 Time remaining: 1s Progress 398 / 9694 Time remaining: 1s Progress 399 / 9694 Time remaining: 1s Progress 400 / 9694 Time remaining: 1s Progress 401 / 9694 Time remaining: 1s Progress 402 / 9694 Time remaining: 1s Progress 403 / 9694 Time remaining: 1s Progress 404 / 9694 Time remaining: 1s Progress 405 / 9694 Time remaining: 1s Progress 406 / 9694 Time remaining: 1s Progress 407 / 9694 Time remaining: 1s Progress 408 / 9694 Time remaining: 1s Progress 409 / 9694 Time remaining: 1s Progress 410 / 9694 Time remaining: 1s Progress 411 / 9694 Time remaining: 1s Progress 412 / 9694 Time remaining: 1s Progress 413 / 9694 Time remaining: 1s Progress 414 / 9694 Time remaining: 1s Progress 415 / 9694 Time remaining: 1s Progress 416 / 9694 Time remaining: 1s Progress 417 / 9694 Time remaining: 1s Progress 418 / 9694 Time remaining: 1s Progress 419 / 9694 Time remaining: 1s Progress 420 / 9694 Time remaining: 1s Progress 421 / 9694 Time remaining: 1s Progress 422 / 9694 Time remaining: 1s Progress 423 / 9694 Time remaining: 1s Progress 424 / 9694 Time remaining: 1s Progress 425 / 9694 Time remaining: 1s Progress 426 / 9694 Time remaining: 1s Progress 427 / 9694 Time remaining: 1s Progress 428 / 9694 Time remaining: 1s Progress 429 / 9694 Time remaining: 1s Progress 430 / 9694 Time remaining: 1s Progress 431 / 9694 Time remaining: 1s Progress 432 / 9694 Time remaining: 1s Progress 433 / 9694 Time remaining: 1s Progress 434 / 9694 Time remaining: 1s Progress 435 / 9694 Time remaining: 1s Progress 436 / 9694 Time remaining: 1s Progress 437 / 9694 Time remaining: 1s Progress 438 / 9694 Time remaining: 1s Progress 439 / 9694 Time remaining: 1s Progress 440 / 9694 Time remaining: 1s Progress 441 / 9694 Time remaining: 1s Progress 442 / 9694 Time remaining: 1s Progress 443 / 9694 Time remaining: 1s Progress 444 / 9694 Time remaining: 1s Progress 445 / 9694 Time remaining: 1s Progress 446 / 9694 Time remaining: 1s Progress 447 / 9694 Time remaining: 1s Progress 448 / 9694 Time remaining: 1s Progress 449 / 9694 Time remaining: 1s Progress 450 / 9694 Time remaining: 1s Progress 451 / 9694 Time remaining: 1s Progress 452 / 9694 Time remaining: 1s Progress 453 / 9694 Time remaining: 1s Progress 454 / 9694 Time remaining: 1s Progress 455 / 9694 Time remaining: 1s Progress 456 / 9694 Time remaining: 1s Progress 457 / 9694 Time remaining: 1s Progress 458 / 9694 Time remaining: 1s Progress 459 / 9694 Time remaining: 1s Progress 460 / 9694 Time remaining: 1s Progress 461 / 9694 Time remaining: 1s Progress 462 / 9694 Time remaining: 1s Progress 463 / 9694 Time remaining: 1s Progress 464 / 9694 Time remaining: 1s Progress 465 / 9694 Time remaining: 1s Progress 466 / 9694 Time remaining: 1s Progress 467 / 9694 Time remaining: 1s Progress 468 / 9694 Time remaining: 1s Progress 469 / 9694 Time remaining: 1s Progress 470 / 9694 Time remaining: 1s Progress 471 / 9694 Time remaining: 1s Progress 472 / 9694 Time remaining: 1s Progress 473 / 9694 Time remaining: 1s Progress 474 / 9694 Time remaining: 1s Progress 475 / 9694 Time remaining: 1s Progress 476 / 9694 Time remaining: 1s Progress 477 / 9694 Time remaining: 1s Progress 478 / 9694 Time remaining: 1s Progress 479 / 9694 Time remaining: 1s Progress 480 / 9694 Time remaining: 1s Progress 481 / 9694 Time remaining: 1s Progress 482 / 9694 Time remaining: 1s Progress 483 / 9694 Time remaining: 1s Progress 484 / 9694 Time remaining: 1s Progress 485 / 9694 Time remaining: 1s Progress 486 / 9694 Time remaining: 1s Progress 487 / 9694 Time remaining: 1s Progress 488 / 9694 Time remaining: 1s Progress 489 / 9694 Time remaining: 1s Progress 490 / 9694 Time remaining: 1s Progress 491 / 9694 Time remaining: 1s Progress 492 / 9694 Time remaining: 1s Progress 493 / 9694 Time remaining: 1s Progress 494 / 9694 Time remaining: 1s Progress 495 / 9694 Time remaining: 1s Progress 496 / 9694 Time remaining: 1s Progress 497 / 9694 Time remaining: 1s Progress 498 / 9694 Time remaining: 1s Progress 499 / 9694 Time remaining: 1s Progress 500 / 9694 Time remaining: 1s Progress 501 / 9694 Time remaining: 1s Progress 502 / 9694 Time remaining: 1s Progress 503 / 9694 Time remaining: 1s Progress 504 / 9694 Time remaining: 1s Progress 505 / 9694 Time remaining: 1s Progress 506 / 9694 Time remaining: 1s Progress 507 / 9694 Time remaining: 1s Progress 508 / 9694 Time remaining: 1s Progress 509 / 9694 Time remaining: 1s Progress 510 / 9694 Time remaining: 1s Progress 511 / 9694 Time remaining: 1s Progress 512 / 9694 Time remaining: 1s Progress 513 / 9694 Time remaining: 1s Progress 514 / 9694 Time remaining: 1s Progress 515 / 9694 Time remaining: 1s Progress 516 / 9694 Time remaining: 1s Progress 517 / 9694 Time remaining: 1s Progress 518 / 9694 Time remaining: 1s Progress 519 / 9694 Time remaining: 1s Progress 520 / 9694 Time remaining: 1s Progress 521 / 9694 Time remaining: 1s Progress 522 / 9694 Time remaining: 1s Progress 523 / 9694 Time remaining: 1s Progress 524 / 9694 Time remaining: 1s Progress 525 / 9694 Time remaining: 1s Progress 526 / 9694 Time remaining: 1s Progress 527 / 9694 Time remaining: 1s Progress 528 / 9694 Time remaining: 1s Progress 529 / 9694 Time remaining: 1s Progress 530 / 9694 Time remaining: 1s Progress 531 / 9694 Time remaining: 1s Progress 532 / 9694 Time remaining: 1s Progress 533 / 9694 Time remaining: 1s Progress 534 / 9694 Time remaining: 1s Progress 535 / 9694 Time remaining: 1s Progress 536 / 9694 Time remaining: 1s Progress 537 / 9694 Time remaining: 1s Progress 538 / 9694 Time remaining: 1s Progress 539 / 9694 Time remaining: 1s Progress 540 / 9694 Time remaining: 1s Progress 541 / 9694 Time remaining: 1s Progress 542 / 9694 Time remaining: 1s Progress 543 / 9694 Time remaining: 1s Progress 544 / 9694 Time remaining: 1s Progress 545 / 9694 Time remaining: 1s Progress 546 / 9694 Time remaining: 1s Progress 547 / 9694 Time remaining: 1s Progress 548 / 9694 Time remaining: 1s Progress 549 / 9694 Time remaining: 1s Progress 550 / 9694 Time remaining: 1s Progress 551 / 9694 Time remaining: 1s Progress 552 / 9694 Time remaining: 1s Progress 553 / 9694 Time remaining: 1s Progress 554 / 9694 Time remaining: 1s Progress 555 / 9694 Time remaining: 1s Progress 556 / 9694 Time remaining: 1s Progress 557 / 9694 Time remaining: 1s Progress 558 / 9694 Time remaining: 1s Progress 559 / 9694 Time remaining: 1s Progress 560 / 9694 Time remaining: 1s Progress 561 / 9694 Time remaining: 1s Progress 562 / 9694 Time remaining: 1s Progress 563 / 9694 Time remaining: 1s Progress 564 / 9694 Time remaining: 1s Progress 565 / 9694 Time remaining: 1s Progress 566 / 9694 Time remaining: 1s Progress 567 / 9694 Time remaining: 1s Progress 568 / 9694 Time remaining: 1s Progress 569 / 9694 Time remaining: 1s Progress 570 / 9694 Time remaining: 1s Progress 571 / 9694 Time remaining: 1s Progress 572 / 9694 Time remaining: 1s Progress 573 / 9694 Time remaining: 1s Progress 574 / 9694 Time remaining: 1s Progress 575 / 9694 Time remaining: 1s Progress 576 / 9694 Time remaining: 1s Progress 577 / 9694 Time remaining: 1s Progress 578 / 9694 Time remaining: 1s Progress 579 / 9694 Time remaining: 1s Progress 580 / 9694 Time remaining: 1s Progress 581 / 9694 Time remaining: 1s Progress 582 / 9694 Time remaining: 1s Progress 583 / 9694 Time remaining: 1s Progress 584 / 9694 Time remaining: 1s Progress 585 / 9694 Time remaining: 1s Progress 586 / 9694 Time remaining: 1s Progress 587 / 9694 Time remaining: 1s Progress 588 / 9694 Time remaining: 1s Progress 589 / 9694 Time remaining: 1s Progress 590 / 9694 Time remaining: 1s Progress 591 / 9694 Time remaining: 1s Progress 592 / 9694 Time remaining: 1s Progress 593 / 9694 Time remaining: 1s Progress 594 / 9694 Time remaining: 1s Progress 595 / 9694 Time remaining: 1s Progress 596 / 9694 Time remaining: 1s Progress 597 / 9694 Time remaining: 1s Progress 598 / 9694 Time remaining: 1s Progress 599 / 9694 Time remaining: 1s Progress 600 / 9694 Time remaining: 1s Progress 601 / 9694 Time remaining: 1s Progress 602 / 9694 Time remaining: 1s Progress 603 / 9694 Time remaining: 1s Progress 604 / 9694 Time remaining: 1s Progress 605 / 9694 Time remaining: 1s Progress 606 / 9694 Time remaining: 1s Progress 607 / 9694 Time remaining: 1s Progress 608 / 9694 Time remaining: 1s Progress 609 / 9694 Time remaining: 1s Progress 610 / 9694 Time remaining: 1s Progress 611 / 9694 Time remaining: 1s Progress 612 / 9694 Time remaining: 1s Progress 613 / 9694 Time remaining: 1s Progress 614 / 9694 Time remaining: 1s Progress 615 / 9694 Time remaining: 1s Progress 616 / 9694 Time remaining: 1s Progress 617 / 9694 Time remaining: 1s Progress 618 / 9694 Time remaining: 1s Progress 619 / 9694 Time remaining: 1s Progress 620 / 9694 Time remaining: 1s Progress 621 / 9694 Time remaining: 1s Progress 622 / 9694 Time remaining: 1s Progress 623 / 9694 Time remaining: 1s Progress 624 / 9694 Time remaining: 1s Progress 625 / 9694 Time remaining: 1s Progress 626 / 9694 Time remaining: 1s Progress 627 / 9694 Time remaining: 1s Progress 628 / 9694 Time remaining: 1s Progress 629 / 9694 Time remaining: 1s Progress 630 / 9694 Time remaining: 1s Progress 631 / 9694 Time remaining: 1s Progress 632 / 9694 Time remaining: 1s Progress 633 / 9694 Time remaining: 1s Progress 634 / 9694 Time remaining: 1s Progress 635 / 9694 Time remaining: 1s Progress 636 / 9694 Time remaining: 1s Progress 637 / 9694 Time remaining: 1s Progress 638 / 9694 Time remaining: 1s Progress 639 / 9694 Time remaining: 1s Progress 640 / 9694 Time remaining: 1s Progress 641 / 9694 Time remaining: 1s Progress 642 / 9694 Time remaining: 1s Progress 643 / 9694 Time remaining: 1s Progress 644 / 9694 Time remaining: 1s Progress 645 / 9694 Time remaining: 1s Progress 646 / 9694 Time remaining: 1s Progress 647 / 9694 Time remaining: 1s Progress 648 / 9694 Time remaining: 1s Progress 649 / 9694 Time remaining: 1s Progress 650 / 9694 Time remaining: 1s Progress 651 / 9694 Time remaining: 1s Progress 652 / 9694 Time remaining: 1s Progress 653 / 9694 Time remaining: 1s Progress 654 / 9694 Time remaining: 1s Progress 655 / 9694 Time remaining: 1s Progress 656 / 9694 Time remaining: 1s Progress 657 / 9694 Time remaining: 1s Progress 658 / 9694 Time remaining: 1s Progress 659 / 9694 Time remaining: 1s Progress 660 / 9694 Time remaining: 1s Progress 661 / 9694 Time remaining: 1s Progress 662 / 9694 Time remaining: 1s Progress 663 / 9694 Time remaining: 1s Progress 664 / 9694 Time remaining: 1s Progress 665 / 9694 Time remaining: 1s Progress 666 / 9694 Time remaining: 1s Progress 667 / 9694 Time remaining: 1s Progress 668 / 9694 Time remaining: 1s Progress 669 / 9694 Time remaining: 1s Progress 670 / 9694 Time remaining: 1s Progress 671 / 9694 Time remaining: 1s Progress 672 / 9694 Time remaining: 1s Progress 673 / 9694 Time remaining: 1s Progress 674 / 9694 Time remaining: 1s Progress 675 / 9694 Time remaining: 1s Progress 676 / 9694 Time remaining: 1s Progress 677 / 9694 Time remaining: 1s Progress 678 / 9694 Time remaining: 1s Progress 679 / 9694 Time remaining: 1s Progress 680 / 9694 Time remaining: 1s Progress 681 / 9694 Time remaining: 1s Progress 682 / 9694 Time remaining: 1s Progress 683 / 9694 Time remaining: 1s Progress 684 / 9694 Time remaining: 1s Progress 685 / 9694 Time remaining: 1s Progress 686 / 9694 Time remaining: 1s Progress 687 / 9694 Time remaining: 1s Progress 688 / 9694 Time remaining: 1s Progress 689 / 9694 Time remaining: 1s Progress 690 / 9694 Time remaining: 1s Progress 691 / 9694 Time remaining: 1s Progress 692 / 9694 Time remaining: 1s Progress 693 / 9694 Time remaining: 1s Progress 694 / 9694 Time remaining: 1s Progress 695 / 9694 Time remaining: 1s Progress 696 / 9694 Time remaining: 1s Progress 697 / 9694 Time remaining: 1s Progress 698 / 9694 Time remaining: 1s Progress 699 / 9694 Time remaining: 1s Progress 700 / 9694 Time remaining: 1s Progress 701 / 9694 Time remaining: 1s Progress 702 / 9694 Time remaining: 1s Progress 703 / 9694 Time remaining: 1s Progress 704 / 9694 Time remaining: 1s Progress 705 / 9694 Time remaining: 1s Progress 706 / 9694 Time remaining: 1s Progress 707 / 9694 Time remaining: 1s Progress 708 / 9694 Time remaining: 1s Progress 709 / 9694 Time remaining: 1s Progress 710 / 9694 Time remaining: 1s Progress 711 / 9694 Time remaining: 1s Progress 712 / 9694 Time remaining: 1s Progress 713 / 9694 Time remaining: 1s Progress 714 / 9694 Time remaining: 1s Progress 715 / 9694 Time remaining: 1s Progress 716 / 9694 Time remaining: 1s Progress 717 / 9694 Time remaining: 1s Progress 718 / 9694 Time remaining: 1s Progress 719 / 9694 Time remaining: 1s Progress 720 / 9694 Time remaining: 1s Progress 721 / 9694 Time remaining: 1s Progress 722 / 9694 Time remaining: 1s Progress 723 / 9694 Time remaining: 1s Progress 724 / 9694 Time remaining: 1s Progress 725 / 9694 Time remaining: 1s Progress 726 / 9694 Time remaining: 1s Progress 727 / 9694 Time remaining: 1s Progress 728 / 9694 Time remaining: 1s Progress 729 / 9694 Time remaining: 1s Progress 730 / 9694 Time remaining: 1s Progress 731 / 9694 Time remaining: 1s Progress 732 / 9694 Time remaining: 1s Progress 733 / 9694 Time remaining: 1s Progress 734 / 9694 Time remaining: 1s Progress 735 / 9694 Time remaining: 1s Progress 736 / 9694 Time remaining: 1s Progress 737 / 9694 Time remaining: 1s Progress 738 / 9694 Time remaining: 1s Progress 739 / 9694 Time remaining: 1s Progress 740 / 9694 Time remaining: 1s Progress 741 / 9694 Time remaining: 1s Progress 742 / 9694 Time remaining: 1s Progress 743 / 9694 Time remaining: 1s Progress 744 / 9694 Time remaining: 1s Progress 745 / 9694 Time remaining: 1s Progress 746 / 9694 Time remaining: 1s Progress 747 / 9694 Time remaining: 1s Progress 748 / 9694 Time remaining: 1s Progress 749 / 9694 Time remaining: 1s Progress 750 / 9694 Time remaining: 1s Progress 751 / 9694 Time remaining: 1s Progress 752 / 9694 Time remaining: 1s Progress 753 / 9694 Time remaining: 1s Progress 754 / 9694 Time remaining: 1s Progress 755 / 9694 Time remaining: 1s Progress 756 / 9694 Time remaining: 1s Progress 757 / 9694 Time remaining: 1s Progress 758 / 9694 Time remaining: 1s Progress 759 / 9694 Time remaining: 1s Progress 760 / 9694 Time remaining: 1s Progress 761 / 9694 Time remaining: 1s Progress 762 / 9694 Time remaining: 1s Progress 763 / 9694 Time remaining: 1s Progress 764 / 9694 Time remaining: 1s Progress 765 / 9694 Time remaining: 1s Progress 766 / 9694 Time remaining: 1s Progress 767 / 9694 Time remaining: 1s Progress 768 / 9694 Time remaining: 1s Progress 769 / 9694 Time remaining: 1s Progress 770 / 9694 Time remaining: 1s Progress 771 / 9694 Time remaining: 1s Progress 772 / 9694 Time remaining: 1s Progress 773 / 9694 Time remaining: 1s Progress 774 / 9694 Time remaining: 1s Progress 775 / 9694 Time remaining: 1s Progress 776 / 9694 Time remaining: 1s Progress 777 / 9694 Time remaining: 1s Progress 778 / 9694 Time remaining: 1s Progress 779 / 9694 Time remaining: 1s Progress 780 / 9694 Time remaining: 1s Progress 781 / 9694 Time remaining: 1s Progress 782 / 9694 Time remaining: 1s Progress 783 / 9694 Time remaining: 1s Progress 784 / 9694 Time remaining: 1s Progress 785 / 9694 Time remaining: 1s Progress 786 / 9694 Time remaining: 1s Progress 787 / 9694 Time remaining: 1s Progress 788 / 9694 Time remaining: 1s Progress 789 / 9694 Time remaining: 1s Progress 790 / 9694 Time remaining: 1s Progress 791 / 9694 Time remaining: 1s Progress 792 / 9694 Time remaining: 1s Progress 793 / 9694 Time remaining: 1s Progress 794 / 9694 Time remaining: 1s Progress 795 / 9694 Time remaining: 1s Progress 796 / 9694 Time remaining: 1s Progress 797 / 9694 Time remaining: 1s Progress 798 / 9694 Time remaining: 1s Progress 799 / 9694 Time remaining: 1s Progress 800 / 9694 Time remaining: 1s Progress 801 / 9694 Time remaining: 1s Progress 802 / 9694 Time remaining: 1s Progress 803 / 9694 Time remaining: 1s Progress 804 / 9694 Time remaining: 1s Progress 805 / 9694 Time remaining: 1s Progress 806 / 9694 Time remaining: 1s Progress 807 / 9694 Time remaining: 1s Progress 808 / 9694 Time remaining: 1s Progress 809 / 9694 Time remaining: 1s Progress 810 / 9694 Time remaining: 1s Progress 811 / 9694 Time remaining: 1s Progress 812 / 9694 Time remaining: 1s Progress 813 / 9694 Time remaining: 1s Progress 814 / 9694 Time remaining: 1s Progress 815 / 9694 Time remaining: 1s Progress 816 / 9694 Time remaining: 1s Progress 817 / 9694 Time remaining: 1s Progress 818 / 9694 Time remaining: 1s Progress 819 / 9694 Time remaining: 1s Progress 820 / 9694 Time remaining: 1s Progress 821 / 9694 Time remaining: 1s Progress 822 / 9694 Time remaining: 1s Progress 823 / 9694 Time remaining: 1s Progress 824 / 9694 Time remaining: 1s Progress 825 / 9694 Time remaining: 1s Progress 826 / 9694 Time remaining: 0s Progress 827 / 9694 Time remaining: 0s Progress 828 / 9694 Time remaining: 0s Progress 829 / 9694 Time remaining: 0s Progress 830 / 9694 Time remaining: 0s Progress 831 / 9694 Time remaining: 0s Progress 832 / 9694 Time remaining: 0s Progress 833 / 9694 Time remaining: 0s Progress 834 / 9694 Time remaining: 0s Progress 835 / 9694 Time remaining: 0s Progress 836 / 9694 Time remaining: 0s Progress 837 / 9694 Time remaining: 0s Progress 838 / 9694 Time remaining: 0s Progress 839 / 9694 Time remaining: 0s Progress 840 / 9694 Time remaining: 0s Progress 841 / 9694 Time remaining: 0s Progress 842 / 9694 Time remaining: 0s Progress 843 / 9694 Time remaining: 0s Progress 844 / 9694 Time remaining: 0s Progress 845 / 9694 Time remaining: 0s Progress 846 / 9694 Time remaining: 0s Progress 847 / 9694 Time remaining: 0s Progress 848 / 9694 Time remaining: 0s Progress 849 / 9694 Time remaining: 0s Progress 850 / 9694 Time remaining: 0s Progress 851 / 9694 Time remaining: 0s Progress 852 / 9694 Time remaining: 0s Progress 853 / 9694 Time remaining: 0s Progress 854 / 9694 Time remaining: 0s Progress 855 / 9694 Time remaining: 0s Progress 856 / 9694 Time remaining: 0s Progress 857 / 9694 Time remaining: 0s Progress 858 / 9694 Time remaining: 0s Progress 859 / 9694 Time remaining: 0s Progress 860 / 9694 Time remaining: 0s Progress 861 / 9694 Time remaining: 0s Progress 862 / 9694 Time remaining: 0s Progress 863 / 9694 Time remaining: 0s Progress 864 / 9694 Time remaining: 0s Progress 865 / 9694 Time remaining: 0s Progress 866 / 9694 Time remaining: 0s Progress 867 / 9694 Time remaining: 0s Progress 868 / 9694 Time remaining: 0s Progress 869 / 9694 Time remaining: 0s Progress 870 / 9694 Time remaining: 0s Progress 871 / 9694 Time remaining: 0s Progress 872 / 9694 Time remaining: 0s Progress 873 / 9694 Time remaining: 0s Progress 874 / 9694 Time remaining: 0s Progress 875 / 9694 Time remaining: 0s Progress 876 / 9694 Time remaining: 0s Progress 877 / 9694 Time remaining: 0s Progress 878 / 9694 Time remaining: 0s Progress 879 / 9694 Time remaining: 0s Progress 880 / 9694 Time remaining: 0s Progress 881 / 9694 Time remaining: 0s Progress 882 / 9694 Time remaining: 0s Progress 883 / 9694 Time remaining: 0s Progress 884 / 9694 Time remaining: 0s Progress 885 / 9694 Time remaining: 0s Progress 886 / 9694 Time remaining: 0s Progress 887 / 9694 Time remaining: 0s Progress 888 / 9694 Time remaining: 0s Progress 889 / 9694 Time remaining: 0s Progress 890 / 9694 Time remaining: 0s Progress 891 / 9694 Time remaining: 0s Progress 892 / 9694 Time remaining: 0s Progress 893 / 9694 Time remaining: 0s Progress 894 / 9694 Time remaining: 0s Progress 895 / 9694 Time remaining: 0s Progress 896 / 9694 Time remaining: 0s Progress 897 / 9694 Time remaining: 0s Progress 898 / 9694 Time remaining: 0s Progress 899 / 9694 Time remaining: 0s Progress 900 / 9694 Time remaining: 0s Progress 901 / 9694 Time remaining: 0s Progress 902 / 9694 Time remaining: 0s Progress 903 / 9694 Time remaining: 0s Progress 904 / 9694 Time remaining: 0s Progress 905 / 9694 Time remaining: 0s Progress 906 / 9694 Time remaining: 0s Progress 907 / 9694 Time remaining: 0s Progress 908 / 9694 Time remaining: 0s Progress 909 / 9694 Time remaining: 0s Progress 910 / 9694 Time remaining: 0s Progress 911 / 9694 Time remaining: 0s Progress 912 / 9694 Time remaining: 0s Progress 913 / 9694 Time remaining: 0s Progress 914 / 9694 Time remaining: 0s Progress 915 / 9694 Time remaining: 0s Progress 916 / 9694 Time remaining: 0s Progress 917 / 9694 Time remaining: 0s Progress 918 / 9694 Time remaining: 0s Progress 919 / 9694 Time remaining: 0s Progress 920 / 9694 Time remaining: 0s Progress 921 / 9694 Time remaining: 0s Progress 922 / 9694 Time remaining: 0s Progress 923 / 9694 Time remaining: 0s Progress 924 / 9694 Time remaining: 0s Progress 925 / 9694 Time remaining: 0s Progress 926 / 9694 Time remaining: 0s Progress 927 / 9694 Time remaining: 0s Progress 928 / 9694 Time remaining: 0s Progress 929 / 9694 Time remaining: 0s Progress 930 / 9694 Time remaining: 0s Progress 931 / 9694 Time remaining: 0s Progress 932 / 9694 Time remaining: 0s Progress 933 / 9694 Time remaining: 0s Progress 934 / 9694 Time remaining: 0s Progress 935 / 9694 Time remaining: 0s Progress 936 / 9694 Time remaining: 0s Progress 937 / 9694 Time remaining: 0s Progress 938 / 9694 Time remaining: 0s Progress 939 / 9694 Time remaining: 0s Progress 940 / 9694 Time remaining: 0s Progress 941 / 9694 Time remaining: 0s Progress 942 / 9694 Time remaining: 0s Progress 943 / 9694 Time remaining: 0s Progress 944 / 9694 Time remaining: 0s Progress 945 / 9694 Time remaining: 0s Progress 946 / 9694 Time remaining: 0s Progress 947 / 9694 Time remaining: 0s Progress 948 / 9694 Time remaining: 0s Progress 949 / 9694 Time remaining: 0s Progress 950 / 9694 Time remaining: 0s Progress 951 / 9694 Time remaining: 0s Progress 952 / 9694 Time remaining: 0s Progress 953 / 9694 Time remaining: 0s Progress 954 / 9694 Time remaining: 0s Progress 955 / 9694 Time remaining: 0s Progress 956 / 9694 Time remaining: 0s Progress 957 / 9694 Time remaining: 0s Progress 958 / 9694 Time remaining: 0s Progress 959 / 9694 Time remaining: 0s Progress 960 / 9694 Time remaining: 0s Progress 961 / 9694 Time remaining: 0s Progress 962 / 9694 Time remaining: 0s Progress 963 / 9694 Time remaining: 0s Progress 964 / 9694 Time remaining: 0s Progress 965 / 9694 Time remaining: 0s Progress 966 / 9694 Time remaining: 0s Progress 967 / 9694 Time remaining: 0s Progress 968 / 9694 Time remaining: 0s Progress 969 / 9694 Time remaining: 0s Progress 970 / 9694 Time remaining: 0s Progress 971 / 9694 Time remaining: 0s Progress 972 / 9694 Time remaining: 0s Progress 973 / 9694 Time remaining: 0s Progress 974 / 9694 Time remaining: 0s Progress 975 / 9694 Time remaining: 0s Progress 976 / 9694 Time remaining: 0s Progress 977 / 9694 Time remaining: 0s Progress 978 / 9694 Time remaining: 0s Progress 979 / 9694 Time remaining: 0s Progress 980 / 9694 Time remaining: 0s Progress 981 / 9694 Time remaining: 0s Progress 982 / 9694 Time remaining: 0s Progress 983 / 9694 Time remaining: 0s Progress 984 / 9694 Time remaining: 0s Progress 985 / 9694 Time remaining: 0s Progress 986 / 9694 Time remaining: 0s Progress 987 / 9694 Time remaining: 0s Progress 988 / 9694 Time remaining: 0s Progress 989 / 9694 Time remaining: 0s Progress 990 / 9694 Time remaining: 0s Progress 991 / 9694 Time remaining: 0s Progress 992 / 9694 Time remaining: 0s Progress 993 / 9694 Time remaining: 0s Progress 994 / 9694 Time remaining: 0s Progress 995 / 9694 Time remaining: 0s Progress 996 / 9694 Time remaining: 0s Progress 997 / 9694 Time remaining: 0s Progress 998 / 9694 Time remaining: 0s Progress 999 / 9694 Time remaining: 0s Progress 1000 / 9694 Time remaining: 0s Progress 1001 / 9694 Time remaining: 0s Progress 1002 / 9694 Time remaining: 0s Progress 1003 / 9694 Time remaining: 0s Progress 1004 / 9694 Time remaining: 0s Progress 1005 / 9694 Time remaining: 0s Progress 1006 / 9694 Time remaining: 0s Progress 1007 / 9694 Time remaining: 0s Progress 1008 / 9694 Time remaining: 0s Progress 1009 / 9694 Time remaining: 0s Progress 1010 / 9694 Time remaining: 0s Progress 1011 / 9694 Time remaining: 0s Progress 1012 / 9694 Time remaining: 0s Progress 1013 / 9694 Time remaining: 0s Progress 1014 / 9694 Time remaining: 0s Progress 1015 / 9694 Time remaining: 0s Progress 1016 / 9694 Time remaining: 0s Progress 1017 / 9694 Time remaining: 0s Progress 1018 / 9694 Time remaining: 0s Progress 1019 / 9694 Time remaining: 0s Progress 1020 / 9694 Time remaining: 0s Progress 1021 / 9694 Time remaining: 0s Progress 1022 / 9694 Time remaining: 0s Progress 1023 / 9694 Time remaining: 0s Progress 1024 / 9694 Time remaining: 0s Progress 1025 / 9694 Time remaining: 0s Progress 1026 / 9694 Time remaining: 0s Progress 1027 / 9694 Time remaining: 0s Progress 1028 / 9694 Time remaining: 0s Progress 1029 / 9694 Time remaining: 0s Progress 1030 / 9694 Time remaining: 0s Progress 1031 / 9694 Time remaining: 0s Progress 1032 / 9694 Time remaining: 0s Progress 1033 / 9694 Time remaining: 0s Progress 1034 / 9694 Time remaining: 0s Progress 1035 / 9694 Time remaining: 0s Progress 1036 / 9694 Time remaining: 0s Progress 1037 / 9694 Time remaining: 0s Progress 1038 / 9694 Time remaining: 0s Progress 1039 / 9694 Time remaining: 0s Progress 1040 / 9694 Time remaining: 0s Progress 1041 / 9694 Time remaining: 0s Progress 1042 / 9694 Time remaining: 0s Progress 1043 / 9694 Time remaining: 0s Progress 1044 / 9694 Time remaining: 0s Progress 1045 / 9694 Time remaining: 0s Progress 1046 / 9694 Time remaining: 0s Progress 1047 / 9694 Time remaining: 0s Progress 1048 / 9694 Time remaining: 0s Progress 1049 / 9694 Time remaining: 0s Progress 1050 / 9694 Time remaining: 0s Progress 1051 / 9694 Time remaining: 0s Progress 1052 / 9694 Time remaining: 0s Progress 1053 / 9694 Time remaining: 0s Progress 1054 / 9694 Time remaining: 0s Progress 1055 / 9694 Time remaining: 0s Progress 1056 / 9694 Time remaining: 0s Progress 1057 / 9694 Time remaining: 0s Progress 1058 / 9694 Time remaining: 0s Progress 1059 / 9694 Time remaining: 0s Progress 1060 / 9694 Time remaining: 0s Progress 1061 / 9694 Time remaining: 0s Progress 1062 / 9694 Time remaining: 0s Progress 1063 / 9694 Time remaining: 0s Progress 1064 / 9694 Time remaining: 0s Progress 1065 / 9694 Time remaining: 0s Progress 1066 / 9694 Time remaining: 0s Progress 1067 / 9694 Time remaining: 0s Progress 1068 / 9694 Time remaining: 0s Progress 1069 / 9694 Time remaining: 0s Progress 1070 / 9694 Time remaining: 0s Progress 1071 / 9694 Time remaining: 0s Progress 1072 / 9694 Time remaining: 0s Progress 1073 / 9694 Time remaining: 0s Progress 1074 / 9694 Time remaining: 0s Progress 1075 / 9694 Time remaining: 0s Progress 1076 / 9694 Time remaining: 0s Progress 1077 / 9694 Time remaining: 0s Progress 1078 / 9694 Time remaining: 0s Progress 1079 / 9694 Time remaining: 0s Progress 1080 / 9694 Time remaining: 0s Progress 1081 / 9694 Time remaining: 0s Progress 1082 / 9694 Time remaining: 0s Progress 1083 / 9694 Time remaining: 0s Progress 1084 / 9694 Time remaining: 0s Progress 1085 / 9694 Time remaining: 0s Progress 1086 / 9694 Time remaining: 0s Progress 1087 / 9694 Time remaining: 0s Progress 1088 / 9694 Time remaining: 0s Progress 1089 / 9694 Time remaining: 0s Progress 1090 / 9694 Time remaining: 0s Progress 1091 / 9694 Time remaining: 0s Progress 1092 / 9694 Time remaining: 0s Progress 1093 / 9694 Time remaining: 0s Progress 1094 / 9694 Time remaining: 0s Progress 1095 / 9694 Time remaining: 0s Progress 1096 / 9694 Time remaining: 0s Progress 1097 / 9694 Time remaining: 0s Progress 1098 / 9694 Time remaining: 0s Progress 1099 / 9694 Time remaining: 0s Progress 1100 / 9694 Time remaining: 0s Progress 1101 / 9694 Time remaining: 0s Progress 1102 / 9694 Time remaining: 0s Progress 1103 / 9694 Time remaining: 0s Progress 1104 / 9694 Time remaining: 0s Progress 1105 / 9694 Time remaining: 0s Progress 1106 / 9694 Time remaining: 0s Progress 1107 / 9694 Time remaining: 0s Progress 1108 / 9694 Time remaining: 0s Progress 1109 / 9694 Time remaining: 0s Progress 1110 / 9694 Time remaining: 0s Progress 1111 / 9694 Time remaining: 0s Progress 1112 / 9694 Time remaining: 0s Progress 1113 / 9694 Time remaining: 0s Progress 1114 / 9694 Time remaining: 0s Progress 1115 / 9694 Time remaining: 0s Progress 1116 / 9694 Time remaining: 0s Progress 1117 / 9694 Time remaining: 0s Progress 1118 / 9694 Time remaining: 0s Progress 1119 / 9694 Time remaining: 0s Progress 1120 / 9694 Time remaining: 0s Progress 1121 / 9694 Time remaining: 0s Progress 1122 / 9694 Time remaining: 0s Progress 1123 / 9694 Time remaining: 0s Progress 1124 / 9694 Time remaining: 0s Progress 1125 / 9694 Time remaining: 0s Progress 1126 / 9694 Time remaining: 0s Progress 1127 / 9694 Time remaining: 0s Progress 1128 / 9694 Time remaining: 0s Progress 1129 / 9694 Time remaining: 0s Progress 1130 / 9694 Time remaining: 0s Progress 1131 / 9694 Time remaining: 0s Progress 1132 / 9694 Time remaining: 0s Progress 1133 / 9694 Time remaining: 0s Progress 1134 / 9694 Time remaining: 0s Progress 1135 / 9694 Time remaining: 0s Progress 1136 / 9694 Time remaining: 0s Progress 1137 / 9694 Time remaining: 0s Progress 1138 / 9694 Time remaining: 0s Progress 1139 / 9694 Time remaining: 0s Progress 1140 / 9694 Time remaining: 0s Progress 1141 / 9694 Time remaining: 0s Progress 1142 / 9694 Time remaining: 0s Progress 1143 / 9694 Time remaining: 0s Progress 1144 / 9694 Time remaining: 0s Progress 1145 / 9694 Time remaining: 0s Progress 1146 / 9694 Time remaining: 0s Progress 1147 / 9694 Time remaining: 0s Progress 1148 / 9694 Time remaining: 0s Progress 1149 / 9694 Time remaining: 0s Progress 1150 / 9694 Time remaining: 0s Progress 1151 / 9694 Time remaining: 0s Progress 1152 / 9694 Time remaining: 0s Progress 1153 / 9694 Time remaining: 0s Progress 1154 / 9694 Time remaining: 0s Progress 1155 / 9694 Time remaining: 0s Progress 1156 / 9694 Time remaining: 0s Progress 1157 / 9694 Time remaining: 0s Progress 1158 / 9694 Time remaining: 0s Progress 1159 / 9694 Time remaining: 0s Progress 1160 / 9694 Time remaining: 0s Progress 1161 / 9694 Time remaining: 0s Progress 1162 / 9694 Time remaining: 0s Progress 1163 / 9694 Time remaining: 0s Progress 1164 / 9694 Time remaining: 0s Progress 1165 / 9694 Time remaining: 0s Progress 1166 / 9694 Time remaining: 0s Progress 1167 / 9694 Time remaining: 0s Progress 1168 / 9694 Time remaining: 0s Progress 1169 / 9694 Time remaining: 0s Progress 1170 / 9694 Time remaining: 0s Progress 1171 / 9694 Time remaining: 0s Progress 1172 / 9694 Time remaining: 0s Progress 1173 / 9694 Time remaining: 0s Progress 1174 / 9694 Time remaining: 0s Progress 1175 / 9694 Time remaining: 0s Progress 1176 / 9694 Time remaining: 0s Progress 1177 / 9694 Time remaining: 0s Progress 1178 / 9694 Time remaining: 0s Progress 1179 / 9694 Time remaining: 0s Progress 1180 / 9694 Time remaining: 0s Progress 1181 / 9694 Time remaining: 0s Progress 1182 / 9694 Time remaining: 0s Progress 1183 / 9694 Time remaining: 0s Progress 1184 / 9694 Time remaining: 0s Progress 1185 / 9694 Time remaining: 0s Progress 1186 / 9694 Time remaining: 0s Progress 1187 / 9694 Time remaining: 0s Progress 1188 / 9694 Time remaining: 0s Progress 1189 / 9694 Time remaining: 0s Progress 1190 / 9694 Time remaining: 0s Progress 1191 / 9694 Time remaining: 0s Progress 1192 / 9694 Time remaining: 0s Progress 1193 / 9694 Time remaining: 0s Progress 1194 / 9694 Time remaining: 0s Progress 1195 / 9694 Time remaining: 0s Progress 1196 / 9694 Time remaining: 0s Progress 1197 / 9694 Time remaining: 0s Progress 1198 / 9694 Time remaining: 0s Progress 1199 / 9694 Time remaining: 0s Progress 1200 / 9694 Time remaining: 0s Progress 1201 / 9694 Time remaining: 0s Progress 1202 / 9694 Time remaining: 0s Progress 1203 / 9694 Time remaining: 0s Progress 1204 / 9694 Time remaining: 0s Progress 1205 / 9694 Time remaining: 0s Progress 1206 / 9694 Time remaining: 0s Progress 1207 / 9694 Time remaining: 0s Progress 1208 / 9694 Time remaining: 0s Progress 1209 / 9694 Time remaining: 0s Progress 1210 / 9694 Time remaining: 0s Progress 1211 / 9694 Time remaining: 0s Progress 1212 / 9694 Time remaining: 0s Progress 1213 / 9694 Time remaining: 0s Progress 1214 / 9694 Time remaining: 0s Progress 1215 / 9694 Time remaining: 0s Progress 1216 / 9694 Time remaining: 0s Progress 1217 / 9694 Time remaining: 0s Progress 1218 / 9694 Time remaining: 0s Progress 1219 / 9694 Time remaining: 0s Progress 1220 / 9694 Time remaining: 0s Progress 1221 / 9694 Time remaining: 0s Progress 1222 / 9694 Time remaining: 0s Progress 1223 / 9694 Time remaining: 0s Progress 1224 / 9694 Time remaining: 0s Progress 1225 / 9694 Time remaining: 0s Progress 1226 / 9694 Time remaining: 0s Progress 1227 / 9694 Time remaining: 0s Progress 1228 / 9694 Time remaining: 0s Progress 1229 / 9694 Time remaining: 0s Progress 1230 / 9694 Time remaining: 0s Progress 1231 / 9694 Time remaining: 0s Progress 1232 / 9694 Time remaining: 0s Progress 1233 / 9694 Time remaining: 0s Progress 1234 / 9694 Time remaining: 0s Progress 1235 / 9694 Time remaining: 0s Progress 1236 / 9694 Time remaining: 0s Progress 1237 / 9694 Time remaining: 0s Progress 1238 / 9694 Time remaining: 0s Progress 1239 / 9694 Time remaining: 0s Progress 1240 / 9694 Time remaining: 0s Progress 1241 / 9694 Time remaining: 0s Progress 1242 / 9694 Time remaining: 0s Progress 1243 / 9694 Time remaining: 0s Progress 1244 / 9694 Time remaining: 0s Progress 1245 / 9694 Time remaining: 0s Progress 1246 / 9694 Time remaining: 0s Progress 1247 / 9694 Time remaining: 0s Progress 1248 / 9694 Time remaining: 0s Progress 1249 / 9694 Time remaining: 0s Progress 1250 / 9694 Time remaining: 0s Progress 1251 / 9694 Time remaining: 0s Progress 1252 / 9694 Time remaining: 0s Progress 1253 / 9694 Time remaining: 0s Progress 1254 / 9694 Time remaining: 0s Progress 1255 / 9694 Time remaining: 0s Progress 1256 / 9694 Time remaining: 0s Progress 1257 / 9694 Time remaining: 0s Progress 1258 / 9694 Time remaining: 0s Progress 1259 / 9694 Time remaining: 0s Progress 1260 / 9694 Time remaining: 0s Progress 1261 / 9694 Time remaining: 0s Progress 1262 / 9694 Time remaining: 0s Progress 1263 / 9694 Time remaining: 0s Progress 1264 / 9694 Time remaining: 0s Progress 1265 / 9694 Time remaining: 0s Progress 1266 / 9694 Time remaining: 0s Progress 1267 / 9694 Time remaining: 0s Progress 1268 / 9694 Time remaining: 0s Progress 1269 / 9694 Time remaining: 0s Progress 1270 / 9694 Time remaining: 0s Progress 1271 / 9694 Time remaining: 0s Progress 1272 / 9694 Time remaining: 0s Progress 1273 / 9694 Time remaining: 0s Progress 1274 / 9694 Time remaining: 0s Progress 1275 / 9694 Time remaining: 0s Progress 1276 / 9694 Time remaining: 0s Progress 1277 / 9694 Time remaining: 0s Progress 1278 / 9694 Time remaining: 0s Progress 1279 / 9694 Time remaining: 0s Progress 1280 / 9694 Time remaining: 0s Progress 1281 / 9694 Time remaining: 0s Progress 1282 / 9694 Time remaining: 0s Progress 1283 / 9694 Time remaining: 0s Progress 1284 / 9694 Time remaining: 0s Progress 1285 / 9694 Time remaining: 0s Progress 1286 / 9694 Time remaining: 0s Progress 1287 / 9694 Time remaining: 0s Progress 1288 / 9694 Time remaining: 0s Progress 1289 / 9694 Time remaining: 0s Progress 1290 / 9694 Time remaining: 0s Progress 1291 / 9694 Time remaining: 0s Progress 1292 / 9694 Time remaining: 0s Progress 1293 / 9694 Time remaining: 0s Progress 1294 / 9694 Time remaining: 0s Progress 1295 / 9694 Time remaining: 0s Progress 1296 / 9694 Time remaining: 0s Progress 1297 / 9694 Time remaining: 0s Progress 1298 / 9694 Time remaining: 0s Progress 1299 / 9694 Time remaining: 0s Progress 1300 / 9694 Time remaining: 0s Progress 1301 / 9694 Time remaining: 0s Progress 1302 / 9694 Time remaining: 0s Progress 1303 / 9694 Time remaining: 0s Progress 1304 / 9694 Time remaining: 0s Progress 1305 / 9694 Time remaining: 0s Progress 1306 / 9694 Time remaining: 0s Progress 1307 / 9694 Time remaining: 0s Progress 1308 / 9694 Time remaining: 0s Progress 1309 / 9694 Time remaining: 0s Progress 1310 / 9694 Time remaining: 0s Progress 1311 / 9694 Time remaining: 0s Progress 1312 / 9694 Time remaining: 0s Progress 1313 / 9694 Time remaining: 0s Progress 1314 / 9694 Time remaining: 0s Progress 1315 / 9694 Time remaining: 0s Progress 1316 / 9694 Time remaining: 0s Progress 1317 / 9694 Time remaining: 0s Progress 1318 / 9694 Time remaining: 0s Progress 1319 / 9694 Time remaining: 0s Progress 1320 / 9694 Time remaining: 0s Progress 1321 / 9694 Time remaining: 0s Progress 1322 / 9694 Time remaining: 0s Progress 1323 / 9694 Time remaining: 0s Progress 1324 / 9694 Time remaining: 0s Progress 1325 / 9694 Time remaining: 0s Progress 1326 / 9694 Time remaining: 0s Progress 1327 / 9694 Time remaining: 0s Progress 1328 / 9694 Time remaining: 0s Progress 1329 / 9694 Time remaining: 0s Progress 1330 / 9694 Time remaining: 0s Progress 1331 / 9694 Time remaining: 0s Progress 1332 / 9694 Time remaining: 0s Progress 1333 / 9694 Time remaining: 0s Progress 1334 / 9694 Time remaining: 0s Progress 1335 / 9694 Time remaining: 0s Progress 1336 / 9694 Time remaining: 0s Progress 1337 / 9694 Time remaining: 0s Progress 1338 / 9694 Time remaining: 0s Progress 1339 / 9694 Time remaining: 0s Progress 1340 / 9694 Time remaining: 0s Progress 1341 / 9694 Time remaining: 0s Progress 1342 / 9694 Time remaining: 0s Progress 1343 / 9694 Time remaining: 0s Progress 1344 / 9694 Time remaining: 0s Progress 1345 / 9694 Time remaining: 0s Progress 1346 / 9694 Time remaining: 0s Progress 1347 / 9694 Time remaining: 0s Progress 1348 / 9694 Time remaining: 0s Progress 1349 / 9694 Time remaining: 0s Progress 1350 / 9694 Time remaining: 0s Progress 1351 / 9694 Time remaining: 0s Progress 1352 / 9694 Time remaining: 0s Progress 1353 / 9694 Time remaining: 0s Progress 1354 / 9694 Time remaining: 0s Progress 1355 / 9694 Time remaining: 0s Progress 1356 / 9694 Time remaining: 0s Progress 1357 / 9694 Time remaining: 0s Progress 1358 / 9694 Time remaining: 0s Progress 1359 / 9694 Time remaining: 0s Progress 1360 / 9694 Time remaining: 0s Progress 1361 / 9694 Time remaining: 0s Progress 1362 / 9694 Time remaining: 0s Progress 1363 / 9694 Time remaining: 0s Progress 1364 / 9694 Time remaining: 0s Progress 1365 / 9694 Time remaining: 0s Progress 1366 / 9694 Time remaining: 0s Progress 1367 / 9694 Time remaining: 0s Progress 1368 / 9694 Time remaining: 0s Progress 1369 / 9694 Time remaining: 0s Progress 1370 / 9694 Time remaining: 0s Progress 1371 / 9694 Time remaining: 0s Progress 1372 / 9694 Time remaining: 0s Progress 1373 / 9694 Time remaining: 0s Progress 1374 / 9694 Time remaining: 0s Progress 1375 / 9694 Time remaining: 0s Progress 1376 / 9694 Time remaining: 0s Progress 1377 / 9694 Time remaining: 0s Progress 1378 / 9694 Time remaining: 0s Progress 1379 / 9694 Time remaining: 0s Progress 1380 / 9694 Time remaining: 0s Progress 1381 / 9694 Time remaining: 0s Progress 1382 / 9694 Time remaining: 0s Progress 1383 / 9694 Time remaining: 0s Progress 1384 / 9694 Time remaining: 0s Progress 1385 / 9694 Time remaining: 0s Progress 1386 / 9694 Time remaining: 0s Progress 1387 / 9694 Time remaining: 0s Progress 1388 / 9694 Time remaining: 0s Progress 1389 / 9694 Time remaining: 0s Progress 1390 / 9694 Time remaining: 0s Progress 1391 / 9694 Time remaining: 0s Progress 1392 / 9694 Time remaining: 0s Progress 1393 / 9694 Time remaining: 0s Progress 1394 / 9694 Time remaining: 0s Progress 1395 / 9694 Time remaining: 0s Progress 1396 / 9694 Time remaining: 0s Progress 1397 / 9694 Time remaining: 0s Progress 1398 / 9694 Time remaining: 0s Progress 1399 / 9694 Time remaining: 0s Progress 1400 / 9694 Time remaining: 0s Progress 1401 / 9694 Time remaining: 0s Progress 1402 / 9694 Time remaining: 0s Progress 1403 / 9694 Time remaining: 0s Progress 1404 / 9694 Time remaining: 0s Progress 1405 / 9694 Time remaining: 0s Progress 1406 / 9694 Time remaining: 0s Progress 1407 / 9694 Time remaining: 0s Progress 1408 / 9694 Time remaining: 0s Progress 1409 / 9694 Time remaining: 0s Progress 1410 / 9694 Time remaining: 0s Progress 1411 / 9694 Time remaining: 0s Progress 1412 / 9694 Time remaining: 0s Progress 1413 / 9694 Time remaining: 0s Progress 1414 / 9694 Time remaining: 0s Progress 1415 / 9694 Time remaining: 0s Progress 1416 / 9694 Time remaining: 0s Progress 1417 / 9694 Time remaining: 0s Progress 1418 / 9694 Time remaining: 0s Progress 1419 / 9694 Time remaining: 0s Progress 1420 / 9694 Time remaining: 0s Progress 1421 / 9694 Time remaining: 0s Progress 1422 / 9694 Time remaining: 0s Progress 1423 / 9694 Time remaining: 0s Progress 1424 / 9694 Time remaining: 0s Progress 1425 / 9694 Time remaining: 0s Progress 1426 / 9694 Time remaining: 0s Progress 1427 / 9694 Time remaining: 0s Progress 1428 / 9694 Time remaining: 0s Progress 1429 / 9694 Time remaining: 0s Progress 1430 / 9694 Time remaining: 0s Progress 1431 / 9694 Time remaining: 0s Progress 1432 / 9694 Time remaining: 0s Progress 1433 / 9694 Time remaining: 0s Progress 1434 / 9694 Time remaining: 0s Progress 1435 / 9694 Time remaining: 0s Progress 1436 / 9694 Time remaining: 0s Progress 1437 / 9694 Time remaining: 0s Progress 1438 / 9694 Time remaining: 0s Progress 1439 / 9694 Time remaining: 0s Progress 1440 / 9694 Time remaining: 0s Progress 1441 / 9694 Time remaining: 0s Progress 1442 / 9694 Time remaining: 0s Progress 1443 / 9694 Time remaining: 0s Progress 1444 / 9694 Time remaining: 0s Progress 1445 / 9694 Time remaining: 0s Progress 1446 / 9694 Time remaining: 0s Progress 1447 / 9694 Time remaining: 0s Progress 1448 / 9694 Time remaining: 0s Progress 1449 / 9694 Time remaining: 0s Progress 1450 / 9694 Time remaining: 0s Progress 1451 / 9694 Time remaining: 0s Progress 1452 / 9694 Time remaining: 0s Progress 1453 / 9694 Time remaining: 0s Progress 1454 / 9694 Time remaining: 0s Progress 1455 / 9694 Time remaining: 0s Progress 1456 / 9694 Time remaining: 0s Progress 1457 / 9694 Time remaining: 0s Progress 1458 / 9694 Time remaining: 0s Progress 1459 / 9694 Time remaining: 0s Progress 1460 / 9694 Time remaining: 0s Progress 1461 / 9694 Time remaining: 0s Progress 1462 / 9694 Time remaining: 0s Progress 1463 / 9694 Time remaining: 0s Progress 1464 / 9694 Time remaining: 0s Progress 1465 / 9694 Time remaining: 0s Progress 1466 / 9694 Time remaining: 0s Progress 1467 / 9694 Time remaining: 0s Progress 1468 / 9694 Time remaining: 0s Progress 1469 / 9694 Time remaining: 0s Progress 1470 / 9694 Time remaining: 0s Progress 1471 / 9694 Time remaining: 0s Progress 1472 / 9694 Time remaining: 0s Progress 1473 / 9694 Time remaining: 0s Progress 1474 / 9694 Time remaining: 0s Progress 1475 / 9694 Time remaining: 0s Progress 1476 / 9694 Time remaining: 0s Progress 1477 / 9694 Time remaining: 0s Progress 1478 / 9694 Time remaining: 0s Progress 1479 / 9694 Time remaining: 0s Progress 1480 / 9694 Time remaining: 0s Progress 1481 / 9694 Time remaining: 0s Progress 1482 / 9694 Time remaining: 0s Progress 1483 / 9694 Time remaining: 0s Progress 1484 / 9694 Time remaining: 0s Progress 1485 / 9694 Time remaining: 0s Progress 1486 / 9694 Time remaining: 0s Progress 1487 / 9694 Time remaining: 0s Progress 1488 / 9694 Time remaining: 0s Progress 1489 / 9694 Time remaining: 0s Progress 1490 / 9694 Time remaining: 0s Progress 1491 / 9694 Time remaining: 0s Progress 1492 / 9694 Time remaining: 0s Progress 1493 / 9694 Time remaining: 0s Progress 1494 / 9694 Time remaining: 0s Progress 1495 / 9694 Time remaining: 0s Progress 1496 / 9694 Time remaining: 0s Progress 1497 / 9694 Time remaining: 0s Progress 1498 / 9694 Time remaining: 0s Progress 1499 / 9694 Time remaining: 0s Progress 1500 / 9694 Time remaining: 0s Progress 1501 / 9694 Time remaining: 0s Progress 1502 / 9694 Time remaining: 0s Progress 1503 / 9694 Time remaining: 0s Progress 1504 / 9694 Time remaining: 0s Progress 1505 / 9694 Time remaining: 0s Progress 1506 / 9694 Time remaining: 0s Progress 1507 / 9694 Time remaining: 0s Progress 1508 / 9694 Time remaining: 0s Progress 1509 / 9694 Time remaining: 0s Progress 1510 / 9694 Time remaining: 0s Progress 1511 / 9694 Time remaining: 0s Progress 1512 / 9694 Time remaining: 0s Progress 1513 / 9694 Time remaining: 0s Progress 1514 / 9694 Time remaining: 0s Progress 1515 / 9694 Time remaining: 0s Progress 1516 / 9694 Time remaining: 0s Progress 1517 / 9694 Time remaining: 0s Progress 1518 / 9694 Time remaining: 0s Progress 1519 / 9694 Time remaining: 0s Progress 1520 / 9694 Time remaining: 0s Progress 1521 / 9694 Time remaining: 0s Progress 1522 / 9694 Time remaining: 0s Progress 1523 / 9694 Time remaining: 0s Progress 1524 / 9694 Time remaining: 0s Progress 1525 / 9694 Time remaining: 0s Progress 1526 / 9694 Time remaining: 0s Progress 1527 / 9694 Time remaining: 0s Progress 1528 / 9694 Time remaining: 0s Progress 1529 / 9694 Time remaining: 0s Progress 1530 / 9694 Time remaining: 0s Progress 1531 / 9694 Time remaining: 0s Progress 1532 / 9694 Time remaining: 0s Progress 1533 / 9694 Time remaining: 0s Progress 1534 / 9694 Time remaining: 0s Progress 1535 / 9694 Time remaining: 0s Progress 1536 / 9694 Time remaining: 0s Progress 1537 / 9694 Time remaining: 0s Progress 1538 / 9694 Time remaining: 0s Progress 1539 / 9694 Time remaining: 0s Progress 1540 / 9694 Time remaining: 0s Progress 1541 / 9694 Time remaining: 0s Progress 1542 / 9694 Time remaining: 0s Progress 1543 / 9694 Time remaining: 0s Progress 1544 / 9694 Time remaining: 0s Progress 1545 / 9694 Time remaining: 0s Progress 1546 / 9694 Time remaining: 0s Progress 1547 / 9694 Time remaining: 0s Progress 1548 / 9694 Time remaining: 0s Progress 1549 / 9694 Time remaining: 0s Progress 1550 / 9694 Time remaining: 0s Progress 1551 / 9694 Time remaining: 0s Progress 1552 / 9694 Time remaining: 0s Progress 1553 / 9694 Time remaining: 0s Progress 1554 / 9694 Time remaining: 0s Progress 1555 / 9694 Time remaining: 0s Progress 1556 / 9694 Time remaining: 0s Progress 1557 / 9694 Time remaining: 0s Progress 1558 / 9694 Time remaining: 0s Progress 1559 / 9694 Time remaining: 0s Progress 1560 / 9694 Time remaining: 0s Progress 1561 / 9694 Time remaining: 0s Progress 1562 / 9694 Time remaining: 0s Progress 1563 / 9694 Time remaining: 0s Progress 1564 / 9694 Time remaining: 0s Progress 1565 / 9694 Time remaining: 0s Progress 1566 / 9694 Time remaining: 0s Progress 1567 / 9694 Time remaining: 0s Progress 1568 / 9694 Time remaining: 0s Progress 1569 / 9694 Time remaining: 0s Progress 1570 / 9694 Time remaining: 0s Progress 1571 / 9694 Time remaining: 0s Progress 1572 / 9694 Time remaining: 0s Progress 1573 / 9694 Time remaining: 0s Progress 1574 / 9694 Time remaining: 0s Progress 1575 / 9694 Time remaining: 0s Progress 1576 / 9694 Time remaining: 0s Progress 1577 / 9694 Time remaining: 0s Progress 1578 / 9694 Time remaining: 0s Progress 1579 / 9694 Time remaining: 0s Progress 1580 / 9694 Time remaining: 0s Progress 1581 / 9694 Time remaining: 0s Progress 1582 / 9694 Time remaining: 0s Progress 1583 / 9694 Time remaining: 0s Progress 1584 / 9694 Time remaining: 0s Progress 1585 / 9694 Time remaining: 0s Progress 1586 / 9694 Time remaining: 0s Progress 1587 / 9694 Time remaining: 0s Progress 1588 / 9694 Time remaining: 0s Progress 1589 / 9694 Time remaining: 0s Progress 1590 / 9694 Time remaining: 0s Progress 1591 / 9694 Time remaining: 0s Progress 1592 / 9694 Time remaining: 0s Progress 1593 / 9694 Time remaining: 0s Progress 1594 / 9694 Time remaining: 0s Progress 1595 / 9694 Time remaining: 0s Progress 1596 / 9694 Time remaining: 0s Progress 1597 / 9694 Time remaining: 0s Progress 1598 / 9694 Time remaining: 0s Progress 1599 / 9694 Time remaining: 0s Progress 1600 / 9694 Time remaining: 0s Progress 1601 / 9694 Time remaining: 0s Progress 1602 / 9694 Time remaining: 0s Progress 1603 / 9694 Time remaining: 0s Progress 1604 / 9694 Time remaining: 0s Progress 1605 / 9694 Time remaining: 0s Progress 1606 / 9694 Time remaining: 0s Progress 1607 / 9694 Time remaining: 0s Progress 1608 / 9694 Time remaining: 0s Progress 1609 / 9694 Time remaining: 0s Progress 1610 / 9694 Time remaining: 0s Progress 1611 / 9694 Time remaining: 0s Progress 1612 / 9694 Time remaining: 0s Progress 1613 / 9694 Time remaining: 0s Progress 1614 / 9694 Time remaining: 0s Progress 1615 / 9694 Time remaining: 0s Progress 1616 / 9694 Time remaining: 0s Progress 1617 / 9694 Time remaining: 0s Progress 1618 / 9694 Time remaining: 0s Progress 1619 / 9694 Time remaining: 0s Progress 1620 / 9694 Time remaining: 0s Progress 1621 / 9694 Time remaining: 0s Progress 1622 / 9694 Time remaining: 0s Progress 1623 / 9694 Time remaining: 0s Progress 1624 / 9694 Time remaining: 0s Progress 1625 / 9694 Time remaining: 0s Progress 1626 / 9694 Time remaining: 0s Progress 1627 / 9694 Time remaining: 0s Progress 1628 / 9694 Time remaining: 0s Progress 1629 / 9694 Time remaining: 0s Progress 1630 / 9694 Time remaining: 0s Progress 1631 / 9694 Time remaining: 0s Progress 1632 / 9694 Time remaining: 0s Progress 1633 / 9694 Time remaining: 0s Progress 1634 / 9694 Time remaining: 0s Progress 1635 / 9694 Time remaining: 0s Progress 1636 / 9694 Time remaining: 0s Progress 1637 / 9694 Time remaining: 0s Progress 1638 / 9694 Time remaining: 0s Progress 1639 / 9694 Time remaining: 0s Progress 1640 / 9694 Time remaining: 0s Progress 1641 / 9694 Time remaining: 0s Progress 1642 / 9694 Time remaining: 0s Progress 1643 / 9694 Time remaining: 0s Progress 1644 / 9694 Time remaining: 0s Progress 1645 / 9694 Time remaining: 0s Progress 1646 / 9694 Time remaining: 0s Progress 1647 / 9694 Time remaining: 0s Progress 1648 / 9694 Time remaining: 0s Progress 1649 / 9694 Time remaining: 0s Progress 1650 / 9694 Time remaining: 0s Progress 1651 / 9694 Time remaining: 0s Progress 1652 / 9694 Time remaining: 0s Progress 1653 / 9694 Time remaining: 0s Progress 1654 / 9694 Time remaining: 0s Progress 1655 / 9694 Time remaining: 0s Progress 1656 / 9694 Time remaining: 0s Progress 1657 / 9694 Time remaining: 0s Progress 1658 / 9694 Time remaining: 0s Progress 1659 / 9694 Time remaining: 0s Progress 1660 / 9694 Time remaining: 0s Progress 1661 / 9694 Time remaining: 0s Progress 1662 / 9694 Time remaining: 0s Progress 1663 / 9694 Time remaining: 0s Progress 1664 / 9694 Time remaining: 0s Progress 1665 / 9694 Time remaining: 0s Progress 1666 / 9694 Time remaining: 0s Progress 1667 / 9694 Time remaining: 0s Progress 1668 / 9694 Time remaining: 0s Progress 1669 / 9694 Time remaining: 0s Progress 1670 / 9694 Time remaining: 0s Progress 1671 / 9694 Time remaining: 0s Progress 1672 / 9694 Time remaining: 0s Progress 1673 / 9694 Time remaining: 0s Progress 1674 / 9694 Time remaining: 0s Progress 1675 / 9694 Time remaining: 0s Progress 1676 / 9694 Time remaining: 0s Progress 1677 / 9694 Time remaining: 0s Progress 1678 / 9694 Time remaining: 0s Progress 1679 / 9694 Time remaining: 0s Progress 1680 / 9694 Time remaining: 0s Progress 1681 / 9694 Time remaining: 0s Progress 1682 / 9694 Time remaining: 0s Progress 1683 / 9694 Time remaining: 0s Progress 1684 / 9694 Time remaining: 0s Progress 1685 / 9694 Time remaining: 0s Progress 1686 / 9694 Time remaining: 0s Progress 1687 / 9694 Time remaining: 0s Progress 1688 / 9694 Time remaining: 0s Progress 1689 / 9694 Time remaining: 0s Progress 1690 / 9694 Time remaining: 0s Progress 1691 / 9694 Time remaining: 0s Progress 1692 / 9694 Time remaining: 0s Progress 1693 / 9694 Time remaining: 0s Progress 1694 / 9694 Time remaining: 0s Progress 1695 / 9694 Time remaining: 0s Progress 1696 / 9694 Time remaining: 0s Progress 1697 / 9694 Time remaining: 0s Progress 1698 / 9694 Time remaining: 0s Progress 1699 / 9694 Time remaining: 0s Progress 1700 / 9694 Time remaining: 0s Progress 1701 / 9694 Time remaining: 0s Progress 1702 / 9694 Time remaining: 0s Progress 1703 / 9694 Time remaining: 0s Progress 1704 / 9694 Time remaining: 0s Progress 1705 / 9694 Time remaining: 0s Progress 1706 / 9694 Time remaining: 0s Progress 1707 / 9694 Time remaining: 0s Progress 1708 / 9694 Time remaining: 0s Progress 1709 / 9694 Time remaining: 0s Progress 1710 / 9694 Time remaining: 0s Progress 1711 / 9694 Time remaining: 0s Progress 1712 / 9694 Time remaining: 0s Progress 1713 / 9694 Time remaining: 0s Progress 1714 / 9694 Time remaining: 0s Progress 1715 / 9694 Time remaining: 0s Progress 1716 / 9694 Time remaining: 0s Progress 1717 / 9694 Time remaining: 0s Progress 1718 / 9694 Time remaining: 0s Progress 1719 / 9694 Time remaining: 0s Progress 1720 / 9694 Time remaining: 0s Progress 1721 / 9694 Time remaining: 0s Progress 1722 / 9694 Time remaining: 0s Progress 1723 / 9694 Time remaining: 0s Progress 1724 / 9694 Time remaining: 0s Progress 1725 / 9694 Time remaining: 0s Progress 1726 / 9694 Time remaining: 0s Progress 1727 / 9694 Time remaining: 0s Progress 1728 / 9694 Time remaining: 0s Progress 1729 / 9694 Time remaining: 0s Progress 1730 / 9694 Time remaining: 0s Progress 1731 / 9694 Time remaining: 0s Progress 1732 / 9694 Time remaining: 0s Progress 1733 / 9694 Time remaining: 0s Progress 1734 / 9694 Time remaining: 0s Progress 1735 / 9694 Time remaining: 0s Progress 1736 / 9694 Time remaining: 0s Progress 1737 / 9694 Time remaining: 0s Progress 1738 / 9694 Time remaining: 0s Progress 1739 / 9694 Time remaining: 0s Progress 1740 / 9694 Time remaining: 0s Progress 1741 / 9694 Time remaining: 0s Progress 1742 / 9694 Time remaining: 0s Progress 1743 / 9694 Time remaining: 0s Progress 1744 / 9694 Time remaining: 0s Progress 1745 / 9694 Time remaining: 0s Progress 1746 / 9694 Time remaining: 0s Progress 1747 / 9694 Time remaining: 0s Progress 1748 / 9694 Time remaining: 0s Progress 1749 / 9694 Time remaining: 0s Progress 1750 / 9694 Time remaining: 0s Progress 1751 / 9694 Time remaining: 0s Progress 1752 / 9694 Time remaining: 0s Progress 1753 / 9694 Time remaining: 0s Progress 1754 / 9694 Time remaining: 0s Progress 1755 / 9694 Time remaining: 0s Progress 1756 / 9694 Time remaining: 0s Progress 1757 / 9694 Time remaining: 0s Progress 1758 / 9694 Time remaining: 0s Progress 1759 / 9694 Time remaining: 0s Progress 1760 / 9694 Time remaining: 0s Progress 1761 / 9694 Time remaining: 0s Progress 1762 / 9694 Time remaining: 0s Progress 1763 / 9694 Time remaining: 0s Progress 1764 / 9694 Time remaining: 0s Progress 1765 / 9694 Time remaining: 0s Progress 1766 / 9694 Time remaining: 0s Progress 1767 / 9694 Time remaining: 0s Progress 1768 / 9694 Time remaining: 0s Progress 1769 / 9694 Time remaining: 0s Progress 1770 / 9694 Time remaining: 0s Progress 1771 / 9694 Time remaining: 0s Progress 1772 / 9694 Time remaining: 0s Progress 1773 / 9694 Time remaining: 0s Progress 1774 / 9694 Time remaining: 0s Progress 1775 / 9694 Time remaining: 0s Progress 1776 / 9694 Time remaining: 0s Progress 1777 / 9694 Time remaining: 0s Progress 1778 / 9694 Time remaining: 0s Progress 1779 / 9694 Time remaining: 0s Progress 1780 / 9694 Time remaining: 0s Progress 1781 / 9694 Time remaining: 0s Progress 1782 / 9694 Time remaining: 0s Progress 1783 / 9694 Time remaining: 0s Progress 1784 / 9694 Time remaining: 0s Progress 1785 / 9694 Time remaining: 0s Progress 1786 / 9694 Time remaining: 0s Progress 1787 / 9694 Time remaining: 0s Progress 1788 / 9694 Time remaining: 0s Progress 1789 / 9694 Time remaining: 0s Progress 1790 / 9694 Time remaining: 0s Progress 1791 / 9694 Time remaining: 0s Progress 1792 / 9694 Time remaining: 0s Progress 1793 / 9694 Time remaining: 0s Progress 1794 / 9694 Time remaining: 0s Progress 1795 / 9694 Time remaining: 0s Progress 1796 / 9694 Time remaining: 0s Progress 1797 / 9694 Time remaining: 0s Progress 1798 / 9694 Time remaining: 0s Progress 1799 / 9694 Time remaining: 0s Progress 1800 / 9694 Time remaining: 0s Progress 1801 / 9694 Time remaining: 0s Progress 1802 / 9694 Time remaining: 0s Progress 1803 / 9694 Time remaining: 0s Progress 1804 / 9694 Time remaining: 0s Progress 1805 / 9694 Time remaining: 0s Progress 1806 / 9694 Time remaining: 0s Progress 1807 / 9694 Time remaining: 0s Progress 1808 / 9694 Time remaining: 0s Progress 1809 / 9694 Time remaining: 0s Progress 1810 / 9694 Time remaining: 0s Progress 1811 / 9694 Time remaining: 0s Progress 1812 / 9694 Time remaining: 0s Progress 1813 / 9694 Time remaining: 0s Progress 1814 / 9694 Time remaining: 0s Progress 1815 / 9694 Time remaining: 0s Progress 1816 / 9694 Time remaining: 0s Progress 1817 / 9694 Time remaining: 0s Progress 1818 / 9694 Time remaining: 0s Progress 1819 / 9694 Time remaining: 0s Progress 1820 / 9694 Time remaining: 0s Progress 1821 / 9694 Time remaining: 0s Progress 1822 / 9694 Time remaining: 0s Progress 1823 / 9694 Time remaining: 0s Progress 1824 / 9694 Time remaining: 0s Progress 1825 / 9694 Time remaining: 0s Progress 1826 / 9694 Time remaining: 0s Progress 1827 / 9694 Time remaining: 0s Progress 1828 / 9694 Time remaining: 0s Progress 1829 / 9694 Time remaining: 0s Progress 1830 / 9694 Time remaining: 0s Progress 1831 / 9694 Time remaining: 0s Progress 1832 / 9694 Time remaining: 0s Progress 1833 / 9694 Time remaining: 0s Progress 1834 / 9694 Time remaining: 0s Progress 1835 / 9694 Time remaining: 0s Progress 1836 / 9694 Time remaining: 0s Progress 1837 / 9694 Time remaining: 0s Progress 1838 / 9694 Time remaining: 0s Progress 1839 / 9694 Time remaining: 0s Progress 1840 / 9694 Time remaining: 0s Progress 1841 / 9694 Time remaining: 0s Progress 1842 / 9694 Time remaining: 0s Progress 1843 / 9694 Time remaining: 0s Progress 1844 / 9694 Time remaining: 0s Progress 1845 / 9694 Time remaining: 0s Progress 1846 / 9694 Time remaining: 0s Progress 1847 / 9694 Time remaining: 0s Progress 1848 / 9694 Time remaining: 0s Progress 1849 / 9694 Time remaining: 0s Progress 1850 / 9694 Time remaining: 0s Progress 1851 / 9694 Time remaining: 0s Progress 1852 / 9694 Time remaining: 0s Progress 1853 / 9694 Time remaining: 0s Progress 1854 / 9694 Time remaining: 0s Progress 1855 / 9694 Time remaining: 0s Progress 1856 / 9694 Time remaining: 0s Progress 1857 / 9694 Time remaining: 0s Progress 1858 / 9694 Time remaining: 0s Progress 1859 / 9694 Time remaining: 0s Progress 1860 / 9694 Time remaining: 0s Progress 1861 / 9694 Time remaining: 0s Progress 1862 / 9694 Time remaining: 0s Progress 1863 / 9694 Time remaining: 0s Progress 1864 / 9694 Time remaining: 0s Progress 1865 / 9694 Time remaining: 0s Progress 1866 / 9694 Time remaining: 0s Progress 1867 / 9694 Time remaining: 0s Progress 1868 / 9694 Time remaining: 0s Progress 1869 / 9694 Time remaining: 0s Progress 1870 / 9694 Time remaining: 0s Progress 1871 / 9694 Time remaining: 0s Progress 1872 / 9694 Time remaining: 0s Progress 1873 / 9694 Time remaining: 0s Progress 1874 / 9694 Time remaining: 0s Progress 1875 / 9694 Time remaining: 0s Progress 1876 / 9694 Time remaining: 0s Progress 1877 / 9694 Time remaining: 0s Progress 1878 / 9694 Time remaining: 0s Progress 1879 / 9694 Time remaining: 0s Progress 1880 / 9694 Time remaining: 0s Progress 1881 / 9694 Time remaining: 0s Progress 1882 / 9694 Time remaining: 0s Progress 1883 / 9694 Time remaining: 0s Progress 1884 / 9694 Time remaining: 0s Progress 1885 / 9694 Time remaining: 0s Progress 1886 / 9694 Time remaining: 0s Progress 1887 / 9694 Time remaining: 0s Progress 1888 / 9694 Time remaining: 0s Progress 1889 / 9694 Time remaining: 0s Progress 1890 / 9694 Time remaining: 0s Progress 1891 / 9694 Time remaining: 0s Progress 1892 / 9694 Time remaining: 0s Progress 1893 / 9694 Time remaining: 0s Progress 1894 / 9694 Time remaining: 0s Progress 1895 / 9694 Time remaining: 0s Progress 1896 / 9694 Time remaining: 0s Progress 1897 / 9694 Time remaining: 0s Progress 1898 / 9694 Time remaining: 0s Progress 1899 / 9694 Time remaining: 0s Progress 1900 / 9694 Time remaining: 0s Progress 1901 / 9694 Time remaining: 0s Progress 1902 / 9694 Time remaining: 0s Progress 1903 / 9694 Time remaining: 0s Progress 1904 / 9694 Time remaining: 0s Progress 1905 / 9694 Time remaining: 0s Progress 1906 / 9694 Time remaining: 0s Progress 1907 / 9694 Time remaining: 0s Progress 1908 / 9694 Time remaining: 0s Progress 1909 / 9694 Time remaining: 0s Progress 1910 / 9694 Time remaining: 0s Progress 1911 / 9694 Time remaining: 0s Progress 1912 / 9694 Time remaining: 0s Progress 1913 / 9694 Time remaining: 0s Progress 1914 / 9694 Time remaining: 0s Progress 1915 / 9694 Time remaining: 0s Progress 1916 / 9694 Time remaining: 0s Progress 1917 / 9694 Time remaining: 0s Progress 1918 / 9694 Time remaining: 0s Progress 1919 / 9694 Time remaining: 0s Progress 1920 / 9694 Time remaining: 0s Progress 1921 / 9694 Time remaining: 0s Progress 1922 / 9694 Time remaining: 0s Progress 1923 / 9694 Time remaining: 0s Progress 1924 / 9694 Time remaining: 0s Progress 1925 / 9694 Time remaining: 0s Progress 1926 / 9694 Time remaining: 0s Progress 1927 / 9694 Time remaining: 0s Progress 1928 / 9694 Time remaining: 0s Progress 1929 / 9694 Time remaining: 0s Progress 1930 / 9694 Time remaining: 0s Progress 1931 / 9694 Time remaining: 0s Progress 1932 / 9694 Time remaining: 0s Progress 1933 / 9694 Time remaining: 0s Progress 1934 / 9694 Time remaining: 0s Progress 1935 / 9694 Time remaining: 0s Progress 1936 / 9694 Time remaining: 0s Progress 1937 / 9694 Time remaining: 0s Progress 1938 / 9694 Time remaining: 0s Progress 1939 / 9694 Time remaining: 0s Progress 1940 / 9694 Time remaining: 0s Progress 1941 / 9694 Time remaining: 0s Progress 1942 / 9694 Time remaining: 0s Progress 1943 / 9694 Time remaining: 0s Progress 1944 / 9694 Time remaining: 0s Progress 1945 / 9694 Time remaining: 0s Progress 1946 / 9694 Time remaining: 0s Progress 1947 / 9694 Time remaining: 0s Progress 1948 / 9694 Time remaining: 0s Progress 1949 / 9694 Time remaining: 0s Progress 1950 / 9694 Time remaining: 0s Progress 1951 / 9694 Time remaining: 0s Progress 1952 / 9694 Time remaining: 0s Progress 1953 / 9694 Time remaining: 0s Progress 1954 / 9694 Time remaining: 0s Progress 1955 / 9694 Time remaining: 0s Progress 1956 / 9694 Time remaining: 0s Progress 1957 / 9694 Time remaining: 0s Progress 1958 / 9694 Time remaining: 0s Progress 1959 / 9694 Time remaining: 0s Progress 1960 / 9694 Time remaining: 0s Progress 1961 / 9694 Time remaining: 0s Progress 1962 / 9694 Time remaining: 0s Progress 1963 / 9694 Time remaining: 0s Progress 1964 / 9694 Time remaining: 0s Progress 1965 / 9694 Time remaining: 0s Progress 1966 / 9694 Time remaining: 0s Progress 1967 / 9694 Time remaining: 0s Progress 1968 / 9694 Time remaining: 0s Progress 1969 / 9694 Time remaining: 0s Progress 1970 / 9694 Time remaining: 0s Progress 1971 / 9694 Time remaining: 0s Progress 1972 / 9694 Time remaining: 0s Progress 1973 / 9694 Time remaining: 0s Progress 1974 / 9694 Time remaining: 0s Progress 1975 / 9694 Time remaining: 0s Progress 1976 / 9694 Time remaining: 0s Progress 1977 / 9694 Time remaining: 0s Progress 1978 / 9694 Time remaining: 0s Progress 1979 / 9694 Time remaining: 0s Progress 1980 / 9694 Time remaining: 0s Progress 1981 / 9694 Time remaining: 0s Progress 1982 / 9694 Time remaining: 0s Progress 1983 / 9694 Time remaining: 0s Progress 1984 / 9694 Time remaining: 0s Progress 1985 / 9694 Time remaining: 0s Progress 1986 / 9694 Time remaining: 0s Progress 1987 / 9694 Time remaining: 0s Progress 1988 / 9694 Time remaining: 0s Progress 1989 / 9694 Time remaining: 0s Progress 1990 / 9694 Time remaining: 0s Progress 1991 / 9694 Time remaining: 0s Progress 1992 / 9694 Time remaining: 0s Progress 1993 / 9694 Time remaining: 0s Progress 1994 / 9694 Time remaining: 0s Progress 1995 / 9694 Time remaining: 0s Progress 1996 / 9694 Time remaining: 0s Progress 1997 / 9694 Time remaining: 0s Progress 1998 / 9694 Time remaining: 0s Progress 1999 / 9694 Time remaining: 0s Progress 2000 / 9694 Time remaining: 0s Progress 2001 / 9694 Time remaining: 0s Progress 2002 / 9694 Time remaining: 0s Progress 2003 / 9694 Time remaining: 0s Progress 2004 / 9694 Time remaining: 0s Progress 2005 / 9694 Time remaining: 0s Progress 2006 / 9694 Time remaining: 0s Progress 2007 / 9694 Time remaining: 0s Progress 2008 / 9694 Time remaining: 0s Progress 2009 / 9694 Time remaining: 0s Progress 2010 / 9694 Time remaining: 0s Progress 2011 / 9694 Time remaining: 0s Progress 2012 / 9694 Time remaining: 0s Progress 2013 / 9694 Time remaining: 0s Progress 2014 / 9694 Time remaining: 0s Progress 2015 / 9694 Time remaining: 0s Progress 2016 / 9694 Time remaining: 0s Progress 2017 / 9694 Time remaining: 0s Progress 2018 / 9694 Time remaining: 0s Progress 2019 / 9694 Time remaining: 0s Progress 2020 / 9694 Time remaining: 0s Progress 2021 / 9694 Time remaining: 0s Progress 2022 / 9694 Time remaining: 0s Progress 2023 / 9694 Time remaining: 0s Progress 2024 / 9694 Time remaining: 0s Progress 2025 / 9694 Time remaining: 0s Progress 2026 / 9694 Time remaining: 0s Progress 2027 / 9694 Time remaining: 0s Progress 2028 / 9694 Time remaining: 0s Progress 2029 / 9694 Time remaining: 0s Progress 2030 / 9694 Time remaining: 0s Progress 2031 / 9694 Time remaining: 0s Progress 2032 / 9694 Time remaining: 0s Progress 2033 / 9694 Time remaining: 0s Progress 2034 / 9694 Time remaining: 0s Progress 2035 / 9694 Time remaining: 0s Progress 2036 / 9694 Time remaining: 0s Progress 2037 / 9694 Time remaining: 0s Progress 2038 / 9694 Time remaining: 0s Progress 2039 / 9694 Time remaining: 0s Progress 2040 / 9694 Time remaining: 0s Progress 2041 / 9694 Time remaining: 0s Progress 2042 / 9694 Time remaining: 0s Progress 2043 / 9694 Time remaining: 0s Progress 2044 / 9694 Time remaining: 0s Progress 2045 / 9694 Time remaining: 0s Progress 2046 / 9694 Time remaining: 0s Progress 2047 / 9694 Time remaining: 0s Progress 2048 / 9694 Time remaining: 0s Progress 2049 / 9694 Time remaining: 0s Progress 2050 / 9694 Time remaining: 0s Progress 2051 / 9694 Time remaining: 0s Progress 2052 / 9694 Time remaining: 0s Progress 2053 / 9694 Time remaining: 0s Progress 2054 / 9694 Time remaining: 0s Progress 2055 / 9694 Time remaining: 0s Progress 2056 / 9694 Time remaining: 0s Progress 2057 / 9694 Time remaining: 0s Progress 2058 / 9694 Time remaining: 0s Progress 2059 / 9694 Time remaining: 0s Progress 2060 / 9694 Time remaining: 0s Progress 2061 / 9694 Time remaining: 0s Progress 2062 / 9694 Time remaining: 0s Progress 2063 / 9694 Time remaining: 0s Progress 2064 / 9694 Time remaining: 0s Progress 2065 / 9694 Time remaining: 0s Progress 2066 / 9694 Time remaining: 0s Progress 2067 / 9694 Time remaining: 0s Progress 2068 / 9694 Time remaining: 0s Progress 2069 / 9694 Time remaining: 0s Progress 2070 / 9694 Time remaining: 0s Progress 2071 / 9694 Time remaining: 0s Progress 2072 / 9694 Time remaining: 0s Progress 2073 / 9694 Time remaining: 0s Progress 2074 / 9694 Time remaining: 0s Progress 2075 / 9694 Time remaining: 0s Progress 2076 / 9694 Time remaining: 0s Progress 2077 / 9694 Time remaining: 0s Progress 2078 / 9694 Time remaining: 0s Progress 2079 / 9694 Time remaining: 0s Progress 2080 / 9694 Time remaining: 0s Progress 2081 / 9694 Time remaining: 0s Progress 2082 / 9694 Time remaining: 0s Progress 2083 / 9694 Time remaining: 0s Progress 2084 / 9694 Time remaining: 0s Progress 2085 / 9694 Time remaining: 0s Progress 2086 / 9694 Time remaining: 0s Progress 2087 / 9694 Time remaining: 0s Progress 2088 / 9694 Time remaining: 0s Progress 2089 / 9694 Time remaining: 0s Progress 2090 / 9694 Time remaining: 0s Progress 2091 / 9694 Time remaining: 0s Progress 2092 / 9694 Time remaining: 0s Progress 2093 / 9694 Time remaining: 0s Progress 2094 / 9694 Time remaining: 0s Progress 2095 / 9694 Time remaining: 0s Progress 2096 / 9694 Time remaining: 0s Progress 2097 / 9694 Time remaining: 0s Progress 2098 / 9694 Time remaining: 0s Progress 2099 / 9694 Time remaining: 0s Progress 2100 / 9694 Time remaining: 0s Progress 2101 / 9694 Time remaining: 0s Progress 2102 / 9694 Time remaining: 0s Progress 2103 / 9694 Time remaining: 0s Progress 2104 / 9694 Time remaining: 0s Progress 2105 / 9694 Time remaining: 0s Progress 2106 / 9694 Time remaining: 0s Progress 2107 / 9694 Time remaining: 0s Progress 2108 / 9694 Time remaining: 0s Progress 2109 / 9694 Time remaining: 0s Progress 2110 / 9694 Time remaining: 0s Progress 2111 / 9694 Time remaining: 0s Progress 2112 / 9694 Time remaining: 0s Progress 2113 / 9694 Time remaining: 0s Progress 2114 / 9694 Time remaining: 0s Progress 2115 / 9694 Time remaining: 0s Progress 2116 / 9694 Time remaining: 0s Progress 2117 / 9694 Time remaining: 0s Progress 2118 / 9694 Time remaining: 0s Progress 2119 / 9694 Time remaining: 0s Progress 2120 / 9694 Time remaining: 0s Progress 2121 / 9694 Time remaining: 0s Progress 2122 / 9694 Time remaining: 0s Progress 2123 / 9694 Time remaining: 0s Progress 2124 / 9694 Time remaining: 0s Progress 2125 / 9694 Time remaining: 0s Progress 2126 / 9694 Time remaining: 0s Progress 2127 / 9694 Time remaining: 0s Progress 2128 / 9694 Time remaining: 0s Progress 2129 / 9694 Time remaining: 0s Progress 2130 / 9694 Time remaining: 0s Progress 2131 / 9694 Time remaining: 0s Progress 2132 / 9694 Time remaining: 0s Progress 2133 / 9694 Time remaining: 0s Progress 2134 / 9694 Time remaining: 0s Progress 2135 / 9694 Time remaining: 0s Progress 2136 / 9694 Time remaining: 0s Progress 2137 / 9694 Time remaining: 0s Progress 2138 / 9694 Time remaining: 0s Progress 2139 / 9694 Time remaining: 0s Progress 2140 / 9694 Time remaining: 0s Progress 2141 / 9694 Time remaining: 0s Progress 2142 / 9694 Time remaining: 0s Progress 2143 / 9694 Time remaining: 0s Progress 2144 / 9694 Time remaining: 0s Progress 2145 / 9694 Time remaining: 0s Progress 2146 / 9694 Time remaining: 0s Progress 2147 / 9694 Time remaining: 0s Progress 2148 / 9694 Time remaining: 0s Progress 2149 / 9694 Time remaining: 0s Progress 2150 / 9694 Time remaining: 0s Progress 2151 / 9694 Time remaining: 0s Progress 2152 / 9694 Time remaining: 0s Progress 2153 / 9694 Time remaining: 0s Progress 2154 / 9694 Time remaining: 0s Progress 2155 / 9694 Time remaining: 0s Progress 2156 / 9694 Time remaining: 0s Progress 2157 / 9694 Time remaining: 0s Progress 2158 / 9694 Time remaining: 0s Progress 2159 / 9694 Time remaining: 0s Progress 2160 / 9694 Time remaining: 0s Progress 2161 / 9694 Time remaining: 0s Progress 2162 / 9694 Time remaining: 0s Progress 2163 / 9694 Time remaining: 0s Progress 2164 / 9694 Time remaining: 0s Progress 2165 / 9694 Time remaining: 0s Progress 2166 / 9694 Time remaining: 0s Progress 2167 / 9694 Time remaining: 0s Progress 2168 / 9694 Time remaining: 0s Progress 2169 / 9694 Time remaining: 0s Progress 2170 / 9694 Time remaining: 0s Progress 2171 / 9694 Time remaining: 0s Progress 2172 / 9694 Time remaining: 0s Progress 2173 / 9694 Time remaining: 0s Progress 2174 / 9694 Time remaining: 0s Progress 2175 / 9694 Time remaining: 0s Progress 2176 / 9694 Time remaining: 0s Progress 2177 / 9694 Time remaining: 0s Progress 2178 / 9694 Time remaining: 0s Progress 2179 / 9694 Time remaining: 0s Progress 2180 / 9694 Time remaining: 0s Progress 2181 / 9694 Time remaining: 0s Progress 2182 / 9694 Time remaining: 0s Progress 2183 / 9694 Time remaining: 0s Progress 2184 / 9694 Time remaining: 0s Progress 2185 / 9694 Time remaining: 0s Progress 2186 / 9694 Time remaining: 0s Progress 2187 / 9694 Time remaining: 0s Progress 2188 / 9694 Time remaining: 0s Progress 2189 / 9694 Time remaining: 0s Progress 2190 / 9694 Time remaining: 0s Progress 2191 / 9694 Time remaining: 0s Progress 2192 / 9694 Time remaining: 0s Progress 2193 / 9694 Time remaining: 0s Progress 2194 / 9694 Time remaining: 0s Progress 2195 / 9694 Time remaining: 0s Progress 2196 / 9694 Time remaining: 0s Progress 2197 / 9694 Time remaining: 0s Progress 2198 / 9694 Time remaining: 0s Progress 2199 / 9694 Time remaining: 0s Progress 2200 / 9694 Time remaining: 0s Progress 2201 / 9694 Time remaining: 0s Progress 2202 / 9694 Time remaining: 0s Progress 2203 / 9694 Time remaining: 0s Progress 2204 / 9694 Time remaining: 0s Progress 2205 / 9694 Time remaining: 0s Progress 2206 / 9694 Time remaining: 0s Progress 2207 / 9694 Time remaining: 0s Progress 2208 / 9694 Time remaining: 0s Progress 2209 / 9694 Time remaining: 0s Progress 2210 / 9694 Time remaining: 0s Progress 2211 / 9694 Time remaining: 0s Progress 2212 / 9694 Time remaining: 0s Progress 2213 / 9694 Time remaining: 0s Progress 2214 / 9694 Time remaining: 0s Progress 2215 / 9694 Time remaining: 0s Progress 2216 / 9694 Time remaining: 0s Progress 2217 / 9694 Time remaining: 0s Progress 2218 / 9694 Time remaining: 0s Progress 2219 / 9694 Time remaining: 0s Progress 2220 / 9694 Time remaining: 0s Progress 2221 / 9694 Time remaining: 0s Progress 2222 / 9694 Time remaining: 0s Progress 2223 / 9694 Time remaining: 0s Progress 2224 / 9694 Time remaining: 0s Progress 2225 / 9694 Time remaining: 0s Progress 2226 / 9694 Time remaining: 0s Progress 2227 / 9694 Time remaining: 0s Progress 2228 / 9694 Time remaining: 0s Progress 2229 / 9694 Time remaining: 0s Progress 2230 / 9694 Time remaining: 0s Progress 2231 / 9694 Time remaining: 0s Progress 2232 / 9694 Time remaining: 0s Progress 2233 / 9694 Time remaining: 0s Progress 2234 / 9694 Time remaining: 0s Progress 2235 / 9694 Time remaining: 0s Progress 2236 / 9694 Time remaining: 0s Progress 2237 / 9694 Time remaining: 0s Progress 2238 / 9694 Time remaining: 0s Progress 2239 / 9694 Time remaining: 0s Progress 2240 / 9694 Time remaining: 0s Progress 2241 / 9694 Time remaining: 0s Progress 2242 / 9694 Time remaining: 0s Progress 2243 / 9694 Time remaining: 0s Progress 2244 / 9694 Time remaining: 0s Progress 2245 / 9694 Time remaining: 0s Progress 2246 / 9694 Time remaining: 0s Progress 2247 / 9694 Time remaining: 0s Progress 2248 / 9694 Time remaining: 0s Progress 2249 / 9694 Time remaining: 0s Progress 2250 / 9694 Time remaining: 0s Progress 2251 / 9694 Time remaining: 0s Progress 2252 / 9694 Time remaining: 0s Progress 2253 / 9694 Time remaining: 0s Progress 2254 / 9694 Time remaining: 0s Progress 2255 / 9694 Time remaining: 0s Progress 2256 / 9694 Time remaining: 0s Progress 2257 / 9694 Time remaining: 0s Progress 2258 / 9694 Time remaining: 0s Progress 2259 / 9694 Time remaining: 0s Progress 2260 / 9694 Time remaining: 0s Progress 2261 / 9694 Time remaining: 0s Progress 2262 / 9694 Time remaining: 0s Progress 2263 / 9694 Time remaining: 0s Progress 2264 / 9694 Time remaining: 0s Progress 2265 / 9694 Time remaining: 0s Progress 2266 / 9694 Time remaining: 0s Progress 2267 / 9694 Time remaining: 0s Progress 2268 / 9694 Time remaining: 0s Progress 2269 / 9694 Time remaining: 0s Progress 2270 / 9694 Time remaining: 0s Progress 2271 / 9694 Time remaining: 0s Progress 2272 / 9694 Time remaining: 0s Progress 2273 / 9694 Time remaining: 0s Progress 2274 / 9694 Time remaining: 0s Progress 2275 / 9694 Time remaining: 0s Progress 2276 / 9694 Time remaining: 0s Progress 2277 / 9694 Time remaining: 0s Progress 2278 / 9694 Time remaining: 0s Progress 2279 / 9694 Time remaining: 0s Progress 2280 / 9694 Time remaining: 0s Progress 2281 / 9694 Time remaining: 0s Progress 2282 / 9694 Time remaining: 0s Progress 2283 / 9694 Time remaining: 0s Progress 2284 / 9694 Time remaining: 0s Progress 2285 / 9694 Time remaining: 0s Progress 2286 / 9694 Time remaining: 0s Progress 2287 / 9694 Time remaining: 0s Progress 2288 / 9694 Time remaining: 0s Progress 2289 / 9694 Time remaining: 0s Progress 2290 / 9694 Time remaining: 0s Progress 2291 / 9694 Time remaining: 0s Progress 2292 / 9694 Time remaining: 0s Progress 2293 / 9694 Time remaining: 0s Progress 2294 / 9694 Time remaining: 0s Progress 2295 / 9694 Time remaining: 0s Progress 2296 / 9694 Time remaining: 0s Progress 2297 / 9694 Time remaining: 0s Progress 2298 / 9694 Time remaining: 0s Progress 2299 / 9694 Time remaining: 0s Progress 2300 / 9694 Time remaining: 0s Progress 2301 / 9694 Time remaining: 0s Progress 2302 / 9694 Time remaining: 0s Progress 2303 / 9694 Time remaining: 0s Progress 2304 / 9694 Time remaining: 0s Progress 2305 / 9694 Time remaining: 0s Progress 2306 / 9694 Time remaining: 0s Progress 2307 / 9694 Time remaining: 0s Progress 2308 / 9694 Time remaining: 0s Progress 2309 / 9694 Time remaining: 0s Progress 2310 / 9694 Time remaining: 0s Progress 2311 / 9694 Time remaining: 0s Progress 2312 / 9694 Time remaining: 0s Progress 2313 / 9694 Time remaining: 0s Progress 2314 / 9694 Time remaining: 0s Progress 2315 / 9694 Time remaining: 0s Progress 2316 / 9694 Time remaining: 0s Progress 2317 / 9694 Time remaining: 0s Progress 2318 / 9694 Time remaining: 0s Progress 2319 / 9694 Time remaining: 0s Progress 2320 / 9694 Time remaining: 0s Progress 2321 / 9694 Time remaining: 0s Progress 2322 / 9694 Time remaining: 0s Progress 2323 / 9694 Time remaining: 0s Progress 2324 / 9694 Time remaining: 0s Progress 2325 / 9694 Time remaining: 0s Progress 2326 / 9694 Time remaining: 0s Progress 2327 / 9694 Time remaining: 0s Progress 2328 / 9694 Time remaining: 0s Progress 2329 / 9694 Time remaining: 0s Progress 2330 / 9694 Time remaining: 0s Progress 2331 / 9694 Time remaining: 0s Progress 2332 / 9694 Time remaining: 0s Progress 2333 / 9694 Time remaining: 0s Progress 2334 / 9694 Time remaining: 0s Progress 2335 / 9694 Time remaining: 0s Progress 2336 / 9694 Time remaining: 0s Progress 2337 / 9694 Time remaining: 0s Progress 2338 / 9694 Time remaining: 0s Progress 2339 / 9694 Time remaining: 0s Progress 2340 / 9694 Time remaining: 0s Progress 2341 / 9694 Time remaining: 0s Progress 2342 / 9694 Time remaining: 0s Progress 2343 / 9694 Time remaining: 0s Progress 2344 / 9694 Time remaining: 0s Progress 2345 / 9694 Time remaining: 0s Progress 2346 / 9694 Time remaining: 0s Progress 2347 / 9694 Time remaining: 0s Progress 2348 / 9694 Time remaining: 0s Progress 2349 / 9694 Time remaining: 0s Progress 2350 / 9694 Time remaining: 0s Progress 2351 / 9694 Time remaining: 0s Progress 2352 / 9694 Time remaining: 0s Progress 2353 / 9694 Time remaining: 0s Progress 2354 / 9694 Time remaining: 0s Progress 2355 / 9694 Time remaining: 0s Progress 2356 / 9694 Time remaining: 0s Progress 2357 / 9694 Time remaining: 0s Progress 2358 / 9694 Time remaining: 0s Progress 2359 / 9694 Time remaining: 0s Progress 2360 / 9694 Time remaining: 0s Progress 2361 / 9694 Time remaining: 0s Progress 2362 / 9694 Time remaining: 0s Progress 2363 / 9694 Time remaining: 0s Progress 2364 / 9694 Time remaining: 0s Progress 2365 / 9694 Time remaining: 0s Progress 2366 / 9694 Time remaining: 0s Progress 2367 / 9694 Time remaining: 0s Progress 2368 / 9694 Time remaining: 0s Progress 2369 / 9694 Time remaining: 0s Progress 2370 / 9694 Time remaining: 0s Progress 2371 / 9694 Time remaining: 0s Progress 2372 / 9694 Time remaining: 0s Progress 2373 / 9694 Time remaining: 0s Progress 2374 / 9694 Time remaining: 0s Progress 2375 / 9694 Time remaining: 0s Progress 2376 / 9694 Time remaining: 0s Progress 2377 / 9694 Time remaining: 0s Progress 2378 / 9694 Time remaining: 0s Progress 2379 / 9694 Time remaining: 0s Progress 2380 / 9694 Time remaining: 0s Progress 2381 / 9694 Time remaining: 0s Progress 2382 / 9694 Time remaining: 0s Progress 2383 / 9694 Time remaining: 0s Progress 2384 / 9694 Time remaining: 0s Progress 2385 / 9694 Time remaining: 0s Progress 2386 / 9694 Time remaining: 0s Progress 2387 / 9694 Time remaining: 0s Progress 2388 / 9694 Time remaining: 0s Progress 2389 / 9694 Time remaining: 0s Progress 2390 / 9694 Time remaining: 0s Progress 2391 / 9694 Time remaining: 0s Progress 2392 / 9694 Time remaining: 0s Progress 2393 / 9694 Time remaining: 0s Progress 2394 / 9694 Time remaining: 0s Progress 2395 / 9694 Time remaining: 0s Progress 2396 / 9694 Time remaining: 0s Progress 2397 / 9694 Time remaining: 0s Progress 2398 / 9694 Time remaining: 0s Progress 2399 / 9694 Time remaining: 0s Progress 2400 / 9694 Time remaining: 0s Progress 2401 / 9694 Time remaining: 0s Progress 2402 / 9694 Time remaining: 0s Progress 2403 / 9694 Time remaining: 0s Progress 2404 / 9694 Time remaining: 0s Progress 2405 / 9694 Time remaining: 0s Progress 2406 / 9694 Time remaining: 0s Progress 2407 / 9694 Time remaining: 0s Progress 2408 / 9694 Time remaining: 0s Progress 2409 / 9694 Time remaining: 0s Progress 2410 / 9694 Time remaining: 0s Progress 2411 / 9694 Time remaining: 0s Progress 2412 / 9694 Time remaining: 0s Progress 2413 / 9694 Time remaining: 0s Progress 2414 / 9694 Time remaining: 0s Progress 2415 / 9694 Time remaining: 0s Progress 2416 / 9694 Time remaining: 0s Progress 2417 / 9694 Time remaining: 0s Progress 2418 / 9694 Time remaining: 0s Progress 2419 / 9694 Time remaining: 0s Progress 2420 / 9694 Time remaining: 0s Progress 2421 / 9694 Time remaining: 0s Progress 2422 / 9694 Time remaining: 0s Progress 2423 / 9694 Time remaining: 0s Progress 2424 / 9694 Time remaining: 0s Progress 2425 / 9694 Time remaining: 0s Progress 2426 / 9694 Time remaining: 0s Progress 2427 / 9694 Time remaining: 0s Progress 2428 / 9694 Time remaining: 0s Progress 2429 / 9694 Time remaining: 0s Progress 2430 / 9694 Time remaining: 0s Progress 2431 / 9694 Time remaining: 0s Progress 2432 / 9694 Time remaining: 0s Progress 2433 / 9694 Time remaining: 0s Progress 2434 / 9694 Time remaining: 0s Progress 2435 / 9694 Time remaining: 0s Progress 2436 / 9694 Time remaining: 0s Progress 2437 / 9694 Time remaining: 0s Progress 2438 / 9694 Time remaining: 0s Progress 2439 / 9694 Time remaining: 0s Progress 2440 / 9694 Time remaining: 0s Progress 2441 / 9694 Time remaining: 0s Progress 2442 / 9694 Time remaining: 0s Progress 2443 / 9694 Time remaining: 0s Progress 2444 / 9694 Time remaining: 0s Progress 2445 / 9694 Time remaining: 0s Progress 2446 / 9694 Time remaining: 0s Progress 2447 / 9694 Time remaining: 0s Progress 2448 / 9694 Time remaining: 0s Progress 2449 / 9694 Time remaining: 0s Progress 2450 / 9694 Time remaining: 0s Progress 2451 / 9694 Time remaining: 0s Progress 2452 / 9694 Time remaining: 0s Progress 2453 / 9694 Time remaining: 0s Progress 2454 / 9694 Time remaining: 0s Progress 2455 / 9694 Time remaining: 0s Progress 2456 / 9694 Time remaining: 0s Progress 2457 / 9694 Time remaining: 0s Progress 2458 / 9694 Time remaining: 0s Progress 2459 / 9694 Time remaining: 0s Progress 2460 / 9694 Time remaining: 0s Progress 2461 / 9694 Time remaining: 0s Progress 2462 / 9694 Time remaining: 0s Progress 2463 / 9694 Time remaining: 0s Progress 2464 / 9694 Time remaining: 0s Progress 2465 / 9694 Time remaining: 0s Progress 2466 / 9694 Time remaining: 0s Progress 2467 / 9694 Time remaining: 0s Progress 2468 / 9694 Time remaining: 0s Progress 2469 / 9694 Time remaining: 0s Progress 2470 / 9694 Time remaining: 0s Progress 2471 / 9694 Time remaining: 0s Progress 2472 / 9694 Time remaining: 0s Progress 2473 / 9694 Time remaining: 0s Progress 2474 / 9694 Time remaining: 0s Progress 2475 / 9694 Time remaining: 0s Progress 2476 / 9694 Time remaining: 0s Progress 2477 / 9694 Time remaining: 0s Progress 2478 / 9694 Time remaining: 0s Progress 2479 / 9694 Time remaining: 0s Progress 2480 / 9694 Time remaining: 0s Progress 2481 / 9694 Time remaining: 0s Progress 2482 / 9694 Time remaining: 0s Progress 2483 / 9694 Time remaining: 0s Progress 2484 / 9694 Time remaining: 0s Progress 2485 / 9694 Time remaining: 0s Progress 2486 / 9694 Time remaining: 0s Progress 2487 / 9694 Time remaining: 0s Progress 2488 / 9694 Time remaining: 0s Progress 2489 / 9694 Time remaining: 0s Progress 2490 / 9694 Time remaining: 0s Progress 2491 / 9694 Time remaining: 0s Progress 2492 / 9694 Time remaining: 0s Progress 2493 / 9694 Time remaining: 0s Progress 2494 / 9694 Time remaining: 0s Progress 2495 / 9694 Time remaining: 0s Progress 2496 / 9694 Time remaining: 0s Progress 2497 / 9694 Time remaining: 0s Progress 2498 / 9694 Time remaining: 0s Progress 2499 / 9694 Time remaining: 0s Progress 2500 / 9694 Time remaining: 0s Progress 2501 / 9694 Time remaining: 0s Progress 2502 / 9694 Time remaining: 0s Progress 2503 / 9694 Time remaining: 0s Progress 2504 / 9694 Time remaining: 0s Progress 2505 / 9694 Time remaining: 0s Progress 2506 / 9694 Time remaining: 0s Progress 2507 / 9694 Time remaining: 0s Progress 2508 / 9694 Time remaining: 0s Progress 2509 / 9694 Time remaining: 0s Progress 2510 / 9694 Time remaining: 0s Progress 2511 / 9694 Time remaining: 0s Progress 2512 / 9694 Time remaining: 0s Progress 2513 / 9694 Time remaining: 0s Progress 2514 / 9694 Time remaining: 0s Progress 2515 / 9694 Time remaining: 0s Progress 2516 / 9694 Time remaining: 0s Progress 2517 / 9694 Time remaining: 0s Progress 2518 / 9694 Time remaining: 0s Progress 2519 / 9694 Time remaining: 0s Progress 2520 / 9694 Time remaining: 0s Progress 2521 / 9694 Time remaining: 0s Progress 2522 / 9694 Time remaining: 0s Progress 2523 / 9694 Time remaining: 0s Progress 2524 / 9694 Time remaining: 0s Progress 2525 / 9694 Time remaining: 0s Progress 2526 / 9694 Time remaining: 0s Progress 2527 / 9694 Time remaining: 0s Progress 2528 / 9694 Time remaining: 0s Progress 2529 / 9694 Time remaining: 0s Progress 2530 / 9694 Time remaining: 0s Progress 2531 / 9694 Time remaining: 0s Progress 2532 / 9694 Time remaining: 0s Progress 2533 / 9694 Time remaining: 0s Progress 2534 / 9694 Time remaining: 0s Progress 2535 / 9694 Time remaining: 0s Progress 2536 / 9694 Time remaining: 0s Progress 2537 / 9694 Time remaining: 0s Progress 2538 / 9694 Time remaining: 0s Progress 2539 / 9694 Time remaining: 0s Progress 2540 / 9694 Time remaining: 0s Progress 2541 / 9694 Time remaining: 0s Progress 2542 / 9694 Time remaining: 0s Progress 2543 / 9694 Time remaining: 0s Progress 2544 / 9694 Time remaining: 0s Progress 2545 / 9694 Time remaining: 0s Progress 2546 / 9694 Time remaining: 0s Progress 2547 / 9694 Time remaining: 0s Progress 2548 / 9694 Time remaining: 0s Progress 2549 / 9694 Time remaining: 0s Progress 2550 / 9694 Time remaining: 0s Progress 2551 / 9694 Time remaining: 0s Progress 2552 / 9694 Time remaining: 0s Progress 2553 / 9694 Time remaining: 0s Progress 2554 / 9694 Time remaining: 0s Progress 2555 / 9694 Time remaining: 0s Progress 2556 / 9694 Time remaining: 0s Progress 2557 / 9694 Time remaining: 0s Progress 2558 / 9694 Time remaining: 0s Progress 2559 / 9694 Time remaining: 0s Progress 2560 / 9694 Time remaining: 0s Progress 2561 / 9694 Time remaining: 0s Progress 2562 / 9694 Time remaining: 0s Progress 2563 / 9694 Time remaining: 0s Progress 2564 / 9694 Time remaining: 0s Progress 2565 / 9694 Time remaining: 0s Progress 2566 / 9694 Time remaining: 0s Progress 2567 / 9694 Time remaining: 0s Progress 2568 / 9694 Time remaining: 0s Progress 2569 / 9694 Time remaining: 0s Progress 2570 / 9694 Time remaining: 0s Progress 2571 / 9694 Time remaining: 0s Progress 2572 / 9694 Time remaining: 0s Progress 2573 / 9694 Time remaining: 0s Progress 2574 / 9694 Time remaining: 0s Progress 2575 / 9694 Time remaining: 0s Progress 2576 / 9694 Time remaining: 0s Progress 2577 / 9694 Time remaining: 0s Progress 2578 / 9694 Time remaining: 0s Progress 2579 / 9694 Time remaining: 0s Progress 2580 / 9694 Time remaining: 0s Progress 2581 / 9694 Time remaining: 0s Progress 2582 / 9694 Time remaining: 0s Progress 2583 / 9694 Time remaining: 0s Progress 2584 / 9694 Time remaining: 0s Progress 2585 / 9694 Time remaining: 0s Progress 2586 / 9694 Time remaining: 0s Progress 2587 / 9694 Time remaining: 0s Progress 2588 / 9694 Time remaining: 0s Progress 2589 / 9694 Time remaining: 0s Progress 2590 / 9694 Time remaining: 0s Progress 2591 / 9694 Time remaining: 0s Progress 2592 / 9694 Time remaining: 0s Progress 2593 / 9694 Time remaining: 0s Progress 2594 / 9694 Time remaining: 0s Progress 2595 / 9694 Time remaining: 0s Progress 2596 / 9694 Time remaining: 0s Progress 2597 / 9694 Time remaining: 0s Progress 2598 / 9694 Time remaining: 0s Progress 2599 / 9694 Time remaining: 0s Progress 2600 / 9694 Time remaining: 0s Progress 2601 / 9694 Time remaining: 0s Progress 2602 / 9694 Time remaining: 0s Progress 2603 / 9694 Time remaining: 0s Progress 2604 / 9694 Time remaining: 0s Progress 2605 / 9694 Time remaining: 0s Progress 2606 / 9694 Time remaining: 0s Progress 2607 / 9694 Time remaining: 0s Progress 2608 / 9694 Time remaining: 0s Progress 2609 / 9694 Time remaining: 0s Progress 2610 / 9694 Time remaining: 0s Progress 2611 / 9694 Time remaining: 0s Progress 2612 / 9694 Time remaining: 0s Progress 2613 / 9694 Time remaining: 0s Progress 2614 / 9694 Time remaining: 0s Progress 2615 / 9694 Time remaining: 0s Progress 2616 / 9694 Time remaining: 0s Progress 2617 / 9694 Time remaining: 0s Progress 2618 / 9694 Time remaining: 0s Progress 2619 / 9694 Time remaining: 0s Progress 2620 / 9694 Time remaining: 0s Progress 2621 / 9694 Time remaining: 0s Progress 2622 / 9694 Time remaining: 0s Progress 2623 / 9694 Time remaining: 0s Progress 2624 / 9694 Time remaining: 0s Progress 2625 / 9694 Time remaining: 0s Progress 2626 / 9694 Time remaining: 0s Progress 2627 / 9694 Time remaining: 0s Progress 2628 / 9694 Time remaining: 0s Progress 2629 / 9694 Time remaining: 0s Progress 2630 / 9694 Time remaining: 0s Progress 2631 / 9694 Time remaining: 0s Progress 2632 / 9694 Time remaining: 0s Progress 2633 / 9694 Time remaining: 0s Progress 2634 / 9694 Time remaining: 0s Progress 2635 / 9694 Time remaining: 0s Progress 2636 / 9694 Time remaining: 0s Progress 2637 / 9694 Time remaining: 0s Progress 2638 / 9694 Time remaining: 0s Progress 2639 / 9694 Time remaining: 0s Progress 2640 / 9694 Time remaining: 0s Progress 2641 / 9694 Time remaining: 0s Progress 2642 / 9694 Time remaining: 0s Progress 2643 / 9694 Time remaining: 0s Progress 2644 / 9694 Time remaining: 0s Progress 2645 / 9694 Time remaining: 0s Progress 2646 / 9694 Time remaining: 0s Progress 2647 / 9694 Time remaining: 0s Progress 2648 / 9694 Time remaining: 0s Progress 2649 / 9694 Time remaining: 0s Progress 2650 / 9694 Time remaining: 0s Progress 2651 / 9694 Time remaining: 0s Progress 2652 / 9694 Time remaining: 0s Progress 2653 / 9694 Time remaining: 0s Progress 2654 / 9694 Time remaining: 0s Progress 2655 / 9694 Time remaining: 0s Progress 2656 / 9694 Time remaining: 0s Progress 2657 / 9694 Time remaining: 0s Progress 2658 / 9694 Time remaining: 0s Progress 2659 / 9694 Time remaining: 0s Progress 2660 / 9694 Time remaining: 0s Progress 2661 / 9694 Time remaining: 0s Progress 2662 / 9694 Time remaining: 0s Progress 2663 / 9694 Time remaining: 0s Progress 2664 / 9694 Time remaining: 0s Progress 2665 / 9694 Time remaining: 0s Progress 2666 / 9694 Time remaining: 0s Progress 2667 / 9694 Time remaining: 0s Progress 2668 / 9694 Time remaining: 0s Progress 2669 / 9694 Time remaining: 0s Progress 2670 / 9694 Time remaining: 0s Progress 2671 / 9694 Time remaining: 0s Progress 2672 / 9694 Time remaining: 0s Progress 2673 / 9694 Time remaining: 0s Progress 2674 / 9694 Time remaining: 0s Progress 2675 / 9694 Time remaining: 0s Progress 2676 / 9694 Time remaining: 0s Progress 2677 / 9694 Time remaining: 0s Progress 2678 / 9694 Time remaining: 0s Progress 2679 / 9694 Time remaining: 0s Progress 2680 / 9694 Time remaining: 0s Progress 2681 / 9694 Time remaining: 0s Progress 2682 / 9694 Time remaining: 0s Progress 2683 / 9694 Time remaining: 0s Progress 2684 / 9694 Time remaining: 0s Progress 2685 / 9694 Time remaining: 0s Progress 2686 / 9694 Time remaining: 0s Progress 2687 / 9694 Time remaining: 0s Progress 2688 / 9694 Time remaining: 0s Progress 2689 / 9694 Time remaining: 0s Progress 2690 / 9694 Time remaining: 0s Progress 2691 / 9694 Time remaining: 0s Progress 2692 / 9694 Time remaining: 0s Progress 2693 / 9694 Time remaining: 0s Progress 2694 / 9694 Time remaining: 0s Progress 2695 / 9694 Time remaining: 0s Progress 2696 / 9694 Time remaining: 0s Progress 2697 / 9694 Time remaining: 0s Progress 2698 / 9694 Time remaining: 0s Progress 2699 / 9694 Time remaining: 0s Progress 2700 / 9694 Time remaining: 0s Progress 2701 / 9694 Time remaining: 0s Progress 2702 / 9694 Time remaining: 0s Progress 2703 / 9694 Time remaining: 0s Progress 2704 / 9694 Time remaining: 0s Progress 2705 / 9694 Time remaining: 0s Progress 2706 / 9694 Time remaining: 0s Progress 2707 / 9694 Time remaining: 0s Progress 2708 / 9694 Time remaining: 0s Progress 2709 / 9694 Time remaining: 0s Progress 2710 / 9694 Time remaining: 0s Progress 2711 / 9694 Time remaining: 0s Progress 2712 / 9694 Time remaining: 0s Progress 2713 / 9694 Time remaining: 0s Progress 2714 / 9694 Time remaining: 0s Progress 2715 / 9694 Time remaining: 0s Progress 2716 / 9694 Time remaining: 0s Progress 2717 / 9694 Time remaining: 0s Progress 2718 / 9694 Time remaining: 0s Progress 2719 / 9694 Time remaining: 0s Progress 2720 / 9694 Time remaining: 0s Progress 2721 / 9694 Time remaining: 0s Progress 2722 / 9694 Time remaining: 0s Progress 2723 / 9694 Time remaining: 0s Progress 2724 / 9694 Time remaining: 0s Progress 2725 / 9694 Time remaining: 0s Progress 2726 / 9694 Time remaining: 0s Progress 2727 / 9694 Time remaining: 0s Progress 2728 / 9694 Time remaining: 0s Progress 2729 / 9694 Time remaining: 0s Progress 2730 / 9694 Time remaining: 0s Progress 2731 / 9694 Time remaining: 0s Progress 2732 / 9694 Time remaining: 0s Progress 2733 / 9694 Time remaining: 0s Progress 2734 / 9694 Time remaining: 0s Progress 2735 / 9694 Time remaining: 0s Progress 2736 / 9694 Time remaining: 0s Progress 2737 / 9694 Time remaining: 0s Progress 2738 / 9694 Time remaining: 0s Progress 2739 / 9694 Time remaining: 0s Progress 2740 / 9694 Time remaining: 0s Progress 2741 / 9694 Time remaining: 0s Progress 2742 / 9694 Time remaining: 0s Progress 2743 / 9694 Time remaining: 0s Progress 2744 / 9694 Time remaining: 0s Progress 2745 / 9694 Time remaining: 0s Progress 2746 / 9694 Time remaining: 0s Progress 2747 / 9694 Time remaining: 0s Progress 2748 / 9694 Time remaining: 0s Progress 2749 / 9694 Time remaining: 0s Progress 2750 / 9694 Time remaining: 0s Progress 2751 / 9694 Time remaining: 0s Progress 2752 / 9694 Time remaining: 0s Progress 2753 / 9694 Time remaining: 0s Progress 2754 / 9694 Time remaining: 0s Progress 2755 / 9694 Time remaining: 0s Progress 2756 / 9694 Time remaining: 0s Progress 2757 / 9694 Time remaining: 0s Progress 2758 / 9694 Time remaining: 0s Progress 2759 / 9694 Time remaining: 0s Progress 2760 / 9694 Time remaining: 0s Progress 2761 / 9694 Time remaining: 0s Progress 2762 / 9694 Time remaining: 0s Progress 2763 / 9694 Time remaining: 0s Progress 2764 / 9694 Time remaining: 0s Progress 2765 / 9694 Time remaining: 0s Progress 2766 / 9694 Time remaining: 0s Progress 2767 / 9694 Time remaining: 0s Progress 2768 / 9694 Time remaining: 0s Progress 2769 / 9694 Time remaining: 0s Progress 2770 / 9694 Time remaining: 0s Progress 2771 / 9694 Time remaining: 0s Progress 2772 / 9694 Time remaining: 0s Progress 2773 / 9694 Time remaining: 0s Progress 2774 / 9694 Time remaining: 0s Progress 2775 / 9694 Time remaining: 0s Progress 2776 / 9694 Time remaining: 0s Progress 2777 / 9694 Time remaining: 0s Progress 2778 / 9694 Time remaining: 0s Progress 2779 / 9694 Time remaining: 0s Progress 2780 / 9694 Time remaining: 0s Progress 2781 / 9694 Time remaining: 0s Progress 2782 / 9694 Time remaining: 0s Progress 2783 / 9694 Time remaining: 0s Progress 2784 / 9694 Time remaining: 0s Progress 2785 / 9694 Time remaining: 0s Progress 2786 / 9694 Time remaining: 0s Progress 2787 / 9694 Time remaining: 0s Progress 2788 / 9694 Time remaining: 0s Progress 2789 / 9694 Time remaining: 0s Progress 2790 / 9694 Time remaining: 0s Progress 2791 / 9694 Time remaining: 0s Progress 2792 / 9694 Time remaining: 0s Progress 2793 / 9694 Time remaining: 0s Progress 2794 / 9694 Time remaining: 0s Progress 2795 / 9694 Time remaining: 0s Progress 2796 / 9694 Time remaining: 0s Progress 2797 / 9694 Time remaining: 0s Progress 2798 / 9694 Time remaining: 0s Progress 2799 / 9694 Time remaining: 0s Progress 2800 / 9694 Time remaining: 0s Progress 2801 / 9694 Time remaining: 0s Progress 2802 / 9694 Time remaining: 0s Progress 2803 / 9694 Time remaining: 0s Progress 2804 / 9694 Time remaining: 0s Progress 2805 / 9694 Time remaining: 0s Progress 2806 / 9694 Time remaining: 0s Progress 2807 / 9694 Time remaining: 0s Progress 2808 / 9694 Time remaining: 0s Progress 2809 / 9694 Time remaining: 0s Progress 2810 / 9694 Time remaining: 0s Progress 2811 / 9694 Time remaining: 0s Progress 2812 / 9694 Time remaining: 0s Progress 2813 / 9694 Time remaining: 0s Progress 2814 / 9694 Time remaining: 0s Progress 2815 / 9694 Time remaining: 0s Progress 2816 / 9694 Time remaining: 0s Progress 2817 / 9694 Time remaining: 0s Progress 2818 / 9694 Time remaining: 0s Progress 2819 / 9694 Time remaining: 0s Progress 2820 / 9694 Time remaining: 0s Progress 2821 / 9694 Time remaining: 0s Progress 2822 / 9694 Time remaining: 0s Progress 2823 / 9694 Time remaining: 0s Progress 2824 / 9694 Time remaining: 0s Progress 2825 / 9694 Time remaining: 0s Progress 2826 / 9694 Time remaining: 0s Progress 2827 / 9694 Time remaining: 0s Progress 2828 / 9694 Time remaining: 0s Progress 2829 / 9694 Time remaining: 0s Progress 2830 / 9694 Time remaining: 0s Progress 2831 / 9694 Time remaining: 0s Progress 2832 / 9694 Time remaining: 0s Progress 2833 / 9694 Time remaining: 0s Progress 2834 / 9694 Time remaining: 0s Progress 2835 / 9694 Time remaining: 0s Progress 2836 / 9694 Time remaining: 0s Progress 2837 / 9694 Time remaining: 0s Progress 2838 / 9694 Time remaining: 0s Progress 2839 / 9694 Time remaining: 0s Progress 2840 / 9694 Time remaining: 0s Progress 2841 / 9694 Time remaining: 0s Progress 2842 / 9694 Time remaining: 0s Progress 2843 / 9694 Time remaining: 0s Progress 2844 / 9694 Time remaining: 0s Progress 2845 / 9694 Time remaining: 0s Progress 2846 / 9694 Time remaining: 0s Progress 2847 / 9694 Time remaining: 0s Progress 2848 / 9694 Time remaining: 0s Progress 2849 / 9694 Time remaining: 0s Progress 2850 / 9694 Time remaining: 0s Progress 2851 / 9694 Time remaining: 0s Progress 2852 / 9694 Time remaining: 0s Progress 2853 / 9694 Time remaining: 0s Progress 2854 / 9694 Time remaining: 0s Progress 2855 / 9694 Time remaining: 0s Progress 2856 / 9694 Time remaining: 0s Progress 2857 / 9694 Time remaining: 0s Progress 2858 / 9694 Time remaining: 0s Progress 2859 / 9694 Time remaining: 0s Progress 2860 / 9694 Time remaining: 0s Progress 2861 / 9694 Time remaining: 0s Progress 2862 / 9694 Time remaining: 0s Progress 2863 / 9694 Time remaining: 0s Progress 2864 / 9694 Time remaining: 0s Progress 2865 / 9694 Time remaining: 0s Progress 2866 / 9694 Time remaining: 0s Progress 2867 / 9694 Time remaining: 0s Progress 2868 / 9694 Time remaining: 0s Progress 2869 / 9694 Time remaining: 0s Progress 2870 / 9694 Time remaining: 0s Progress 2871 / 9694 Time remaining: 0s Progress 2872 / 9694 Time remaining: 0s Progress 2873 / 9694 Time remaining: 0s Progress 2874 / 9694 Time remaining: 0s Progress 2875 / 9694 Time remaining: 0s Progress 2876 / 9694 Time remaining: 0s Progress 2877 / 9694 Time remaining: 0s Progress 2878 / 9694 Time remaining: 0s Progress 2879 / 9694 Time remaining: 0s Progress 2880 / 9694 Time remaining: 0s Progress 2881 / 9694 Time remaining: 0s Progress 2882 / 9694 Time remaining: 0s Progress 2883 / 9694 Time remaining: 0s Progress 2884 / 9694 Time remaining: 0s Progress 2885 / 9694 Time remaining: 0s Progress 2886 / 9694 Time remaining: 0s Progress 2887 / 9694 Time remaining: 0s Progress 2888 / 9694 Time remaining: 0s Progress 2889 / 9694 Time remaining: 0s Progress 2890 / 9694 Time remaining: 0s Progress 2891 / 9694 Time remaining: 0s Progress 2892 / 9694 Time remaining: 0s Progress 2893 / 9694 Time remaining: 0s Progress 2894 / 9694 Time remaining: 0s Progress 2895 / 9694 Time remaining: 0s Progress 2896 / 9694 Time remaining: 0s Progress 2897 / 9694 Time remaining: 0s Progress 2898 / 9694 Time remaining: 0s Progress 2899 / 9694 Time remaining: 0s Progress 2900 / 9694 Time remaining: 0s Progress 2901 / 9694 Time remaining: 0s Progress 2902 / 9694 Time remaining: 0s Progress 2903 / 9694 Time remaining: 0s Progress 2904 / 9694 Time remaining: 0s Progress 2905 / 9694 Time remaining: 0s Progress 2906 / 9694 Time remaining: 0s Progress 2907 / 9694 Time remaining: 0s Progress 2908 / 9694 Time remaining: 0s Progress 2909 / 9694 Time remaining: 0s Progress 2910 / 9694 Time remaining: 0s Progress 2911 / 9694 Time remaining: 0s Progress 2912 / 9694 Time remaining: 0s Progress 2913 / 9694 Time remaining: 0s Progress 2914 / 9694 Time remaining: 0s Progress 2915 / 9694 Time remaining: 0s Progress 2916 / 9694 Time remaining: 0s Progress 2917 / 9694 Time remaining: 0s Progress 2918 / 9694 Time remaining: 0s Progress 2919 / 9694 Time remaining: 0s Progress 2920 / 9694 Time remaining: 0s Progress 2921 / 9694 Time remaining: 0s Progress 2922 / 9694 Time remaining: 0s Progress 2923 / 9694 Time remaining: 0s Progress 2924 / 9694 Time remaining: 0s Progress 2925 / 9694 Time remaining: 0s Progress 2926 / 9694 Time remaining: 0s Progress 2927 / 9694 Time remaining: 0s Progress 2928 / 9694 Time remaining: 0s Progress 2929 / 9694 Time remaining: 0s Progress 2930 / 9694 Time remaining: 0s Progress 2931 / 9694 Time remaining: 0s Progress 2932 / 9694 Time remaining: 0s Progress 2933 / 9694 Time remaining: 0s Progress 2934 / 9694 Time remaining: 0s Progress 2935 / 9694 Time remaining: 0s Progress 2936 / 9694 Time remaining: 0s Progress 2937 / 9694 Time remaining: 0s Progress 2938 / 9694 Time remaining: 0s Progress 2939 / 9694 Time remaining: 0s Progress 2940 / 9694 Time remaining: 0s Progress 2941 / 9694 Time remaining: 0s Progress 2942 / 9694 Time remaining: 0s Progress 2943 / 9694 Time remaining: 0s Progress 2944 / 9694 Time remaining: 0s Progress 2945 / 9694 Time remaining: 0s Progress 2946 / 9694 Time remaining: 0s Progress 2947 / 9694 Time remaining: 0s Progress 2948 / 9694 Time remaining: 0s Progress 2949 / 9694 Time remaining: 0s Progress 2950 / 9694 Time remaining: 0s Progress 2951 / 9694 Time remaining: 0s Progress 2952 / 9694 Time remaining: 0s Progress 2953 / 9694 Time remaining: 0s Progress 2954 / 9694 Time remaining: 0s Progress 2955 / 9694 Time remaining: 0s Progress 2956 / 9694 Time remaining: 0s Progress 2957 / 9694 Time remaining: 0s Progress 2958 / 9694 Time remaining: 0s Progress 2959 / 9694 Time remaining: 0s Progress 2960 / 9694 Time remaining: 0s Progress 2961 / 9694 Time remaining: 0s Progress 2962 / 9694 Time remaining: 0s Progress 2963 / 9694 Time remaining: 0s Progress 2964 / 9694 Time remaining: 0s Progress 2965 / 9694 Time remaining: 0s Progress 2966 / 9694 Time remaining: 0s Progress 2967 / 9694 Time remaining: 0s Progress 2968 / 9694 Time remaining: 0s Progress 2969 / 9694 Time remaining: 0s Progress 2970 / 9694 Time remaining: 0s Progress 2971 / 9694 Time remaining: 0s Progress 2972 / 9694 Time remaining: 0s Progress 2973 / 9694 Time remaining: 0s Progress 2974 / 9694 Time remaining: 0s Progress 2975 / 9694 Time remaining: 0s Progress 2976 / 9694 Time remaining: 0s Progress 2977 / 9694 Time remaining: 0s Progress 2978 / 9694 Time remaining: 0s Progress 2979 / 9694 Time remaining: 0s Progress 2980 / 9694 Time remaining: 0s Progress 2981 / 9694 Time remaining: 0s Progress 2982 / 9694 Time remaining: 0s Progress 2983 / 9694 Time remaining: 0s Progress 2984 / 9694 Time remaining: 0s Progress 2985 / 9694 Time remaining: 0s Progress 2986 / 9694 Time remaining: 0s Progress 2987 / 9694 Time remaining: 0s Progress 2988 / 9694 Time remaining: 0s Progress 2989 / 9694 Time remaining: 0s Progress 2990 / 9694 Time remaining: 0s Progress 2991 / 9694 Time remaining: 0s Progress 2992 / 9694 Time remaining: 0s Progress 2993 / 9694 Time remaining: 0s Progress 2994 / 9694 Time remaining: 0s Progress 2995 / 9694 Time remaining: 0s Progress 2996 / 9694 Time remaining: 0s Progress 2997 / 9694 Time remaining: 0s Progress 2998 / 9694 Time remaining: 0s Progress 2999 / 9694 Time remaining: 0s Progress 3000 / 9694 Time remaining: 0s Progress 3001 / 9694 Time remaining: 0s Progress 3002 / 9694 Time remaining: 0s Progress 3003 / 9694 Time remaining: 0s Progress 3004 / 9694 Time remaining: 0s Progress 3005 / 9694 Time remaining: 0s Progress 3006 / 9694 Time remaining: 0s Progress 3007 / 9694 Time remaining: 0s Progress 3008 / 9694 Time remaining: 0s Progress 3009 / 9694 Time remaining: 0s Progress 3010 / 9694 Time remaining: 0s Progress 3011 / 9694 Time remaining: 0s Progress 3012 / 9694 Time remaining: 0s Progress 3013 / 9694 Time remaining: 0s Progress 3014 / 9694 Time remaining: 0s Progress 3015 / 9694 Time remaining: 0s Progress 3016 / 9694 Time remaining: 0s Progress 3017 / 9694 Time remaining: 0s Progress 3018 / 9694 Time remaining: 0s Progress 3019 / 9694 Time remaining: 0s Progress 3020 / 9694 Time remaining: 0s Progress 3021 / 9694 Time remaining: 0s Progress 3022 / 9694 Time remaining: 0s Progress 3023 / 9694 Time remaining: 0s Progress 3024 / 9694 Time remaining: 0s Progress 3025 / 9694 Time remaining: 0s Progress 3026 / 9694 Time remaining: 0s Progress 3027 / 9694 Time remaining: 0s Progress 3028 / 9694 Time remaining: 0s Progress 3029 / 9694 Time remaining: 0s Progress 3030 / 9694 Time remaining: 0s Progress 3031 / 9694 Time remaining: 0s Progress 3032 / 9694 Time remaining: 0s Progress 3033 / 9694 Time remaining: 0s Progress 3034 / 9694 Time remaining: 0s Progress 3035 / 9694 Time remaining: 0s Progress 3036 / 9694 Time remaining: 0s Progress 3037 / 9694 Time remaining: 0s Progress 3038 / 9694 Time remaining: 0s Progress 3039 / 9694 Time remaining: 0s Progress 3040 / 9694 Time remaining: 0s Progress 3041 / 9694 Time remaining: 0s Progress 3042 / 9694 Time remaining: 0s Progress 3043 / 9694 Time remaining: 0s Progress 3044 / 9694 Time remaining: 0s Progress 3045 / 9694 Time remaining: 0s Progress 3046 / 9694 Time remaining: 0s Progress 3047 / 9694 Time remaining: 0s Progress 3048 / 9694 Time remaining: 0s Progress 3049 / 9694 Time remaining: 0s Progress 3050 / 9694 Time remaining: 0s Progress 3051 / 9694 Time remaining: 0s Progress 3052 / 9694 Time remaining: 0s Progress 3053 / 9694 Time remaining: 0s Progress 3054 / 9694 Time remaining: 0s Progress 3055 / 9694 Time remaining: 0s Progress 3056 / 9694 Time remaining: 0s Progress 3057 / 9694 Time remaining: 0s Progress 3058 / 9694 Time remaining: 0s Progress 3059 / 9694 Time remaining: 0s Progress 3060 / 9694 Time remaining: 0s Progress 3061 / 9694 Time remaining: 0s Progress 3062 / 9694 Time remaining: 0s Progress 3063 / 9694 Time remaining: 0s Progress 3064 / 9694 Time remaining: 0s Progress 3065 / 9694 Time remaining: 0s Progress 3066 / 9694 Time remaining: 0s Progress 3067 / 9694 Time remaining: 0s Progress 3068 / 9694 Time remaining: 0s Progress 3069 / 9694 Time remaining: 0s Progress 3070 / 9694 Time remaining: 0s Progress 3071 / 9694 Time remaining: 0s Progress 3072 / 9694 Time remaining: 0s Progress 3073 / 9694 Time remaining: 0s Progress 3074 / 9694 Time remaining: 0s Progress 3075 / 9694 Time remaining: 0s Progress 3076 / 9694 Time remaining: 0s Progress 3077 / 9694 Time remaining: 0s Progress 3078 / 9694 Time remaining: 0s Progress 3079 / 9694 Time remaining: 0s Progress 3080 / 9694 Time remaining: 0s Progress 3081 / 9694 Time remaining: 0s Progress 3082 / 9694 Time remaining: 0s Progress 3083 / 9694 Time remaining: 0s Progress 3084 / 9694 Time remaining: 0s Progress 3085 / 9694 Time remaining: 0s Progress 3086 / 9694 Time remaining: 0s Progress 3087 / 9694 Time remaining: 0s Progress 3088 / 9694 Time remaining: 0s Progress 3089 / 9694 Time remaining: 0s Progress 3090 / 9694 Time remaining: 0s Progress 3091 / 9694 Time remaining: 0s Progress 3092 / 9694 Time remaining: 0s Progress 3093 / 9694 Time remaining: 0s Progress 3094 / 9694 Time remaining: 0s Progress 3095 / 9694 Time remaining: 0s Progress 3096 / 9694 Time remaining: 0s Progress 3097 / 9694 Time remaining: 0s Progress 3098 / 9694 Time remaining: 0s Progress 3099 / 9694 Time remaining: 0s Progress 3100 / 9694 Time remaining: 0s Progress 3101 / 9694 Time remaining: 0s Progress 3102 / 9694 Time remaining: 0s Progress 3103 / 9694 Time remaining: 0s Progress 3104 / 9694 Time remaining: 0s Progress 3105 / 9694 Time remaining: 0s Progress 3106 / 9694 Time remaining: 0s Progress 3107 / 9694 Time remaining: 0s Progress 3108 / 9694 Time remaining: 0s Progress 3109 / 9694 Time remaining: 0s Progress 3110 / 9694 Time remaining: 0s Progress 3111 / 9694 Time remaining: 0s Progress 3112 / 9694 Time remaining: 0s Progress 3113 / 9694 Time remaining: 0s Progress 3114 / 9694 Time remaining: 0s Progress 3115 / 9694 Time remaining: 0s Progress 3116 / 9694 Time remaining: 0s Progress 3117 / 9694 Time remaining: 0s Progress 3118 / 9694 Time remaining: 0s Progress 3119 / 9694 Time remaining: 0s Progress 3120 / 9694 Time remaining: 0s Progress 3121 / 9694 Time remaining: 0s Progress 3122 / 9694 Time remaining: 0s Progress 3123 / 9694 Time remaining: 0s Progress 3124 / 9694 Time remaining: 0s Progress 3125 / 9694 Time remaining: 0s Progress 3126 / 9694 Time remaining: 0s Progress 3127 / 9694 Time remaining: 0s Progress 3128 / 9694 Time remaining: 0s Progress 3129 / 9694 Time remaining: 0s Progress 3130 / 9694 Time remaining: 0s Progress 3131 / 9694 Time remaining: 0s Progress 3132 / 9694 Time remaining: 0s Progress 3133 / 9694 Time remaining: 0s Progress 3134 / 9694 Time remaining: 0s Progress 3135 / 9694 Time remaining: 0s Progress 3136 / 9694 Time remaining: 0s Progress 3137 / 9694 Time remaining: 0s Progress 3138 / 9694 Time remaining: 0s Progress 3139 / 9694 Time remaining: 0s Progress 3140 / 9694 Time remaining: 0s Progress 3141 / 9694 Time remaining: 0s Progress 3142 / 9694 Time remaining: 0s Progress 3143 / 9694 Time remaining: 0s Progress 3144 / 9694 Time remaining: 0s Progress 3145 / 9694 Time remaining: 0s Progress 3146 / 9694 Time remaining: 0s Progress 3147 / 9694 Time remaining: 0s Progress 3148 / 9694 Time remaining: 0s Progress 3149 / 9694 Time remaining: 0s Progress 3150 / 9694 Time remaining: 0s Progress 3151 / 9694 Time remaining: 0s Progress 3152 / 9694 Time remaining: 0s Progress 3153 / 9694 Time remaining: 0s Progress 3154 / 9694 Time remaining: 0s Progress 3155 / 9694 Time remaining: 0s Progress 3156 / 9694 Time remaining: 0s Progress 3157 / 9694 Time remaining: 0s Progress 3158 / 9694 Time remaining: 0s Progress 3159 / 9694 Time remaining: 0s Progress 3160 / 9694 Time remaining: 0s Progress 3161 / 9694 Time remaining: 0s Progress 3162 / 9694 Time remaining: 0s Progress 3163 / 9694 Time remaining: 0s Progress 3164 / 9694 Time remaining: 0s Progress 3165 / 9694 Time remaining: 0s Progress 3166 / 9694 Time remaining: 0s Progress 3167 / 9694 Time remaining: 0s Progress 3168 / 9694 Time remaining: 0s Progress 3169 / 9694 Time remaining: 0s Progress 3170 / 9694 Time remaining: 0s Progress 3171 / 9694 Time remaining: 0s Progress 3172 / 9694 Time remaining: 0s Progress 3173 / 9694 Time remaining: 0s Progress 3174 / 9694 Time remaining: 0s Progress 3175 / 9694 Time remaining: 0s Progress 3176 / 9694 Time remaining: 0s Progress 3177 / 9694 Time remaining: 0s Progress 3178 / 9694 Time remaining: 0s Progress 3179 / 9694 Time remaining: 0s Progress 3180 / 9694 Time remaining: 0s Progress 3181 / 9694 Time remaining: 0s Progress 3182 / 9694 Time remaining: 0s Progress 3183 / 9694 Time remaining: 0s Progress 3184 / 9694 Time remaining: 0s Progress 3185 / 9694 Time remaining: 0s Progress 3186 / 9694 Time remaining: 0s Progress 3187 / 9694 Time remaining: 0s Progress 3188 / 9694 Time remaining: 0s Progress 3189 / 9694 Time remaining: 0s Progress 3190 / 9694 Time remaining: 0s Progress 3191 / 9694 Time remaining: 0s Progress 3192 / 9694 Time remaining: 0s Progress 3193 / 9694 Time remaining: 0s Progress 3194 / 9694 Time remaining: 0s Progress 3195 / 9694 Time remaining: 0s Progress 3196 / 9694 Time remaining: 0s Progress 3197 / 9694 Time remaining: 0s Progress 3198 / 9694 Time remaining: 0s Progress 3199 / 9694 Time remaining: 0s Progress 3200 / 9694 Time remaining: 0s Progress 3201 / 9694 Time remaining: 0s Progress 3202 / 9694 Time remaining: 0s Progress 3203 / 9694 Time remaining: 0s Progress 3204 / 9694 Time remaining: 0s Progress 3205 / 9694 Time remaining: 0s Progress 3206 / 9694 Time remaining: 0s Progress 3207 / 9694 Time remaining: 0s Progress 3208 / 9694 Time remaining: 0s Progress 3209 / 9694 Time remaining: 0s Progress 3210 / 9694 Time remaining: 0s Progress 3211 / 9694 Time remaining: 0s Progress 3212 / 9694 Time remaining: 0s Progress 3213 / 9694 Time remaining: 0s Progress 3214 / 9694 Time remaining: 0s Progress 3215 / 9694 Time remaining: 0s Progress 3216 / 9694 Time remaining: 0s Progress 3217 / 9694 Time remaining: 0s Progress 3218 / 9694 Time remaining: 0s Progress 3219 / 9694 Time remaining: 0s Progress 3220 / 9694 Time remaining: 0s Progress 3221 / 9694 Time remaining: 0s Progress 3222 / 9694 Time remaining: 0s Progress 3223 / 9694 Time remaining: 0s Progress 3224 / 9694 Time remaining: 0s Progress 3225 / 9694 Time remaining: 0s Progress 3226 / 9694 Time remaining: 0s Progress 3227 / 9694 Time remaining: 0s Progress 3228 / 9694 Time remaining: 0s Progress 3229 / 9694 Time remaining: 0s Progress 3230 / 9694 Time remaining: 0s Progress 3231 / 9694 Time remaining: 0s Progress 3232 / 9694 Time remaining: 0s Progress 3233 / 9694 Time remaining: 0s Progress 3234 / 9694 Time remaining: 0s Progress 3235 / 9694 Time remaining: 0s Progress 3236 / 9694 Time remaining: 0s Progress 3237 / 9694 Time remaining: 0s Progress 3238 / 9694 Time remaining: 0s Progress 3239 / 9694 Time remaining: 0s Progress 3240 / 9694 Time remaining: 0s Progress 3241 / 9694 Time remaining: 0s Progress 3242 / 9694 Time remaining: 0s Progress 3243 / 9694 Time remaining: 0s Progress 3244 / 9694 Time remaining: 0s Progress 3245 / 9694 Time remaining: 0s Progress 3246 / 9694 Time remaining: 0s Progress 3247 / 9694 Time remaining: 0s Progress 3248 / 9694 Time remaining: 0s Progress 3249 / 9694 Time remaining: 0s Progress 3250 / 9694 Time remaining: 0s Progress 3251 / 9694 Time remaining: 0s Progress 3252 / 9694 Time remaining: 0s Progress 3253 / 9694 Time remaining: 0s Progress 3254 / 9694 Time remaining: 0s Progress 3255 / 9694 Time remaining: 0s Progress 3256 / 9694 Time remaining: 0s Progress 3257 / 9694 Time remaining: 0s Progress 3258 / 9694 Time remaining: 0s Progress 3259 / 9694 Time remaining: 0s Progress 3260 / 9694 Time remaining: 0s Progress 3261 / 9694 Time remaining: 0s Progress 3262 / 9694 Time remaining: 0s Progress 3263 / 9694 Time remaining: 0s Progress 3264 / 9694 Time remaining: 0s Progress 3265 / 9694 Time remaining: 0s Progress 3266 / 9694 Time remaining: 0s Progress 3267 / 9694 Time remaining: 0s Progress 3268 / 9694 Time remaining: 0s Progress 3269 / 9694 Time remaining: 0s Progress 3270 / 9694 Time remaining: 0s Progress 3271 / 9694 Time remaining: 0s Progress 3272 / 9694 Time remaining: 0s Progress 3273 / 9694 Time remaining: 0s Progress 3274 / 9694 Time remaining: 0s Progress 3275 / 9694 Time remaining: 0s Progress 3276 / 9694 Time remaining: 0s Progress 3277 / 9694 Time remaining: 0s Progress 3278 / 9694 Time remaining: 0s Progress 3279 / 9694 Time remaining: 0s Progress 3280 / 9694 Time remaining: 0s Progress 3281 / 9694 Time remaining: 0s Progress 3282 / 9694 Time remaining: 0s Progress 3283 / 9694 Time remaining: 0s Progress 3284 / 9694 Time remaining: 0s Progress 3285 / 9694 Time remaining: 0s Progress 3286 / 9694 Time remaining: 0s Progress 3287 / 9694 Time remaining: 0s Progress 3288 / 9694 Time remaining: 0s Progress 3289 / 9694 Time remaining: 0s Progress 3290 / 9694 Time remaining: 0s Progress 3291 / 9694 Time remaining: 0s Progress 3292 / 9694 Time remaining: 0s Progress 3293 / 9694 Time remaining: 0s Progress 3294 / 9694 Time remaining: 0s Progress 3295 / 9694 Time remaining: 0s Progress 3296 / 9694 Time remaining: 0s Progress 3297 / 9694 Time remaining: 0s Progress 3298 / 9694 Time remaining: 0s Progress 3299 / 9694 Time remaining: 0s Progress 3300 / 9694 Time remaining: 0s Progress 3301 / 9694 Time remaining: 0s Progress 3302 / 9694 Time remaining: 0s Progress 3303 / 9694 Time remaining: 0s Progress 3304 / 9694 Time remaining: 0s Progress 3305 / 9694 Time remaining: 0s Progress 3306 / 9694 Time remaining: 0s Progress 3307 / 9694 Time remaining: 0s Progress 3308 / 9694 Time remaining: 0s Progress 3309 / 9694 Time remaining: 0s Progress 3310 / 9694 Time remaining: 0s Progress 3311 / 9694 Time remaining: 0s Progress 3312 / 9694 Time remaining: 0s Progress 3313 / 9694 Time remaining: 0s Progress 3314 / 9694 Time remaining: 0s Progress 3315 / 9694 Time remaining: 0s Progress 3316 / 9694 Time remaining: 0s Progress 3317 / 9694 Time remaining: 0s Progress 3318 / 9694 Time remaining: 0s Progress 3319 / 9694 Time remaining: 0s Progress 3320 / 9694 Time remaining: 0s Progress 3321 / 9694 Time remaining: 0s Progress 3322 / 9694 Time remaining: 0s Progress 3323 / 9694 Time remaining: 0s Progress 3324 / 9694 Time remaining: 0s Progress 3325 / 9694 Time remaining: 0s Progress 3326 / 9694 Time remaining: 0s Progress 3327 / 9694 Time remaining: 0s Progress 3328 / 9694 Time remaining: 0s Progress 3329 / 9694 Time remaining: 0s Progress 3330 / 9694 Time remaining: 0s Progress 3331 / 9694 Time remaining: 0s Progress 3332 / 9694 Time remaining: 0s Progress 3333 / 9694 Time remaining: 0s Progress 3334 / 9694 Time remaining: 0s Progress 3335 / 9694 Time remaining: 0s Progress 3336 / 9694 Time remaining: 0s Progress 3337 / 9694 Time remaining: 0s Progress 3338 / 9694 Time remaining: 0s Progress 3339 / 9694 Time remaining: 0s Progress 3340 / 9694 Time remaining: 0s Progress 3341 / 9694 Time remaining: 0s Progress 3342 / 9694 Time remaining: 0s Progress 3343 / 9694 Time remaining: 0s Progress 3344 / 9694 Time remaining: 0s Progress 3345 / 9694 Time remaining: 0s Progress 3346 / 9694 Time remaining: 0s Progress 3347 / 9694 Time remaining: 0s Progress 3348 / 9694 Time remaining: 0s Progress 3349 / 9694 Time remaining: 0s Progress 3350 / 9694 Time remaining: 0s Progress 3351 / 9694 Time remaining: 0s Progress 3352 / 9694 Time remaining: 0s Progress 3353 / 9694 Time remaining: 0s Progress 3354 / 9694 Time remaining: 0s Progress 3355 / 9694 Time remaining: 0s Progress 3356 / 9694 Time remaining: 0s Progress 3357 / 9694 Time remaining: 0s Progress 3358 / 9694 Time remaining: 0s Progress 3359 / 9694 Time remaining: 0s Progress 3360 / 9694 Time remaining: 0s Progress 3361 / 9694 Time remaining: 0s Progress 3362 / 9694 Time remaining: 0s Progress 3363 / 9694 Time remaining: 0s Progress 3364 / 9694 Time remaining: 0s Progress 3365 / 9694 Time remaining: 0s Progress 3366 / 9694 Time remaining: 0s Progress 3367 / 9694 Time remaining: 0s Progress 3368 / 9694 Time remaining: 0s Progress 3369 / 9694 Time remaining: 0s Progress 3370 / 9694 Time remaining: 0s Progress 3371 / 9694 Time remaining: 0s Progress 3372 / 9694 Time remaining: 0s Progress 3373 / 9694 Time remaining: 0s Progress 3374 / 9694 Time remaining: 0s Progress 3375 / 9694 Time remaining: 0s Progress 3376 / 9694 Time remaining: 0s Progress 3377 / 9694 Time remaining: 0s Progress 3378 / 9694 Time remaining: 0s Progress 3379 / 9694 Time remaining: 0s Progress 3380 / 9694 Time remaining: 0s Progress 3381 / 9694 Time remaining: 0s Progress 3382 / 9694 Time remaining: 0s Progress 3383 / 9694 Time remaining: 0s Progress 3384 / 9694 Time remaining: 0s Progress 3385 / 9694 Time remaining: 0s Progress 3386 / 9694 Time remaining: 0s Progress 3387 / 9694 Time remaining: 0s Progress 3388 / 9694 Time remaining: 0s Progress 3389 / 9694 Time remaining: 0s Progress 3390 / 9694 Time remaining: 0s Progress 3391 / 9694 Time remaining: 0s Progress 3392 / 9694 Time remaining: 0s Progress 3393 / 9694 Time remaining: 0s Progress 3394 / 9694 Time remaining: 0s Progress 3395 / 9694 Time remaining: 0s Progress 3396 / 9694 Time remaining: 0s Progress 3397 / 9694 Time remaining: 0s Progress 3398 / 9694 Time remaining: 0s Progress 3399 / 9694 Time remaining: 0s Progress 3400 / 9694 Time remaining: 0s Progress 3401 / 9694 Time remaining: 0s Progress 3402 / 9694 Time remaining: 0s Progress 3403 / 9694 Time remaining: 0s Progress 3404 / 9694 Time remaining: 0s Progress 3405 / 9694 Time remaining: 0s Progress 3406 / 9694 Time remaining: 0s Progress 3407 / 9694 Time remaining: 0s Progress 3408 / 9694 Time remaining: 0s Progress 3409 / 9694 Time remaining: 0s Progress 3410 / 9694 Time remaining: 0s Progress 3411 / 9694 Time remaining: 0s Progress 3412 / 9694 Time remaining: 0s Progress 3413 / 9694 Time remaining: 0s Progress 3414 / 9694 Time remaining: 0s Progress 3415 / 9694 Time remaining: 0s Progress 3416 / 9694 Time remaining: 0s Progress 3417 / 9694 Time remaining: 0s Progress 3418 / 9694 Time remaining: 0s Progress 3419 / 9694 Time remaining: 0s Progress 3420 / 9694 Time remaining: 0s Progress 3421 / 9694 Time remaining: 0s Progress 3422 / 9694 Time remaining: 0s Progress 3423 / 9694 Time remaining: 0s Progress 3424 / 9694 Time remaining: 0s Progress 3425 / 9694 Time remaining: 0s Progress 3426 / 9694 Time remaining: 0s Progress 3427 / 9694 Time remaining: 0s Progress 3428 / 9694 Time remaining: 0s Progress 3429 / 9694 Time remaining: 0s Progress 3430 / 9694 Time remaining: 0s Progress 3431 / 9694 Time remaining: 0s Progress 3432 / 9694 Time remaining: 0s Progress 3433 / 9694 Time remaining: 0s Progress 3434 / 9694 Time remaining: 0s Progress 3435 / 9694 Time remaining: 0s Progress 3436 / 9694 Time remaining: 0s Progress 3437 / 9694 Time remaining: 0s Progress 3438 / 9694 Time remaining: 0s Progress 3439 / 9694 Time remaining: 0s Progress 3440 / 9694 Time remaining: 0s Progress 3441 / 9694 Time remaining: 0s Progress 3442 / 9694 Time remaining: 0s Progress 3443 / 9694 Time remaining: 0s Progress 3444 / 9694 Time remaining: 0s Progress 3445 / 9694 Time remaining: 0s Progress 3446 / 9694 Time remaining: 0s Progress 3447 / 9694 Time remaining: 0s Progress 3448 / 9694 Time remaining: 0s Progress 3449 / 9694 Time remaining: 0s Progress 3450 / 9694 Time remaining: 0s Progress 3451 / 9694 Time remaining: 0s Progress 3452 / 9694 Time remaining: 0s Progress 3453 / 9694 Time remaining: 0s Progress 3454 / 9694 Time remaining: 0s Progress 3455 / 9694 Time remaining: 0s Progress 3456 / 9694 Time remaining: 0s Progress 3457 / 9694 Time remaining: 0s Progress 3458 / 9694 Time remaining: 0s Progress 3459 / 9694 Time remaining: 0s Progress 3460 / 9694 Time remaining: 0s Progress 3461 / 9694 Time remaining: 0s Progress 3462 / 9694 Time remaining: 0s Progress 3463 / 9694 Time remaining: 0s Progress 3464 / 9694 Time remaining: 0s Progress 3465 / 9694 Time remaining: 0s Progress 3466 / 9694 Time remaining: 0s Progress 3467 / 9694 Time remaining: 0s Progress 3468 / 9694 Time remaining: 0s Progress 3469 / 9694 Time remaining: 0s Progress 3470 / 9694 Time remaining: 0s Progress 3471 / 9694 Time remaining: 0s Progress 3472 / 9694 Time remaining: 0s Progress 3473 / 9694 Time remaining: 0s Progress 3474 / 9694 Time remaining: 0s Progress 3475 / 9694 Time remaining: 0s Progress 3476 / 9694 Time remaining: 0s Progress 3477 / 9694 Time remaining: 0s Progress 3478 / 9694 Time remaining: 0s Progress 3479 / 9694 Time remaining: 0s Progress 3480 / 9694 Time remaining: 0s Progress 3481 / 9694 Time remaining: 0s Progress 3482 / 9694 Time remaining: 0s Progress 3483 / 9694 Time remaining: 0s Progress 3484 / 9694 Time remaining: 0s Progress 3485 / 9694 Time remaining: 0s Progress 3486 / 9694 Time remaining: 0s Progress 3487 / 9694 Time remaining: 0s Progress 3488 / 9694 Time remaining: 0s Progress 3489 / 9694 Time remaining: 0s Progress 3490 / 9694 Time remaining: 0s Progress 3491 / 9694 Time remaining: 0s Progress 3492 / 9694 Time remaining: 0s Progress 3493 / 9694 Time remaining: 0s Progress 3494 / 9694 Time remaining: 0s Progress 3495 / 9694 Time remaining: 0s Progress 3496 / 9694 Time remaining: 0s Progress 3497 / 9694 Time remaining: 0s Progress 3498 / 9694 Time remaining: 0s Progress 3499 / 9694 Time remaining: 0s Progress 3500 / 9694 Time remaining: 0s Progress 3501 / 9694 Time remaining: 0s Progress 3502 / 9694 Time remaining: 0s Progress 3503 / 9694 Time remaining: 0s Progress 3504 / 9694 Time remaining: 0s Progress 3505 / 9694 Time remaining: 0s Progress 3506 / 9694 Time remaining: 0s Progress 3507 / 9694 Time remaining: 0s Progress 3508 / 9694 Time remaining: 0s Progress 3509 / 9694 Time remaining: 0s Progress 3510 / 9694 Time remaining: 0s Progress 3511 / 9694 Time remaining: 0s Progress 3512 / 9694 Time remaining: 0s Progress 3513 / 9694 Time remaining: 0s Progress 3514 / 9694 Time remaining: 0s Progress 3515 / 9694 Time remaining: 0s Progress 3516 / 9694 Time remaining: 0s Progress 3517 / 9694 Time remaining: 0s Progress 3518 / 9694 Time remaining: 0s Progress 3519 / 9694 Time remaining: 0s Progress 3520 / 9694 Time remaining: 0s Progress 3521 / 9694 Time remaining: 0s Progress 3522 / 9694 Time remaining: 0s Progress 3523 / 9694 Time remaining: 0s Progress 3524 / 9694 Time remaining: 0s Progress 3525 / 9694 Time remaining: 0s Progress 3526 / 9694 Time remaining: 0s Progress 3527 / 9694 Time remaining: 0s Progress 3528 / 9694 Time remaining: 0s Progress 3529 / 9694 Time remaining: 0s Progress 3530 / 9694 Time remaining: 0s Progress 3531 / 9694 Time remaining: 0s Progress 3532 / 9694 Time remaining: 0s Progress 3533 / 9694 Time remaining: 0s Progress 3534 / 9694 Time remaining: 0s Progress 3535 / 9694 Time remaining: 0s Progress 3536 / 9694 Time remaining: 0s Progress 3537 / 9694 Time remaining: 0s Progress 3538 / 9694 Time remaining: 0s Progress 3539 / 9694 Time remaining: 0s Progress 3540 / 9694 Time remaining: 0s Progress 3541 / 9694 Time remaining: 0s Progress 3542 / 9694 Time remaining: 0s Progress 3543 / 9694 Time remaining: 0s Progress 3544 / 9694 Time remaining: 0s Progress 3545 / 9694 Time remaining: 0s Progress 3546 / 9694 Time remaining: 0s Progress 3547 / 9694 Time remaining: 0s Progress 3548 / 9694 Time remaining: 0s Progress 3549 / 9694 Time remaining: 0s Progress 3550 / 9694 Time remaining: 0s Progress 3551 / 9694 Time remaining: 0s Progress 3552 / 9694 Time remaining: 0s Progress 3553 / 9694 Time remaining: 0s Progress 3554 / 9694 Time remaining: 0s Progress 3555 / 9694 Time remaining: 0s Progress 3556 / 9694 Time remaining: 0s Progress 3557 / 9694 Time remaining: 0s Progress 3558 / 9694 Time remaining: 0s Progress 3559 / 9694 Time remaining: 0s Progress 3560 / 9694 Time remaining: 0s Progress 3561 / 9694 Time remaining: 0s Progress 3562 / 9694 Time remaining: 0s Progress 3563 / 9694 Time remaining: 0s Progress 3564 / 9694 Time remaining: 0s Progress 3565 / 9694 Time remaining: 0s Progress 3566 / 9694 Time remaining: 0s Progress 3567 / 9694 Time remaining: 0s Progress 3568 / 9694 Time remaining: 0s Progress 3569 / 9694 Time remaining: 0s Progress 3570 / 9694 Time remaining: 0s Progress 3571 / 9694 Time remaining: 0s Progress 3572 / 9694 Time remaining: 0s Progress 3573 / 9694 Time remaining: 0s Progress 3574 / 9694 Time remaining: 0s Progress 3575 / 9694 Time remaining: 0s Progress 3576 / 9694 Time remaining: 0s Progress 3577 / 9694 Time remaining: 0s Progress 3578 / 9694 Time remaining: 0s Progress 3579 / 9694 Time remaining: 0s Progress 3580 / 9694 Time remaining: 0s Progress 3581 / 9694 Time remaining: 0s Progress 3582 / 9694 Time remaining: 0s Progress 3583 / 9694 Time remaining: 0s Progress 3584 / 9694 Time remaining: 0s Progress 3585 / 9694 Time remaining: 0s Progress 3586 / 9694 Time remaining: 0s Progress 3587 / 9694 Time remaining: 0s Progress 3588 / 9694 Time remaining: 0s Progress 3589 / 9694 Time remaining: 0s Progress 3590 / 9694 Time remaining: 0s Progress 3591 / 9694 Time remaining: 0s Progress 3592 / 9694 Time remaining: 0s Progress 3593 / 9694 Time remaining: 0s Progress 3594 / 9694 Time remaining: 0s Progress 3595 / 9694 Time remaining: 0s Progress 3596 / 9694 Time remaining: 0s Progress 3597 / 9694 Time remaining: 0s Progress 3598 / 9694 Time remaining: 0s Progress 3599 / 9694 Time remaining: 0s Progress 3600 / 9694 Time remaining: 0s Progress 3601 / 9694 Time remaining: 0s Progress 3602 / 9694 Time remaining: 0s Progress 3603 / 9694 Time remaining: 0s Progress 3604 / 9694 Time remaining: 0s Progress 3605 / 9694 Time remaining: 0s Progress 3606 / 9694 Time remaining: 0s Progress 3607 / 9694 Time remaining: 0s Progress 3608 / 9694 Time remaining: 0s Progress 3609 / 9694 Time remaining: 0s Progress 3610 / 9694 Time remaining: 0s Progress 3611 / 9694 Time remaining: 0s Progress 3612 / 9694 Time remaining: 0s Progress 3613 / 9694 Time remaining: 0s Progress 3614 / 9694 Time remaining: 0s Progress 3615 / 9694 Time remaining: 0s Progress 3616 / 9694 Time remaining: 0s Progress 3617 / 9694 Time remaining: 0s Progress 3618 / 9694 Time remaining: 0s Progress 3619 / 9694 Time remaining: 0s Progress 3620 / 9694 Time remaining: 0s Progress 3621 / 9694 Time remaining: 0s Progress 3622 / 9694 Time remaining: 0s Progress 3623 / 9694 Time remaining: 0s Progress 3624 / 9694 Time remaining: 0s Progress 3625 / 9694 Time remaining: 0s Progress 3626 / 9694 Time remaining: 0s Progress 3627 / 9694 Time remaining: 0s Progress 3628 / 9694 Time remaining: 0s Progress 3629 / 9694 Time remaining: 0s Progress 3630 / 9694 Time remaining: 0s Progress 3631 / 9694 Time remaining: 0s Progress 3632 / 9694 Time remaining: 0s Progress 3633 / 9694 Time remaining: 0s Progress 3634 / 9694 Time remaining: 0s Progress 3635 / 9694 Time remaining: 0s Progress 3636 / 9694 Time remaining: 0s Progress 3637 / 9694 Time remaining: 0s Progress 3638 / 9694 Time remaining: 0s Progress 3639 / 9694 Time remaining: 0s Progress 3640 / 9694 Time remaining: 0s Progress 3641 / 9694 Time remaining: 0s Progress 3642 / 9694 Time remaining: 0s Progress 3643 / 9694 Time remaining: 0s Progress 3644 / 9694 Time remaining: 0s Progress 3645 / 9694 Time remaining: 0s Progress 3646 / 9694 Time remaining: 0s Progress 3647 / 9694 Time remaining: 0s Progress 3648 / 9694 Time remaining: 0s Progress 3649 / 9694 Time remaining: 0s Progress 3650 / 9694 Time remaining: 0s Progress 3651 / 9694 Time remaining: 0s Progress 3652 / 9694 Time remaining: 0s Progress 3653 / 9694 Time remaining: 0s Progress 3654 / 9694 Time remaining: 0s Progress 3655 / 9694 Time remaining: 0s Progress 3656 / 9694 Time remaining: 0s Progress 3657 / 9694 Time remaining: 0s Progress 3658 / 9694 Time remaining: 0s Progress 3659 / 9694 Time remaining: 0s Progress 3660 / 9694 Time remaining: 0s Progress 3661 / 9694 Time remaining: 0s Progress 3662 / 9694 Time remaining: 0s Progress 3663 / 9694 Time remaining: 0s Progress 3664 / 9694 Time remaining: 0s Progress 3665 / 9694 Time remaining: 0s Progress 3666 / 9694 Time remaining: 0s Progress 3667 / 9694 Time remaining: 0s Progress 3668 / 9694 Time remaining: 0s Progress 3669 / 9694 Time remaining: 0s Progress 3670 / 9694 Time remaining: 0s Progress 3671 / 9694 Time remaining: 0s Progress 3672 / 9694 Time remaining: 0s Progress 3673 / 9694 Time remaining: 0s Progress 3674 / 9694 Time remaining: 0s Progress 3675 / 9694 Time remaining: 0s Progress 3676 / 9694 Time remaining: 0s Progress 3677 / 9694 Time remaining: 0s Progress 3678 / 9694 Time remaining: 0s Progress 3679 / 9694 Time remaining: 0s Progress 3680 / 9694 Time remaining: 0s Progress 3681 / 9694 Time remaining: 0s Progress 3682 / 9694 Time remaining: 0s Progress 3683 / 9694 Time remaining: 0s Progress 3684 / 9694 Time remaining: 0s Progress 3685 / 9694 Time remaining: 0s Progress 3686 / 9694 Time remaining: 0s Progress 3687 / 9694 Time remaining: 0s Progress 3688 / 9694 Time remaining: 0s Progress 3689 / 9694 Time remaining: 0s Progress 3690 / 9694 Time remaining: 0s Progress 3691 / 9694 Time remaining: 0s Progress 3692 / 9694 Time remaining: 0s Progress 3693 / 9694 Time remaining: 0s Progress 3694 / 9694 Time remaining: 0s Progress 3695 / 9694 Time remaining: 0s Progress 3696 / 9694 Time remaining: 0s Progress 3697 / 9694 Time remaining: 0s Progress 3698 / 9694 Time remaining: 0s Progress 3699 / 9694 Time remaining: 0s Progress 3700 / 9694 Time remaining: 0s Progress 3701 / 9694 Time remaining: 0s Progress 3702 / 9694 Time remaining: 0s Progress 3703 / 9694 Time remaining: 0s Progress 3704 / 9694 Time remaining: 0s Progress 3705 / 9694 Time remaining: 0s Progress 3706 / 9694 Time remaining: 0s Progress 3707 / 9694 Time remaining: 0s Progress 3708 / 9694 Time remaining: 0s Progress 3709 / 9694 Time remaining: 0s Progress 3710 / 9694 Time remaining: 0s Progress 3711 / 9694 Time remaining: 0s Progress 3712 / 9694 Time remaining: 0s Progress 3713 / 9694 Time remaining: 0s Progress 3714 / 9694 Time remaining: 0s Progress 3715 / 9694 Time remaining: 0s Progress 3716 / 9694 Time remaining: 0s Progress 3717 / 9694 Time remaining: 0s Progress 3718 / 9694 Time remaining: 0s Progress 3719 / 9694 Time remaining: 0s Progress 3720 / 9694 Time remaining: 0s Progress 3721 / 9694 Time remaining: 0s Progress 3722 / 9694 Time remaining: 0s Progress 3723 / 9694 Time remaining: 0s Progress 3724 / 9694 Time remaining: 0s Progress 3725 / 9694 Time remaining: 0s Progress 3726 / 9694 Time remaining: 0s Progress 3727 / 9694 Time remaining: 0s Progress 3728 / 9694 Time remaining: 0s Progress 3729 / 9694 Time remaining: 0s Progress 3730 / 9694 Time remaining: 0s Progress 3731 / 9694 Time remaining: 0s Progress 3732 / 9694 Time remaining: 0s Progress 3733 / 9694 Time remaining: 0s Progress 3734 / 9694 Time remaining: 0s Progress 3735 / 9694 Time remaining: 0s Progress 3736 / 9694 Time remaining: 0s Progress 3737 / 9694 Time remaining: 0s Progress 3738 / 9694 Time remaining: 0s Progress 3739 / 9694 Time remaining: 0s Progress 3740 / 9694 Time remaining: 0s Progress 3741 / 9694 Time remaining: 0s Progress 3742 / 9694 Time remaining: 0s Progress 3743 / 9694 Time remaining: 0s Progress 3744 / 9694 Time remaining: 0s Progress 3745 / 9694 Time remaining: 0s Progress 3746 / 9694 Time remaining: 0s Progress 3747 / 9694 Time remaining: 0s Progress 3748 / 9694 Time remaining: 0s Progress 3749 / 9694 Time remaining: 0s Progress 3750 / 9694 Time remaining: 0s Progress 3751 / 9694 Time remaining: 0s Progress 3752 / 9694 Time remaining: 0s Progress 3753 / 9694 Time remaining: 0s Progress 3754 / 9694 Time remaining: 0s Progress 3755 / 9694 Time remaining: 0s Progress 3756 / 9694 Time remaining: 0s Progress 3757 / 9694 Time remaining: 0s Progress 3758 / 9694 Time remaining: 0s Progress 3759 / 9694 Time remaining: 0s Progress 3760 / 9694 Time remaining: 0s Progress 3761 / 9694 Time remaining: 0s Progress 3762 / 9694 Time remaining: 0s Progress 3763 / 9694 Time remaining: 0s Progress 3764 / 9694 Time remaining: 0s Progress 3765 / 9694 Time remaining: 0s Progress 3766 / 9694 Time remaining: 0s Progress 3767 / 9694 Time remaining: 0s Progress 3768 / 9694 Time remaining: 0s Progress 3769 / 9694 Time remaining: 0s Progress 3770 / 9694 Time remaining: 0s Progress 3771 / 9694 Time remaining: 0s Progress 3772 / 9694 Time remaining: 0s Progress 3773 / 9694 Time remaining: 0s Progress 3774 / 9694 Time remaining: 0s Progress 3775 / 9694 Time remaining: 0s Progress 3776 / 9694 Time remaining: 0s Progress 3777 / 9694 Time remaining: 0s Progress 3778 / 9694 Time remaining: 0s Progress 3779 / 9694 Time remaining: 0s Progress 3780 / 9694 Time remaining: 0s Progress 3781 / 9694 Time remaining: 0s Progress 3782 / 9694 Time remaining: 0s Progress 3783 / 9694 Time remaining: 0s Progress 3784 / 9694 Time remaining: 0s Progress 3785 / 9694 Time remaining: 0s Progress 3786 / 9694 Time remaining: 0s Progress 3787 / 9694 Time remaining: 0s Progress 3788 / 9694 Time remaining: 0s Progress 3789 / 9694 Time remaining: 0s Progress 3790 / 9694 Time remaining: 0s Progress 3791 / 9694 Time remaining: 0s Progress 3792 / 9694 Time remaining: 0s Progress 3793 / 9694 Time remaining: 0s Progress 3794 / 9694 Time remaining: 0s Progress 3795 / 9694 Time remaining: 0s Progress 3796 / 9694 Time remaining: 0s Progress 3797 / 9694 Time remaining: 0s Progress 3798 / 9694 Time remaining: 0s Progress 3799 / 9694 Time remaining: 0s Progress 3800 / 9694 Time remaining: 0s Progress 3801 / 9694 Time remaining: 0s Progress 3802 / 9694 Time remaining: 0s Progress 3803 / 9694 Time remaining: 0s Progress 3804 / 9694 Time remaining: 0s Progress 3805 / 9694 Time remaining: 0s Progress 3806 / 9694 Time remaining: 0s Progress 3807 / 9694 Time remaining: 0s Progress 3808 / 9694 Time remaining: 0s Progress 3809 / 9694 Time remaining: 0s Progress 3810 / 9694 Time remaining: 0s Progress 3811 / 9694 Time remaining: 0s Progress 3812 / 9694 Time remaining: 0s Progress 3813 / 9694 Time remaining: 0s Progress 3814 / 9694 Time remaining: 0s Progress 3815 / 9694 Time remaining: 0s Progress 3816 / 9694 Time remaining: 0s Progress 3817 / 9694 Time remaining: 0s Progress 3818 / 9694 Time remaining: 0s Progress 3819 / 9694 Time remaining: 0s Progress 3820 / 9694 Time remaining: 0s Progress 3821 / 9694 Time remaining: 0s Progress 3822 / 9694 Time remaining: 0s Progress 3823 / 9694 Time remaining: 0s Progress 3824 / 9694 Time remaining: 0s Progress 3825 / 9694 Time remaining: 0s Progress 3826 / 9694 Time remaining: 0s Progress 3827 / 9694 Time remaining: 0s Progress 3828 / 9694 Time remaining: 0s Progress 3829 / 9694 Time remaining: 0s Progress 3830 / 9694 Time remaining: 0s Progress 3831 / 9694 Time remaining: 0s Progress 3832 / 9694 Time remaining: 0s Progress 3833 / 9694 Time remaining: 0s Progress 3834 / 9694 Time remaining: 0s Progress 3835 / 9694 Time remaining: 0s Progress 3836 / 9694 Time remaining: 0s Progress 3837 / 9694 Time remaining: 0s Progress 3838 / 9694 Time remaining: 0s Progress 3839 / 9694 Time remaining: 0s Progress 3840 / 9694 Time remaining: 0s Progress 3841 / 9694 Time remaining: 0s Progress 3842 / 9694 Time remaining: 0s Progress 3843 / 9694 Time remaining: 0s Progress 3844 / 9694 Time remaining: 0s Progress 3845 / 9694 Time remaining: 0s Progress 3846 / 9694 Time remaining: 0s Progress 3847 / 9694 Time remaining: 0s Progress 3848 / 9694 Time remaining: 0s Progress 3849 / 9694 Time remaining: 0s Progress 3850 / 9694 Time remaining: 0s Progress 3851 / 9694 Time remaining: 0s Progress 3852 / 9694 Time remaining: 0s Progress 3853 / 9694 Time remaining: 0s Progress 3854 / 9694 Time remaining: 0s Progress 3855 / 9694 Time remaining: 0s Progress 3856 / 9694 Time remaining: 0s Progress 3857 / 9694 Time remaining: 0s Progress 3858 / 9694 Time remaining: 0s Progress 3859 / 9694 Time remaining: 0s Progress 3860 / 9694 Time remaining: 0s Progress 3861 / 9694 Time remaining: 0s Progress 3862 / 9694 Time remaining: 0s Progress 3863 / 9694 Time remaining: 0s Progress 3864 / 9694 Time remaining: 0s Progress 3865 / 9694 Time remaining: 0s Progress 3866 / 9694 Time remaining: 0s Progress 3867 / 9694 Time remaining: 0s Progress 3868 / 9694 Time remaining: 0s Progress 3869 / 9694 Time remaining: 0s Progress 3870 / 9694 Time remaining: 0s Progress 3871 / 9694 Time remaining: 0s Progress 3872 / 9694 Time remaining: 0s Progress 3873 / 9694 Time remaining: 0s Progress 3874 / 9694 Time remaining: 0s Progress 3875 / 9694 Time remaining: 0s Progress 3876 / 9694 Time remaining: 0s Progress 3877 / 9694 Time remaining: 0s Progress 3878 / 9694 Time remaining: 0s Progress 3879 / 9694 Time remaining: 0s Progress 3880 / 9694 Time remaining: 0s Progress 3881 / 9694 Time remaining: 0s Progress 3882 / 9694 Time remaining: 0s Progress 3883 / 9694 Time remaining: 0s Progress 3884 / 9694 Time remaining: 0s Progress 3885 / 9694 Time remaining: 0s Progress 3886 / 9694 Time remaining: 0s Progress 3887 / 9694 Time remaining: 0s Progress 3888 / 9694 Time remaining: 0s Progress 3889 / 9694 Time remaining: 0s Progress 3890 / 9694 Time remaining: 0s Progress 3891 / 9694 Time remaining: 0s Progress 3892 / 9694 Time remaining: 0s Progress 3893 / 9694 Time remaining: 0s Progress 3894 / 9694 Time remaining: 0s Progress 3895 / 9694 Time remaining: 0s Progress 3896 / 9694 Time remaining: 0s Progress 3897 / 9694 Time remaining: 0s Progress 3898 / 9694 Time remaining: 0s Progress 3899 / 9694 Time remaining: 0s Progress 3900 / 9694 Time remaining: 0s Progress 3901 / 9694 Time remaining: 0s Progress 3902 / 9694 Time remaining: 0s Progress 3903 / 9694 Time remaining: 0s Progress 3904 / 9694 Time remaining: 0s Progress 3905 / 9694 Time remaining: 0s Progress 3906 / 9694 Time remaining: 0s Progress 3907 / 9694 Time remaining: 0s Progress 3908 / 9694 Time remaining: 0s Progress 3909 / 9694 Time remaining: 0s Progress 3910 / 9694 Time remaining: 0s Progress 3911 / 9694 Time remaining: 0s Progress 3912 / 9694 Time remaining: 0s Progress 3913 / 9694 Time remaining: 0s Progress 3914 / 9694 Time remaining: 0s Progress 3915 / 9694 Time remaining: 0s Progress 3916 / 9694 Time remaining: 0s Progress 3917 / 9694 Time remaining: 0s Progress 3918 / 9694 Time remaining: 0s Progress 3919 / 9694 Time remaining: 0s Progress 3920 / 9694 Time remaining: 0s Progress 3921 / 9694 Time remaining: 0s Progress 3922 / 9694 Time remaining: 0s Progress 3923 / 9694 Time remaining: 0s Progress 3924 / 9694 Time remaining: 0s Progress 3925 / 9694 Time remaining: 0s Progress 3926 / 9694 Time remaining: 0s Progress 3927 / 9694 Time remaining: 0s Progress 3928 / 9694 Time remaining: 0s Progress 3929 / 9694 Time remaining: 0s Progress 3930 / 9694 Time remaining: 0s Progress 3931 / 9694 Time remaining: 0s Progress 3932 / 9694 Time remaining: 0s Progress 3933 / 9694 Time remaining: 0s Progress 3934 / 9694 Time remaining: 0s Progress 3935 / 9694 Time remaining: 0s Progress 3936 / 9694 Time remaining: 0s Progress 3937 / 9694 Time remaining: 0s Progress 3938 / 9694 Time remaining: 0s Progress 3939 / 9694 Time remaining: 0s Progress 3940 / 9694 Time remaining: 0s Progress 3941 / 9694 Time remaining: 0s Progress 3942 / 9694 Time remaining: 0s Progress 3943 / 9694 Time remaining: 0s Progress 3944 / 9694 Time remaining: 0s Progress 3945 / 9694 Time remaining: 0s Progress 3946 / 9694 Time remaining: 0s Progress 3947 / 9694 Time remaining: 0s Progress 3948 / 9694 Time remaining: 0s Progress 3949 / 9694 Time remaining: 0s Progress 3950 / 9694 Time remaining: 0s Progress 3951 / 9694 Time remaining: 0s Progress 3952 / 9694 Time remaining: 0s Progress 3953 / 9694 Time remaining: 0s Progress 3954 / 9694 Time remaining: 0s Progress 3955 / 9694 Time remaining: 0s Progress 3956 / 9694 Time remaining: 0s Progress 3957 / 9694 Time remaining: 0s Progress 3958 / 9694 Time remaining: 0s Progress 3959 / 9694 Time remaining: 0s Progress 3960 / 9694 Time remaining: 0s Progress 3961 / 9694 Time remaining: 0s Progress 3962 / 9694 Time remaining: 0s Progress 3963 / 9694 Time remaining: 0s Progress 3964 / 9694 Time remaining: 0s Progress 3965 / 9694 Time remaining: 0s Progress 3966 / 9694 Time remaining: 0s Progress 3967 / 9694 Time remaining: 0s Progress 3968 / 9694 Time remaining: 0s Progress 3969 / 9694 Time remaining: 0s Progress 3970 / 9694 Time remaining: 0s Progress 3971 / 9694 Time remaining: 0s Progress 3972 / 9694 Time remaining: 0s Progress 3973 / 9694 Time remaining: 0s Progress 3974 / 9694 Time remaining: 0s Progress 3975 / 9694 Time remaining: 0s Progress 3976 / 9694 Time remaining: 0s Progress 3977 / 9694 Time remaining: 0s Progress 3978 / 9694 Time remaining: 0s Progress 3979 / 9694 Time remaining: 0s Progress 3980 / 9694 Time remaining: 0s Progress 3981 / 9694 Time remaining: 0s Progress 3982 / 9694 Time remaining: 0s Progress 3983 / 9694 Time remaining: 0s Progress 3984 / 9694 Time remaining: 0s Progress 3985 / 9694 Time remaining: 0s Progress 3986 / 9694 Time remaining: 0s Progress 3987 / 9694 Time remaining: 0s Progress 3988 / 9694 Time remaining: 0s Progress 3989 / 9694 Time remaining: 0s Progress 3990 / 9694 Time remaining: 0s Progress 3991 / 9694 Time remaining: 0s Progress 3992 / 9694 Time remaining: 0s Progress 3993 / 9694 Time remaining: 0s Progress 3994 / 9694 Time remaining: 0s Progress 3995 / 9694 Time remaining: 0s Progress 3996 / 9694 Time remaining: 0s Progress 3997 / 9694 Time remaining: 0s Progress 3998 / 9694 Time remaining: 0s Progress 3999 / 9694 Time remaining: 0s Progress 4000 / 9694 Time remaining: 0s Progress 4001 / 9694 Time remaining: 0s Progress 4002 / 9694 Time remaining: 0s Progress 4003 / 9694 Time remaining: 0s Progress 4004 / 9694 Time remaining: 0s Progress 4005 / 9694 Time remaining: 0s Progress 4006 / 9694 Time remaining: 0s Progress 4007 / 9694 Time remaining: 0s Progress 4008 / 9694 Time remaining: 0s Progress 4009 / 9694 Time remaining: 0s Progress 4010 / 9694 Time remaining: 0s Progress 4011 / 9694 Time remaining: 0s Progress 4012 / 9694 Time remaining: 0s Progress 4013 / 9694 Time remaining: 0s Progress 4014 / 9694 Time remaining: 0s Progress 4015 / 9694 Time remaining: 0s Progress 4016 / 9694 Time remaining: 0s Progress 4017 / 9694 Time remaining: 0s Progress 4018 / 9694 Time remaining: 0s Progress 4019 / 9694 Time remaining: 0s Progress 4020 / 9694 Time remaining: 0s Progress 4021 / 9694 Time remaining: 0s Progress 4022 / 9694 Time remaining: 0s Progress 4023 / 9694 Time remaining: 0s Progress 4024 / 9694 Time remaining: 0s Progress 4025 / 9694 Time remaining: 0s Progress 4026 / 9694 Time remaining: 0s Progress 4027 / 9694 Time remaining: 0s Progress 4028 / 9694 Time remaining: 0s Progress 4029 / 9694 Time remaining: 0s Progress 4030 / 9694 Time remaining: 0s Progress 4031 / 9694 Time remaining: 0s Progress 4032 / 9694 Time remaining: 0s Progress 4033 / 9694 Time remaining: 0s Progress 4034 / 9694 Time remaining: 0s Progress 4035 / 9694 Time remaining: 0s Progress 4036 / 9694 Time remaining: 0s Progress 4037 / 9694 Time remaining: 0s Progress 4038 / 9694 Time remaining: 0s Progress 4039 / 9694 Time remaining: 0s Progress 4040 / 9694 Time remaining: 0s Progress 4041 / 9694 Time remaining: 0s Progress 4042 / 9694 Time remaining: 0s Progress 4043 / 9694 Time remaining: 0s Progress 4044 / 9694 Time remaining: 0s Progress 4045 / 9694 Time remaining: 0s Progress 4046 / 9694 Time remaining: 0s Progress 4047 / 9694 Time remaining: 0s Progress 4048 / 9694 Time remaining: 0s Progress 4049 / 9694 Time remaining: 0s Progress 4050 / 9694 Time remaining: 0s Progress 4051 / 9694 Time remaining: 0s Progress 4052 / 9694 Time remaining: 0s Progress 4053 / 9694 Time remaining: 0s Progress 4054 / 9694 Time remaining: 0s Progress 4055 / 9694 Time remaining: 0s Progress 4056 / 9694 Time remaining: 0s Progress 4057 / 9694 Time remaining: 0s Progress 4058 / 9694 Time remaining: 0s Progress 4059 / 9694 Time remaining: 0s Progress 4060 / 9694 Time remaining: 0s Progress 4061 / 9694 Time remaining: 0s Progress 4062 / 9694 Time remaining: 0s Progress 4063 / 9694 Time remaining: 0s Progress 4064 / 9694 Time remaining: 0s Progress 4065 / 9694 Time remaining: 0s Progress 4066 / 9694 Time remaining: 0s Progress 4067 / 9694 Time remaining: 0s Progress 4068 / 9694 Time remaining: 0s Progress 4069 / 9694 Time remaining: 0s Progress 4070 / 9694 Time remaining: 0s Progress 4071 / 9694 Time remaining: 0s Progress 4072 / 9694 Time remaining: 0s Progress 4073 / 9694 Time remaining: 0s Progress 4074 / 9694 Time remaining: 0s Progress 4075 / 9694 Time remaining: 0s Progress 4076 / 9694 Time remaining: 0s Progress 4077 / 9694 Time remaining: 0s Progress 4078 / 9694 Time remaining: 0s Progress 4079 / 9694 Time remaining: 0s Progress 4080 / 9694 Time remaining: 0s Progress 4081 / 9694 Time remaining: 0s Progress 4082 / 9694 Time remaining: 0s Progress 4083 / 9694 Time remaining: 0s Progress 4084 / 9694 Time remaining: 0s Progress 4085 / 9694 Time remaining: 0s Progress 4086 / 9694 Time remaining: 0s Progress 4087 / 9694 Time remaining: 0s Progress 4088 / 9694 Time remaining: 0s Progress 4089 / 9694 Time remaining: 0s Progress 4090 / 9694 Time remaining: 0s Progress 4091 / 9694 Time remaining: 0s Progress 4092 / 9694 Time remaining: 0s Progress 4093 / 9694 Time remaining: 0s Progress 4094 / 9694 Time remaining: 0s Progress 4095 / 9694 Time remaining: 0s Progress 4096 / 9694 Time remaining: 0s Progress 4097 / 9694 Time remaining: 0s Progress 4098 / 9694 Time remaining: 0s Progress 4099 / 9694 Time remaining: 0s Progress 4100 / 9694 Time remaining: 0s Progress 4101 / 9694 Time remaining: 0s Progress 4102 / 9694 Time remaining: 0s Progress 4103 / 9694 Time remaining: 0s Progress 4104 / 9694 Time remaining: 0s Progress 4105 / 9694 Time remaining: 0s Progress 4106 / 9694 Time remaining: 0s Progress 4107 / 9694 Time remaining: 0s Progress 4108 / 9694 Time remaining: 0s Progress 4109 / 9694 Time remaining: 0s Progress 4110 / 9694 Time remaining: 0s Progress 4111 / 9694 Time remaining: 0s Progress 4112 / 9694 Time remaining: 0s Progress 4113 / 9694 Time remaining: 0s Progress 4114 / 9694 Time remaining: 0s Progress 4115 / 9694 Time remaining: 0s Progress 4116 / 9694 Time remaining: 0s Progress 4117 / 9694 Time remaining: 0s Progress 4118 / 9694 Time remaining: 0s Progress 4119 / 9694 Time remaining: 0s Progress 4120 / 9694 Time remaining: 0s Progress 4121 / 9694 Time remaining: 0s Progress 4122 / 9694 Time remaining: 0s Progress 4123 / 9694 Time remaining: 0s Progress 4124 / 9694 Time remaining: 0s Progress 4125 / 9694 Time remaining: 0s Progress 4126 / 9694 Time remaining: 0s Progress 4127 / 9694 Time remaining: 0s Progress 4128 / 9694 Time remaining: 0s Progress 4129 / 9694 Time remaining: 0s Progress 4130 / 9694 Time remaining: 0s Progress 4131 / 9694 Time remaining: 0s Progress 4132 / 9694 Time remaining: 0s Progress 4133 / 9694 Time remaining: 0s Progress 4134 / 9694 Time remaining: 0s Progress 4135 / 9694 Time remaining: 0s Progress 4136 / 9694 Time remaining: 0s Progress 4137 / 9694 Time remaining: 0s Progress 4138 / 9694 Time remaining: 0s Progress 4139 / 9694 Time remaining: 0s Progress 4140 / 9694 Time remaining: 0s Progress 4141 / 9694 Time remaining: 0s Progress 4142 / 9694 Time remaining: 0s Progress 4143 / 9694 Time remaining: 0s Progress 4144 / 9694 Time remaining: 0s Progress 4145 / 9694 Time remaining: 0s Progress 4146 / 9694 Time remaining: 0s Progress 4147 / 9694 Time remaining: 0s Progress 4148 / 9694 Time remaining: 0s Progress 4149 / 9694 Time remaining: 0s Progress 4150 / 9694 Time remaining: 0s Progress 4151 / 9694 Time remaining: 0s Progress 4152 / 9694 Time remaining: 0s Progress 4153 / 9694 Time remaining: 0s Progress 4154 / 9694 Time remaining: 0s Progress 4155 / 9694 Time remaining: 0s Progress 4156 / 9694 Time remaining: 0s Progress 4157 / 9694 Time remaining: 0s Progress 4158 / 9694 Time remaining: 0s Progress 4159 / 9694 Time remaining: 0s Progress 4160 / 9694 Time remaining: 0s Progress 4161 / 9694 Time remaining: 0s Progress 4162 / 9694 Time remaining: 0s Progress 4163 / 9694 Time remaining: 0s Progress 4164 / 9694 Time remaining: 0s Progress 4165 / 9694 Time remaining: 0s Progress 4166 / 9694 Time remaining: 0s Progress 4167 / 9694 Time remaining: 0s Progress 4168 / 9694 Time remaining: 0s Progress 4169 / 9694 Time remaining: 0s Progress 4170 / 9694 Time remaining: 0s Progress 4171 / 9694 Time remaining: 0s Progress 4172 / 9694 Time remaining: 0s Progress 4173 / 9694 Time remaining: 0s Progress 4174 / 9694 Time remaining: 0s Progress 4175 / 9694 Time remaining: 0s Progress 4176 / 9694 Time remaining: 0s Progress 4177 / 9694 Time remaining: 0s Progress 4178 / 9694 Time remaining: 0s Progress 4179 / 9694 Time remaining: 0s Progress 4180 / 9694 Time remaining: 0s Progress 4181 / 9694 Time remaining: 0s Progress 4182 / 9694 Time remaining: 0s Progress 4183 / 9694 Time remaining: 0s Progress 4184 / 9694 Time remaining: 0s Progress 4185 / 9694 Time remaining: 0s Progress 4186 / 9694 Time remaining: 0s Progress 4187 / 9694 Time remaining: 0s Progress 4188 / 9694 Time remaining: 0s Progress 4189 / 9694 Time remaining: 0s Progress 4190 / 9694 Time remaining: 0s Progress 4191 / 9694 Time remaining: 0s Progress 4192 / 9694 Time remaining: 0s Progress 4193 / 9694 Time remaining: 0s Progress 4194 / 9694 Time remaining: 0s Progress 4195 / 9694 Time remaining: 0s Progress 4196 / 9694 Time remaining: 0s Progress 4197 / 9694 Time remaining: 0s Progress 4198 / 9694 Time remaining: 0s Progress 4199 / 9694 Time remaining: 0s Progress 4200 / 9694 Time remaining: 0s Progress 4201 / 9694 Time remaining: 0s Progress 4202 / 9694 Time remaining: 0s Progress 4203 / 9694 Time remaining: 0s Progress 4204 / 9694 Time remaining: 0s Progress 4205 / 9694 Time remaining: 0s Progress 4206 / 9694 Time remaining: 0s Progress 4207 / 9694 Time remaining: 0s Progress 4208 / 9694 Time remaining: 0s Progress 4209 / 9694 Time remaining: 0s Progress 4210 / 9694 Time remaining: 0s Progress 4211 / 9694 Time remaining: 0s Progress 4212 / 9694 Time remaining: 0s Progress 4213 / 9694 Time remaining: 0s Progress 4214 / 9694 Time remaining: 0s Progress 4215 / 9694 Time remaining: 0s Progress 4216 / 9694 Time remaining: 0s Progress 4217 / 9694 Time remaining: 0s Progress 4218 / 9694 Time remaining: 0s Progress 4219 / 9694 Time remaining: 0s Progress 4220 / 9694 Time remaining: 0s Progress 4221 / 9694 Time remaining: 0s Progress 4222 / 9694 Time remaining: 0s Progress 4223 / 9694 Time remaining: 0s Progress 4224 / 9694 Time remaining: 0s Progress 4225 / 9694 Time remaining: 0s Progress 4226 / 9694 Time remaining: 0s Progress 4227 / 9694 Time remaining: 0s Progress 4228 / 9694 Time remaining: 0s Progress 4229 / 9694 Time remaining: 0s Progress 4230 / 9694 Time remaining: 0s Progress 4231 / 9694 Time remaining: 0s Progress 4232 / 9694 Time remaining: 0s Progress 4233 / 9694 Time remaining: 0s Progress 4234 / 9694 Time remaining: 0s Progress 4235 / 9694 Time remaining: 0s Progress 4236 / 9694 Time remaining: 0s Progress 4237 / 9694 Time remaining: 0s Progress 4238 / 9694 Time remaining: 0s Progress 4239 / 9694 Time remaining: 0s Progress 4240 / 9694 Time remaining: 0s Progress 4241 / 9694 Time remaining: 0s Progress 4242 / 9694 Time remaining: 0s Progress 4243 / 9694 Time remaining: 0s Progress 4244 / 9694 Time remaining: 0s Progress 4245 / 9694 Time remaining: 0s Progress 4246 / 9694 Time remaining: 0s Progress 4247 / 9694 Time remaining: 0s Progress 4248 / 9694 Time remaining: 0s Progress 4249 / 9694 Time remaining: 0s Progress 4250 / 9694 Time remaining: 0s Progress 4251 / 9694 Time remaining: 0s Progress 4252 / 9694 Time remaining: 0s Progress 4253 / 9694 Time remaining: 0s Progress 4254 / 9694 Time remaining: 0s Progress 4255 / 9694 Time remaining: 0s Progress 4256 / 9694 Time remaining: 0s Progress 4257 / 9694 Time remaining: 0s Progress 4258 / 9694 Time remaining: 0s Progress 4259 / 9694 Time remaining: 0s Progress 4260 / 9694 Time remaining: 0s Progress 4261 / 9694 Time remaining: 0s Progress 4262 / 9694 Time remaining: 0s Progress 4263 / 9694 Time remaining: 0s Progress 4264 / 9694 Time remaining: 0s Progress 4265 / 9694 Time remaining: 0s Progress 4266 / 9694 Time remaining: 0s Progress 4267 / 9694 Time remaining: 0s Progress 4268 / 9694 Time remaining: 0s Progress 4269 / 9694 Time remaining: 0s Progress 4270 / 9694 Time remaining: 0s Progress 4271 / 9694 Time remaining: 0s Progress 4272 / 9694 Time remaining: 0s Progress 4273 / 9694 Time remaining: 0s Progress 4274 / 9694 Time remaining: 0s Progress 4275 / 9694 Time remaining: 0s Progress 4276 / 9694 Time remaining: 0s Progress 4277 / 9694 Time remaining: 0s Progress 4278 / 9694 Time remaining: 0s Progress 4279 / 9694 Time remaining: 0s Progress 4280 / 9694 Time remaining: 0s Progress 4281 / 9694 Time remaining: 0s Progress 4282 / 9694 Time remaining: 0s Progress 4283 / 9694 Time remaining: 0s Progress 4284 / 9694 Time remaining: 0s Progress 4285 / 9694 Time remaining: 0s Progress 4286 / 9694 Time remaining: 0s Progress 4287 / 9694 Time remaining: 0s Progress 4288 / 9694 Time remaining: 0s Progress 4289 / 9694 Time remaining: 0s Progress 4290 / 9694 Time remaining: 0s Progress 4291 / 9694 Time remaining: 0s Progress 4292 / 9694 Time remaining: 0s Progress 4293 / 9694 Time remaining: 0s Progress 4294 / 9694 Time remaining: 0s Progress 4295 / 9694 Time remaining: 0s Progress 4296 / 9694 Time remaining: 0s Progress 4297 / 9694 Time remaining: 0s Progress 4298 / 9694 Time remaining: 0s Progress 4299 / 9694 Time remaining: 0s Progress 4300 / 9694 Time remaining: 0s Progress 4301 / 9694 Time remaining: 0s Progress 4302 / 9694 Time remaining: 0s Progress 4303 / 9694 Time remaining: 0s Progress 4304 / 9694 Time remaining: 0s Progress 4305 / 9694 Time remaining: 0s Progress 4306 / 9694 Time remaining: 0s Progress 4307 / 9694 Time remaining: 0s Progress 4308 / 9694 Time remaining: 0s Progress 4309 / 9694 Time remaining: 0s Progress 4310 / 9694 Time remaining: 0s Progress 4311 / 9694 Time remaining: 0s Progress 4312 / 9694 Time remaining: 0s Progress 4313 / 9694 Time remaining: 0s Progress 4314 / 9694 Time remaining: 0s Progress 4315 / 9694 Time remaining: 0s Progress 4316 / 9694 Time remaining: 0s Progress 4317 / 9694 Time remaining: 0s Progress 4318 / 9694 Time remaining: 0s Progress 4319 / 9694 Time remaining: 0s Progress 4320 / 9694 Time remaining: 0s Progress 4321 / 9694 Time remaining: 0s Progress 4322 / 9694 Time remaining: 0s Progress 4323 / 9694 Time remaining: 0s Progress 4324 / 9694 Time remaining: 0s Progress 4325 / 9694 Time remaining: 0s Progress 4326 / 9694 Time remaining: 0s Progress 4327 / 9694 Time remaining: 0s Progress 4328 / 9694 Time remaining: 0s Progress 4329 / 9694 Time remaining: 0s Progress 4330 / 9694 Time remaining: 0s Progress 4331 / 9694 Time remaining: 0s Progress 4332 / 9694 Time remaining: 0s Progress 4333 / 9694 Time remaining: 0s Progress 4334 / 9694 Time remaining: 0s Progress 4335 / 9694 Time remaining: 0s Progress 4336 / 9694 Time remaining: 0s Progress 4337 / 9694 Time remaining: 0s Progress 4338 / 9694 Time remaining: 0s Progress 4339 / 9694 Time remaining: 0s Progress 4340 / 9694 Time remaining: 0s Progress 4341 / 9694 Time remaining: 0s Progress 4342 / 9694 Time remaining: 0s Progress 4343 / 9694 Time remaining: 0s Progress 4344 / 9694 Time remaining: 0s Progress 4345 / 9694 Time remaining: 0s Progress 4346 / 9694 Time remaining: 0s Progress 4347 / 9694 Time remaining: 0s Progress 4348 / 9694 Time remaining: 0s Progress 4349 / 9694 Time remaining: 0s Progress 4350 / 9694 Time remaining: 0s Progress 4351 / 9694 Time remaining: 0s Progress 4352 / 9694 Time remaining: 0s Progress 4353 / 9694 Time remaining: 0s Progress 4354 / 9694 Time remaining: 0s Progress 4355 / 9694 Time remaining: 0s Progress 4356 / 9694 Time remaining: 0s Progress 4357 / 9694 Time remaining: 0s Progress 4358 / 9694 Time remaining: 0s Progress 4359 / 9694 Time remaining: 0s Progress 4360 / 9694 Time remaining: 0s Progress 4361 / 9694 Time remaining: 0s Progress 4362 / 9694 Time remaining: 0s Progress 4363 / 9694 Time remaining: 0s Progress 4364 / 9694 Time remaining: 0s Progress 4365 / 9694 Time remaining: 0s Progress 4366 / 9694 Time remaining: 0s Progress 4367 / 9694 Time remaining: 0s Progress 4368 / 9694 Time remaining: 0s Progress 4369 / 9694 Time remaining: 0s Progress 4370 / 9694 Time remaining: 0s Progress 4371 / 9694 Time remaining: 0s Progress 4372 / 9694 Time remaining: 0s Progress 4373 / 9694 Time remaining: 0s Progress 4374 / 9694 Time remaining: 0s Progress 4375 / 9694 Time remaining: 0s Progress 4376 / 9694 Time remaining: 0s Progress 4377 / 9694 Time remaining: 0s Progress 4378 / 9694 Time remaining: 0s Progress 4379 / 9694 Time remaining: 0s Progress 4380 / 9694 Time remaining: 0s Progress 4381 / 9694 Time remaining: 0s Progress 4382 / 9694 Time remaining: 0s Progress 4383 / 9694 Time remaining: 0s Progress 4384 / 9694 Time remaining: 0s Progress 4385 / 9694 Time remaining: 0s Progress 4386 / 9694 Time remaining: 0s Progress 4387 / 9694 Time remaining: 0s Progress 4388 / 9694 Time remaining: 0s Progress 4389 / 9694 Time remaining: 0s Progress 4390 / 9694 Time remaining: 0s Progress 4391 / 9694 Time remaining: 0s Progress 4392 / 9694 Time remaining: 0s Progress 4393 / 9694 Time remaining: 0s Progress 4394 / 9694 Time remaining: 0s Progress 4395 / 9694 Time remaining: 0s Progress 4396 / 9694 Time remaining: 0s Progress 4397 / 9694 Time remaining: 0s Progress 4398 / 9694 Time remaining: 0s Progress 4399 / 9694 Time remaining: 0s Progress 4400 / 9694 Time remaining: 0s Progress 4401 / 9694 Time remaining: 0s Progress 4402 / 9694 Time remaining: 0s Progress 4403 / 9694 Time remaining: 0s Progress 4404 / 9694 Time remaining: 0s Progress 4405 / 9694 Time remaining: 0s Progress 4406 / 9694 Time remaining: 0s Progress 4407 / 9694 Time remaining: 0s Progress 4408 / 9694 Time remaining: 0s Progress 4409 / 9694 Time remaining: 0s Progress 4410 / 9694 Time remaining: 0s Progress 4411 / 9694 Time remaining: 0s Progress 4412 / 9694 Time remaining: 0s Progress 4413 / 9694 Time remaining: 0s Progress 4414 / 9694 Time remaining: 0s Progress 4415 / 9694 Time remaining: 0s Progress 4416 / 9694 Time remaining: 0s Progress 4417 / 9694 Time remaining: 0s Progress 4418 / 9694 Time remaining: 0s Progress 4419 / 9694 Time remaining: 0s Progress 4420 / 9694 Time remaining: 0s Progress 4421 / 9694 Time remaining: 0s Progress 4422 / 9694 Time remaining: 0s Progress 4423 / 9694 Time remaining: 0s Progress 4424 / 9694 Time remaining: 0s Progress 4425 / 9694 Time remaining: 0s Progress 4426 / 9694 Time remaining: 0s Progress 4427 / 9694 Time remaining: 0s Progress 4428 / 9694 Time remaining: 0s Progress 4429 / 9694 Time remaining: 0s Progress 4430 / 9694 Time remaining: 0s Progress 4431 / 9694 Time remaining: 0s Progress 4432 / 9694 Time remaining: 0s Progress 4433 / 9694 Time remaining: 0s Progress 4434 / 9694 Time remaining: 0s Progress 4435 / 9694 Time remaining: 0s Progress 4436 / 9694 Time remaining: 0s Progress 4437 / 9694 Time remaining: 0s Progress 4438 / 9694 Time remaining: 0s Progress 4439 / 9694 Time remaining: 0s Progress 4440 / 9694 Time remaining: 0s Progress 4441 / 9694 Time remaining: 0s Progress 4442 / 9694 Time remaining: 0s Progress 4443 / 9694 Time remaining: 0s Progress 4444 / 9694 Time remaining: 0s Progress 4445 / 9694 Time remaining: 0s Progress 4446 / 9694 Time remaining: 0s Progress 4447 / 9694 Time remaining: 0s Progress 4448 / 9694 Time remaining: 0s Progress 4449 / 9694 Time remaining: 0s Progress 4450 / 9694 Time remaining: 0s Progress 4451 / 9694 Time remaining: 0s Progress 4452 / 9694 Time remaining: 0s Progress 4453 / 9694 Time remaining: 0s Progress 4454 / 9694 Time remaining: 0s Progress 4455 / 9694 Time remaining: 0s Progress 4456 / 9694 Time remaining: 0s Progress 4457 / 9694 Time remaining: 0s Progress 4458 / 9694 Time remaining: 0s Progress 4459 / 9694 Time remaining: 0s Progress 4460 / 9694 Time remaining: 0s Progress 4461 / 9694 Time remaining: 0s Progress 4462 / 9694 Time remaining: 0s Progress 4463 / 9694 Time remaining: 0s Progress 4464 / 9694 Time remaining: 0s Progress 4465 / 9694 Time remaining: 0s Progress 4466 / 9694 Time remaining: 0s Progress 4467 / 9694 Time remaining: 0s Progress 4468 / 9694 Time remaining: 0s Progress 4469 / 9694 Time remaining: 0s Progress 4470 / 9694 Time remaining: 0s Progress 4471 / 9694 Time remaining: 0s Progress 4472 / 9694 Time remaining: 0s Progress 4473 / 9694 Time remaining: 0s Progress 4474 / 9694 Time remaining: 0s Progress 4475 / 9694 Time remaining: 0s Progress 4476 / 9694 Time remaining: 0s Progress 4477 / 9694 Time remaining: 0s Progress 4478 / 9694 Time remaining: 0s Progress 4479 / 9694 Time remaining: 0s Progress 4480 / 9694 Time remaining: 0s Progress 4481 / 9694 Time remaining: 0s Progress 4482 / 9694 Time remaining: 0s Progress 4483 / 9694 Time remaining: 0s Progress 4484 / 9694 Time remaining: 0s Progress 4485 / 9694 Time remaining: 0s Progress 4486 / 9694 Time remaining: 0s Progress 4487 / 9694 Time remaining: 0s Progress 4488 / 9694 Time remaining: 0s Progress 4489 / 9694 Time remaining: 0s Progress 4490 / 9694 Time remaining: 0s Progress 4491 / 9694 Time remaining: 0s Progress 4492 / 9694 Time remaining: 0s Progress 4493 / 9694 Time remaining: 0s Progress 4494 / 9694 Time remaining: 0s Progress 4495 / 9694 Time remaining: 0s Progress 4496 / 9694 Time remaining: 0s Progress 4497 / 9694 Time remaining: 0s Progress 4498 / 9694 Time remaining: 0s Progress 4499 / 9694 Time remaining: 0s Progress 4500 / 9694 Time remaining: 0s Progress 4501 / 9694 Time remaining: 0s Progress 4502 / 9694 Time remaining: 0s Progress 4503 / 9694 Time remaining: 0s Progress 4504 / 9694 Time remaining: 0s Progress 4505 / 9694 Time remaining: 0s Progress 4506 / 9694 Time remaining: 0s Progress 4507 / 9694 Time remaining: 0s Progress 4508 / 9694 Time remaining: 0s Progress 4509 / 9694 Time remaining: 0s Progress 4510 / 9694 Time remaining: 0s Progress 4511 / 9694 Time remaining: 0s Progress 4512 / 9694 Time remaining: 0s Progress 4513 / 9694 Time remaining: 0s Progress 4514 / 9694 Time remaining: 0s Progress 4515 / 9694 Time remaining: 0s Progress 4516 / 9694 Time remaining: 0s Progress 4517 / 9694 Time remaining: 0s Progress 4518 / 9694 Time remaining: 0s Progress 4519 / 9694 Time remaining: 0s Progress 4520 / 9694 Time remaining: 0s Progress 4521 / 9694 Time remaining: 0s Progress 4522 / 9694 Time remaining: 0s Progress 4523 / 9694 Time remaining: 0s Progress 4524 / 9694 Time remaining: 0s Progress 4525 / 9694 Time remaining: 0s Progress 4526 / 9694 Time remaining: 0s Progress 4527 / 9694 Time remaining: 0s Progress 4528 / 9694 Time remaining: 0s Progress 4529 / 9694 Time remaining: 0s Progress 4530 / 9694 Time remaining: 0s Progress 4531 / 9694 Time remaining: 0s Progress 4532 / 9694 Time remaining: 0s Progress 4533 / 9694 Time remaining: 0s Progress 4534 / 9694 Time remaining: 0s Progress 4535 / 9694 Time remaining: 0s Progress 4536 / 9694 Time remaining: 0s Progress 4537 / 9694 Time remaining: 0s Progress 4538 / 9694 Time remaining: 0s Progress 4539 / 9694 Time remaining: 0s Progress 4540 / 9694 Time remaining: 0s Progress 4541 / 9694 Time remaining: 0s Progress 4542 / 9694 Time remaining: 0s Progress 4543 / 9694 Time remaining: 0s Progress 4544 / 9694 Time remaining: 0s Progress 4545 / 9694 Time remaining: 0s Progress 4546 / 9694 Time remaining: 0s Progress 4547 / 9694 Time remaining: 0s Progress 4548 / 9694 Time remaining: 0s Progress 4549 / 9694 Time remaining: 0s Progress 4550 / 9694 Time remaining: 0s Progress 4551 / 9694 Time remaining: 0s Progress 4552 / 9694 Time remaining: 0s Progress 4553 / 9694 Time remaining: 0s Progress 4554 / 9694 Time remaining: 0s Progress 4555 / 9694 Time remaining: 0s Progress 4556 / 9694 Time remaining: 0s Progress 4557 / 9694 Time remaining: 0s Progress 4558 / 9694 Time remaining: 0s Progress 4559 / 9694 Time remaining: 0s Progress 4560 / 9694 Time remaining: 0s Progress 4561 / 9694 Time remaining: 0s Progress 4562 / 9694 Time remaining: 0s Progress 4563 / 9694 Time remaining: 0s Progress 4564 / 9694 Time remaining: 0s Progress 4565 / 9694 Time remaining: 0s Progress 4566 / 9694 Time remaining: 0s Progress 4567 / 9694 Time remaining: 0s Progress 4568 / 9694 Time remaining: 0s Progress 4569 / 9694 Time remaining: 0s Progress 4570 / 9694 Time remaining: 0s Progress 4571 / 9694 Time remaining: 0s Progress 4572 / 9694 Time remaining: 0s Progress 4573 / 9694 Time remaining: 0s Progress 4574 / 9694 Time remaining: 0s Progress 4575 / 9694 Time remaining: 0s Progress 4576 / 9694 Time remaining: 0s Progress 4577 / 9694 Time remaining: 0s Progress 4578 / 9694 Time remaining: 0s Progress 4579 / 9694 Time remaining: 0s Progress 4580 / 9694 Time remaining: 0s Progress 4581 / 9694 Time remaining: 0s Progress 4582 / 9694 Time remaining: 0s Progress 4583 / 9694 Time remaining: 0s Progress 4584 / 9694 Time remaining: 0s Progress 4585 / 9694 Time remaining: 0s Progress 4586 / 9694 Time remaining: 0s Progress 4587 / 9694 Time remaining: 0s Progress 4588 / 9694 Time remaining: 0s Progress 4589 / 9694 Time remaining: 0s Progress 4590 / 9694 Time remaining: 0s Progress 4591 / 9694 Time remaining: 0s Progress 4592 / 9694 Time remaining: 0s Progress 4593 / 9694 Time remaining: 0s Progress 4594 / 9694 Time remaining: 0s Progress 4595 / 9694 Time remaining: 0s Progress 4596 / 9694 Time remaining: 0s Progress 4597 / 9694 Time remaining: 0s Progress 4598 / 9694 Time remaining: 0s Progress 4599 / 9694 Time remaining: 0s Progress 4600 / 9694 Time remaining: 0s Progress 4601 / 9694 Time remaining: 0s Progress 4602 / 9694 Time remaining: 0s Progress 4603 / 9694 Time remaining: 0s Progress 4604 / 9694 Time remaining: 0s Progress 4605 / 9694 Time remaining: 0s Progress 4606 / 9694 Time remaining: 0s Progress 4607 / 9694 Time remaining: 0s Progress 4608 / 9694 Time remaining: 0s Progress 4609 / 9694 Time remaining: 0s Progress 4610 / 9694 Time remaining: 0s Progress 4611 / 9694 Time remaining: 0s Progress 4612 / 9694 Time remaining: 0s Progress 4613 / 9694 Time remaining: 0s Progress 4614 / 9694 Time remaining: 0s Progress 4615 / 9694 Time remaining: 0s Progress 4616 / 9694 Time remaining: 0s Progress 4617 / 9694 Time remaining: 0s Progress 4618 / 9694 Time remaining: 0s Progress 4619 / 9694 Time remaining: 0s Progress 4620 / 9694 Time remaining: 0s Progress 4621 / 9694 Time remaining: 0s Progress 4622 / 9694 Time remaining: 0s Progress 4623 / 9694 Time remaining: 0s Progress 4624 / 9694 Time remaining: 0s Progress 4625 / 9694 Time remaining: 0s Progress 4626 / 9694 Time remaining: 0s Progress 4627 / 9694 Time remaining: 0s Progress 4628 / 9694 Time remaining: 0s Progress 4629 / 9694 Time remaining: 0s Progress 4630 / 9694 Time remaining: 0s Progress 4631 / 9694 Time remaining: 0s Progress 4632 / 9694 Time remaining: 0s Progress 4633 / 9694 Time remaining: 0s Progress 4634 / 9694 Time remaining: 0s Progress 4635 / 9694 Time remaining: 0s Progress 4636 / 9694 Time remaining: 0s Progress 4637 / 9694 Time remaining: 0s Progress 4638 / 9694 Time remaining: 0s Progress 4639 / 9694 Time remaining: 0s Progress 4640 / 9694 Time remaining: 0s Progress 4641 / 9694 Time remaining: 0s Progress 4642 / 9694 Time remaining: 0s Progress 4643 / 9694 Time remaining: 0s Progress 4644 / 9694 Time remaining: 0s Progress 4645 / 9694 Time remaining: 0s Progress 4646 / 9694 Time remaining: 0s Progress 4647 / 9694 Time remaining: 0s Progress 4648 / 9694 Time remaining: 0s Progress 4649 / 9694 Time remaining: 0s Progress 4650 / 9694 Time remaining: 0s Progress 4651 / 9694 Time remaining: 0s Progress 4652 / 9694 Time remaining: 0s Progress 4653 / 9694 Time remaining: 0s Progress 4654 / 9694 Time remaining: 0s Progress 4655 / 9694 Time remaining: 0s Progress 4656 / 9694 Time remaining: 0s Progress 4657 / 9694 Time remaining: 0s Progress 4658 / 9694 Time remaining: 0s Progress 4659 / 9694 Time remaining: 0s Progress 4660 / 9694 Time remaining: 0s Progress 4661 / 9694 Time remaining: 0s Progress 4662 / 9694 Time remaining: 0s Progress 4663 / 9694 Time remaining: 0s Progress 4664 / 9694 Time remaining: 0s Progress 4665 / 9694 Time remaining: 0s Progress 4666 / 9694 Time remaining: 0s Progress 4667 / 9694 Time remaining: 0s Progress 4668 / 9694 Time remaining: 0s Progress 4669 / 9694 Time remaining: 0s Progress 4670 / 9694 Time remaining: 0s Progress 4671 / 9694 Time remaining: 0s Progress 4672 / 9694 Time remaining: 0s Progress 4673 / 9694 Time remaining: 0s Progress 4674 / 9694 Time remaining: 0s Progress 4675 / 9694 Time remaining: 0s Progress 4676 / 9694 Time remaining: 0s Progress 4677 / 9694 Time remaining: 0s Progress 4678 / 9694 Time remaining: 0s Progress 4679 / 9694 Time remaining: 0s Progress 4680 / 9694 Time remaining: 0s Progress 4681 / 9694 Time remaining: 0s Progress 4682 / 9694 Time remaining: 0s Progress 4683 / 9694 Time remaining: 0s Progress 4684 / 9694 Time remaining: 0s Progress 4685 / 9694 Time remaining: 0s Progress 4686 / 9694 Time remaining: 0s Progress 4687 / 9694 Time remaining: 0s Progress 4688 / 9694 Time remaining: 0s Progress 4689 / 9694 Time remaining: 0s Progress 4690 / 9694 Time remaining: 0s Progress 4691 / 9694 Time remaining: 0s Progress 4692 / 9694 Time remaining: 0s Progress 4693 / 9694 Time remaining: 0s Progress 4694 / 9694 Time remaining: 0s Progress 4695 / 9694 Time remaining: 0s Progress 4696 / 9694 Time remaining: 0s Progress 4697 / 9694 Time remaining: 0s Progress 4698 / 9694 Time remaining: 0s Progress 4699 / 9694 Time remaining: 0s Progress 4700 / 9694 Time remaining: 0s Progress 4701 / 9694 Time remaining: 0s Progress 4702 / 9694 Time remaining: 0s Progress 4703 / 9694 Time remaining: 0s Progress 4704 / 9694 Time remaining: 0s Progress 4705 / 9694 Time remaining: 0s Progress 4706 / 9694 Time remaining: 0s Progress 4707 / 9694 Time remaining: 0s Progress 4708 / 9694 Time remaining: 0s Progress 4709 / 9694 Time remaining: 0s Progress 4710 / 9694 Time remaining: 0s Progress 4711 / 9694 Time remaining: 0s Progress 4712 / 9694 Time remaining: 0s Progress 4713 / 9694 Time remaining: 0s Progress 4714 / 9694 Time remaining: 0s Progress 4715 / 9694 Time remaining: 0s Progress 4716 / 9694 Time remaining: 0s Progress 4717 / 9694 Time remaining: 0s Progress 4718 / 9694 Time remaining: 0s Progress 4719 / 9694 Time remaining: 0s Progress 4720 / 9694 Time remaining: 0s Progress 4721 / 9694 Time remaining: 0s Progress 4722 / 9694 Time remaining: 0s Progress 4723 / 9694 Time remaining: 0s Progress 4724 / 9694 Time remaining: 0s Progress 4725 / 9694 Time remaining: 0s Progress 4726 / 9694 Time remaining: 0s Progress 4727 / 9694 Time remaining: 0s Progress 4728 / 9694 Time remaining: 0s Progress 4729 / 9694 Time remaining: 0s Progress 4730 / 9694 Time remaining: 0s Progress 4731 / 9694 Time remaining: 0s Progress 4732 / 9694 Time remaining: 0s Progress 4733 / 9694 Time remaining: 0s Progress 4734 / 9694 Time remaining: 0s Progress 4735 / 9694 Time remaining: 0s Progress 4736 / 9694 Time remaining: 0s Progress 4737 / 9694 Time remaining: 0s Progress 4738 / 9694 Time remaining: 0s Progress 4739 / 9694 Time remaining: 0s Progress 4740 / 9694 Time remaining: 0s Progress 4741 / 9694 Time remaining: 0s Progress 4742 / 9694 Time remaining: 0s Progress 4743 / 9694 Time remaining: 0s Progress 4744 / 9694 Time remaining: 0s Progress 4745 / 9694 Time remaining: 0s Progress 4746 / 9694 Time remaining: 0s Progress 4747 / 9694 Time remaining: 0s Progress 4748 / 9694 Time remaining: 0s Progress 4749 / 9694 Time remaining: 0s Progress 4750 / 9694 Time remaining: 0s Progress 4751 / 9694 Time remaining: 0s Progress 4752 / 9694 Time remaining: 0s Progress 4753 / 9694 Time remaining: 0s Progress 4754 / 9694 Time remaining: 0s Progress 4755 / 9694 Time remaining: 0s Progress 4756 / 9694 Time remaining: 0s Progress 4757 / 9694 Time remaining: 0s Progress 4758 / 9694 Time remaining: 0s Progress 4759 / 9694 Time remaining: 0s Progress 4760 / 9694 Time remaining: 0s Progress 4761 / 9694 Time remaining: 0s Progress 4762 / 9694 Time remaining: 0s Progress 4763 / 9694 Time remaining: 0s Progress 4764 / 9694 Time remaining: 0s Progress 4765 / 9694 Time remaining: 0s Progress 4766 / 9694 Time remaining: 0s Progress 4767 / 9694 Time remaining: 0s Progress 4768 / 9694 Time remaining: 0s Progress 4769 / 9694 Time remaining: 0s Progress 4770 / 9694 Time remaining: 0s Progress 4771 / 9694 Time remaining: 0s Progress 4772 / 9694 Time remaining: 0s Progress 4773 / 9694 Time remaining: 0s Progress 4774 / 9694 Time remaining: 0s Progress 4775 / 9694 Time remaining: 0s Progress 4776 / 9694 Time remaining: 0s Progress 4777 / 9694 Time remaining: 0s Progress 4778 / 9694 Time remaining: 0s Progress 4779 / 9694 Time remaining: 0s Progress 4780 / 9694 Time remaining: 0s Progress 4781 / 9694 Time remaining: 0s Progress 4782 / 9694 Time remaining: 0s Progress 4783 / 9694 Time remaining: 0s Progress 4784 / 9694 Time remaining: 0s Progress 4785 / 9694 Time remaining: 0s Progress 4786 / 9694 Time remaining: 0s Progress 4787 / 9694 Time remaining: 0s Progress 4788 / 9694 Time remaining: 0s Progress 4789 / 9694 Time remaining: 0s Progress 4790 / 9694 Time remaining: 0s Progress 4791 / 9694 Time remaining: 0s Progress 4792 / 9694 Time remaining: 0s Progress 4793 / 9694 Time remaining: 0s Progress 4794 / 9694 Time remaining: 0s Progress 4795 / 9694 Time remaining: 0s Progress 4796 / 9694 Time remaining: 0s Progress 4797 / 9694 Time remaining: 0s Progress 4798 / 9694 Time remaining: 0s Progress 4799 / 9694 Time remaining: 0s Progress 4800 / 9694 Time remaining: 0s Progress 4801 / 9694 Time remaining: 0s Progress 4802 / 9694 Time remaining: 0s Progress 4803 / 9694 Time remaining: 0s Progress 4804 / 9694 Time remaining: 0s Progress 4805 / 9694 Time remaining: 0s Progress 4806 / 9694 Time remaining: 0s Progress 4807 / 9694 Time remaining: 0s Progress 4808 / 9694 Time remaining: 0s Progress 4809 / 9694 Time remaining: 0s Progress 4810 / 9694 Time remaining: 0s Progress 4811 / 9694 Time remaining: 0s Progress 4812 / 9694 Time remaining: 0s Progress 4813 / 9694 Time remaining: 0s Progress 4814 / 9694 Time remaining: 0s Progress 4815 / 9694 Time remaining: 0s Progress 4816 / 9694 Time remaining: 0s Progress 4817 / 9694 Time remaining: 0s Progress 4818 / 9694 Time remaining: 0s Progress 4819 / 9694 Time remaining: 0s Progress 4820 / 9694 Time remaining: 0s Progress 4821 / 9694 Time remaining: 0s Progress 4822 / 9694 Time remaining: 0s Progress 4823 / 9694 Time remaining: 0s Progress 4824 / 9694 Time remaining: 0s Progress 4825 / 9694 Time remaining: 0s Progress 4826 / 9694 Time remaining: 0s Progress 4827 / 9694 Time remaining: 0s Progress 4828 / 9694 Time remaining: 0s Progress 4829 / 9694 Time remaining: 0s Progress 4830 / 9694 Time remaining: 0s Progress 4831 / 9694 Time remaining: 0s Progress 4832 / 9694 Time remaining: 0s Progress 4833 / 9694 Time remaining: 0s Progress 4834 / 9694 Time remaining: 0s Progress 4835 / 9694 Time remaining: 0s Progress 4836 / 9694 Time remaining: 0s Progress 4837 / 9694 Time remaining: 0s Progress 4838 / 9694 Time remaining: 0s Progress 4839 / 9694 Time remaining: 0s Progress 4840 / 9694 Time remaining: 0s Progress 4841 / 9694 Time remaining: 0s Progress 4842 / 9694 Time remaining: 0s Progress 4843 / 9694 Time remaining: 0s Progress 4844 / 9694 Time remaining: 0s Progress 4845 / 9694 Time remaining: 0s Progress 4846 / 9694 Time remaining: 0s Progress 4847 / 9694 Time remaining: 0s Progress 4848 / 9694 Time remaining: 0s Progress 4849 / 9694 Time remaining: 0s Progress 4850 / 9694 Time remaining: 0s Progress 4851 / 9694 Time remaining: 0s Progress 4852 / 9694 Time remaining: 0s Progress 4853 / 9694 Time remaining: 0s Progress 4854 / 9694 Time remaining: 0s Progress 4855 / 9694 Time remaining: 0s Progress 4856 / 9694 Time remaining: 0s Progress 4857 / 9694 Time remaining: 0s Progress 4858 / 9694 Time remaining: 0s Progress 4859 / 9694 Time remaining: 0s Progress 4860 / 9694 Time remaining: 0s Progress 4861 / 9694 Time remaining: 0s Progress 4862 / 9694 Time remaining: 0s Progress 4863 / 9694 Time remaining: 0s Progress 4864 / 9694 Time remaining: 0s Progress 4865 / 9694 Time remaining: 0s Progress 4866 / 9694 Time remaining: 0s Progress 4867 / 9694 Time remaining: 0s Progress 4868 / 9694 Time remaining: 0s Progress 4869 / 9694 Time remaining: 0s Progress 4870 / 9694 Time remaining: 0s Progress 4871 / 9694 Time remaining: 0s Progress 4872 / 9694 Time remaining: 0s Progress 4873 / 9694 Time remaining: 0s Progress 4874 / 9694 Time remaining: 0s Progress 4875 / 9694 Time remaining: 0s Progress 4876 / 9694 Time remaining: 0s Progress 4877 / 9694 Time remaining: 0s Progress 4878 / 9694 Time remaining: 0s Progress 4879 / 9694 Time remaining: 0s Progress 4880 / 9694 Time remaining: 0s Progress 4881 / 9694 Time remaining: 0s Progress 4882 / 9694 Time remaining: 0s Progress 4883 / 9694 Time remaining: 0s Progress 4884 / 9694 Time remaining: 0s Progress 4885 / 9694 Time remaining: 0s Progress 4886 / 9694 Time remaining: 0s Progress 4887 / 9694 Time remaining: 0s Progress 4888 / 9694 Time remaining: 0s Progress 4889 / 9694 Time remaining: 0s Progress 4890 / 9694 Time remaining: 0s Progress 4891 / 9694 Time remaining: 0s Progress 4892 / 9694 Time remaining: 0s Progress 4893 / 9694 Time remaining: 0s Progress 4894 / 9694 Time remaining: 0s Progress 4895 / 9694 Time remaining: 0s Progress 4896 / 9694 Time remaining: 0s Progress 4897 / 9694 Time remaining: 0s Progress 4898 / 9694 Time remaining: 0s Progress 4899 / 9694 Time remaining: 0s Progress 4900 / 9694 Time remaining: 0s Progress 4901 / 9694 Time remaining: 0s Progress 4902 / 9694 Time remaining: 0s Progress 4903 / 9694 Time remaining: 0s Progress 4904 / 9694 Time remaining: 0s Progress 4905 / 9694 Time remaining: 0s Progress 4906 / 9694 Time remaining: 0s Progress 4907 / 9694 Time remaining: 0s Progress 4908 / 9694 Time remaining: 0s Progress 4909 / 9694 Time remaining: 0s Progress 4910 / 9694 Time remaining: 0s Progress 4911 / 9694 Time remaining: 0s Progress 4912 / 9694 Time remaining: 0s Progress 4913 / 9694 Time remaining: 0s Progress 4914 / 9694 Time remaining: 0s Progress 4915 / 9694 Time remaining: 0s Progress 4916 / 9694 Time remaining: 0s Progress 4917 / 9694 Time remaining: 0s Progress 4918 / 9694 Time remaining: 0s Progress 4919 / 9694 Time remaining: 0s Progress 4920 / 9694 Time remaining: 0s Progress 4921 / 9694 Time remaining: 0s Progress 4922 / 9694 Time remaining: 0s Progress 4923 / 9694 Time remaining: 0s Progress 4924 / 9694 Time remaining: 0s Progress 4925 / 9694 Time remaining: 0s Progress 4926 / 9694 Time remaining: 0s Progress 4927 / 9694 Time remaining: 0s Progress 4928 / 9694 Time remaining: 0s Progress 4929 / 9694 Time remaining: 0s Progress 4930 / 9694 Time remaining: 0s Progress 4931 / 9694 Time remaining: 0s Progress 4932 / 9694 Time remaining: 0s Progress 4933 / 9694 Time remaining: 0s Progress 4934 / 9694 Time remaining: 0s Progress 4935 / 9694 Time remaining: 0s Progress 4936 / 9694 Time remaining: 0s Progress 4937 / 9694 Time remaining: 0s Progress 4938 / 9694 Time remaining: 0s Progress 4939 / 9694 Time remaining: 0s Progress 4940 / 9694 Time remaining: 0s Progress 4941 / 9694 Time remaining: 0s Progress 4942 / 9694 Time remaining: 0s Progress 4943 / 9694 Time remaining: 0s Progress 4944 / 9694 Time remaining: 0s Progress 4945 / 9694 Time remaining: 0s Progress 4946 / 9694 Time remaining: 0s Progress 4947 / 9694 Time remaining: 0s Progress 4948 / 9694 Time remaining: 0s Progress 4949 / 9694 Time remaining: 0s Progress 4950 / 9694 Time remaining: 0s Progress 4951 / 9694 Time remaining: 0s Progress 4952 / 9694 Time remaining: 0s Progress 4953 / 9694 Time remaining: 0s Progress 4954 / 9694 Time remaining: 0s Progress 4955 / 9694 Time remaining: 0s Progress 4956 / 9694 Time remaining: 0s Progress 4957 / 9694 Time remaining: 0s Progress 4958 / 9694 Time remaining: 0s Progress 4959 / 9694 Time remaining: 0s Progress 4960 / 9694 Time remaining: 0s Progress 4961 / 9694 Time remaining: 0s Progress 4962 / 9694 Time remaining: 0s Progress 4963 / 9694 Time remaining: 0s Progress 4964 / 9694 Time remaining: 0s Progress 4965 / 9694 Time remaining: 0s Progress 4966 / 9694 Time remaining: 0s Progress 4967 / 9694 Time remaining: 0s Progress 4968 / 9694 Time remaining: 0s Progress 4969 / 9694 Time remaining: 0s Progress 4970 / 9694 Time remaining: 0s Progress 4971 / 9694 Time remaining: 0s Progress 4972 / 9694 Time remaining: 0s Progress 4973 / 9694 Time remaining: 0s Progress 4974 / 9694 Time remaining: 0s Progress 4975 / 9694 Time remaining: 0s Progress 4976 / 9694 Time remaining: 0s Progress 4977 / 9694 Time remaining: 0s Progress 4978 / 9694 Time remaining: 0s Progress 4979 / 9694 Time remaining: 0s Progress 4980 / 9694 Time remaining: 0s Progress 4981 / 9694 Time remaining: 0s Progress 4982 / 9694 Time remaining: 0s Progress 4983 / 9694 Time remaining: 0s Progress 4984 / 9694 Time remaining: 0s Progress 4985 / 9694 Time remaining: 0s Progress 4986 / 9694 Time remaining: 0s Progress 4987 / 9694 Time remaining: 0s Progress 4988 / 9694 Time remaining: 0s Progress 4989 / 9694 Time remaining: 0s Progress 4990 / 9694 Time remaining: 0s Progress 4991 / 9694 Time remaining: 0s Progress 4992 / 9694 Time remaining: 0s Progress 4993 / 9694 Time remaining: 0s Progress 4994 / 9694 Time remaining: 0s Progress 4995 / 9694 Time remaining: 0s Progress 4996 / 9694 Time remaining: 0s Progress 4997 / 9694 Time remaining: 0s Progress 4998 / 9694 Time remaining: 0s Progress 4999 / 9694 Time remaining: 0s Progress 5000 / 9694 Time remaining: 0s Progress 5001 / 9694 Time remaining: 0s Progress 5002 / 9694 Time remaining: 0s Progress 5003 / 9694 Time remaining: 0s Progress 5004 / 9694 Time remaining: 0s Progress 5005 / 9694 Time remaining: 0s Progress 5006 / 9694 Time remaining: 0s Progress 5007 / 9694 Time remaining: 0s Progress 5008 / 9694 Time remaining: 0s Progress 5009 / 9694 Time remaining: 0s Progress 5010 / 9694 Time remaining: 0s Progress 5011 / 9694 Time remaining: 0s Progress 5012 / 9694 Time remaining: 0s Progress 5013 / 9694 Time remaining: 0s Progress 5014 / 9694 Time remaining: 0s Progress 5015 / 9694 Time remaining: 0s Progress 5016 / 9694 Time remaining: 0s Progress 5017 / 9694 Time remaining: 0s Progress 5018 / 9694 Time remaining: 0s Progress 5019 / 9694 Time remaining: 0s Progress 5020 / 9694 Time remaining: 0s Progress 5021 / 9694 Time remaining: 0s Progress 5022 / 9694 Time remaining: 0s Progress 5023 / 9694 Time remaining: 0s Progress 5024 / 9694 Time remaining: 0s Progress 5025 / 9694 Time remaining: 0s Progress 5026 / 9694 Time remaining: 0s Progress 5027 / 9694 Time remaining: 0s Progress 5028 / 9694 Time remaining: 0s Progress 5029 / 9694 Time remaining: 0s Progress 5030 / 9694 Time remaining: 0s Progress 5031 / 9694 Time remaining: 0s Progress 5032 / 9694 Time remaining: 0s Progress 5033 / 9694 Time remaining: 0s Progress 5034 / 9694 Time remaining: 0s Progress 5035 / 9694 Time remaining: 0s Progress 5036 / 9694 Time remaining: 0s Progress 5037 / 9694 Time remaining: 0s Progress 5038 / 9694 Time remaining: 0s Progress 5039 / 9694 Time remaining: 0s Progress 5040 / 9694 Time remaining: 0s Progress 5041 / 9694 Time remaining: 0s Progress 5042 / 9694 Time remaining: 0s Progress 5043 / 9694 Time remaining: 0s Progress 5044 / 9694 Time remaining: 0s Progress 5045 / 9694 Time remaining: 0s Progress 5046 / 9694 Time remaining: 0s Progress 5047 / 9694 Time remaining: 0s Progress 5048 / 9694 Time remaining: 0s Progress 5049 / 9694 Time remaining: 0s Progress 5050 / 9694 Time remaining: 0s Progress 5051 / 9694 Time remaining: 0s Progress 5052 / 9694 Time remaining: 0s Progress 5053 / 9694 Time remaining: 0s Progress 5054 / 9694 Time remaining: 0s Progress 5055 / 9694 Time remaining: 0s Progress 5056 / 9694 Time remaining: 0s Progress 5057 / 9694 Time remaining: 0s Progress 5058 / 9694 Time remaining: 0s Progress 5059 / 9694 Time remaining: 0s Progress 5060 / 9694 Time remaining: 0s Progress 5061 / 9694 Time remaining: 0s Progress 5062 / 9694 Time remaining: 0s Progress 5063 / 9694 Time remaining: 0s Progress 5064 / 9694 Time remaining: 0s Progress 5065 / 9694 Time remaining: 0s Progress 5066 / 9694 Time remaining: 0s Progress 5067 / 9694 Time remaining: 0s Progress 5068 / 9694 Time remaining: 0s Progress 5069 / 9694 Time remaining: 0s Progress 5070 / 9694 Time remaining: 0s Progress 5071 / 9694 Time remaining: 0s Progress 5072 / 9694 Time remaining: 0s Progress 5073 / 9694 Time remaining: 0s Progress 5074 / 9694 Time remaining: 0s Progress 5075 / 9694 Time remaining: 0s Progress 5076 / 9694 Time remaining: 0s Progress 5077 / 9694 Time remaining: 0s Progress 5078 / 9694 Time remaining: 0s Progress 5079 / 9694 Time remaining: 0s Progress 5080 / 9694 Time remaining: 0s Progress 5081 / 9694 Time remaining: 0s Progress 5082 / 9694 Time remaining: 0s Progress 5083 / 9694 Time remaining: 0s Progress 5084 / 9694 Time remaining: 0s Progress 5085 / 9694 Time remaining: 0s Progress 5086 / 9694 Time remaining: 0s Progress 5087 / 9694 Time remaining: 0s Progress 5088 / 9694 Time remaining: 0s Progress 5089 / 9694 Time remaining: 0s Progress 5090 / 9694 Time remaining: 0s Progress 5091 / 9694 Time remaining: 0s Progress 5092 / 9694 Time remaining: 0s Progress 5093 / 9694 Time remaining: 0s Progress 5094 / 9694 Time remaining: 0s Progress 5095 / 9694 Time remaining: 0s Progress 5096 / 9694 Time remaining: 0s Progress 5097 / 9694 Time remaining: 0s Progress 5098 / 9694 Time remaining: 0s Progress 5099 / 9694 Time remaining: 0s Progress 5100 / 9694 Time remaining: 0s Progress 5101 / 9694 Time remaining: 0s Progress 5102 / 9694 Time remaining: 0s Progress 5103 / 9694 Time remaining: 0s Progress 5104 / 9694 Time remaining: 0s Progress 5105 / 9694 Time remaining: 0s Progress 5106 / 9694 Time remaining: 0s Progress 5107 / 9694 Time remaining: 0s Progress 5108 / 9694 Time remaining: 0s Progress 5109 / 9694 Time remaining: 0s Progress 5110 / 9694 Time remaining: 0s Progress 5111 / 9694 Time remaining: 0s Progress 5112 / 9694 Time remaining: 0s Progress 5113 / 9694 Time remaining: 0s Progress 5114 / 9694 Time remaining: 0s Progress 5115 / 9694 Time remaining: 0s Progress 5116 / 9694 Time remaining: 0s Progress 5117 / 9694 Time remaining: 0s Progress 5118 / 9694 Time remaining: 0s Progress 5119 / 9694 Time remaining: 0s Progress 5120 / 9694 Time remaining: 0s Progress 5121 / 9694 Time remaining: 0s Progress 5122 / 9694 Time remaining: 0s Progress 5123 / 9694 Time remaining: 0s Progress 5124 / 9694 Time remaining: 0s Progress 5125 / 9694 Time remaining: 0s Progress 5126 / 9694 Time remaining: 0s Progress 5127 / 9694 Time remaining: 0s Progress 5128 / 9694 Time remaining: 0s Progress 5129 / 9694 Time remaining: 0s Progress 5130 / 9694 Time remaining: 0s Progress 5131 / 9694 Time remaining: 0s Progress 5132 / 9694 Time remaining: 0s Progress 5133 / 9694 Time remaining: 0s Progress 5134 / 9694 Time remaining: 0s Progress 5135 / 9694 Time remaining: 0s Progress 5136 / 9694 Time remaining: 0s Progress 5137 / 9694 Time remaining: 0s Progress 5138 / 9694 Time remaining: 0s Progress 5139 / 9694 Time remaining: 0s Progress 5140 / 9694 Time remaining: 0s Progress 5141 / 9694 Time remaining: 0s Progress 5142 / 9694 Time remaining: 0s Progress 5143 / 9694 Time remaining: 0s Progress 5144 / 9694 Time remaining: 0s Progress 5145 / 9694 Time remaining: 0s Progress 5146 / 9694 Time remaining: 0s Progress 5147 / 9694 Time remaining: 0s Progress 5148 / 9694 Time remaining: 0s Progress 5149 / 9694 Time remaining: 0s Progress 5150 / 9694 Time remaining: 0s Progress 5151 / 9694 Time remaining: 0s Progress 5152 / 9694 Time remaining: 0s Progress 5153 / 9694 Time remaining: 0s Progress 5154 / 9694 Time remaining: 0s Progress 5155 / 9694 Time remaining: 0s Progress 5156 / 9694 Time remaining: 0s Progress 5157 / 9694 Time remaining: 0s Progress 5158 / 9694 Time remaining: 0s Progress 5159 / 9694 Time remaining: 0s Progress 5160 / 9694 Time remaining: 0s Progress 5161 / 9694 Time remaining: 0s Progress 5162 / 9694 Time remaining: 0s Progress 5163 / 9694 Time remaining: 0s Progress 5164 / 9694 Time remaining: 0s Progress 5165 / 9694 Time remaining: 0s Progress 5166 / 9694 Time remaining: 0s Progress 5167 / 9694 Time remaining: 0s Progress 5168 / 9694 Time remaining: 0s Progress 5169 / 9694 Time remaining: 0s Progress 5170 / 9694 Time remaining: 0s Progress 5171 / 9694 Time remaining: 0s Progress 5172 / 9694 Time remaining: 0s Progress 5173 / 9694 Time remaining: 0s Progress 5174 / 9694 Time remaining: 0s Progress 5175 / 9694 Time remaining: 0s Progress 5176 / 9694 Time remaining: 0s Progress 5177 / 9694 Time remaining: 0s Progress 5178 / 9694 Time remaining: 0s Progress 5179 / 9694 Time remaining: 0s Progress 5180 / 9694 Time remaining: 0s Progress 5181 / 9694 Time remaining: 0s Progress 5182 / 9694 Time remaining: 0s Progress 5183 / 9694 Time remaining: 0s Progress 5184 / 9694 Time remaining: 0s Progress 5185 / 9694 Time remaining: 0s Progress 5186 / 9694 Time remaining: 0s Progress 5187 / 9694 Time remaining: 0s Progress 5188 / 9694 Time remaining: 0s Progress 5189 / 9694 Time remaining: 0s Progress 5190 / 9694 Time remaining: 0s Progress 5191 / 9694 Time remaining: 0s Progress 5192 / 9694 Time remaining: 0s Progress 5193 / 9694 Time remaining: 0s Progress 5194 / 9694 Time remaining: 0s Progress 5195 / 9694 Time remaining: 0s Progress 5196 / 9694 Time remaining: 0s Progress 5197 / 9694 Time remaining: 0s Progress 5198 / 9694 Time remaining: 0s Progress 5199 / 9694 Time remaining: 0s Progress 5200 / 9694 Time remaining: 0s Progress 5201 / 9694 Time remaining: 0s Progress 5202 / 9694 Time remaining: 0s Progress 5203 / 9694 Time remaining: 0s Progress 5204 / 9694 Time remaining: 0s Progress 5205 / 9694 Time remaining: 0s Progress 5206 / 9694 Time remaining: 0s Progress 5207 / 9694 Time remaining: 0s Progress 5208 / 9694 Time remaining: 0s Progress 5209 / 9694 Time remaining: 0s Progress 5210 / 9694 Time remaining: 0s Progress 5211 / 9694 Time remaining: 0s Progress 5212 / 9694 Time remaining: 0s Progress 5213 / 9694 Time remaining: 0s Progress 5214 / 9694 Time remaining: 0s Progress 5215 / 9694 Time remaining: 0s Progress 5216 / 9694 Time remaining: 0s Progress 5217 / 9694 Time remaining: 0s Progress 5218 / 9694 Time remaining: 0s Progress 5219 / 9694 Time remaining: 0s Progress 5220 / 9694 Time remaining: 0s Progress 5221 / 9694 Time remaining: 0s Progress 5222 / 9694 Time remaining: 0s Progress 5223 / 9694 Time remaining: 0s Progress 5224 / 9694 Time remaining: 0s Progress 5225 / 9694 Time remaining: 0s Progress 5226 / 9694 Time remaining: 0s Progress 5227 / 9694 Time remaining: 0s Progress 5228 / 9694 Time remaining: 0s Progress 5229 / 9694 Time remaining: 0s Progress 5230 / 9694 Time remaining: 0s Progress 5231 / 9694 Time remaining: 0s Progress 5232 / 9694 Time remaining: 0s Progress 5233 / 9694 Time remaining: 0s Progress 5234 / 9694 Time remaining: 0s Progress 5235 / 9694 Time remaining: 0s Progress 5236 / 9694 Time remaining: 0s Progress 5237 / 9694 Time remaining: 0s Progress 5238 / 9694 Time remaining: 0s Progress 5239 / 9694 Time remaining: 0s Progress 5240 / 9694 Time remaining: 0s Progress 5241 / 9694 Time remaining: 0s Progress 5242 / 9694 Time remaining: 0s Progress 5243 / 9694 Time remaining: 0s Progress 5244 / 9694 Time remaining: 0s Progress 5245 / 9694 Time remaining: 0s Progress 5246 / 9694 Time remaining: 0s Progress 5247 / 9694 Time remaining: 0s Progress 5248 / 9694 Time remaining: 0s Progress 5249 / 9694 Time remaining: 0s Progress 5250 / 9694 Time remaining: 0s Progress 5251 / 9694 Time remaining: 0s Progress 5252 / 9694 Time remaining: 0s Progress 5253 / 9694 Time remaining: 0s Progress 5254 / 9694 Time remaining: 0s Progress 5255 / 9694 Time remaining: 0s Progress 5256 / 9694 Time remaining: 0s Progress 5257 / 9694 Time remaining: 0s Progress 5258 / 9694 Time remaining: 0s Progress 5259 / 9694 Time remaining: 0s Progress 5260 / 9694 Time remaining: 0s Progress 5261 / 9694 Time remaining: 0s Progress 5262 / 9694 Time remaining: 0s Progress 5263 / 9694 Time remaining: 0s Progress 5264 / 9694 Time remaining: 0s Progress 5265 / 9694 Time remaining: 0s Progress 5266 / 9694 Time remaining: 0s Progress 5267 / 9694 Time remaining: 0s Progress 5268 / 9694 Time remaining: 0s Progress 5269 / 9694 Time remaining: 0s Progress 5270 / 9694 Time remaining: 0s Progress 5271 / 9694 Time remaining: 0s Progress 5272 / 9694 Time remaining: 0s Progress 5273 / 9694 Time remaining: 0s Progress 5274 / 9694 Time remaining: 0s Progress 5275 / 9694 Time remaining: 0s Progress 5276 / 9694 Time remaining: 0s Progress 5277 / 9694 Time remaining: 0s Progress 5278 / 9694 Time remaining: 0s Progress 5279 / 9694 Time remaining: 0s Progress 5280 / 9694 Time remaining: 0s Progress 5281 / 9694 Time remaining: 0s Progress 5282 / 9694 Time remaining: 0s Progress 5283 / 9694 Time remaining: 0s Progress 5284 / 9694 Time remaining: 0s Progress 5285 / 9694 Time remaining: 0s Progress 5286 / 9694 Time remaining: 0s Progress 5287 / 9694 Time remaining: 0s Progress 5288 / 9694 Time remaining: 0s Progress 5289 / 9694 Time remaining: 0s Progress 5290 / 9694 Time remaining: 0s Progress 5291 / 9694 Time remaining: 0s Progress 5292 / 9694 Time remaining: 0s Progress 5293 / 9694 Time remaining: 0s Progress 5294 / 9694 Time remaining: 0s Progress 5295 / 9694 Time remaining: 0s Progress 5296 / 9694 Time remaining: 0s Progress 5297 / 9694 Time remaining: 0s Progress 5298 / 9694 Time remaining: 0s Progress 5299 / 9694 Time remaining: 0s Progress 5300 / 9694 Time remaining: 0s Progress 5301 / 9694 Time remaining: 0s Progress 5302 / 9694 Time remaining: 0s Progress 5303 / 9694 Time remaining: 0s Progress 5304 / 9694 Time remaining: 0s Progress 5305 / 9694 Time remaining: 0s Progress 5306 / 9694 Time remaining: 0s Progress 5307 / 9694 Time remaining: 0s Progress 5308 / 9694 Time remaining: 0s Progress 5309 / 9694 Time remaining: 0s Progress 5310 / 9694 Time remaining: 0s Progress 5311 / 9694 Time remaining: 0s Progress 5312 / 9694 Time remaining: 0s Progress 5313 / 9694 Time remaining: 0s Progress 5314 / 9694 Time remaining: 0s Progress 5315 / 9694 Time remaining: 0s Progress 5316 / 9694 Time remaining: 0s Progress 5317 / 9694 Time remaining: 0s Progress 5318 / 9694 Time remaining: 0s Progress 5319 / 9694 Time remaining: 0s Progress 5320 / 9694 Time remaining: 0s Progress 5321 / 9694 Time remaining: 0s Progress 5322 / 9694 Time remaining: 0s Progress 5323 / 9694 Time remaining: 0s Progress 5324 / 9694 Time remaining: 0s Progress 5325 / 9694 Time remaining: 0s Progress 5326 / 9694 Time remaining: 0s Progress 5327 / 9694 Time remaining: 0s Progress 5328 / 9694 Time remaining: 0s Progress 5329 / 9694 Time remaining: 0s Progress 5330 / 9694 Time remaining: 0s Progress 5331 / 9694 Time remaining: 0s Progress 5332 / 9694 Time remaining: 0s Progress 5333 / 9694 Time remaining: 0s Progress 5334 / 9694 Time remaining: 0s Progress 5335 / 9694 Time remaining: 0s Progress 5336 / 9694 Time remaining: 0s Progress 5337 / 9694 Time remaining: 0s Progress 5338 / 9694 Time remaining: 0s Progress 5339 / 9694 Time remaining: 0s Progress 5340 / 9694 Time remaining: 0s Progress 5341 / 9694 Time remaining: 0s Progress 5342 / 9694 Time remaining: 0s Progress 5343 / 9694 Time remaining: 0s Progress 5344 / 9694 Time remaining: 0s Progress 5345 / 9694 Time remaining: 0s Progress 5346 / 9694 Time remaining: 0s Progress 5347 / 9694 Time remaining: 0s Progress 5348 / 9694 Time remaining: 0s Progress 5349 / 9694 Time remaining: 0s Progress 5350 / 9694 Time remaining: 0s Progress 5351 / 9694 Time remaining: 0s Progress 5352 / 9694 Time remaining: 0s Progress 5353 / 9694 Time remaining: 0s Progress 5354 / 9694 Time remaining: 0s Progress 5355 / 9694 Time remaining: 0s Progress 5356 / 9694 Time remaining: 0s Progress 5357 / 9694 Time remaining: 0s Progress 5358 / 9694 Time remaining: 0s Progress 5359 / 9694 Time remaining: 0s Progress 5360 / 9694 Time remaining: 0s Progress 5361 / 9694 Time remaining: 0s Progress 5362 / 9694 Time remaining: 0s Progress 5363 / 9694 Time remaining: 0s Progress 5364 / 9694 Time remaining: 0s Progress 5365 / 9694 Time remaining: 0s Progress 5366 / 9694 Time remaining: 0s Progress 5367 / 9694 Time remaining: 0s Progress 5368 / 9694 Time remaining: 0s Progress 5369 / 9694 Time remaining: 0s Progress 5370 / 9694 Time remaining: 0s Progress 5371 / 9694 Time remaining: 0s Progress 5372 / 9694 Time remaining: 0s Progress 5373 / 9694 Time remaining: 0s Progress 5374 / 9694 Time remaining: 0s Progress 5375 / 9694 Time remaining: 0s Progress 5376 / 9694 Time remaining: 0s Progress 5377 / 9694 Time remaining: 0s Progress 5378 / 9694 Time remaining: 0s Progress 5379 / 9694 Time remaining: 0s Progress 5380 / 9694 Time remaining: 0s Progress 5381 / 9694 Time remaining: 0s Progress 5382 / 9694 Time remaining: 0s Progress 5383 / 9694 Time remaining: 0s Progress 5384 / 9694 Time remaining: 0s Progress 5385 / 9694 Time remaining: 0s Progress 5386 / 9694 Time remaining: 0s Progress 5387 / 9694 Time remaining: 0s Progress 5388 / 9694 Time remaining: 0s Progress 5389 / 9694 Time remaining: 0s Progress 5390 / 9694 Time remaining: 0s Progress 5391 / 9694 Time remaining: 0s Progress 5392 / 9694 Time remaining: 0s Progress 5393 / 9694 Time remaining: 0s Progress 5394 / 9694 Time remaining: 0s Progress 5395 / 9694 Time remaining: 0s Progress 5396 / 9694 Time remaining: 0s Progress 5397 / 9694 Time remaining: 0s Progress 5398 / 9694 Time remaining: 0s Progress 5399 / 9694 Time remaining: 0s Progress 5400 / 9694 Time remaining: 0s Progress 5401 / 9694 Time remaining: 0s Progress 5402 / 9694 Time remaining: 0s Progress 5403 / 9694 Time remaining: 0s Progress 5404 / 9694 Time remaining: 0s Progress 5405 / 9694 Time remaining: 0s Progress 5406 / 9694 Time remaining: 0s Progress 5407 / 9694 Time remaining: 0s Progress 5408 / 9694 Time remaining: 0s Progress 5409 / 9694 Time remaining: 0s Progress 5410 / 9694 Time remaining: 0s Progress 5411 / 9694 Time remaining: 0s Progress 5412 / 9694 Time remaining: 0s Progress 5413 / 9694 Time remaining: 0s Progress 5414 / 9694 Time remaining: 0s Progress 5415 / 9694 Time remaining: 0s Progress 5416 / 9694 Time remaining: 0s Progress 5417 / 9694 Time remaining: 0s Progress 5418 / 9694 Time remaining: 0s Progress 5419 / 9694 Time remaining: 0s Progress 5420 / 9694 Time remaining: 0s Progress 5421 / 9694 Time remaining: 0s Progress 5422 / 9694 Time remaining: 0s Progress 5423 / 9694 Time remaining: 0s Progress 5424 / 9694 Time remaining: 0s Progress 5425 / 9694 Time remaining: 0s Progress 5426 / 9694 Time remaining: 0s Progress 5427 / 9694 Time remaining: 0s Progress 5428 / 9694 Time remaining: 0s Progress 5429 / 9694 Time remaining: 0s Progress 5430 / 9694 Time remaining: 0s Progress 5431 / 9694 Time remaining: 0s Progress 5432 / 9694 Time remaining: 0s Progress 5433 / 9694 Time remaining: 0s Progress 5434 / 9694 Time remaining: 0s Progress 5435 / 9694 Time remaining: 0s Progress 5436 / 9694 Time remaining: 0s Progress 5437 / 9694 Time remaining: 0s Progress 5438 / 9694 Time remaining: 0s Progress 5439 / 9694 Time remaining: 0s Progress 5440 / 9694 Time remaining: 0s Progress 5441 / 9694 Time remaining: 0s Progress 5442 / 9694 Time remaining: 0s Progress 5443 / 9694 Time remaining: 0s Progress 5444 / 9694 Time remaining: 0s Progress 5445 / 9694 Time remaining: 0s Progress 5446 / 9694 Time remaining: 0s Progress 5447 / 9694 Time remaining: 0s Progress 5448 / 9694 Time remaining: 0s Progress 5449 / 9694 Time remaining: 0s Progress 5450 / 9694 Time remaining: 0s Progress 5451 / 9694 Time remaining: 0s Progress 5452 / 9694 Time remaining: 0s Progress 5453 / 9694 Time remaining: 0s Progress 5454 / 9694 Time remaining: 0s Progress 5455 / 9694 Time remaining: 0s Progress 5456 / 9694 Time remaining: 0s Progress 5457 / 9694 Time remaining: 0s Progress 5458 / 9694 Time remaining: 0s Progress 5459 / 9694 Time remaining: 0s Progress 5460 / 9694 Time remaining: 0s Progress 5461 / 9694 Time remaining: 0s Progress 5462 / 9694 Time remaining: 0s Progress 5463 / 9694 Time remaining: 0s Progress 5464 / 9694 Time remaining: 0s Progress 5465 / 9694 Time remaining: 0s Progress 5466 / 9694 Time remaining: 0s Progress 5467 / 9694 Time remaining: 0s Progress 5468 / 9694 Time remaining: 0s Progress 5469 / 9694 Time remaining: 0s Progress 5470 / 9694 Time remaining: 0s Progress 5471 / 9694 Time remaining: 0s Progress 5472 / 9694 Time remaining: 0s Progress 5473 / 9694 Time remaining: 0s Progress 5474 / 9694 Time remaining: 0s Progress 5475 / 9694 Time remaining: 0s Progress 5476 / 9694 Time remaining: 0s Progress 5477 / 9694 Time remaining: 0s Progress 5478 / 9694 Time remaining: 0s Progress 5479 / 9694 Time remaining: 0s Progress 5480 / 9694 Time remaining: 0s Progress 5481 / 9694 Time remaining: 0s Progress 5482 / 9694 Time remaining: 0s Progress 5483 / 9694 Time remaining: 0s Progress 5484 / 9694 Time remaining: 0s Progress 5485 / 9694 Time remaining: 0s Progress 5486 / 9694 Time remaining: 0s Progress 5487 / 9694 Time remaining: 0s Progress 5488 / 9694 Time remaining: 0s Progress 5489 / 9694 Time remaining: 0s Progress 5490 / 9694 Time remaining: 0s Progress 5491 / 9694 Time remaining: 0s Progress 5492 / 9694 Time remaining: 0s Progress 5493 / 9694 Time remaining: 0s Progress 5494 / 9694 Time remaining: 0s Progress 5495 / 9694 Time remaining: 0s Progress 5496 / 9694 Time remaining: 0s Progress 5497 / 9694 Time remaining: 0s Progress 5498 / 9694 Time remaining: 0s Progress 5499 / 9694 Time remaining: 0s Progress 5500 / 9694 Time remaining: 0s Progress 5501 / 9694 Time remaining: 0s Progress 5502 / 9694 Time remaining: 0s Progress 5503 / 9694 Time remaining: 0s Progress 5504 / 9694 Time remaining: 0s Progress 5505 / 9694 Time remaining: 0s Progress 5506 / 9694 Time remaining: 0s Progress 5507 / 9694 Time remaining: 0s Progress 5508 / 9694 Time remaining: 0s Progress 5509 / 9694 Time remaining: 0s Progress 5510 / 9694 Time remaining: 0s Progress 5511 / 9694 Time remaining: 0s Progress 5512 / 9694 Time remaining: 0s Progress 5513 / 9694 Time remaining: 0s Progress 5514 / 9694 Time remaining: 0s Progress 5515 / 9694 Time remaining: 0s Progress 5516 / 9694 Time remaining: 0s Progress 5517 / 9694 Time remaining: 0s Progress 5518 / 9694 Time remaining: 0s Progress 5519 / 9694 Time remaining: 0s Progress 5520 / 9694 Time remaining: 0s Progress 5521 / 9694 Time remaining: 0s Progress 5522 / 9694 Time remaining: 0s Progress 5523 / 9694 Time remaining: 0s Progress 5524 / 9694 Time remaining: 0s Progress 5525 / 9694 Time remaining: 0s Progress 5526 / 9694 Time remaining: 0s Progress 5527 / 9694 Time remaining: 0s Progress 5528 / 9694 Time remaining: 0s Progress 5529 / 9694 Time remaining: 0s Progress 5530 / 9694 Time remaining: 0s Progress 5531 / 9694 Time remaining: 0s Progress 5532 / 9694 Time remaining: 0s Progress 5533 / 9694 Time remaining: 0s Progress 5534 / 9694 Time remaining: 0s Progress 5535 / 9694 Time remaining: 0s Progress 5536 / 9694 Time remaining: 0s Progress 5537 / 9694 Time remaining: 0s Progress 5538 / 9694 Time remaining: 0s Progress 5539 / 9694 Time remaining: 0s Progress 5540 / 9694 Time remaining: 0s Progress 5541 / 9694 Time remaining: 0s Progress 5542 / 9694 Time remaining: 0s Progress 5543 / 9694 Time remaining: 0s Progress 5544 / 9694 Time remaining: 0s Progress 5545 / 9694 Time remaining: 0s Progress 5546 / 9694 Time remaining: 0s Progress 5547 / 9694 Time remaining: 0s Progress 5548 / 9694 Time remaining: 0s Progress 5549 / 9694 Time remaining: 0s Progress 5550 / 9694 Time remaining: 0s Progress 5551 / 9694 Time remaining: 0s Progress 5552 / 9694 Time remaining: 0s Progress 5553 / 9694 Time remaining: 0s Progress 5554 / 9694 Time remaining: 0s Progress 5555 / 9694 Time remaining: 0s Progress 5556 / 9694 Time remaining: 0s Progress 5557 / 9694 Time remaining: 0s Progress 5558 / 9694 Time remaining: 0s Progress 5559 / 9694 Time remaining: 0s Progress 5560 / 9694 Time remaining: 0s Progress 5561 / 9694 Time remaining: 0s Progress 5562 / 9694 Time remaining: 0s Progress 5563 / 9694 Time remaining: 0s Progress 5564 / 9694 Time remaining: 0s Progress 5565 / 9694 Time remaining: 0s Progress 5566 / 9694 Time remaining: 0s Progress 5567 / 9694 Time remaining: 0s Progress 5568 / 9694 Time remaining: 0s Progress 5569 / 9694 Time remaining: 0s Progress 5570 / 9694 Time remaining: 0s Progress 5571 / 9694 Time remaining: 0s Progress 5572 / 9694 Time remaining: 0s Progress 5573 / 9694 Time remaining: 0s Progress 5574 / 9694 Time remaining: 0s Progress 5575 / 9694 Time remaining: 0s Progress 5576 / 9694 Time remaining: 0s Progress 5577 / 9694 Time remaining: 0s Progress 5578 / 9694 Time remaining: 0s Progress 5579 / 9694 Time remaining: 0s Progress 5580 / 9694 Time remaining: 0s Progress 5581 / 9694 Time remaining: 0s Progress 5582 / 9694 Time remaining: 0s Progress 5583 / 9694 Time remaining: 0s Progress 5584 / 9694 Time remaining: 0s Progress 5585 / 9694 Time remaining: 0s Progress 5586 / 9694 Time remaining: 0s Progress 5587 / 9694 Time remaining: 0s Progress 5588 / 9694 Time remaining: 0s Progress 5589 / 9694 Time remaining: 0s Progress 5590 / 9694 Time remaining: 0s Progress 5591 / 9694 Time remaining: 0s Progress 5592 / 9694 Time remaining: 0s Progress 5593 / 9694 Time remaining: 0s Progress 5594 / 9694 Time remaining: 0s Progress 5595 / 9694 Time remaining: 0s Progress 5596 / 9694 Time remaining: 0s Progress 5597 / 9694 Time remaining: 0s Progress 5598 / 9694 Time remaining: 0s Progress 5599 / 9694 Time remaining: 0s Progress 5600 / 9694 Time remaining: 0s Progress 5601 / 9694 Time remaining: 0s Progress 5602 / 9694 Time remaining: 0s Progress 5603 / 9694 Time remaining: 0s Progress 5604 / 9694 Time remaining: 0s Progress 5605 / 9694 Time remaining: 0s Progress 5606 / 9694 Time remaining: 0s Progress 5607 / 9694 Time remaining: 0s Progress 5608 / 9694 Time remaining: 0s Progress 5609 / 9694 Time remaining: 0s Progress 5610 / 9694 Time remaining: 0s Progress 5611 / 9694 Time remaining: 0s Progress 5612 / 9694 Time remaining: 0s Progress 5613 / 9694 Time remaining: 0s Progress 5614 / 9694 Time remaining: 0s Progress 5615 / 9694 Time remaining: 0s Progress 5616 / 9694 Time remaining: 0s Progress 5617 / 9694 Time remaining: 0s Progress 5618 / 9694 Time remaining: 0s Progress 5619 / 9694 Time remaining: 0s Progress 5620 / 9694 Time remaining: 0s Progress 5621 / 9694 Time remaining: 0s Progress 5622 / 9694 Time remaining: 0s Progress 5623 / 9694 Time remaining: 0s Progress 5624 / 9694 Time remaining: 0s Progress 5625 / 9694 Time remaining: 0s Progress 5626 / 9694 Time remaining: 0s Progress 5627 / 9694 Time remaining: 0s Progress 5628 / 9694 Time remaining: 0s Progress 5629 / 9694 Time remaining: 0s Progress 5630 / 9694 Time remaining: 0s Progress 5631 / 9694 Time remaining: 0s Progress 5632 / 9694 Time remaining: 0s Progress 5633 / 9694 Time remaining: 0s Progress 5634 / 9694 Time remaining: 0s Progress 5635 / 9694 Time remaining: 0s Progress 5636 / 9694 Time remaining: 0s Progress 5637 / 9694 Time remaining: 0s Progress 5638 / 9694 Time remaining: 0s Progress 5639 / 9694 Time remaining: 0s Progress 5640 / 9694 Time remaining: 0s Progress 5641 / 9694 Time remaining: 0s Progress 5642 / 9694 Time remaining: 0s Progress 5643 / 9694 Time remaining: 0s Progress 5644 / 9694 Time remaining: 0s Progress 5645 / 9694 Time remaining: 0s Progress 5646 / 9694 Time remaining: 0s Progress 5647 / 9694 Time remaining: 0s Progress 5648 / 9694 Time remaining: 0s Progress 5649 / 9694 Time remaining: 0s Progress 5650 / 9694 Time remaining: 0s Progress 5651 / 9694 Time remaining: 0s Progress 5652 / 9694 Time remaining: 0s Progress 5653 / 9694 Time remaining: 0s Progress 5654 / 9694 Time remaining: 0s Progress 5655 / 9694 Time remaining: 0s Progress 5656 / 9694 Time remaining: 0s Progress 5657 / 9694 Time remaining: 0s Progress 5658 / 9694 Time remaining: 0s Progress 5659 / 9694 Time remaining: 0s Progress 5660 / 9694 Time remaining: 0s Progress 5661 / 9694 Time remaining: 0s Progress 5662 / 9694 Time remaining: 0s Progress 5663 / 9694 Time remaining: 0s Progress 5664 / 9694 Time remaining: 0s Progress 5665 / 9694 Time remaining: 0s Progress 5666 / 9694 Time remaining: 0s Progress 5667 / 9694 Time remaining: 0s Progress 5668 / 9694 Time remaining: 0s Progress 5669 / 9694 Time remaining: 0s Progress 5670 / 9694 Time remaining: 0s Progress 5671 / 9694 Time remaining: 0s Progress 5672 / 9694 Time remaining: 0s Progress 5673 / 9694 Time remaining: 0s Progress 5674 / 9694 Time remaining: 0s Progress 5675 / 9694 Time remaining: 0s Progress 5676 / 9694 Time remaining: 0s Progress 5677 / 9694 Time remaining: 0s Progress 5678 / 9694 Time remaining: 0s Progress 5679 / 9694 Time remaining: 0s Progress 5680 / 9694 Time remaining: 0s Progress 5681 / 9694 Time remaining: 0s Progress 5682 / 9694 Time remaining: 0s Progress 5683 / 9694 Time remaining: 0s Progress 5684 / 9694 Time remaining: 0s Progress 5685 / 9694 Time remaining: 0s Progress 5686 / 9694 Time remaining: 0s Progress 5687 / 9694 Time remaining: 0s Progress 5688 / 9694 Time remaining: 0s Progress 5689 / 9694 Time remaining: 0s Progress 5690 / 9694 Time remaining: 0s Progress 5691 / 9694 Time remaining: 0s Progress 5692 / 9694 Time remaining: 0s Progress 5693 / 9694 Time remaining: 0s Progress 5694 / 9694 Time remaining: 0s Progress 5695 / 9694 Time remaining: 0s Progress 5696 / 9694 Time remaining: 0s Progress 5697 / 9694 Time remaining: 0s Progress 5698 / 9694 Time remaining: 0s Progress 5699 / 9694 Time remaining: 0s Progress 5700 / 9694 Time remaining: 0s Progress 5701 / 9694 Time remaining: 0s Progress 5702 / 9694 Time remaining: 0s Progress 5703 / 9694 Time remaining: 0s Progress 5704 / 9694 Time remaining: 0s Progress 5705 / 9694 Time remaining: 0s Progress 5706 / 9694 Time remaining: 0s Progress 5707 / 9694 Time remaining: 0s Progress 5708 / 9694 Time remaining: 0s Progress 5709 / 9694 Time remaining: 0s Progress 5710 / 9694 Time remaining: 0s Progress 5711 / 9694 Time remaining: 0s Progress 5712 / 9694 Time remaining: 0s Progress 5713 / 9694 Time remaining: 0s Progress 5714 / 9694 Time remaining: 0s Progress 5715 / 9694 Time remaining: 0s Progress 5716 / 9694 Time remaining: 0s Progress 5717 / 9694 Time remaining: 0s Progress 5718 / 9694 Time remaining: 0s Progress 5719 / 9694 Time remaining: 0s Progress 5720 / 9694 Time remaining: 0s Progress 5721 / 9694 Time remaining: 0s Progress 5722 / 9694 Time remaining: 0s Progress 5723 / 9694 Time remaining: 0s Progress 5724 / 9694 Time remaining: 0s Progress 5725 / 9694 Time remaining: 0s Progress 5726 / 9694 Time remaining: 0s Progress 5727 / 9694 Time remaining: 0s Progress 5728 / 9694 Time remaining: 0s Progress 5729 / 9694 Time remaining: 0s Progress 5730 / 9694 Time remaining: 0s Progress 5731 / 9694 Time remaining: 0s Progress 5732 / 9694 Time remaining: 0s Progress 5733 / 9694 Time remaining: 0s Progress 5734 / 9694 Time remaining: 0s Progress 5735 / 9694 Time remaining: 0s Progress 5736 / 9694 Time remaining: 0s Progress 5737 / 9694 Time remaining: 0s Progress 5738 / 9694 Time remaining: 0s Progress 5739 / 9694 Time remaining: 0s Progress 5740 / 9694 Time remaining: 0s Progress 5741 / 9694 Time remaining: 0s Progress 5742 / 9694 Time remaining: 0s Progress 5743 / 9694 Time remaining: 0s Progress 5744 / 9694 Time remaining: 0s Progress 5745 / 9694 Time remaining: 0s Progress 5746 / 9694 Time remaining: 0s Progress 5747 / 9694 Time remaining: 0s Progress 5748 / 9694 Time remaining: 0s Progress 5749 / 9694 Time remaining: 0s Progress 5750 / 9694 Time remaining: 0s Progress 5751 / 9694 Time remaining: 0s Progress 5752 / 9694 Time remaining: 0s Progress 5753 / 9694 Time remaining: 0s Progress 5754 / 9694 Time remaining: 0s Progress 5755 / 9694 Time remaining: 0s Progress 5756 / 9694 Time remaining: 0s Progress 5757 / 9694 Time remaining: 0s Progress 5758 / 9694 Time remaining: 0s Progress 5759 / 9694 Time remaining: 0s Progress 5760 / 9694 Time remaining: 0s Progress 5761 / 9694 Time remaining: 0s Progress 5762 / 9694 Time remaining: 0s Progress 5763 / 9694 Time remaining: 0s Progress 5764 / 9694 Time remaining: 0s Progress 5765 / 9694 Time remaining: 0s Progress 5766 / 9694 Time remaining: 0s Progress 5767 / 9694 Time remaining: 0s Progress 5768 / 9694 Time remaining: 0s Progress 5769 / 9694 Time remaining: 0s Progress 5770 / 9694 Time remaining: 0s Progress 5771 / 9694 Time remaining: 0s Progress 5772 / 9694 Time remaining: 0s Progress 5773 / 9694 Time remaining: 0s Progress 5774 / 9694 Time remaining: 0s Progress 5775 / 9694 Time remaining: 0s Progress 5776 / 9694 Time remaining: 0s Progress 5777 / 9694 Time remaining: 0s Progress 5778 / 9694 Time remaining: 0s Progress 5779 / 9694 Time remaining: 0s Progress 5780 / 9694 Time remaining: 0s Progress 5781 / 9694 Time remaining: 0s Progress 5782 / 9694 Time remaining: 0s Progress 5783 / 9694 Time remaining: 0s Progress 5784 / 9694 Time remaining: 0s Progress 5785 / 9694 Time remaining: 0s Progress 5786 / 9694 Time remaining: 0s Progress 5787 / 9694 Time remaining: 0s Progress 5788 / 9694 Time remaining: 0s Progress 5789 / 9694 Time remaining: 0s Progress 5790 / 9694 Time remaining: 0s Progress 5791 / 9694 Time remaining: 0s Progress 5792 / 9694 Time remaining: 0s Progress 5793 / 9694 Time remaining: 0s Progress 5794 / 9694 Time remaining: 0s Progress 5795 / 9694 Time remaining: 0s Progress 5796 / 9694 Time remaining: 0s Progress 5797 / 9694 Time remaining: 0s Progress 5798 / 9694 Time remaining: 0s Progress 5799 / 9694 Time remaining: 0s Progress 5800 / 9694 Time remaining: 0s Progress 5801 / 9694 Time remaining: 0s Progress 5802 / 9694 Time remaining: 0s Progress 5803 / 9694 Time remaining: 0s Progress 5804 / 9694 Time remaining: 0s Progress 5805 / 9694 Time remaining: 0s Progress 5806 / 9694 Time remaining: 0s Progress 5807 / 9694 Time remaining: 0s Progress 5808 / 9694 Time remaining: 0s Progress 5809 / 9694 Time remaining: 0s Progress 5810 / 9694 Time remaining: 0s Progress 5811 / 9694 Time remaining: 0s Progress 5812 / 9694 Time remaining: 0s Progress 5813 / 9694 Time remaining: 0s Progress 5814 / 9694 Time remaining: 0s Progress 5815 / 9694 Time remaining: 0s Progress 5816 / 9694 Time remaining: 0s Progress 5817 / 9694 Time remaining: 0s Progress 5818 / 9694 Time remaining: 0s Progress 5819 / 9694 Time remaining: 0s Progress 5820 / 9694 Time remaining: 0s Progress 5821 / 9694 Time remaining: 0s Progress 5822 / 9694 Time remaining: 0s Progress 5823 / 9694 Time remaining: 0s Progress 5824 / 9694 Time remaining: 0s Progress 5825 / 9694 Time remaining: 0s Progress 5826 / 9694 Time remaining: 0s Progress 5827 / 9694 Time remaining: 0s Progress 5828 / 9694 Time remaining: 0s Progress 5829 / 9694 Time remaining: 0s Progress 5830 / 9694 Time remaining: 0s Progress 5831 / 9694 Time remaining: 0s Progress 5832 / 9694 Time remaining: 0s Progress 5833 / 9694 Time remaining: 0s Progress 5834 / 9694 Time remaining: 0s Progress 5835 / 9694 Time remaining: 0s Progress 5836 / 9694 Time remaining: 0s Progress 5837 / 9694 Time remaining: 0s Progress 5838 / 9694 Time remaining: 0s Progress 5839 / 9694 Time remaining: 0s Progress 5840 / 9694 Time remaining: 0s Progress 5841 / 9694 Time remaining: 0s Progress 5842 / 9694 Time remaining: 0s Progress 5843 / 9694 Time remaining: 0s Progress 5844 / 9694 Time remaining: 0s Progress 5845 / 9694 Time remaining: 0s Progress 5846 / 9694 Time remaining: 0s Progress 5847 / 9694 Time remaining: 0s Progress 5848 / 9694 Time remaining: 0s Progress 5849 / 9694 Time remaining: 0s Progress 5850 / 9694 Time remaining: 0s Progress 5851 / 9694 Time remaining: 0s Progress 5852 / 9694 Time remaining: 0s Progress 5853 / 9694 Time remaining: 0s Progress 5854 / 9694 Time remaining: 0s Progress 5855 / 9694 Time remaining: 0s Progress 5856 / 9694 Time remaining: 0s Progress 5857 / 9694 Time remaining: 0s Progress 5858 / 9694 Time remaining: 0s Progress 5859 / 9694 Time remaining: 0s Progress 5860 / 9694 Time remaining: 0s Progress 5861 / 9694 Time remaining: 0s Progress 5862 / 9694 Time remaining: 0s Progress 5863 / 9694 Time remaining: 0s Progress 5864 / 9694 Time remaining: 0s Progress 5865 / 9694 Time remaining: 0s Progress 5866 / 9694 Time remaining: 0s Progress 5867 / 9694 Time remaining: 0s Progress 5868 / 9694 Time remaining: 0s Progress 5869 / 9694 Time remaining: 0s Progress 5870 / 9694 Time remaining: 0s Progress 5871 / 9694 Time remaining: 0s Progress 5872 / 9694 Time remaining: 0s Progress 5873 / 9694 Time remaining: 0s Progress 5874 / 9694 Time remaining: 0s Progress 5875 / 9694 Time remaining: 0s Progress 5876 / 9694 Time remaining: 0s Progress 5877 / 9694 Time remaining: 0s Progress 5878 / 9694 Time remaining: 0s Progress 5879 / 9694 Time remaining: 0s Progress 5880 / 9694 Time remaining: 0s Progress 5881 / 9694 Time remaining: 0s Progress 5882 / 9694 Time remaining: 0s Progress 5883 / 9694 Time remaining: 0s Progress 5884 / 9694 Time remaining: 0s Progress 5885 / 9694 Time remaining: 0s Progress 5886 / 9694 Time remaining: 0s Progress 5887 / 9694 Time remaining: 0s Progress 5888 / 9694 Time remaining: 0s Progress 5889 / 9694 Time remaining: 0s Progress 5890 / 9694 Time remaining: 0s Progress 5891 / 9694 Time remaining: 0s Progress 5892 / 9694 Time remaining: 0s Progress 5893 / 9694 Time remaining: 0s Progress 5894 / 9694 Time remaining: 0s Progress 5895 / 9694 Time remaining: 0s Progress 5896 / 9694 Time remaining: 0s Progress 5897 / 9694 Time remaining: 0s Progress 5898 / 9694 Time remaining: 0s Progress 5899 / 9694 Time remaining: 0s Progress 5900 / 9694 Time remaining: 0s Progress 5901 / 9694 Time remaining: 0s Progress 5902 / 9694 Time remaining: 0s Progress 5903 / 9694 Time remaining: 0s Progress 5904 / 9694 Time remaining: 0s Progress 5905 / 9694 Time remaining: 0s Progress 5906 / 9694 Time remaining: 0s Progress 5907 / 9694 Time remaining: 0s Progress 5908 / 9694 Time remaining: 0s Progress 5909 / 9694 Time remaining: 0s Progress 5910 / 9694 Time remaining: 0s Progress 5911 / 9694 Time remaining: 0s Progress 5912 / 9694 Time remaining: 0s Progress 5913 / 9694 Time remaining: 0s Progress 5914 / 9694 Time remaining: 0s Progress 5915 / 9694 Time remaining: 0s Progress 5916 / 9694 Time remaining: 0s Progress 5917 / 9694 Time remaining: 0s Progress 5918 / 9694 Time remaining: 0s Progress 5919 / 9694 Time remaining: 0s Progress 5920 / 9694 Time remaining: 0s Progress 5921 / 9694 Time remaining: 0s Progress 5922 / 9694 Time remaining: 0s Progress 5923 / 9694 Time remaining: 0s Progress 5924 / 9694 Time remaining: 0s Progress 5925 / 9694 Time remaining: 0s Progress 5926 / 9694 Time remaining: 0s Progress 5927 / 9694 Time remaining: 0s Progress 5928 / 9694 Time remaining: 0s Progress 5929 / 9694 Time remaining: 0s Progress 5930 / 9694 Time remaining: 0s Progress 5931 / 9694 Time remaining: 0s Progress 5932 / 9694 Time remaining: 0s Progress 5933 / 9694 Time remaining: 0s Progress 5934 / 9694 Time remaining: 0s Progress 5935 / 9694 Time remaining: 0s Progress 5936 / 9694 Time remaining: 0s Progress 5937 / 9694 Time remaining: 0s Progress 5938 / 9694 Time remaining: 0s Progress 5939 / 9694 Time remaining: 0s Progress 5940 / 9694 Time remaining: 0s Progress 5941 / 9694 Time remaining: 0s Progress 5942 / 9694 Time remaining: 0s Progress 5943 / 9694 Time remaining: 0s Progress 5944 / 9694 Time remaining: 0s Progress 5945 / 9694 Time remaining: 0s Progress 5946 / 9694 Time remaining: 0s Progress 5947 / 9694 Time remaining: 0s Progress 5948 / 9694 Time remaining: 0s Progress 5949 / 9694 Time remaining: 0s Progress 5950 / 9694 Time remaining: 0s Progress 5951 / 9694 Time remaining: 0s Progress 5952 / 9694 Time remaining: 0s Progress 5953 / 9694 Time remaining: 0s Progress 5954 / 9694 Time remaining: 0s Progress 5955 / 9694 Time remaining: 0s Progress 5956 / 9694 Time remaining: 0s Progress 5957 / 9694 Time remaining: 0s Progress 5958 / 9694 Time remaining: 0s Progress 5959 / 9694 Time remaining: 0s Progress 5960 / 9694 Time remaining: 0s Progress 5961 / 9694 Time remaining: 0s Progress 5962 / 9694 Time remaining: 0s Progress 5963 / 9694 Time remaining: 0s Progress 5964 / 9694 Time remaining: 0s Progress 5965 / 9694 Time remaining: 0s Progress 5966 / 9694 Time remaining: 0s Progress 5967 / 9694 Time remaining: 0s Progress 5968 / 9694 Time remaining: 0s Progress 5969 / 9694 Time remaining: 0s Progress 5970 / 9694 Time remaining: 0s Progress 5971 / 9694 Time remaining: 0s Progress 5972 / 9694 Time remaining: 0s Progress 5973 / 9694 Time remaining: 0s Progress 5974 / 9694 Time remaining: 0s Progress 5975 / 9694 Time remaining: 0s Progress 5976 / 9694 Time remaining: 0s Progress 5977 / 9694 Time remaining: 0s Progress 5978 / 9694 Time remaining: 0s Progress 5979 / 9694 Time remaining: 0s Progress 5980 / 9694 Time remaining: 0s Progress 5981 / 9694 Time remaining: 0s Progress 5982 / 9694 Time remaining: 0s Progress 5983 / 9694 Time remaining: 0s Progress 5984 / 9694 Time remaining: 0s Progress 5985 / 9694 Time remaining: 0s Progress 5986 / 9694 Time remaining: 0s Progress 5987 / 9694 Time remaining: 0s Progress 5988 / 9694 Time remaining: 0s Progress 5989 / 9694 Time remaining: 0s Progress 5990 / 9694 Time remaining: 0s Progress 5991 / 9694 Time remaining: 0s Progress 5992 / 9694 Time remaining: 0s Progress 5993 / 9694 Time remaining: 0s Progress 5994 / 9694 Time remaining: 0s Progress 5995 / 9694 Time remaining: 0s Progress 5996 / 9694 Time remaining: 0s Progress 5997 / 9694 Time remaining: 0s Progress 5998 / 9694 Time remaining: 0s Progress 5999 / 9694 Time remaining: 0s Progress 6000 / 9694 Time remaining: 0s Progress 6001 / 9694 Time remaining: 0s Progress 6002 / 9694 Time remaining: 0s Progress 6003 / 9694 Time remaining: 0s Progress 6004 / 9694 Time remaining: 0s Progress 6005 / 9694 Time remaining: 0s Progress 6006 / 9694 Time remaining: 0s Progress 6007 / 9694 Time remaining: 0s Progress 6008 / 9694 Time remaining: 0s Progress 6009 / 9694 Time remaining: 0s Progress 6010 / 9694 Time remaining: 0s Progress 6011 / 9694 Time remaining: 0s Progress 6012 / 9694 Time remaining: 0s Progress 6013 / 9694 Time remaining: 0s Progress 6014 / 9694 Time remaining: 0s Progress 6015 / 9694 Time remaining: 0s Progress 6016 / 9694 Time remaining: 0s Progress 6017 / 9694 Time remaining: 0s Progress 6018 / 9694 Time remaining: 0s Progress 6019 / 9694 Time remaining: 0s Progress 6020 / 9694 Time remaining: 0s Progress 6021 / 9694 Time remaining: 0s Progress 6022 / 9694 Time remaining: 0s Progress 6023 / 9694 Time remaining: 0s Progress 6024 / 9694 Time remaining: 0s Progress 6025 / 9694 Time remaining: 0s Progress 6026 / 9694 Time remaining: 0s Progress 6027 / 9694 Time remaining: 0s Progress 6028 / 9694 Time remaining: 0s Progress 6029 / 9694 Time remaining: 0s Progress 6030 / 9694 Time remaining: 0s Progress 6031 / 9694 Time remaining: 0s Progress 6032 / 9694 Time remaining: 0s Progress 6033 / 9694 Time remaining: 0s Progress 6034 / 9694 Time remaining: 0s Progress 6035 / 9694 Time remaining: 0s Progress 6036 / 9694 Time remaining: 0s Progress 6037 / 9694 Time remaining: 0s Progress 6038 / 9694 Time remaining: 0s Progress 6039 / 9694 Time remaining: 0s Progress 6040 / 9694 Time remaining: 0s Progress 6041 / 9694 Time remaining: 0s Progress 6042 / 9694 Time remaining: 0s Progress 6043 / 9694 Time remaining: 0s Progress 6044 / 9694 Time remaining: 0s Progress 6045 / 9694 Time remaining: 0s Progress 6046 / 9694 Time remaining: 0s Progress 6047 / 9694 Time remaining: 0s Progress 6048 / 9694 Time remaining: 0s Progress 6049 / 9694 Time remaining: 0s Progress 6050 / 9694 Time remaining: 0s Progress 6051 / 9694 Time remaining: 0s Progress 6052 / 9694 Time remaining: 0s Progress 6053 / 9694 Time remaining: 0s Progress 6054 / 9694 Time remaining: 0s Progress 6055 / 9694 Time remaining: 0s Progress 6056 / 9694 Time remaining: 0s Progress 6057 / 9694 Time remaining: 0s Progress 6058 / 9694 Time remaining: 0s Progress 6059 / 9694 Time remaining: 0s Progress 6060 / 9694 Time remaining: 0s Progress 6061 / 9694 Time remaining: 0s Progress 6062 / 9694 Time remaining: 0s Progress 6063 / 9694 Time remaining: 0s Progress 6064 / 9694 Time remaining: 0s Progress 6065 / 9694 Time remaining: 0s Progress 6066 / 9694 Time remaining: 0s Progress 6067 / 9694 Time remaining: 0s Progress 6068 / 9694 Time remaining: 0s Progress 6069 / 9694 Time remaining: 0s Progress 6070 / 9694 Time remaining: 0s Progress 6071 / 9694 Time remaining: 0s Progress 6072 / 9694 Time remaining: 0s Progress 6073 / 9694 Time remaining: 0s Progress 6074 / 9694 Time remaining: 0s Progress 6075 / 9694 Time remaining: 0s Progress 6076 / 9694 Time remaining: 0s Progress 6077 / 9694 Time remaining: 0s Progress 6078 / 9694 Time remaining: 0s Progress 6079 / 9694 Time remaining: 0s Progress 6080 / 9694 Time remaining: 0s Progress 6081 / 9694 Time remaining: 0s Progress 6082 / 9694 Time remaining: 0s Progress 6083 / 9694 Time remaining: 0s Progress 6084 / 9694 Time remaining: 0s Progress 6085 / 9694 Time remaining: 0s Progress 6086 / 9694 Time remaining: 0s Progress 6087 / 9694 Time remaining: 0s Progress 6088 / 9694 Time remaining: 0s Progress 6089 / 9694 Time remaining: 0s Progress 6090 / 9694 Time remaining: 0s Progress 6091 / 9694 Time remaining: 0s Progress 6092 / 9694 Time remaining: 0s Progress 6093 / 9694 Time remaining: 0s Progress 6094 / 9694 Time remaining: 0s Progress 6095 / 9694 Time remaining: 0s Progress 6096 / 9694 Time remaining: 0s Progress 6097 / 9694 Time remaining: 0s Progress 6098 / 9694 Time remaining: 0s Progress 6099 / 9694 Time remaining: 0s Progress 6100 / 9694 Time remaining: 0s Progress 6101 / 9694 Time remaining: 0s Progress 6102 / 9694 Time remaining: 0s Progress 6103 / 9694 Time remaining: 0s Progress 6104 / 9694 Time remaining: 0s Progress 6105 / 9694 Time remaining: 0s Progress 6106 / 9694 Time remaining: 0s Progress 6107 / 9694 Time remaining: 0s Progress 6108 / 9694 Time remaining: 0s Progress 6109 / 9694 Time remaining: 0s Progress 6110 / 9694 Time remaining: 0s Progress 6111 / 9694 Time remaining: 0s Progress 6112 / 9694 Time remaining: 0s Progress 6113 / 9694 Time remaining: 0s Progress 6114 / 9694 Time remaining: 0s Progress 6115 / 9694 Time remaining: 0s Progress 6116 / 9694 Time remaining: 0s Progress 6117 / 9694 Time remaining: 0s Progress 6118 / 9694 Time remaining: 0s Progress 6119 / 9694 Time remaining: 0s Progress 6120 / 9694 Time remaining: 0s Progress 6121 / 9694 Time remaining: 0s Progress 6122 / 9694 Time remaining: 0s Progress 6123 / 9694 Time remaining: 0s Progress 6124 / 9694 Time remaining: 0s Progress 6125 / 9694 Time remaining: 0s Progress 6126 / 9694 Time remaining: 0s Progress 6127 / 9694 Time remaining: 0s Progress 6128 / 9694 Time remaining: 0s Progress 6129 / 9694 Time remaining: 0s Progress 6130 / 9694 Time remaining: 0s Progress 6131 / 9694 Time remaining: 0s Progress 6132 / 9694 Time remaining: 0s Progress 6133 / 9694 Time remaining: 0s Progress 6134 / 9694 Time remaining: 0s Progress 6135 / 9694 Time remaining: 0s Progress 6136 / 9694 Time remaining: 0s Progress 6137 / 9694 Time remaining: 0s Progress 6138 / 9694 Time remaining: 0s Progress 6139 / 9694 Time remaining: 0s Progress 6140 / 9694 Time remaining: 0s Progress 6141 / 9694 Time remaining: 0s Progress 6142 / 9694 Time remaining: 0s Progress 6143 / 9694 Time remaining: 0s Progress 6144 / 9694 Time remaining: 0s Progress 6145 / 9694 Time remaining: 0s Progress 6146 / 9694 Time remaining: 0s Progress 6147 / 9694 Time remaining: 0s Progress 6148 / 9694 Time remaining: 0s Progress 6149 / 9694 Time remaining: 0s Progress 6150 / 9694 Time remaining: 0s Progress 6151 / 9694 Time remaining: 0s Progress 6152 / 9694 Time remaining: 0s Progress 6153 / 9694 Time remaining: 0s Progress 6154 / 9694 Time remaining: 0s Progress 6155 / 9694 Time remaining: 0s Progress 6156 / 9694 Time remaining: 0s Progress 6157 / 9694 Time remaining: 0s Progress 6158 / 9694 Time remaining: 0s Progress 6159 / 9694 Time remaining: 0s Progress 6160 / 9694 Time remaining: 0s Progress 6161 / 9694 Time remaining: 0s Progress 6162 / 9694 Time remaining: 0s Progress 6163 / 9694 Time remaining: 0s Progress 6164 / 9694 Time remaining: 0s Progress 6165 / 9694 Time remaining: 0s Progress 6166 / 9694 Time remaining: 0s Progress 6167 / 9694 Time remaining: 0s Progress 6168 / 9694 Time remaining: 0s Progress 6169 / 9694 Time remaining: 0s Progress 6170 / 9694 Time remaining: 0s Progress 6171 / 9694 Time remaining: 0s Progress 6172 / 9694 Time remaining: 0s Progress 6173 / 9694 Time remaining: 0s Progress 6174 / 9694 Time remaining: 0s Progress 6175 / 9694 Time remaining: 0s Progress 6176 / 9694 Time remaining: 0s Progress 6177 / 9694 Time remaining: 0s Progress 6178 / 9694 Time remaining: 0s Progress 6179 / 9694 Time remaining: 0s Progress 6180 / 9694 Time remaining: 0s Progress 6181 / 9694 Time remaining: 0s Progress 6182 / 9694 Time remaining: 0s Progress 6183 / 9694 Time remaining: 0s Progress 6184 / 9694 Time remaining: 0s Progress 6185 / 9694 Time remaining: 0s Progress 6186 / 9694 Time remaining: 0s Progress 6187 / 9694 Time remaining: 0s Progress 6188 / 9694 Time remaining: 0s Progress 6189 / 9694 Time remaining: 0s Progress 6190 / 9694 Time remaining: 0s Progress 6191 / 9694 Time remaining: 0s Progress 6192 / 9694 Time remaining: 0s Progress 6193 / 9694 Time remaining: 0s Progress 6194 / 9694 Time remaining: 0s Progress 6195 / 9694 Time remaining: 0s Progress 6196 / 9694 Time remaining: 0s Progress 6197 / 9694 Time remaining: 0s Progress 6198 / 9694 Time remaining: 0s Progress 6199 / 9694 Time remaining: 0s Progress 6200 / 9694 Time remaining: 0s Progress 6201 / 9694 Time remaining: 0s Progress 6202 / 9694 Time remaining: 0s Progress 6203 / 9694 Time remaining: 0s Progress 6204 / 9694 Time remaining: 0s Progress 6205 / 9694 Time remaining: 0s Progress 6206 / 9694 Time remaining: 0s Progress 6207 / 9694 Time remaining: 0s Progress 6208 / 9694 Time remaining: 0s Progress 6209 / 9694 Time remaining: 0s Progress 6210 / 9694 Time remaining: 0s Progress 6211 / 9694 Time remaining: 0s Progress 6212 / 9694 Time remaining: 0s Progress 6213 / 9694 Time remaining: 0s Progress 6214 / 9694 Time remaining: 0s Progress 6215 / 9694 Time remaining: 0s Progress 6216 / 9694 Time remaining: 0s Progress 6217 / 9694 Time remaining: 0s Progress 6218 / 9694 Time remaining: 0s Progress 6219 / 9694 Time remaining: 0s Progress 6220 / 9694 Time remaining: 0s Progress 6221 / 9694 Time remaining: 0s Progress 6222 / 9694 Time remaining: 0s Progress 6223 / 9694 Time remaining: 0s Progress 6224 / 9694 Time remaining: 0s Progress 6225 / 9694 Time remaining: 0s Progress 6226 / 9694 Time remaining: 0s Progress 6227 / 9694 Time remaining: 0s Progress 6228 / 9694 Time remaining: 0s Progress 6229 / 9694 Time remaining: 0s Progress 6230 / 9694 Time remaining: 0s Progress 6231 / 9694 Time remaining: 0s Progress 6232 / 9694 Time remaining: 0s Progress 6233 / 9694 Time remaining: 0s Progress 6234 / 9694 Time remaining: 0s Progress 6235 / 9694 Time remaining: 0s Progress 6236 / 9694 Time remaining: 0s Progress 6237 / 9694 Time remaining: 0s Progress 6238 / 9694 Time remaining: 0s Progress 6239 / 9694 Time remaining: 0s Progress 6240 / 9694 Time remaining: 0s Progress 6241 / 9694 Time remaining: 0s Progress 6242 / 9694 Time remaining: 0s Progress 6243 / 9694 Time remaining: 0s Progress 6244 / 9694 Time remaining: 0s Progress 6245 / 9694 Time remaining: 0s Progress 6246 / 9694 Time remaining: 0s Progress 6247 / 9694 Time remaining: 0s Progress 6248 / 9694 Time remaining: 0s Progress 6249 / 9694 Time remaining: 0s Progress 6250 / 9694 Time remaining: 0s Progress 6251 / 9694 Time remaining: 0s Progress 6252 / 9694 Time remaining: 0s Progress 6253 / 9694 Time remaining: 0s Progress 6254 / 9694 Time remaining: 0s Progress 6255 / 9694 Time remaining: 0s Progress 6256 / 9694 Time remaining: 0s Progress 6257 / 9694 Time remaining: 0s Progress 6258 / 9694 Time remaining: 0s Progress 6259 / 9694 Time remaining: 0s Progress 6260 / 9694 Time remaining: 0s Progress 6261 / 9694 Time remaining: 0s Progress 6262 / 9694 Time remaining: 0s Progress 6263 / 9694 Time remaining: 0s Progress 6264 / 9694 Time remaining: 0s Progress 6265 / 9694 Time remaining: 0s Progress 6266 / 9694 Time remaining: 0s Progress 6267 / 9694 Time remaining: 0s Progress 6268 / 9694 Time remaining: 0s Progress 6269 / 9694 Time remaining: 0s Progress 6270 / 9694 Time remaining: 0s Progress 6271 / 9694 Time remaining: 0s Progress 6272 / 9694 Time remaining: 0s Progress 6273 / 9694 Time remaining: 0s Progress 6274 / 9694 Time remaining: 0s Progress 6275 / 9694 Time remaining: 0s Progress 6276 / 9694 Time remaining: 0s Progress 6277 / 9694 Time remaining: 0s Progress 6278 / 9694 Time remaining: 0s Progress 6279 / 9694 Time remaining: 0s Progress 6280 / 9694 Time remaining: 0s Progress 6281 / 9694 Time remaining: 0s Progress 6282 / 9694 Time remaining: 0s Progress 6283 / 9694 Time remaining: 0s Progress 6284 / 9694 Time remaining: 0s Progress 6285 / 9694 Time remaining: 0s Progress 6286 / 9694 Time remaining: 0s Progress 6287 / 9694 Time remaining: 0s Progress 6288 / 9694 Time remaining: 0s Progress 6289 / 9694 Time remaining: 0s Progress 6290 / 9694 Time remaining: 0s Progress 6291 / 9694 Time remaining: 0s Progress 6292 / 9694 Time remaining: 0s Progress 6293 / 9694 Time remaining: 0s Progress 6294 / 9694 Time remaining: 0s Progress 6295 / 9694 Time remaining: 0s Progress 6296 / 9694 Time remaining: 0s Progress 6297 / 9694 Time remaining: 0s Progress 6298 / 9694 Time remaining: 0s Progress 6299 / 9694 Time remaining: 0s Progress 6300 / 9694 Time remaining: 0s Progress 6301 / 9694 Time remaining: 0s Progress 6302 / 9694 Time remaining: 0s Progress 6303 / 9694 Time remaining: 0s Progress 6304 / 9694 Time remaining: 0s Progress 6305 / 9694 Time remaining: 0s Progress 6306 / 9694 Time remaining: 0s Progress 6307 / 9694 Time remaining: 0s Progress 6308 / 9694 Time remaining: 0s Progress 6309 / 9694 Time remaining: 0s Progress 6310 / 9694 Time remaining: 0s Progress 6311 / 9694 Time remaining: 0s Progress 6312 / 9694 Time remaining: 0s Progress 6313 / 9694 Time remaining: 0s Progress 6314 / 9694 Time remaining: 0s Progress 6315 / 9694 Time remaining: 0s Progress 6316 / 9694 Time remaining: 0s Progress 6317 / 9694 Time remaining: 0s Progress 6318 / 9694 Time remaining: 0s Progress 6319 / 9694 Time remaining: 0s Progress 6320 / 9694 Time remaining: 0s Progress 6321 / 9694 Time remaining: 0s Progress 6322 / 9694 Time remaining: 0s Progress 6323 / 9694 Time remaining: 0s Progress 6324 / 9694 Time remaining: 0s Progress 6325 / 9694 Time remaining: 0s Progress 6326 / 9694 Time remaining: 0s Progress 6327 / 9694 Time remaining: 0s Progress 6328 / 9694 Time remaining: 0s Progress 6329 / 9694 Time remaining: 0s Progress 6330 / 9694 Time remaining: 0s Progress 6331 / 9694 Time remaining: 0s Progress 6332 / 9694 Time remaining: 0s Progress 6333 / 9694 Time remaining: 0s Progress 6334 / 9694 Time remaining: 0s Progress 6335 / 9694 Time remaining: 0s Progress 6336 / 9694 Time remaining: 0s Progress 6337 / 9694 Time remaining: 0s Progress 6338 / 9694 Time remaining: 0s Progress 6339 / 9694 Time remaining: 0s Progress 6340 / 9694 Time remaining: 0s Progress 6341 / 9694 Time remaining: 0s Progress 6342 / 9694 Time remaining: 0s Progress 6343 / 9694 Time remaining: 0s Progress 6344 / 9694 Time remaining: 0s Progress 6345 / 9694 Time remaining: 0s Progress 6346 / 9694 Time remaining: 0s Progress 6347 / 9694 Time remaining: 0s Progress 6348 / 9694 Time remaining: 0s Progress 6349 / 9694 Time remaining: 0s Progress 6350 / 9694 Time remaining: 0s Progress 6351 / 9694 Time remaining: 0s Progress 6352 / 9694 Time remaining: 0s Progress 6353 / 9694 Time remaining: 0s Progress 6354 / 9694 Time remaining: 0s Progress 6355 / 9694 Time remaining: 0s Progress 6356 / 9694 Time remaining: 0s Progress 6357 / 9694 Time remaining: 0s Progress 6358 / 9694 Time remaining: 0s Progress 6359 / 9694 Time remaining: 0s Progress 6360 / 9694 Time remaining: 0s Progress 6361 / 9694 Time remaining: 0s Progress 6362 / 9694 Time remaining: 0s Progress 6363 / 9694 Time remaining: 0s Progress 6364 / 9694 Time remaining: 0s Progress 6365 / 9694 Time remaining: 0s Progress 6366 / 9694 Time remaining: 0s Progress 6367 / 9694 Time remaining: 0s Progress 6368 / 9694 Time remaining: 0s Progress 6369 / 9694 Time remaining: 0s Progress 6370 / 9694 Time remaining: 0s Progress 6371 / 9694 Time remaining: 0s Progress 6372 / 9694 Time remaining: 0s Progress 6373 / 9694 Time remaining: 0s Progress 6374 / 9694 Time remaining: 0s Progress 6375 / 9694 Time remaining: 0s Progress 6376 / 9694 Time remaining: 0s Progress 6377 / 9694 Time remaining: 0s Progress 6378 / 9694 Time remaining: 0s Progress 6379 / 9694 Time remaining: 0s Progress 6380 / 9694 Time remaining: 0s Progress 6381 / 9694 Time remaining: 0s Progress 6382 / 9694 Time remaining: 0s Progress 6383 / 9694 Time remaining: 0s Progress 6384 / 9694 Time remaining: 0s Progress 6385 / 9694 Time remaining: 0s Progress 6386 / 9694 Time remaining: 0s Progress 6387 / 9694 Time remaining: 0s Progress 6388 / 9694 Time remaining: 0s Progress 6389 / 9694 Time remaining: 0s Progress 6390 / 9694 Time remaining: 0s Progress 6391 / 9694 Time remaining: 0s Progress 6392 / 9694 Time remaining: 0s Progress 6393 / 9694 Time remaining: 0s Progress 6394 / 9694 Time remaining: 0s Progress 6395 / 9694 Time remaining: 0s Progress 6396 / 9694 Time remaining: 0s Progress 6397 / 9694 Time remaining: 0s Progress 6398 / 9694 Time remaining: 0s Progress 6399 / 9694 Time remaining: 0s Progress 6400 / 9694 Time remaining: 0s Progress 6401 / 9694 Time remaining: 0s Progress 6402 / 9694 Time remaining: 0s Progress 6403 / 9694 Time remaining: 0s Progress 6404 / 9694 Time remaining: 0s Progress 6405 / 9694 Time remaining: 0s Progress 6406 / 9694 Time remaining: 0s Progress 6407 / 9694 Time remaining: 0s Progress 6408 / 9694 Time remaining: 0s Progress 6409 / 9694 Time remaining: 0s Progress 6410 / 9694 Time remaining: 0s Progress 6411 / 9694 Time remaining: 0s Progress 6412 / 9694 Time remaining: 0s Progress 6413 / 9694 Time remaining: 0s Progress 6414 / 9694 Time remaining: 0s Progress 6415 / 9694 Time remaining: 0s Progress 6416 / 9694 Time remaining: 0s Progress 6417 / 9694 Time remaining: 0s Progress 6418 / 9694 Time remaining: 0s Progress 6419 / 9694 Time remaining: 0s Progress 6420 / 9694 Time remaining: 0s Progress 6421 / 9694 Time remaining: 0s Progress 6422 / 9694 Time remaining: 0s Progress 6423 / 9694 Time remaining: 0s Progress 6424 / 9694 Time remaining: 0s Progress 6425 / 9694 Time remaining: 0s Progress 6426 / 9694 Time remaining: 0s Progress 6427 / 9694 Time remaining: 0s Progress 6428 / 9694 Time remaining: 0s Progress 6429 / 9694 Time remaining: 0s Progress 6430 / 9694 Time remaining: 0s Progress 6431 / 9694 Time remaining: 0s Progress 6432 / 9694 Time remaining: 0s Progress 6433 / 9694 Time remaining: 0s Progress 6434 / 9694 Time remaining: 0s Progress 6435 / 9694 Time remaining: 0s Progress 6436 / 9694 Time remaining: 0s Progress 6437 / 9694 Time remaining: 0s Progress 6438 / 9694 Time remaining: 0s Progress 6439 / 9694 Time remaining: 0s Progress 6440 / 9694 Time remaining: 0s Progress 6441 / 9694 Time remaining: 0s Progress 6442 / 9694 Time remaining: 0s Progress 6443 / 9694 Time remaining: 0s Progress 6444 / 9694 Time remaining: 0s Progress 6445 / 9694 Time remaining: 0s Progress 6446 / 9694 Time remaining: 0s Progress 6447 / 9694 Time remaining: 0s Progress 6448 / 9694 Time remaining: 0s Progress 6449 / 9694 Time remaining: 0s Progress 6450 / 9694 Time remaining: 0s Progress 6451 / 9694 Time remaining: 0s Progress 6452 / 9694 Time remaining: 0s Progress 6453 / 9694 Time remaining: 0s Progress 6454 / 9694 Time remaining: 0s Progress 6455 / 9694 Time remaining: 0s Progress 6456 / 9694 Time remaining: 0s Progress 6457 / 9694 Time remaining: 0s Progress 6458 / 9694 Time remaining: 0s Progress 6459 / 9694 Time remaining: 0s Progress 6460 / 9694 Time remaining: 0s Progress 6461 / 9694 Time remaining: 0s Progress 6462 / 9694 Time remaining: 0s Progress 6463 / 9694 Time remaining: 0s Progress 6464 / 9694 Time remaining: 0s Progress 6465 / 9694 Time remaining: 0s Progress 6466 / 9694 Time remaining: 0s Progress 6467 / 9694 Time remaining: 0s Progress 6468 / 9694 Time remaining: 0s Progress 6469 / 9694 Time remaining: 0s Progress 6470 / 9694 Time remaining: 0s Progress 6471 / 9694 Time remaining: 0s Progress 6472 / 9694 Time remaining: 0s Progress 6473 / 9694 Time remaining: 0s Progress 6474 / 9694 Time remaining: 0s Progress 6475 / 9694 Time remaining: 0s Progress 6476 / 9694 Time remaining: 0s Progress 6477 / 9694 Time remaining: 0s Progress 6478 / 9694 Time remaining: 0s Progress 6479 / 9694 Time remaining: 0s Progress 6480 / 9694 Time remaining: 0s Progress 6481 / 9694 Time remaining: 0s Progress 6482 / 9694 Time remaining: 0s Progress 6483 / 9694 Time remaining: 0s Progress 6484 / 9694 Time remaining: 0s Progress 6485 / 9694 Time remaining: 0s Progress 6486 / 9694 Time remaining: 0s Progress 6487 / 9694 Time remaining: 0s Progress 6488 / 9694 Time remaining: 0s Progress 6489 / 9694 Time remaining: 0s Progress 6490 / 9694 Time remaining: 0s Progress 6491 / 9694 Time remaining: 0s Progress 6492 / 9694 Time remaining: 0s Progress 6493 / 9694 Time remaining: 0s Progress 6494 / 9694 Time remaining: 0s Progress 6495 / 9694 Time remaining: 0s Progress 6496 / 9694 Time remaining: 0s Progress 6497 / 9694 Time remaining: 0s Progress 6498 / 9694 Time remaining: 0s Progress 6499 / 9694 Time remaining: 0s Progress 6500 / 9694 Time remaining: 0s Progress 6501 / 9694 Time remaining: 0s Progress 6502 / 9694 Time remaining: 0s Progress 6503 / 9694 Time remaining: 0s Progress 6504 / 9694 Time remaining: 0s Progress 6505 / 9694 Time remaining: 0s Progress 6506 / 9694 Time remaining: 0s Progress 6507 / 9694 Time remaining: 0s Progress 6508 / 9694 Time remaining: 0s Progress 6509 / 9694 Time remaining: 0s Progress 6510 / 9694 Time remaining: 0s Progress 6511 / 9694 Time remaining: 0s Progress 6512 / 9694 Time remaining: 0s Progress 6513 / 9694 Time remaining: 0s Progress 6514 / 9694 Time remaining: 0s Progress 6515 / 9694 Time remaining: 0s Progress 6516 / 9694 Time remaining: 0s Progress 6517 / 9694 Time remaining: 0s Progress 6518 / 9694 Time remaining: 0s Progress 6519 / 9694 Time remaining: 0s Progress 6520 / 9694 Time remaining: 0s Progress 6521 / 9694 Time remaining: 0s Progress 6522 / 9694 Time remaining: 0s Progress 6523 / 9694 Time remaining: 0s Progress 6524 / 9694 Time remaining: 0s Progress 6525 / 9694 Time remaining: 0s Progress 6526 / 9694 Time remaining: 0s Progress 6527 / 9694 Time remaining: 0s Progress 6528 / 9694 Time remaining: 0s Progress 6529 / 9694 Time remaining: 0s Progress 6530 / 9694 Time remaining: 0s Progress 6531 / 9694 Time remaining: 0s Progress 6532 / 9694 Time remaining: 0s Progress 6533 / 9694 Time remaining: 0s Progress 6534 / 9694 Time remaining: 0s Progress 6535 / 9694 Time remaining: 0s Progress 6536 / 9694 Time remaining: 0s Progress 6537 / 9694 Time remaining: 0s Progress 6538 / 9694 Time remaining: 0s Progress 6539 / 9694 Time remaining: 0s Progress 6540 / 9694 Time remaining: 0s Progress 6541 / 9694 Time remaining: 0s Progress 6542 / 9694 Time remaining: 0s Progress 6543 / 9694 Time remaining: 0s Progress 6544 / 9694 Time remaining: 0s Progress 6545 / 9694 Time remaining: 0s Progress 6546 / 9694 Time remaining: 0s Progress 6547 / 9694 Time remaining: 0s Progress 6548 / 9694 Time remaining: 0s Progress 6549 / 9694 Time remaining: 0s Progress 6550 / 9694 Time remaining: 0s Progress 6551 / 9694 Time remaining: 0s Progress 6552 / 9694 Time remaining: 0s Progress 6553 / 9694 Time remaining: 0s Progress 6554 / 9694 Time remaining: 0s Progress 6555 / 9694 Time remaining: 0s Progress 6556 / 9694 Time remaining: 0s Progress 6557 / 9694 Time remaining: 0s Progress 6558 / 9694 Time remaining: 0s Progress 6559 / 9694 Time remaining: 0s Progress 6560 / 9694 Time remaining: 0s Progress 6561 / 9694 Time remaining: 0s Progress 6562 / 9694 Time remaining: 0s Progress 6563 / 9694 Time remaining: 0s Progress 6564 / 9694 Time remaining: 0s Progress 6565 / 9694 Time remaining: 0s Progress 6566 / 9694 Time remaining: 0s Progress 6567 / 9694 Time remaining: 0s Progress 6568 / 9694 Time remaining: 0s Progress 6569 / 9694 Time remaining: 0s Progress 6570 / 9694 Time remaining: 0s Progress 6571 / 9694 Time remaining: 0s Progress 6572 / 9694 Time remaining: 0s Progress 6573 / 9694 Time remaining: 0s Progress 6574 / 9694 Time remaining: 0s Progress 6575 / 9694 Time remaining: 0s Progress 6576 / 9694 Time remaining: 0s Progress 6577 / 9694 Time remaining: 0s Progress 6578 / 9694 Time remaining: 0s Progress 6579 / 9694 Time remaining: 0s Progress 6580 / 9694 Time remaining: 0s Progress 6581 / 9694 Time remaining: 0s Progress 6582 / 9694 Time remaining: 0s Progress 6583 / 9694 Time remaining: 0s Progress 6584 / 9694 Time remaining: 0s Progress 6585 / 9694 Time remaining: 0s Progress 6586 / 9694 Time remaining: 0s Progress 6587 / 9694 Time remaining: 0s Progress 6588 / 9694 Time remaining: 0s Progress 6589 / 9694 Time remaining: 0s Progress 6590 / 9694 Time remaining: 0s Progress 6591 / 9694 Time remaining: 0s Progress 6592 / 9694 Time remaining: 0s Progress 6593 / 9694 Time remaining: 0s Progress 6594 / 9694 Time remaining: 0s Progress 6595 / 9694 Time remaining: 0s Progress 6596 / 9694 Time remaining: 0s Progress 6597 / 9694 Time remaining: 0s Progress 6598 / 9694 Time remaining: 0s Progress 6599 / 9694 Time remaining: 0s Progress 6600 / 9694 Time remaining: 0s Progress 6601 / 9694 Time remaining: 0s Progress 6602 / 9694 Time remaining: 0s Progress 6603 / 9694 Time remaining: 0s Progress 6604 / 9694 Time remaining: 0s Progress 6605 / 9694 Time remaining: 0s Progress 6606 / 9694 Time remaining: 0s Progress 6607 / 9694 Time remaining: 0s Progress 6608 / 9694 Time remaining: 0s Progress 6609 / 9694 Time remaining: 0s Progress 6610 / 9694 Time remaining: 0s Progress 6611 / 9694 Time remaining: 0s Progress 6612 / 9694 Time remaining: 0s Progress 6613 / 9694 Time remaining: 0s Progress 6614 / 9694 Time remaining: 0s Progress 6615 / 9694 Time remaining: 0s Progress 6616 / 9694 Time remaining: 0s Progress 6617 / 9694 Time remaining: 0s Progress 6618 / 9694 Time remaining: 0s Progress 6619 / 9694 Time remaining: 0s Progress 6620 / 9694 Time remaining: 0s Progress 6621 / 9694 Time remaining: 0s Progress 6622 / 9694 Time remaining: 0s Progress 6623 / 9694 Time remaining: 0s Progress 6624 / 9694 Time remaining: 0s Progress 6625 / 9694 Time remaining: 0s Progress 6626 / 9694 Time remaining: 0s Progress 6627 / 9694 Time remaining: 0s Progress 6628 / 9694 Time remaining: 0s Progress 6629 / 9694 Time remaining: 0s Progress 6630 / 9694 Time remaining: 0s Progress 6631 / 9694 Time remaining: 0s Progress 6632 / 9694 Time remaining: 0s Progress 6633 / 9694 Time remaining: 0s Progress 6634 / 9694 Time remaining: 0s Progress 6635 / 9694 Time remaining: 0s Progress 6636 / 9694 Time remaining: 0s Progress 6637 / 9694 Time remaining: 0s Progress 6638 / 9694 Time remaining: 0s Progress 6639 / 9694 Time remaining: 0s Progress 6640 / 9694 Time remaining: 0s Progress 6641 / 9694 Time remaining: 0s Progress 6642 / 9694 Time remaining: 0s Progress 6643 / 9694 Time remaining: 0s Progress 6644 / 9694 Time remaining: 0s Progress 6645 / 9694 Time remaining: 0s Progress 6646 / 9694 Time remaining: 0s Progress 6647 / 9694 Time remaining: 0s Progress 6648 / 9694 Time remaining: 0s Progress 6649 / 9694 Time remaining: 0s Progress 6650 / 9694 Time remaining: 0s Progress 6651 / 9694 Time remaining: 0s Progress 6652 / 9694 Time remaining: 0s Progress 6653 / 9694 Time remaining: 0s Progress 6654 / 9694 Time remaining: 0s Progress 6655 / 9694 Time remaining: 0s Progress 6656 / 9694 Time remaining: 0s Progress 6657 / 9694 Time remaining: 0s Progress 6658 / 9694 Time remaining: 0s Progress 6659 / 9694 Time remaining: 0s Progress 6660 / 9694 Time remaining: 0s Progress 6661 / 9694 Time remaining: 0s Progress 6662 / 9694 Time remaining: 0s Progress 6663 / 9694 Time remaining: 0s Progress 6664 / 9694 Time remaining: 0s Progress 6665 / 9694 Time remaining: 0s Progress 6666 / 9694 Time remaining: 0s Progress 6667 / 9694 Time remaining: 0s Progress 6668 / 9694 Time remaining: 0s Progress 6669 / 9694 Time remaining: 0s Progress 6670 / 9694 Time remaining: 0s Progress 6671 / 9694 Time remaining: 0s Progress 6672 / 9694 Time remaining: 0s Progress 6673 / 9694 Time remaining: 0s Progress 6674 / 9694 Time remaining: 0s Progress 6675 / 9694 Time remaining: 0s Progress 6676 / 9694 Time remaining: 0s Progress 6677 / 9694 Time remaining: 0s Progress 6678 / 9694 Time remaining: 0s Progress 6679 / 9694 Time remaining: 0s Progress 6680 / 9694 Time remaining: 0s Progress 6681 / 9694 Time remaining: 0s Progress 6682 / 9694 Time remaining: 0s Progress 6683 / 9694 Time remaining: 0s Progress 6684 / 9694 Time remaining: 0s Progress 6685 / 9694 Time remaining: 0s Progress 6686 / 9694 Time remaining: 0s Progress 6687 / 9694 Time remaining: 0s Progress 6688 / 9694 Time remaining: 0s Progress 6689 / 9694 Time remaining: 0s Progress 6690 / 9694 Time remaining: 0s Progress 6691 / 9694 Time remaining: 0s Progress 6692 / 9694 Time remaining: 0s Progress 6693 / 9694 Time remaining: 0s Progress 6694 / 9694 Time remaining: 0s Progress 6695 / 9694 Time remaining: 0s Progress 6696 / 9694 Time remaining: 0s Progress 6697 / 9694 Time remaining: 0s Progress 6698 / 9694 Time remaining: 0s Progress 6699 / 9694 Time remaining: 0s Progress 6700 / 9694 Time remaining: 0s Progress 6701 / 9694 Time remaining: 0s Progress 6702 / 9694 Time remaining: 0s Progress 6703 / 9694 Time remaining: 0s Progress 6704 / 9694 Time remaining: 0s Progress 6705 / 9694 Time remaining: 0s Progress 6706 / 9694 Time remaining: 0s Progress 6707 / 9694 Time remaining: 0s Progress 6708 / 9694 Time remaining: 0s Progress 6709 / 9694 Time remaining: 0s Progress 6710 / 9694 Time remaining: 0s Progress 6711 / 9694 Time remaining: 0s Progress 6712 / 9694 Time remaining: 0s Progress 6713 / 9694 Time remaining: 0s Progress 6714 / 9694 Time remaining: 0s Progress 6715 / 9694 Time remaining: 0s Progress 6716 / 9694 Time remaining: 0s Progress 6717 / 9694 Time remaining: 0s Progress 6718 / 9694 Time remaining: 0s Progress 6719 / 9694 Time remaining: 0s Progress 6720 / 9694 Time remaining: 0s Progress 6721 / 9694 Time remaining: 0s Progress 6722 / 9694 Time remaining: 0s Progress 6723 / 9694 Time remaining: 0s Progress 6724 / 9694 Time remaining: 0s Progress 6725 / 9694 Time remaining: 0s Progress 6726 / 9694 Time remaining: 0s Progress 6727 / 9694 Time remaining: 0s Progress 6728 / 9694 Time remaining: 0s Progress 6729 / 9694 Time remaining: 0s Progress 6730 / 9694 Time remaining: 0s Progress 6731 / 9694 Time remaining: 0s Progress 6732 / 9694 Time remaining: 0s Progress 6733 / 9694 Time remaining: 0s Progress 6734 / 9694 Time remaining: 0s Progress 6735 / 9694 Time remaining: 0s Progress 6736 / 9694 Time remaining: 0s Progress 6737 / 9694 Time remaining: 0s Progress 6738 / 9694 Time remaining: 0s Progress 6739 / 9694 Time remaining: 0s Progress 6740 / 9694 Time remaining: 0s Progress 6741 / 9694 Time remaining: 0s Progress 6742 / 9694 Time remaining: 0s Progress 6743 / 9694 Time remaining: 0s Progress 6744 / 9694 Time remaining: 0s Progress 6745 / 9694 Time remaining: 0s Progress 6746 / 9694 Time remaining: 0s Progress 6747 / 9694 Time remaining: 0s Progress 6748 / 9694 Time remaining: 0s Progress 6749 / 9694 Time remaining: 0s Progress 6750 / 9694 Time remaining: 0s Progress 6751 / 9694 Time remaining: 0s Progress 6752 / 9694 Time remaining: 0s Progress 6753 / 9694 Time remaining: 0s Progress 6754 / 9694 Time remaining: 0s Progress 6755 / 9694 Time remaining: 0s Progress 6756 / 9694 Time remaining: 0s Progress 6757 / 9694 Time remaining: 0s Progress 6758 / 9694 Time remaining: 0s Progress 6759 / 9694 Time remaining: 0s Progress 6760 / 9694 Time remaining: 0s Progress 6761 / 9694 Time remaining: 0s Progress 6762 / 9694 Time remaining: 0s Progress 6763 / 9694 Time remaining: 0s Progress 6764 / 9694 Time remaining: 0s Progress 6765 / 9694 Time remaining: 0s Progress 6766 / 9694 Time remaining: 0s Progress 6767 / 9694 Time remaining: 0s Progress 6768 / 9694 Time remaining: 0s Progress 6769 / 9694 Time remaining: 0s Progress 6770 / 9694 Time remaining: 0s Progress 6771 / 9694 Time remaining: 0s Progress 6772 / 9694 Time remaining: 0s Progress 6773 / 9694 Time remaining: 0s Progress 6774 / 9694 Time remaining: 0s Progress 6775 / 9694 Time remaining: 0s Progress 6776 / 9694 Time remaining: 0s Progress 6777 / 9694 Time remaining: 0s Progress 6778 / 9694 Time remaining: 0s Progress 6779 / 9694 Time remaining: 0s Progress 6780 / 9694 Time remaining: 0s Progress 6781 / 9694 Time remaining: 0s Progress 6782 / 9694 Time remaining: 0s Progress 6783 / 9694 Time remaining: 0s Progress 6784 / 9694 Time remaining: 0s Progress 6785 / 9694 Time remaining: 0s Progress 6786 / 9694 Time remaining: 0s Progress 6787 / 9694 Time remaining: 0s Progress 6788 / 9694 Time remaining: 0s Progress 6789 / 9694 Time remaining: 0s Progress 6790 / 9694 Time remaining: 0s Progress 6791 / 9694 Time remaining: 0s Progress 6792 / 9694 Time remaining: 0s Progress 6793 / 9694 Time remaining: 0s Progress 6794 / 9694 Time remaining: 0s Progress 6795 / 9694 Time remaining: 0s Progress 6796 / 9694 Time remaining: 0s Progress 6797 / 9694 Time remaining: 0s Progress 6798 / 9694 Time remaining: 0s Progress 6799 / 9694 Time remaining: 0s Progress 6800 / 9694 Time remaining: 0s Progress 6801 / 9694 Time remaining: 0s Progress 6802 / 9694 Time remaining: 0s Progress 6803 / 9694 Time remaining: 0s Progress 6804 / 9694 Time remaining: 0s Progress 6805 / 9694 Time remaining: 0s Progress 6806 / 9694 Time remaining: 0s Progress 6807 / 9694 Time remaining: 0s Progress 6808 / 9694 Time remaining: 0s Progress 6809 / 9694 Time remaining: 0s Progress 6810 / 9694 Time remaining: 0s Progress 6811 / 9694 Time remaining: 0s Progress 6812 / 9694 Time remaining: 0s Progress 6813 / 9694 Time remaining: 0s Progress 6814 / 9694 Time remaining: 0s Progress 6815 / 9694 Time remaining: 0s Progress 6816 / 9694 Time remaining: 0s Progress 6817 / 9694 Time remaining: 0s Progress 6818 / 9694 Time remaining: 0s Progress 6819 / 9694 Time remaining: 0s Progress 6820 / 9694 Time remaining: 0s Progress 6821 / 9694 Time remaining: 0s Progress 6822 / 9694 Time remaining: 0s Progress 6823 / 9694 Time remaining: 0s Progress 6824 / 9694 Time remaining: 0s Progress 6825 / 9694 Time remaining: 0s Progress 6826 / 9694 Time remaining: 0s Progress 6827 / 9694 Time remaining: 0s Progress 6828 / 9694 Time remaining: 0s Progress 6829 / 9694 Time remaining: 0s Progress 6830 / 9694 Time remaining: 0s Progress 6831 / 9694 Time remaining: 0s Progress 6832 / 9694 Time remaining: 0s Progress 6833 / 9694 Time remaining: 0s Progress 6834 / 9694 Time remaining: 0s Progress 6835 / 9694 Time remaining: 0s Progress 6836 / 9694 Time remaining: 0s Progress 6837 / 9694 Time remaining: 0s Progress 6838 / 9694 Time remaining: 0s Progress 6839 / 9694 Time remaining: 0s Progress 6840 / 9694 Time remaining: 0s Progress 6841 / 9694 Time remaining: 0s Progress 6842 / 9694 Time remaining: 0s Progress 6843 / 9694 Time remaining: 0s Progress 6844 / 9694 Time remaining: 0s Progress 6845 / 9694 Time remaining: 0s Progress 6846 / 9694 Time remaining: 0s Progress 6847 / 9694 Time remaining: 0s Progress 6848 / 9694 Time remaining: 0s Progress 6849 / 9694 Time remaining: 0s Progress 6850 / 9694 Time remaining: 0s Progress 6851 / 9694 Time remaining: 0s Progress 6852 / 9694 Time remaining: 0s Progress 6853 / 9694 Time remaining: 0s Progress 6854 / 9694 Time remaining: 0s Progress 6855 / 9694 Time remaining: 0s Progress 6856 / 9694 Time remaining: 0s Progress 6857 / 9694 Time remaining: 0s Progress 6858 / 9694 Time remaining: 0s Progress 6859 / 9694 Time remaining: 0s Progress 6860 / 9694 Time remaining: 0s Progress 6861 / 9694 Time remaining: 0s Progress 6862 / 9694 Time remaining: 0s Progress 6863 / 9694 Time remaining: 0s Progress 6864 / 9694 Time remaining: 0s Progress 6865 / 9694 Time remaining: 0s Progress 6866 / 9694 Time remaining: 0s Progress 6867 / 9694 Time remaining: 0s Progress 6868 / 9694 Time remaining: 0s Progress 6869 / 9694 Time remaining: 0s Progress 6870 / 9694 Time remaining: 0s Progress 6871 / 9694 Time remaining: 0s Progress 6872 / 9694 Time remaining: 0s Progress 6873 / 9694 Time remaining: 0s Progress 6874 / 9694 Time remaining: 0s Progress 6875 / 9694 Time remaining: 0s Progress 6876 / 9694 Time remaining: 0s Progress 6877 / 9694 Time remaining: 0s Progress 6878 / 9694 Time remaining: 0s Progress 6879 / 9694 Time remaining: 0s Progress 6880 / 9694 Time remaining: 0s Progress 6881 / 9694 Time remaining: 0s Progress 6882 / 9694 Time remaining: 0s Progress 6883 / 9694 Time remaining: 0s Progress 6884 / 9694 Time remaining: 0s Progress 6885 / 9694 Time remaining: 0s Progress 6886 / 9694 Time remaining: 0s Progress 6887 / 9694 Time remaining: 0s Progress 6888 / 9694 Time remaining: 0s Progress 6889 / 9694 Time remaining: 0s Progress 6890 / 9694 Time remaining: 0s Progress 6891 / 9694 Time remaining: 0s Progress 6892 / 9694 Time remaining: 0s Progress 6893 / 9694 Time remaining: 0s Progress 6894 / 9694 Time remaining: 0s Progress 6895 / 9694 Time remaining: 0s Progress 6896 / 9694 Time remaining: 0s Progress 6897 / 9694 Time remaining: 0s Progress 6898 / 9694 Time remaining: 0s Progress 6899 / 9694 Time remaining: 0s Progress 6900 / 9694 Time remaining: 0s Progress 6901 / 9694 Time remaining: 0s Progress 6902 / 9694 Time remaining: 0s Progress 6903 / 9694 Time remaining: 0s Progress 6904 / 9694 Time remaining: 0s Progress 6905 / 9694 Time remaining: 0s Progress 6906 / 9694 Time remaining: 0s Progress 6907 / 9694 Time remaining: 0s Progress 6908 / 9694 Time remaining: 0s Progress 6909 / 9694 Time remaining: 0s Progress 6910 / 9694 Time remaining: 0s Progress 6911 / 9694 Time remaining: 0s Progress 6912 / 9694 Time remaining: 0s Progress 6913 / 9694 Time remaining: 0s Progress 6914 / 9694 Time remaining: 0s Progress 6915 / 9694 Time remaining: 0s Progress 6916 / 9694 Time remaining: 0s Progress 6917 / 9694 Time remaining: 0s Progress 6918 / 9694 Time remaining: 0s Progress 6919 / 9694 Time remaining: 0s Progress 6920 / 9694 Time remaining: 0s Progress 6921 / 9694 Time remaining: 0s Progress 6922 / 9694 Time remaining: 0s Progress 6923 / 9694 Time remaining: 0s Progress 6924 / 9694 Time remaining: 0s Progress 6925 / 9694 Time remaining: 0s Progress 6926 / 9694 Time remaining: 0s Progress 6927 / 9694 Time remaining: 0s Progress 6928 / 9694 Time remaining: 0s Progress 6929 / 9694 Time remaining: 0s Progress 6930 / 9694 Time remaining: 0s Progress 6931 / 9694 Time remaining: 0s Progress 6932 / 9694 Time remaining: 0s Progress 6933 / 9694 Time remaining: 0s Progress 6934 / 9694 Time remaining: 0s Progress 6935 / 9694 Time remaining: 0s Progress 6936 / 9694 Time remaining: 0s Progress 6937 / 9694 Time remaining: 0s Progress 6938 / 9694 Time remaining: 0s Progress 6939 / 9694 Time remaining: 0s Progress 6940 / 9694 Time remaining: 0s Progress 6941 / 9694 Time remaining: 0s Progress 6942 / 9694 Time remaining: 0s Progress 6943 / 9694 Time remaining: 0s Progress 6944 / 9694 Time remaining: 0s Progress 6945 / 9694 Time remaining: 0s Progress 6946 / 9694 Time remaining: 0s Progress 6947 / 9694 Time remaining: 0s Progress 6948 / 9694 Time remaining: 0s Progress 6949 / 9694 Time remaining: 0s Progress 6950 / 9694 Time remaining: 0s Progress 6951 / 9694 Time remaining: 0s Progress 6952 / 9694 Time remaining: 0s Progress 6953 / 9694 Time remaining: 0s Progress 6954 / 9694 Time remaining: 0s Progress 6955 / 9694 Time remaining: 0s Progress 6956 / 9694 Time remaining: 0s Progress 6957 / 9694 Time remaining: 0s Progress 6958 / 9694 Time remaining: 0s Progress 6959 / 9694 Time remaining: 0s Progress 6960 / 9694 Time remaining: 0s Progress 6961 / 9694 Time remaining: 0s Progress 6962 / 9694 Time remaining: 0s Progress 6963 / 9694 Time remaining: 0s Progress 6964 / 9694 Time remaining: 0s Progress 6965 / 9694 Time remaining: 0s Progress 6966 / 9694 Time remaining: 0s Progress 6967 / 9694 Time remaining: 0s Progress 6968 / 9694 Time remaining: 0s Progress 6969 / 9694 Time remaining: 0s Progress 6970 / 9694 Time remaining: 0s Progress 6971 / 9694 Time remaining: 0s Progress 6972 / 9694 Time remaining: 0s Progress 6973 / 9694 Time remaining: 0s Progress 6974 / 9694 Time remaining: 0s Progress 6975 / 9694 Time remaining: 0s Progress 6976 / 9694 Time remaining: 0s Progress 6977 / 9694 Time remaining: 0s Progress 6978 / 9694 Time remaining: 0s Progress 6979 / 9694 Time remaining: 0s Progress 6980 / 9694 Time remaining: 0s Progress 6981 / 9694 Time remaining: 0s Progress 6982 / 9694 Time remaining: 0s Progress 6983 / 9694 Time remaining: 0s Progress 6984 / 9694 Time remaining: 0s Progress 6985 / 9694 Time remaining: 0s Progress 6986 / 9694 Time remaining: 0s Progress 6987 / 9694 Time remaining: 0s Progress 6988 / 9694 Time remaining: 0s Progress 6989 / 9694 Time remaining: 0s Progress 6990 / 9694 Time remaining: 0s Progress 6991 / 9694 Time remaining: 0s Progress 6992 / 9694 Time remaining: 0s Progress 6993 / 9694 Time remaining: 0s Progress 6994 / 9694 Time remaining: 0s Progress 6995 / 9694 Time remaining: 0s Progress 6996 / 9694 Time remaining: 0s Progress 6997 / 9694 Time remaining: 0s Progress 6998 / 9694 Time remaining: 0s Progress 6999 / 9694 Time remaining: 0s Progress 7000 / 9694 Time remaining: 0s Progress 7001 / 9694 Time remaining: 0s Progress 7002 / 9694 Time remaining: 0s Progress 7003 / 9694 Time remaining: 0s Progress 7004 / 9694 Time remaining: 0s Progress 7005 / 9694 Time remaining: 0s Progress 7006 / 9694 Time remaining: 0s Progress 7007 / 9694 Time remaining: 0s Progress 7008 / 9694 Time remaining: 0s Progress 7009 / 9694 Time remaining: 0s Progress 7010 / 9694 Time remaining: 0s Progress 7011 / 9694 Time remaining: 0s Progress 7012 / 9694 Time remaining: 0s Progress 7013 / 9694 Time remaining: 0s Progress 7014 / 9694 Time remaining: 0s Progress 7015 / 9694 Time remaining: 0s Progress 7016 / 9694 Time remaining: 0s Progress 7017 / 9694 Time remaining: 0s Progress 7018 / 9694 Time remaining: 0s Progress 7019 / 9694 Time remaining: 0s Progress 7020 / 9694 Time remaining: 0s Progress 7021 / 9694 Time remaining: 0s Progress 7022 / 9694 Time remaining: 0s Progress 7023 / 9694 Time remaining: 0s Progress 7024 / 9694 Time remaining: 0s Progress 7025 / 9694 Time remaining: 0s Progress 7026 / 9694 Time remaining: 0s Progress 7027 / 9694 Time remaining: 0s Progress 7028 / 9694 Time remaining: 0s Progress 7029 / 9694 Time remaining: 0s Progress 7030 / 9694 Time remaining: 0s Progress 7031 / 9694 Time remaining: 0s Progress 7032 / 9694 Time remaining: 0s Progress 7033 / 9694 Time remaining: 0s Progress 7034 / 9694 Time remaining: 0s Progress 7035 / 9694 Time remaining: 0s Progress 7036 / 9694 Time remaining: 0s Progress 7037 / 9694 Time remaining: 0s Progress 7038 / 9694 Time remaining: 0s Progress 7039 / 9694 Time remaining: 0s Progress 7040 / 9694 Time remaining: 0s Progress 7041 / 9694 Time remaining: 0s Progress 7042 / 9694 Time remaining: 0s Progress 7043 / 9694 Time remaining: 0s Progress 7044 / 9694 Time remaining: 0s Progress 7045 / 9694 Time remaining: 0s Progress 7046 / 9694 Time remaining: 0s Progress 7047 / 9694 Time remaining: 0s Progress 7048 / 9694 Time remaining: 0s Progress 7049 / 9694 Time remaining: 0s Progress 7050 / 9694 Time remaining: 0s Progress 7051 / 9694 Time remaining: 0s Progress 7052 / 9694 Time remaining: 0s Progress 7053 / 9694 Time remaining: 0s Progress 7054 / 9694 Time remaining: 0s Progress 7055 / 9694 Time remaining: 0s Progress 7056 / 9694 Time remaining: 0s Progress 7057 / 9694 Time remaining: 0s Progress 7058 / 9694 Time remaining: 0s Progress 7059 / 9694 Time remaining: 0s Progress 7060 / 9694 Time remaining: 0s Progress 7061 / 9694 Time remaining: 0s Progress 7062 / 9694 Time remaining: 0s Progress 7063 / 9694 Time remaining: 0s Progress 7064 / 9694 Time remaining: 0s Progress 7065 / 9694 Time remaining: 0s Progress 7066 / 9694 Time remaining: 0s Progress 7067 / 9694 Time remaining: 0s Progress 7068 / 9694 Time remaining: 0s Progress 7069 / 9694 Time remaining: 0s Progress 7070 / 9694 Time remaining: 0s Progress 7071 / 9694 Time remaining: 0s Progress 7072 / 9694 Time remaining: 0s Progress 7073 / 9694 Time remaining: 0s Progress 7074 / 9694 Time remaining: 0s Progress 7075 / 9694 Time remaining: 0s Progress 7076 / 9694 Time remaining: 0s Progress 7077 / 9694 Time remaining: 0s Progress 7078 / 9694 Time remaining: 0s Progress 7079 / 9694 Time remaining: 0s Progress 7080 / 9694 Time remaining: 0s Progress 7081 / 9694 Time remaining: 0s Progress 7082 / 9694 Time remaining: 0s Progress 7083 / 9694 Time remaining: 0s Progress 7084 / 9694 Time remaining: 0s Progress 7085 / 9694 Time remaining: 0s Progress 7086 / 9694 Time remaining: 0s Progress 7087 / 9694 Time remaining: 0s Progress 7088 / 9694 Time remaining: 0s Progress 7089 / 9694 Time remaining: 0s Progress 7090 / 9694 Time remaining: 0s Progress 7091 / 9694 Time remaining: 0s Progress 7092 / 9694 Time remaining: 0s Progress 7093 / 9694 Time remaining: 0s Progress 7094 / 9694 Time remaining: 0s Progress 7095 / 9694 Time remaining: 0s Progress 7096 / 9694 Time remaining: 0s Progress 7097 / 9694 Time remaining: 0s Progress 7098 / 9694 Time remaining: 0s Progress 7099 / 9694 Time remaining: 0s Progress 7100 / 9694 Time remaining: 0s Progress 7101 / 9694 Time remaining: 0s Progress 7102 / 9694 Time remaining: 0s Progress 7103 / 9694 Time remaining: 0s Progress 7104 / 9694 Time remaining: 0s Progress 7105 / 9694 Time remaining: 0s Progress 7106 / 9694 Time remaining: 0s Progress 7107 / 9694 Time remaining: 0s Progress 7108 / 9694 Time remaining: 0s Progress 7109 / 9694 Time remaining: 0s Progress 7110 / 9694 Time remaining: 0s Progress 7111 / 9694 Time remaining: 0s Progress 7112 / 9694 Time remaining: 0s Progress 7113 / 9694 Time remaining: 0s Progress 7114 / 9694 Time remaining: 0s Progress 7115 / 9694 Time remaining: 0s Progress 7116 / 9694 Time remaining: 0s Progress 7117 / 9694 Time remaining: 0s Progress 7118 / 9694 Time remaining: 0s Progress 7119 / 9694 Time remaining: 0s Progress 7120 / 9694 Time remaining: 0s Progress 7121 / 9694 Time remaining: 0s Progress 7122 / 9694 Time remaining: 0s Progress 7123 / 9694 Time remaining: 0s Progress 7124 / 9694 Time remaining: 0s Progress 7125 / 9694 Time remaining: 0s Progress 7126 / 9694 Time remaining: 0s Progress 7127 / 9694 Time remaining: 0s Progress 7128 / 9694 Time remaining: 0s Progress 7129 / 9694 Time remaining: 0s Progress 7130 / 9694 Time remaining: 0s Progress 7131 / 9694 Time remaining: 0s Progress 7132 / 9694 Time remaining: 0s Progress 7133 / 9694 Time remaining: 0s Progress 7134 / 9694 Time remaining: 0s Progress 7135 / 9694 Time remaining: 0s Progress 7136 / 9694 Time remaining: 0s Progress 7137 / 9694 Time remaining: 0s Progress 7138 / 9694 Time remaining: 0s Progress 7139 / 9694 Time remaining: 0s Progress 7140 / 9694 Time remaining: 0s Progress 7141 / 9694 Time remaining: 0s Progress 7142 / 9694 Time remaining: 0s Progress 7143 / 9694 Time remaining: 0s Progress 7144 / 9694 Time remaining: 0s Progress 7145 / 9694 Time remaining: 0s Progress 7146 / 9694 Time remaining: 0s Progress 7147 / 9694 Time remaining: 0s Progress 7148 / 9694 Time remaining: 0s Progress 7149 / 9694 Time remaining: 0s Progress 7150 / 9694 Time remaining: 0s Progress 7151 / 9694 Time remaining: 0s Progress 7152 / 9694 Time remaining: 0s Progress 7153 / 9694 Time remaining: 0s Progress 7154 / 9694 Time remaining: 0s Progress 7155 / 9694 Time remaining: 0s Progress 7156 / 9694 Time remaining: 0s Progress 7157 / 9694 Time remaining: 0s Progress 7158 / 9694 Time remaining: 0s Progress 7159 / 9694 Time remaining: 0s Progress 7160 / 9694 Time remaining: 0s Progress 7161 / 9694 Time remaining: 0s Progress 7162 / 9694 Time remaining: 0s Progress 7163 / 9694 Time remaining: 0s Progress 7164 / 9694 Time remaining: 0s Progress 7165 / 9694 Time remaining: 0s Progress 7166 / 9694 Time remaining: 0s Progress 7167 / 9694 Time remaining: 0s Progress 7168 / 9694 Time remaining: 0s Progress 7169 / 9694 Time remaining: 0s Progress 7170 / 9694 Time remaining: 0s Progress 7171 / 9694 Time remaining: 0s Progress 7172 / 9694 Time remaining: 0s Progress 7173 / 9694 Time remaining: 0s Progress 7174 / 9694 Time remaining: 0s Progress 7175 / 9694 Time remaining: 0s Progress 7176 / 9694 Time remaining: 0s Progress 7177 / 9694 Time remaining: 0s Progress 7178 / 9694 Time remaining: 0s Progress 7179 / 9694 Time remaining: 0s Progress 7180 / 9694 Time remaining: 0s Progress 7181 / 9694 Time remaining: 0s Progress 7182 / 9694 Time remaining: 0s Progress 7183 / 9694 Time remaining: 0s Progress 7184 / 9694 Time remaining: 0s Progress 7185 / 9694 Time remaining: 0s Progress 7186 / 9694 Time remaining: 0s Progress 7187 / 9694 Time remaining: 0s Progress 7188 / 9694 Time remaining: 0s Progress 7189 / 9694 Time remaining: 0s Progress 7190 / 9694 Time remaining: 0s Progress 7191 / 9694 Time remaining: 0s Progress 7192 / 9694 Time remaining: 0s Progress 7193 / 9694 Time remaining: 0s Progress 7194 / 9694 Time remaining: 0s Progress 7195 / 9694 Time remaining: 0s Progress 7196 / 9694 Time remaining: 0s Progress 7197 / 9694 Time remaining: 0s Progress 7198 / 9694 Time remaining: 0s Progress 7199 / 9694 Time remaining: 0s Progress 7200 / 9694 Time remaining: 0s Progress 7201 / 9694 Time remaining: 0s Progress 7202 / 9694 Time remaining: 0s Progress 7203 / 9694 Time remaining: 0s Progress 7204 / 9694 Time remaining: 0s Progress 7205 / 9694 Time remaining: 0s Progress 7206 / 9694 Time remaining: 0s Progress 7207 / 9694 Time remaining: 0s Progress 7208 / 9694 Time remaining: 0s Progress 7209 / 9694 Time remaining: 0s Progress 7210 / 9694 Time remaining: 0s Progress 7211 / 9694 Time remaining: 0s Progress 7212 / 9694 Time remaining: 0s Progress 7213 / 9694 Time remaining: 0s Progress 7214 / 9694 Time remaining: 0s Progress 7215 / 9694 Time remaining: 0s Progress 7216 / 9694 Time remaining: 0s Progress 7217 / 9694 Time remaining: 0s Progress 7218 / 9694 Time remaining: 0s Progress 7219 / 9694 Time remaining: 0s Progress 7220 / 9694 Time remaining: 0s Progress 7221 / 9694 Time remaining: 0s Progress 7222 / 9694 Time remaining: 0s Progress 7223 / 9694 Time remaining: 0s Progress 7224 / 9694 Time remaining: 0s Progress 7225 / 9694 Time remaining: 0s Progress 7226 / 9694 Time remaining: 0s Progress 7227 / 9694 Time remaining: 0s Progress 7228 / 9694 Time remaining: 0s Progress 7229 / 9694 Time remaining: 0s Progress 7230 / 9694 Time remaining: 0s Progress 7231 / 9694 Time remaining: 0s Progress 7232 / 9694 Time remaining: 0s Progress 7233 / 9694 Time remaining: 0s Progress 7234 / 9694 Time remaining: 0s Progress 7235 / 9694 Time remaining: 0s Progress 7236 / 9694 Time remaining: 0s Progress 7237 / 9694 Time remaining: 0s Progress 7238 / 9694 Time remaining: 0s Progress 7239 / 9694 Time remaining: 0s Progress 7240 / 9694 Time remaining: 0s Progress 7241 / 9694 Time remaining: 0s Progress 7242 / 9694 Time remaining: 0s Progress 7243 / 9694 Time remaining: 0s Progress 7244 / 9694 Time remaining: 0s Progress 7245 / 9694 Time remaining: 0s Progress 7246 / 9694 Time remaining: 0s Progress 7247 / 9694 Time remaining: 0s Progress 7248 / 9694 Time remaining: 0s Progress 7249 / 9694 Time remaining: 0s Progress 7250 / 9694 Time remaining: 0s Progress 7251 / 9694 Time remaining: 0s Progress 7252 / 9694 Time remaining: 0s Progress 7253 / 9694 Time remaining: 0s Progress 7254 / 9694 Time remaining: 0s Progress 7255 / 9694 Time remaining: 0s Progress 7256 / 9694 Time remaining: 0s Progress 7257 / 9694 Time remaining: 0s Progress 7258 / 9694 Time remaining: 0s Progress 7259 / 9694 Time remaining: 0s Progress 7260 / 9694 Time remaining: 0s Progress 7261 / 9694 Time remaining: 0s Progress 7262 / 9694 Time remaining: 0s Progress 7263 / 9694 Time remaining: 0s Progress 7264 / 9694 Time remaining: 0s Progress 7265 / 9694 Time remaining: 0s Progress 7266 / 9694 Time remaining: 0s Progress 7267 / 9694 Time remaining: 0s Progress 7268 / 9694 Time remaining: 0s Progress 7269 / 9694 Time remaining: 0s Progress 7270 / 9694 Time remaining: 0s Progress 7271 / 9694 Time remaining: 0s Progress 7272 / 9694 Time remaining: 0s Progress 7273 / 9694 Time remaining: 0s Progress 7274 / 9694 Time remaining: 0s Progress 7275 / 9694 Time remaining: 0s Progress 7276 / 9694 Time remaining: 0s Progress 7277 / 9694 Time remaining: 0s Progress 7278 / 9694 Time remaining: 0s Progress 7279 / 9694 Time remaining: 0s Progress 7280 / 9694 Time remaining: 0s Progress 7281 / 9694 Time remaining: 0s Progress 7282 / 9694 Time remaining: 0s Progress 7283 / 9694 Time remaining: 0s Progress 7284 / 9694 Time remaining: 0s Progress 7285 / 9694 Time remaining: 0s Progress 7286 / 9694 Time remaining: 0s Progress 7287 / 9694 Time remaining: 0s Progress 7288 / 9694 Time remaining: 0s Progress 7289 / 9694 Time remaining: 0s Progress 7290 / 9694 Time remaining: 0s Progress 7291 / 9694 Time remaining: 0s Progress 7292 / 9694 Time remaining: 0s Progress 7293 / 9694 Time remaining: 0s Progress 7294 / 9694 Time remaining: 0s Progress 7295 / 9694 Time remaining: 0s Progress 7296 / 9694 Time remaining: 0s Progress 7297 / 9694 Time remaining: 0s Progress 7298 / 9694 Time remaining: 0s Progress 7299 / 9694 Time remaining: 0s Progress 7300 / 9694 Time remaining: 0s Progress 7301 / 9694 Time remaining: 0s Progress 7302 / 9694 Time remaining: 0s Progress 7303 / 9694 Time remaining: 0s Progress 7304 / 9694 Time remaining: 0s Progress 7305 / 9694 Time remaining: 0s Progress 7306 / 9694 Time remaining: 0s Progress 7307 / 9694 Time remaining: 0s Progress 7308 / 9694 Time remaining: 0s Progress 7309 / 9694 Time remaining: 0s Progress 7310 / 9694 Time remaining: 0s Progress 7311 / 9694 Time remaining: 0s Progress 7312 / 9694 Time remaining: 0s Progress 7313 / 9694 Time remaining: 0s Progress 7314 / 9694 Time remaining: 0s Progress 7315 / 9694 Time remaining: 0s Progress 7316 / 9694 Time remaining: 0s Progress 7317 / 9694 Time remaining: 0s Progress 7318 / 9694 Time remaining: 0s Progress 7319 / 9694 Time remaining: 0s Progress 7320 / 9694 Time remaining: 0s Progress 7321 / 9694 Time remaining: 0s Progress 7322 / 9694 Time remaining: 0s Progress 7323 / 9694 Time remaining: 0s Progress 7324 / 9694 Time remaining: 0s Progress 7325 / 9694 Time remaining: 0s Progress 7326 / 9694 Time remaining: 0s Progress 7327 / 9694 Time remaining: 0s Progress 7328 / 9694 Time remaining: 0s Progress 7329 / 9694 Time remaining: 0s Progress 7330 / 9694 Time remaining: 0s Progress 7331 / 9694 Time remaining: 0s Progress 7332 / 9694 Time remaining: 0s Progress 7333 / 9694 Time remaining: 0s Progress 7334 / 9694 Time remaining: 0s Progress 7335 / 9694 Time remaining: 0s Progress 7336 / 9694 Time remaining: 0s Progress 7337 / 9694 Time remaining: 0s Progress 7338 / 9694 Time remaining: 0s Progress 7339 / 9694 Time remaining: 0s Progress 7340 / 9694 Time remaining: 0s Progress 7341 / 9694 Time remaining: 0s Progress 7342 / 9694 Time remaining: 0s Progress 7343 / 9694 Time remaining: 0s Progress 7344 / 9694 Time remaining: 0s Progress 7345 / 9694 Time remaining: 0s Progress 7346 / 9694 Time remaining: 0s Progress 7347 / 9694 Time remaining: 0s Progress 7348 / 9694 Time remaining: 0s Progress 7349 / 9694 Time remaining: 0s Progress 7350 / 9694 Time remaining: 0s Progress 7351 / 9694 Time remaining: 0s Progress 7352 / 9694 Time remaining: 0s Progress 7353 / 9694 Time remaining: 0s Progress 7354 / 9694 Time remaining: 0s Progress 7355 / 9694 Time remaining: 0s Progress 7356 / 9694 Time remaining: 0s Progress 7357 / 9694 Time remaining: 0s Progress 7358 / 9694 Time remaining: 0s Progress 7359 / 9694 Time remaining: 0s Progress 7360 / 9694 Time remaining: 0s Progress 7361 / 9694 Time remaining: 0s Progress 7362 / 9694 Time remaining: 0s Progress 7363 / 9694 Time remaining: 0s Progress 7364 / 9694 Time remaining: 0s Progress 7365 / 9694 Time remaining: 0s Progress 7366 / 9694 Time remaining: 0s Progress 7367 / 9694 Time remaining: 0s Progress 7368 / 9694 Time remaining: 0s Progress 7369 / 9694 Time remaining: 0s Progress 7370 / 9694 Time remaining: 0s Progress 7371 / 9694 Time remaining: 0s Progress 7372 / 9694 Time remaining: 0s Progress 7373 / 9694 Time remaining: 0s Progress 7374 / 9694 Time remaining: 0s Progress 7375 / 9694 Time remaining: 0s Progress 7376 / 9694 Time remaining: 0s Progress 7377 / 9694 Time remaining: 0s Progress 7378 / 9694 Time remaining: 0s Progress 7379 / 9694 Time remaining: 0s Progress 7380 / 9694 Time remaining: 0s Progress 7381 / 9694 Time remaining: 0s Progress 7382 / 9694 Time remaining: 0s Progress 7383 / 9694 Time remaining: 0s Progress 7384 / 9694 Time remaining: 0s Progress 7385 / 9694 Time remaining: 0s Progress 7386 / 9694 Time remaining: 0s Progress 7387 / 9694 Time remaining: 0s Progress 7388 / 9694 Time remaining: 0s Progress 7389 / 9694 Time remaining: 0s Progress 7390 / 9694 Time remaining: 0s Progress 7391 / 9694 Time remaining: 0s Progress 7392 / 9694 Time remaining: 0s Progress 7393 / 9694 Time remaining: 0s Progress 7394 / 9694 Time remaining: 0s Progress 7395 / 9694 Time remaining: 0s Progress 7396 / 9694 Time remaining: 0s Progress 7397 / 9694 Time remaining: 0s Progress 7398 / 9694 Time remaining: 0s Progress 7399 / 9694 Time remaining: 0s Progress 7400 / 9694 Time remaining: 0s Progress 7401 / 9694 Time remaining: 0s Progress 7402 / 9694 Time remaining: 0s Progress 7403 / 9694 Time remaining: 0s Progress 7404 / 9694 Time remaining: 0s Progress 7405 / 9694 Time remaining: 0s Progress 7406 / 9694 Time remaining: 0s Progress 7407 / 9694 Time remaining: 0s Progress 7408 / 9694 Time remaining: 0s Progress 7409 / 9694 Time remaining: 0s Progress 7410 / 9694 Time remaining: 0s Progress 7411 / 9694 Time remaining: 0s Progress 7412 / 9694 Time remaining: 0s Progress 7413 / 9694 Time remaining: 0s Progress 7414 / 9694 Time remaining: 0s Progress 7415 / 9694 Time remaining: 0s Progress 7416 / 9694 Time remaining: 0s Progress 7417 / 9694 Time remaining: 0s Progress 7418 / 9694 Time remaining: 0s Progress 7419 / 9694 Time remaining: 0s Progress 7420 / 9694 Time remaining: 0s Progress 7421 / 9694 Time remaining: 0s Progress 7422 / 9694 Time remaining: 0s Progress 7423 / 9694 Time remaining: 0s Progress 7424 / 9694 Time remaining: 0s Progress 7425 / 9694 Time remaining: 0s Progress 7426 / 9694 Time remaining: 0s Progress 7427 / 9694 Time remaining: 0s Progress 7428 / 9694 Time remaining: 0s Progress 7429 / 9694 Time remaining: 0s Progress 7430 / 9694 Time remaining: 0s Progress 7431 / 9694 Time remaining: 0s Progress 7432 / 9694 Time remaining: 0s Progress 7433 / 9694 Time remaining: 0s Progress 7434 / 9694 Time remaining: 0s Progress 7435 / 9694 Time remaining: 0s Progress 7436 / 9694 Time remaining: 0s Progress 7437 / 9694 Time remaining: 0s Progress 7438 / 9694 Time remaining: 0s Progress 7439 / 9694 Time remaining: 0s Progress 7440 / 9694 Time remaining: 0s Progress 7441 / 9694 Time remaining: 0s Progress 7442 / 9694 Time remaining: 0s Progress 7443 / 9694 Time remaining: 0s Progress 7444 / 9694 Time remaining: 0s Progress 7445 / 9694 Time remaining: 0s Progress 7446 / 9694 Time remaining: 0s Progress 7447 / 9694 Time remaining: 0s Progress 7448 / 9694 Time remaining: 0s Progress 7449 / 9694 Time remaining: 0s Progress 7450 / 9694 Time remaining: 0s Progress 7451 / 9694 Time remaining: 0s Progress 7452 / 9694 Time remaining: 0s Progress 7453 / 9694 Time remaining: 0s Progress 7454 / 9694 Time remaining: 0s Progress 7455 / 9694 Time remaining: 0s Progress 7456 / 9694 Time remaining: 0s Progress 7457 / 9694 Time remaining: 0s Progress 7458 / 9694 Time remaining: 0s Progress 7459 / 9694 Time remaining: 0s Progress 7460 / 9694 Time remaining: 0s Progress 7461 / 9694 Time remaining: 0s Progress 7462 / 9694 Time remaining: 0s Progress 7463 / 9694 Time remaining: 0s Progress 7464 / 9694 Time remaining: 0s Progress 7465 / 9694 Time remaining: 0s Progress 7466 / 9694 Time remaining: 0s Progress 7467 / 9694 Time remaining: 0s Progress 7468 / 9694 Time remaining: 0s Progress 7469 / 9694 Time remaining: 0s Progress 7470 / 9694 Time remaining: 0s Progress 7471 / 9694 Time remaining: 0s Progress 7472 / 9694 Time remaining: 0s Progress 7473 / 9694 Time remaining: 0s Progress 7474 / 9694 Time remaining: 0s Progress 7475 / 9694 Time remaining: 0s Progress 7476 / 9694 Time remaining: 0s Progress 7477 / 9694 Time remaining: 0s Progress 7478 / 9694 Time remaining: 0s Progress 7479 / 9694 Time remaining: 0s Progress 7480 / 9694 Time remaining: 0s Progress 7481 / 9694 Time remaining: 0s Progress 7482 / 9694 Time remaining: 0s Progress 7483 / 9694 Time remaining: 0s Progress 7484 / 9694 Time remaining: 0s Progress 7485 / 9694 Time remaining: 0s Progress 7486 / 9694 Time remaining: 0s Progress 7487 / 9694 Time remaining: 0s Progress 7488 / 9694 Time remaining: 0s Progress 7489 / 9694 Time remaining: 0s Progress 7490 / 9694 Time remaining: 0s Progress 7491 / 9694 Time remaining: 0s Progress 7492 / 9694 Time remaining: 0s Progress 7493 / 9694 Time remaining: 0s Progress 7494 / 9694 Time remaining: 0s Progress 7495 / 9694 Time remaining: 0s Progress 7496 / 9694 Time remaining: 0s Progress 7497 / 9694 Time remaining: 0s Progress 7498 / 9694 Time remaining: 0s Progress 7499 / 9694 Time remaining: 0s Progress 7500 / 9694 Time remaining: 0s Progress 7501 / 9694 Time remaining: 0s Progress 7502 / 9694 Time remaining: 0s Progress 7503 / 9694 Time remaining: 0s Progress 7504 / 9694 Time remaining: 0s Progress 7505 / 9694 Time remaining: 0s Progress 7506 / 9694 Time remaining: 0s Progress 7507 / 9694 Time remaining: 0s Progress 7508 / 9694 Time remaining: 0s Progress 7509 / 9694 Time remaining: 0s Progress 7510 / 9694 Time remaining: 0s Progress 7511 / 9694 Time remaining: 0s Progress 7512 / 9694 Time remaining: 0s Progress 7513 / 9694 Time remaining: 0s Progress 7514 / 9694 Time remaining: 0s Progress 7515 / 9694 Time remaining: 0s Progress 7516 / 9694 Time remaining: 0s Progress 7517 / 9694 Time remaining: 0s Progress 7518 / 9694 Time remaining: 0s Progress 7519 / 9694 Time remaining: 0s Progress 7520 / 9694 Time remaining: 0s Progress 7521 / 9694 Time remaining: 0s Progress 7522 / 9694 Time remaining: 0s Progress 7523 / 9694 Time remaining: 0s Progress 7524 / 9694 Time remaining: 0s Progress 7525 / 9694 Time remaining: 0s Progress 7526 / 9694 Time remaining: 0s Progress 7527 / 9694 Time remaining: 0s Progress 7528 / 9694 Time remaining: 0s Progress 7529 / 9694 Time remaining: 0s Progress 7530 / 9694 Time remaining: 0s Progress 7531 / 9694 Time remaining: 0s Progress 7532 / 9694 Time remaining: 0s Progress 7533 / 9694 Time remaining: 0s Progress 7534 / 9694 Time remaining: 0s Progress 7535 / 9694 Time remaining: 0s Progress 7536 / 9694 Time remaining: 0s Progress 7537 / 9694 Time remaining: 0s Progress 7538 / 9694 Time remaining: 0s Progress 7539 / 9694 Time remaining: 0s Progress 7540 / 9694 Time remaining: 0s Progress 7541 / 9694 Time remaining: 0s Progress 7542 / 9694 Time remaining: 0s Progress 7543 / 9694 Time remaining: 0s Progress 7544 / 9694 Time remaining: 0s Progress 7545 / 9694 Time remaining: 0s Progress 7546 / 9694 Time remaining: 0s Progress 7547 / 9694 Time remaining: 0s Progress 7548 / 9694 Time remaining: 0s Progress 7549 / 9694 Time remaining: 0s Progress 7550 / 9694 Time remaining: 0s Progress 7551 / 9694 Time remaining: 0s Progress 7552 / 9694 Time remaining: 0s Progress 7553 / 9694 Time remaining: 0s Progress 7554 / 9694 Time remaining: 0s Progress 7555 / 9694 Time remaining: 0s Progress 7556 / 9694 Time remaining: 0s Progress 7557 / 9694 Time remaining: 0s Progress 7558 / 9694 Time remaining: 0s Progress 7559 / 9694 Time remaining: 0s Progress 7560 / 9694 Time remaining: 0s Progress 7561 / 9694 Time remaining: 0s Progress 7562 / 9694 Time remaining: 0s Progress 7563 / 9694 Time remaining: 0s Progress 7564 / 9694 Time remaining: 0s Progress 7565 / 9694 Time remaining: 0s Progress 7566 / 9694 Time remaining: 0s Progress 7567 / 9694 Time remaining: 0s Progress 7568 / 9694 Time remaining: 0s Progress 7569 / 9694 Time remaining: 0s Progress 7570 / 9694 Time remaining: 0s Progress 7571 / 9694 Time remaining: 0s Progress 7572 / 9694 Time remaining: 0s Progress 7573 / 9694 Time remaining: 0s Progress 7574 / 9694 Time remaining: 0s Progress 7575 / 9694 Time remaining: 0s Progress 7576 / 9694 Time remaining: 0s Progress 7577 / 9694 Time remaining: 0s Progress 7578 / 9694 Time remaining: 0s Progress 7579 / 9694 Time remaining: 0s Progress 7580 / 9694 Time remaining: 0s Progress 7581 / 9694 Time remaining: 0s Progress 7582 / 9694 Time remaining: 0s Progress 7583 / 9694 Time remaining: 0s Progress 7584 / 9694 Time remaining: 0s Progress 7585 / 9694 Time remaining: 0s Progress 7586 / 9694 Time remaining: 0s Progress 7587 / 9694 Time remaining: 0s Progress 7588 / 9694 Time remaining: 0s Progress 7589 / 9694 Time remaining: 0s Progress 7590 / 9694 Time remaining: 0s Progress 7591 / 9694 Time remaining: 0s Progress 7592 / 9694 Time remaining: 0s Progress 7593 / 9694 Time remaining: 0s Progress 7594 / 9694 Time remaining: 0s Progress 7595 / 9694 Time remaining: 0s Progress 7596 / 9694 Time remaining: 0s Progress 7597 / 9694 Time remaining: 0s Progress 7598 / 9694 Time remaining: 0s Progress 7599 / 9694 Time remaining: 0s Progress 7600 / 9694 Time remaining: 0s Progress 7601 / 9694 Time remaining: 0s Progress 7602 / 9694 Time remaining: 0s Progress 7603 / 9694 Time remaining: 0s Progress 7604 / 9694 Time remaining: 0s Progress 7605 / 9694 Time remaining: 0s Progress 7606 / 9694 Time remaining: 0s Progress 7607 / 9694 Time remaining: 0s Progress 7608 / 9694 Time remaining: 0s Progress 7609 / 9694 Time remaining: 0s Progress 7610 / 9694 Time remaining: 0s Progress 7611 / 9694 Time remaining: 0s Progress 7612 / 9694 Time remaining: 0s Progress 7613 / 9694 Time remaining: 0s Progress 7614 / 9694 Time remaining: 0s Progress 7615 / 9694 Time remaining: 0s Progress 7616 / 9694 Time remaining: 0s Progress 7617 / 9694 Time remaining: 0s Progress 7618 / 9694 Time remaining: 0s Progress 7619 / 9694 Time remaining: 0s Progress 7620 / 9694 Time remaining: 0s Progress 7621 / 9694 Time remaining: 0s Progress 7622 / 9694 Time remaining: 0s Progress 7623 / 9694 Time remaining: 0s Progress 7624 / 9694 Time remaining: 0s Progress 7625 / 9694 Time remaining: 0s Progress 7626 / 9694 Time remaining: 0s Progress 7627 / 9694 Time remaining: 0s Progress 7628 / 9694 Time remaining: 0s Progress 7629 / 9694 Time remaining: 0s Progress 7630 / 9694 Time remaining: 0s Progress 7631 / 9694 Time remaining: 0s Progress 7632 / 9694 Time remaining: 0s Progress 7633 / 9694 Time remaining: 0s Progress 7634 / 9694 Time remaining: 0s Progress 7635 / 9694 Time remaining: 0s Progress 7636 / 9694 Time remaining: 0s Progress 7637 / 9694 Time remaining: 0s Progress 7638 / 9694 Time remaining: 0s Progress 7639 / 9694 Time remaining: 0s Progress 7640 / 9694 Time remaining: 0s Progress 7641 / 9694 Time remaining: 0s Progress 7642 / 9694 Time remaining: 0s Progress 7643 / 9694 Time remaining: 0s Progress 7644 / 9694 Time remaining: 0s Progress 7645 / 9694 Time remaining: 0s Progress 7646 / 9694 Time remaining: 0s Progress 7647 / 9694 Time remaining: 0s Progress 7648 / 9694 Time remaining: 0s Progress 7649 / 9694 Time remaining: 0s Progress 7650 / 9694 Time remaining: 0s Progress 7651 / 9694 Time remaining: 0s Progress 7652 / 9694 Time remaining: 0s Progress 7653 / 9694 Time remaining: 0s Progress 7654 / 9694 Time remaining: 0s Progress 7655 / 9694 Time remaining: 0s Progress 7656 / 9694 Time remaining: 0s Progress 7657 / 9694 Time remaining: 0s Progress 7658 / 9694 Time remaining: 0s Progress 7659 / 9694 Time remaining: 0s Progress 7660 / 9694 Time remaining: 0s Progress 7661 / 9694 Time remaining: 0s Progress 7662 / 9694 Time remaining: 0s Progress 7663 / 9694 Time remaining: 0s Progress 7664 / 9694 Time remaining: 0s Progress 7665 / 9694 Time remaining: 0s Progress 7666 / 9694 Time remaining: 0s Progress 7667 / 9694 Time remaining: 0s Progress 7668 / 9694 Time remaining: 0s Progress 7669 / 9694 Time remaining: 0s Progress 7670 / 9694 Time remaining: 0s Progress 7671 / 9694 Time remaining: 0s Progress 7672 / 9694 Time remaining: 0s Progress 7673 / 9694 Time remaining: 0s Progress 7674 / 9694 Time remaining: 0s Progress 7675 / 9694 Time remaining: 0s Progress 7676 / 9694 Time remaining: 0s Progress 7677 / 9694 Time remaining: 0s Progress 7678 / 9694 Time remaining: 0s Progress 7679 / 9694 Time remaining: 0s Progress 7680 / 9694 Time remaining: 0s Progress 7681 / 9694 Time remaining: 0s Progress 7682 / 9694 Time remaining: 0s Progress 7683 / 9694 Time remaining: 0s Progress 7684 / 9694 Time remaining: 0s Progress 7685 / 9694 Time remaining: 0s Progress 7686 / 9694 Time remaining: 0s Progress 7687 / 9694 Time remaining: 0s Progress 7688 / 9694 Time remaining: 0s Progress 7689 / 9694 Time remaining: 0s Progress 7690 / 9694 Time remaining: 0s Progress 7691 / 9694 Time remaining: 0s Progress 7692 / 9694 Time remaining: 0s Progress 7693 / 9694 Time remaining: 0s Progress 7694 / 9694 Time remaining: 0s Progress 7695 / 9694 Time remaining: 0s Progress 7696 / 9694 Time remaining: 0s Progress 7697 / 9694 Time remaining: 0s Progress 7698 / 9694 Time remaining: 0s Progress 7699 / 9694 Time remaining: 0s Progress 7700 / 9694 Time remaining: 0s Progress 7701 / 9694 Time remaining: 0s Progress 7702 / 9694 Time remaining: 0s Progress 7703 / 9694 Time remaining: 0s Progress 7704 / 9694 Time remaining: 0s Progress 7705 / 9694 Time remaining: 0s Progress 7706 / 9694 Time remaining: 0s Progress 7707 / 9694 Time remaining: 0s Progress 7708 / 9694 Time remaining: 0s Progress 7709 / 9694 Time remaining: 0s Progress 7710 / 9694 Time remaining: 0s Progress 7711 / 9694 Time remaining: 0s Progress 7712 / 9694 Time remaining: 0s Progress 7713 / 9694 Time remaining: 0s Progress 7714 / 9694 Time remaining: 0s Progress 7715 / 9694 Time remaining: 0s Progress 7716 / 9694 Time remaining: 0s Progress 7717 / 9694 Time remaining: 0s Progress 7718 / 9694 Time remaining: 0s Progress 7719 / 9694 Time remaining: 0s Progress 7720 / 9694 Time remaining: 0s Progress 7721 / 9694 Time remaining: 0s Progress 7722 / 9694 Time remaining: 0s Progress 7723 / 9694 Time remaining: 0s Progress 7724 / 9694 Time remaining: 0s Progress 7725 / 9694 Time remaining: 0s Progress 7726 / 9694 Time remaining: 0s Progress 7727 / 9694 Time remaining: 0s Progress 7728 / 9694 Time remaining: 0s Progress 7729 / 9694 Time remaining: 0s Progress 7730 / 9694 Time remaining: 0s Progress 7731 / 9694 Time remaining: 0s Progress 7732 / 9694 Time remaining: 0s Progress 7733 / 9694 Time remaining: 0s Progress 7734 / 9694 Time remaining: 0s Progress 7735 / 9694 Time remaining: 0s Progress 7736 / 9694 Time remaining: 0s Progress 7737 / 9694 Time remaining: 0s Progress 7738 / 9694 Time remaining: 0s Progress 7739 / 9694 Time remaining: 0s Progress 7740 / 9694 Time remaining: 0s Progress 7741 / 9694 Time remaining: 0s Progress 7742 / 9694 Time remaining: 0s Progress 7743 / 9694 Time remaining: 0s Progress 7744 / 9694 Time remaining: 0s Progress 7745 / 9694 Time remaining: 0s Progress 7746 / 9694 Time remaining: 0s Progress 7747 / 9694 Time remaining: 0s Progress 7748 / 9694 Time remaining: 0s Progress 7749 / 9694 Time remaining: 0s Progress 7750 / 9694 Time remaining: 0s Progress 7751 / 9694 Time remaining: 0s Progress 7752 / 9694 Time remaining: 0s Progress 7753 / 9694 Time remaining: 0s Progress 7754 / 9694 Time remaining: 0s Progress 7755 / 9694 Time remaining: 0s Progress 7756 / 9694 Time remaining: 0s Progress 7757 / 9694 Time remaining: 0s Progress 7758 / 9694 Time remaining: 0s Progress 7759 / 9694 Time remaining: 0s Progress 7760 / 9694 Time remaining: 0s Progress 7761 / 9694 Time remaining: 0s Progress 7762 / 9694 Time remaining: 0s Progress 7763 / 9694 Time remaining: 0s Progress 7764 / 9694 Time remaining: 0s Progress 7765 / 9694 Time remaining: 0s Progress 7766 / 9694 Time remaining: 0s Progress 7767 / 9694 Time remaining: 0s Progress 7768 / 9694 Time remaining: 0s Progress 7769 / 9694 Time remaining: 0s Progress 7770 / 9694 Time remaining: 0s Progress 7771 / 9694 Time remaining: 0s Progress 7772 / 9694 Time remaining: 0s Progress 7773 / 9694 Time remaining: 0s Progress 7774 / 9694 Time remaining: 0s Progress 7775 / 9694 Time remaining: 0s Progress 7776 / 9694 Time remaining: 0s Progress 7777 / 9694 Time remaining: 0s Progress 7778 / 9694 Time remaining: 0s Progress 7779 / 9694 Time remaining: 0s Progress 7780 / 9694 Time remaining: 0s Progress 7781 / 9694 Time remaining: 0s Progress 7782 / 9694 Time remaining: 0s Progress 7783 / 9694 Time remaining: 0s Progress 7784 / 9694 Time remaining: 0s Progress 7785 / 9694 Time remaining: 0s Progress 7786 / 9694 Time remaining: 0s Progress 7787 / 9694 Time remaining: 0s Progress 7788 / 9694 Time remaining: 0s Progress 7789 / 9694 Time remaining: 0s Progress 7790 / 9694 Time remaining: 0s Progress 7791 / 9694 Time remaining: 0s Progress 7792 / 9694 Time remaining: 0s Progress 7793 / 9694 Time remaining: 0s Progress 7794 / 9694 Time remaining: 0s Progress 7795 / 9694 Time remaining: 0s Progress 7796 / 9694 Time remaining: 0s Progress 7797 / 9694 Time remaining: 0s Progress 7798 / 9694 Time remaining: 0s Progress 7799 / 9694 Time remaining: 0s Progress 7800 / 9694 Time remaining: 0s Progress 7801 / 9694 Time remaining: 0s Progress 7802 / 9694 Time remaining: 0s Progress 7803 / 9694 Time remaining: 0s Progress 7804 / 9694 Time remaining: 0s Progress 7805 / 9694 Time remaining: 0s Progress 7806 / 9694 Time remaining: 0s Progress 7807 / 9694 Time remaining: 0s Progress 7808 / 9694 Time remaining: 0s Progress 7809 / 9694 Time remaining: 0s Progress 7810 / 9694 Time remaining: 0s Progress 7811 / 9694 Time remaining: 0s Progress 7812 / 9694 Time remaining: 0s Progress 7813 / 9694 Time remaining: 0s Progress 7814 / 9694 Time remaining: 0s Progress 7815 / 9694 Time remaining: 0s Progress 7816 / 9694 Time remaining: 0s Progress 7817 / 9694 Time remaining: 0s Progress 7818 / 9694 Time remaining: 0s Progress 7819 / 9694 Time remaining: 0s Progress 7820 / 9694 Time remaining: 0s Progress 7821 / 9694 Time remaining: 0s Progress 7822 / 9694 Time remaining: 0s Progress 7823 / 9694 Time remaining: 0s Progress 7824 / 9694 Time remaining: 0s Progress 7825 / 9694 Time remaining: 0s Progress 7826 / 9694 Time remaining: 0s Progress 7827 / 9694 Time remaining: 0s Progress 7828 / 9694 Time remaining: 0s Progress 7829 / 9694 Time remaining: 0s Progress 7830 / 9694 Time remaining: 0s Progress 7831 / 9694 Time remaining: 0s Progress 7832 / 9694 Time remaining: 0s Progress 7833 / 9694 Time remaining: 0s Progress 7834 / 9694 Time remaining: 0s Progress 7835 / 9694 Time remaining: 0s Progress 7836 / 9694 Time remaining: 0s Progress 7837 / 9694 Time remaining: 0s Progress 7838 / 9694 Time remaining: 0s Progress 7839 / 9694 Time remaining: 0s Progress 7840 / 9694 Time remaining: 0s Progress 7841 / 9694 Time remaining: 0s Progress 7842 / 9694 Time remaining: 0s Progress 7843 / 9694 Time remaining: 0s Progress 7844 / 9694 Time remaining: 0s Progress 7845 / 9694 Time remaining: 0s Progress 7846 / 9694 Time remaining: 0s Progress 7847 / 9694 Time remaining: 0s Progress 7848 / 9694 Time remaining: 0s Progress 7849 / 9694 Time remaining: 0s Progress 7850 / 9694 Time remaining: 0s Progress 7851 / 9694 Time remaining: 0s Progress 7852 / 9694 Time remaining: 0s Progress 7853 / 9694 Time remaining: 0s Progress 7854 / 9694 Time remaining: 0s Progress 7855 / 9694 Time remaining: 0s Progress 7856 / 9694 Time remaining: 0s Progress 7857 / 9694 Time remaining: 0s Progress 7858 / 9694 Time remaining: 0s Progress 7859 / 9694 Time remaining: 0s Progress 7860 / 9694 Time remaining: 0s Progress 7861 / 9694 Time remaining: 0s Progress 7862 / 9694 Time remaining: 0s Progress 7863 / 9694 Time remaining: 0s Progress 7864 / 9694 Time remaining: 0s Progress 7865 / 9694 Time remaining: 0s Progress 7866 / 9694 Time remaining: 0s Progress 7867 / 9694 Time remaining: 0s Progress 7868 / 9694 Time remaining: 0s Progress 7869 / 9694 Time remaining: 0s Progress 7870 / 9694 Time remaining: 0s Progress 7871 / 9694 Time remaining: 0s Progress 7872 / 9694 Time remaining: 0s Progress 7873 / 9694 Time remaining: 0s Progress 7874 / 9694 Time remaining: 0s Progress 7875 / 9694 Time remaining: 0s Progress 7876 / 9694 Time remaining: 0s Progress 7877 / 9694 Time remaining: 0s Progress 7878 / 9694 Time remaining: 0s Progress 7879 / 9694 Time remaining: 0s Progress 7880 / 9694 Time remaining: 0s Progress 7881 / 9694 Time remaining: 0s Progress 7882 / 9694 Time remaining: 0s Progress 7883 / 9694 Time remaining: 0s Progress 7884 / 9694 Time remaining: 0s Progress 7885 / 9694 Time remaining: 0s Progress 7886 / 9694 Time remaining: 0s Progress 7887 / 9694 Time remaining: 0s Progress 7888 / 9694 Time remaining: 0s Progress 7889 / 9694 Time remaining: 0s Progress 7890 / 9694 Time remaining: 0s Progress 7891 / 9694 Time remaining: 0s Progress 7892 / 9694 Time remaining: 0s Progress 7893 / 9694 Time remaining: 0s Progress 7894 / 9694 Time remaining: 0s Progress 7895 / 9694 Time remaining: 0s Progress 7896 / 9694 Time remaining: 0s Progress 7897 / 9694 Time remaining: 0s Progress 7898 / 9694 Time remaining: 0s Progress 7899 / 9694 Time remaining: 0s Progress 7900 / 9694 Time remaining: 0s Progress 7901 / 9694 Time remaining: 0s Progress 7902 / 9694 Time remaining: 0s Progress 7903 / 9694 Time remaining: 0s Progress 7904 / 9694 Time remaining: 0s Progress 7905 / 9694 Time remaining: 0s Progress 7906 / 9694 Time remaining: 0s Progress 7907 / 9694 Time remaining: 0s Progress 7908 / 9694 Time remaining: 0s Progress 7909 / 9694 Time remaining: 0s Progress 7910 / 9694 Time remaining: 0s Progress 7911 / 9694 Time remaining: 0s Progress 7912 / 9694 Time remaining: 0s Progress 7913 / 9694 Time remaining: 0s Progress 7914 / 9694 Time remaining: 0s Progress 7915 / 9694 Time remaining: 0s Progress 7916 / 9694 Time remaining: 0s Progress 7917 / 9694 Time remaining: 0s Progress 7918 / 9694 Time remaining: 0s Progress 7919 / 9694 Time remaining: 0s Progress 7920 / 9694 Time remaining: 0s Progress 7921 / 9694 Time remaining: 0s Progress 7922 / 9694 Time remaining: 0s Progress 7923 / 9694 Time remaining: 0s Progress 7924 / 9694 Time remaining: 0s Progress 7925 / 9694 Time remaining: 0s Progress 7926 / 9694 Time remaining: 0s Progress 7927 / 9694 Time remaining: 0s Progress 7928 / 9694 Time remaining: 0s Progress 7929 / 9694 Time remaining: 0s Progress 7930 / 9694 Time remaining: 0s Progress 7931 / 9694 Time remaining: 0s Progress 7932 / 9694 Time remaining: 0s Progress 7933 / 9694 Time remaining: 0s Progress 7934 / 9694 Time remaining: 0s Progress 7935 / 9694 Time remaining: 0s Progress 7936 / 9694 Time remaining: 0s Progress 7937 / 9694 Time remaining: 0s Progress 7938 / 9694 Time remaining: 0s Progress 7939 / 9694 Time remaining: 0s Progress 7940 / 9694 Time remaining: 0s Progress 7941 / 9694 Time remaining: 0s Progress 7942 / 9694 Time remaining: 0s Progress 7943 / 9694 Time remaining: 0s Progress 7944 / 9694 Time remaining: 0s Progress 7945 / 9694 Time remaining: 0s Progress 7946 / 9694 Time remaining: 0s Progress 7947 / 9694 Time remaining: 0s Progress 7948 / 9694 Time remaining: 0s Progress 7949 / 9694 Time remaining: 0s Progress 7950 / 9694 Time remaining: 0s Progress 7951 / 9694 Time remaining: 0s Progress 7952 / 9694 Time remaining: 0s Progress 7953 / 9694 Time remaining: 0s Progress 7954 / 9694 Time remaining: 0s Progress 7955 / 9694 Time remaining: 0s Progress 7956 / 9694 Time remaining: 0s Progress 7957 / 9694 Time remaining: 0s Progress 7958 / 9694 Time remaining: 0s Progress 7959 / 9694 Time remaining: 0s Progress 7960 / 9694 Time remaining: 0s Progress 7961 / 9694 Time remaining: 0s Progress 7962 / 9694 Time remaining: 0s Progress 7963 / 9694 Time remaining: 0s Progress 7964 / 9694 Time remaining: 0s Progress 7965 / 9694 Time remaining: 0s Progress 7966 / 9694 Time remaining: 0s Progress 7967 / 9694 Time remaining: 0s Progress 7968 / 9694 Time remaining: 0s Progress 7969 / 9694 Time remaining: 0s Progress 7970 / 9694 Time remaining: 0s Progress 7971 / 9694 Time remaining: 0s Progress 7972 / 9694 Time remaining: 0s Progress 7973 / 9694 Time remaining: 0s Progress 7974 / 9694 Time remaining: 0s Progress 7975 / 9694 Time remaining: 0s Progress 7976 / 9694 Time remaining: 0s Progress 7977 / 9694 Time remaining: 0s Progress 7978 / 9694 Time remaining: 0s Progress 7979 / 9694 Time remaining: 0s Progress 7980 / 9694 Time remaining: 0s Progress 7981 / 9694 Time remaining: 0s Progress 7982 / 9694 Time remaining: 0s Progress 7983 / 9694 Time remaining: 0s Progress 7984 / 9694 Time remaining: 0s Progress 7985 / 9694 Time remaining: 0s Progress 7986 / 9694 Time remaining: 0s Progress 7987 / 9694 Time remaining: 0s Progress 7988 / 9694 Time remaining: 0s Progress 7989 / 9694 Time remaining: 0s Progress 7990 / 9694 Time remaining: 0s Progress 7991 / 9694 Time remaining: 0s Progress 7992 / 9694 Time remaining: 0s Progress 7993 / 9694 Time remaining: 0s Progress 7994 / 9694 Time remaining: 0s Progress 7995 / 9694 Time remaining: 0s Progress 7996 / 9694 Time remaining: 0s Progress 7997 / 9694 Time remaining: 0s Progress 7998 / 9694 Time remaining: 0s Progress 7999 / 9694 Time remaining: 0s Progress 8000 / 9694 Time remaining: 0s Progress 8001 / 9694 Time remaining: 0s Progress 8002 / 9694 Time remaining: 0s Progress 8003 / 9694 Time remaining: 0s Progress 8004 / 9694 Time remaining: 0s Progress 8005 / 9694 Time remaining: 0s Progress 8006 / 9694 Time remaining: 0s Progress 8007 / 9694 Time remaining: 0s Progress 8008 / 9694 Time remaining: 0s Progress 8009 / 9694 Time remaining: 0s Progress 8010 / 9694 Time remaining: 0s Progress 8011 / 9694 Time remaining: 0s Progress 8012 / 9694 Time remaining: 0s Progress 8013 / 9694 Time remaining: 0s Progress 8014 / 9694 Time remaining: 0s Progress 8015 / 9694 Time remaining: 0s Progress 8016 / 9694 Time remaining: 0s Progress 8017 / 9694 Time remaining: 0s Progress 8018 / 9694 Time remaining: 0s Progress 8019 / 9694 Time remaining: 0s Progress 8020 / 9694 Time remaining: 0s Progress 8021 / 9694 Time remaining: 0s Progress 8022 / 9694 Time remaining: 0s Progress 8023 / 9694 Time remaining: 0s Progress 8024 / 9694 Time remaining: 0s Progress 8025 / 9694 Time remaining: 0s Progress 8026 / 9694 Time remaining: 0s Progress 8027 / 9694 Time remaining: 0s Progress 8028 / 9694 Time remaining: 0s Progress 8029 / 9694 Time remaining: 0s Progress 8030 / 9694 Time remaining: 0s Progress 8031 / 9694 Time remaining: 0s Progress 8032 / 9694 Time remaining: 0s Progress 8033 / 9694 Time remaining: 0s Progress 8034 / 9694 Time remaining: 0s Progress 8035 / 9694 Time remaining: 0s Progress 8036 / 9694 Time remaining: 0s Progress 8037 / 9694 Time remaining: 0s Progress 8038 / 9694 Time remaining: 0s Progress 8039 / 9694 Time remaining: 0s Progress 8040 / 9694 Time remaining: 0s Progress 8041 / 9694 Time remaining: 0s Progress 8042 / 9694 Time remaining: 0s Progress 8043 / 9694 Time remaining: 0s Progress 8044 / 9694 Time remaining: 0s Progress 8045 / 9694 Time remaining: 0s Progress 8046 / 9694 Time remaining: 0s Progress 8047 / 9694 Time remaining: 0s Progress 8048 / 9694 Time remaining: 0s Progress 8049 / 9694 Time remaining: 0s Progress 8050 / 9694 Time remaining: 0s Progress 8051 / 9694 Time remaining: 0s Progress 8052 / 9694 Time remaining: 0s Progress 8053 / 9694 Time remaining: 0s Progress 8054 / 9694 Time remaining: 0s Progress 8055 / 9694 Time remaining: 0s Progress 8056 / 9694 Time remaining: 0s Progress 8057 / 9694 Time remaining: 0s Progress 8058 / 9694 Time remaining: 0s Progress 8059 / 9694 Time remaining: 0s Progress 8060 / 9694 Time remaining: 0s Progress 8061 / 9694 Time remaining: 0s Progress 8062 / 9694 Time remaining: 0s Progress 8063 / 9694 Time remaining: 0s Progress 8064 / 9694 Time remaining: 0s Progress 8065 / 9694 Time remaining: 0s Progress 8066 / 9694 Time remaining: 0s Progress 8067 / 9694 Time remaining: 0s Progress 8068 / 9694 Time remaining: 0s Progress 8069 / 9694 Time remaining: 0s Progress 8070 / 9694 Time remaining: 0s Progress 8071 / 9694 Time remaining: 0s Progress 8072 / 9694 Time remaining: 0s Progress 8073 / 9694 Time remaining: 0s Progress 8074 / 9694 Time remaining: 0s Progress 8075 / 9694 Time remaining: 0s Progress 8076 / 9694 Time remaining: 0s Progress 8077 / 9694 Time remaining: 0s Progress 8078 / 9694 Time remaining: 0s Progress 8079 / 9694 Time remaining: 0s Progress 8080 / 9694 Time remaining: 0s Progress 8081 / 9694 Time remaining: 0s Progress 8082 / 9694 Time remaining: 0s Progress 8083 / 9694 Time remaining: 0s Progress 8084 / 9694 Time remaining: 0s Progress 8085 / 9694 Time remaining: 0s Progress 8086 / 9694 Time remaining: 0s Progress 8087 / 9694 Time remaining: 0s Progress 8088 / 9694 Time remaining: 0s Progress 8089 / 9694 Time remaining: 0s Progress 8090 / 9694 Time remaining: 0s Progress 8091 / 9694 Time remaining: 0s Progress 8092 / 9694 Time remaining: 0s Progress 8093 / 9694 Time remaining: 0s Progress 8094 / 9694 Time remaining: 0s Progress 8095 / 9694 Time remaining: 0s Progress 8096 / 9694 Time remaining: 0s Progress 8097 / 9694 Time remaining: 0s Progress 8098 / 9694 Time remaining: 0s Progress 8099 / 9694 Time remaining: 0s Progress 8100 / 9694 Time remaining: 0s Progress 8101 / 9694 Time remaining: 0s Progress 8102 / 9694 Time remaining: 0s Progress 8103 / 9694 Time remaining: 0s Progress 8104 / 9694 Time remaining: 0s Progress 8105 / 9694 Time remaining: 0s Progress 8106 / 9694 Time remaining: 0s Progress 8107 / 9694 Time remaining: 0s Progress 8108 / 9694 Time remaining: 0s Progress 8109 / 9694 Time remaining: 0s Progress 8110 / 9694 Time remaining: 0s Progress 8111 / 9694 Time remaining: 0s Progress 8112 / 9694 Time remaining: 0s Progress 8113 / 9694 Time remaining: 0s Progress 8114 / 9694 Time remaining: 0s Progress 8115 / 9694 Time remaining: 0s Progress 8116 / 9694 Time remaining: 0s Progress 8117 / 9694 Time remaining: 0s Progress 8118 / 9694 Time remaining: 0s Progress 8119 / 9694 Time remaining: 0s Progress 8120 / 9694 Time remaining: 0s Progress 8121 / 9694 Time remaining: 0s Progress 8122 / 9694 Time remaining: 0s Progress 8123 / 9694 Time remaining: 0s Progress 8124 / 9694 Time remaining: 0s Progress 8125 / 9694 Time remaining: 0s Progress 8126 / 9694 Time remaining: 0s Progress 8127 / 9694 Time remaining: 0s Progress 8128 / 9694 Time remaining: 0s Progress 8129 / 9694 Time remaining: 0s Progress 8130 / 9694 Time remaining: 0s Progress 8131 / 9694 Time remaining: 0s Progress 8132 / 9694 Time remaining: 0s Progress 8133 / 9694 Time remaining: 0s Progress 8134 / 9694 Time remaining: 0s Progress 8135 / 9694 Time remaining: 0s Progress 8136 / 9694 Time remaining: 0s Progress 8137 / 9694 Time remaining: 0s Progress 8138 / 9694 Time remaining: 0s Progress 8139 / 9694 Time remaining: 0s Progress 8140 / 9694 Time remaining: 0s Progress 8141 / 9694 Time remaining: 0s Progress 8142 / 9694 Time remaining: 0s Progress 8143 / 9694 Time remaining: 0s Progress 8144 / 9694 Time remaining: 0s Progress 8145 / 9694 Time remaining: 0s Progress 8146 / 9694 Time remaining: 0s Progress 8147 / 9694 Time remaining: 0s Progress 8148 / 9694 Time remaining: 0s Progress 8149 / 9694 Time remaining: 0s Progress 8150 / 9694 Time remaining: 0s Progress 8151 / 9694 Time remaining: 0s Progress 8152 / 9694 Time remaining: 0s Progress 8153 / 9694 Time remaining: 0s Progress 8154 / 9694 Time remaining: 0s Progress 8155 / 9694 Time remaining: 0s Progress 8156 / 9694 Time remaining: 0s Progress 8157 / 9694 Time remaining: 0s Progress 8158 / 9694 Time remaining: 0s Progress 8159 / 9694 Time remaining: 0s Progress 8160 / 9694 Time remaining: 0s Progress 8161 / 9694 Time remaining: 0s Progress 8162 / 9694 Time remaining: 0s Progress 8163 / 9694 Time remaining: 0s Progress 8164 / 9694 Time remaining: 0s Progress 8165 / 9694 Time remaining: 0s Progress 8166 / 9694 Time remaining: 0s Progress 8167 / 9694 Time remaining: 0s Progress 8168 / 9694 Time remaining: 0s Progress 8169 / 9694 Time remaining: 0s Progress 8170 / 9694 Time remaining: 0s Progress 8171 / 9694 Time remaining: 0s Progress 8172 / 9694 Time remaining: 0s Progress 8173 / 9694 Time remaining: 0s Progress 8174 / 9694 Time remaining: 0s Progress 8175 / 9694 Time remaining: 0s Progress 8176 / 9694 Time remaining: 0s Progress 8177 / 9694 Time remaining: 0s Progress 8178 / 9694 Time remaining: 0s Progress 8179 / 9694 Time remaining: 0s Progress 8180 / 9694 Time remaining: 0s Progress 8181 / 9694 Time remaining: 0s Progress 8182 / 9694 Time remaining: 0s Progress 8183 / 9694 Time remaining: 0s Progress 8184 / 9694 Time remaining: 0s Progress 8185 / 9694 Time remaining: 0s Progress 8186 / 9694 Time remaining: 0s Progress 8187 / 9694 Time remaining: 0s Progress 8188 / 9694 Time remaining: 0s Progress 8189 / 9694 Time remaining: 0s Progress 8190 / 9694 Time remaining: 0s Progress 8191 / 9694 Time remaining: 0s Progress 8192 / 9694 Time remaining: 0s Progress 8193 / 9694 Time remaining: 0s Progress 8194 / 9694 Time remaining: 0s Progress 8195 / 9694 Time remaining: 0s Progress 8196 / 9694 Time remaining: 0s Progress 8197 / 9694 Time remaining: 0s Progress 8198 / 9694 Time remaining: 0s Progress 8199 / 9694 Time remaining: 0s Progress 8200 / 9694 Time remaining: 0s Progress 8201 / 9694 Time remaining: 0s Progress 8202 / 9694 Time remaining: 0s Progress 8203 / 9694 Time remaining: 0s Progress 8204 / 9694 Time remaining: 0s Progress 8205 / 9694 Time remaining: 0s Progress 8206 / 9694 Time remaining: 0s Progress 8207 / 9694 Time remaining: 0s Progress 8208 / 9694 Time remaining: 0s Progress 8209 / 9694 Time remaining: 0s Progress 8210 / 9694 Time remaining: 0s Progress 8211 / 9694 Time remaining: 0s Progress 8212 / 9694 Time remaining: 0s Progress 8213 / 9694 Time remaining: 0s Progress 8214 / 9694 Time remaining: 0s Progress 8215 / 9694 Time remaining: 0s Progress 8216 / 9694 Time remaining: 0s Progress 8217 / 9694 Time remaining: 0s Progress 8218 / 9694 Time remaining: 0s Progress 8219 / 9694 Time remaining: 0s Progress 8220 / 9694 Time remaining: 0s Progress 8221 / 9694 Time remaining: 0s Progress 8222 / 9694 Time remaining: 0s Progress 8223 / 9694 Time remaining: 0s Progress 8224 / 9694 Time remaining: 0s Progress 8225 / 9694 Time remaining: 0s Progress 8226 / 9694 Time remaining: 0s Progress 8227 / 9694 Time remaining: 0s Progress 8228 / 9694 Time remaining: 0s Progress 8229 / 9694 Time remaining: 0s Progress 8230 / 9694 Time remaining: 0s Progress 8231 / 9694 Time remaining: 0s Progress 8232 / 9694 Time remaining: 0s Progress 8233 / 9694 Time remaining: 0s Progress 8234 / 9694 Time remaining: 0s Progress 8235 / 9694 Time remaining: 0s Progress 8236 / 9694 Time remaining: 0s Progress 8237 / 9694 Time remaining: 0s Progress 8238 / 9694 Time remaining: 0s Progress 8239 / 9694 Time remaining: 0s Progress 8240 / 9694 Time remaining: 0s Progress 8241 / 9694 Time remaining: 0s Progress 8242 / 9694 Time remaining: 0s Progress 8243 / 9694 Time remaining: 0s Progress 8244 / 9694 Time remaining: 0s Progress 8245 / 9694 Time remaining: 0s Progress 8246 / 9694 Time remaining: 0s Progress 8247 / 9694 Time remaining: 0s Progress 8248 / 9694 Time remaining: 0s Progress 8249 / 9694 Time remaining: 0s Progress 8250 / 9694 Time remaining: 0s Progress 8251 / 9694 Time remaining: 0s Progress 8252 / 9694 Time remaining: 0s Progress 8253 / 9694 Time remaining: 0s Progress 8254 / 9694 Time remaining: 0s Progress 8255 / 9694 Time remaining: 0s Progress 8256 / 9694 Time remaining: 0s Progress 8257 / 9694 Time remaining: 0s Progress 8258 / 9694 Time remaining: 0s Progress 8259 / 9694 Time remaining: 0s Progress 8260 / 9694 Time remaining: 0s Progress 8261 / 9694 Time remaining: 0s Progress 8262 / 9694 Time remaining: 0s Progress 8263 / 9694 Time remaining: 0s Progress 8264 / 9694 Time remaining: 0s Progress 8265 / 9694 Time remaining: 0s Progress 8266 / 9694 Time remaining: 0s Progress 8267 / 9694 Time remaining: 0s Progress 8268 / 9694 Time remaining: 0s Progress 8269 / 9694 Time remaining: 0s Progress 8270 / 9694 Time remaining: 0s Progress 8271 / 9694 Time remaining: 0s Progress 8272 / 9694 Time remaining: 0s Progress 8273 / 9694 Time remaining: 0s Progress 8274 / 9694 Time remaining: 0s Progress 8275 / 9694 Time remaining: 0s Progress 8276 / 9694 Time remaining: 0s Progress 8277 / 9694 Time remaining: 0s Progress 8278 / 9694 Time remaining: 0s Progress 8279 / 9694 Time remaining: 0s Progress 8280 / 9694 Time remaining: 0s Progress 8281 / 9694 Time remaining: 0s Progress 8282 / 9694 Time remaining: 0s Progress 8283 / 9694 Time remaining: 0s Progress 8284 / 9694 Time remaining: 0s Progress 8285 / 9694 Time remaining: 0s Progress 8286 / 9694 Time remaining: 0s Progress 8287 / 9694 Time remaining: 0s Progress 8288 / 9694 Time remaining: 0s Progress 8289 / 9694 Time remaining: 0s Progress 8290 / 9694 Time remaining: 0s Progress 8291 / 9694 Time remaining: 0s Progress 8292 / 9694 Time remaining: 0s Progress 8293 / 9694 Time remaining: 0s Progress 8294 / 9694 Time remaining: 0s Progress 8295 / 9694 Time remaining: 0s Progress 8296 / 9694 Time remaining: 0s Progress 8297 / 9694 Time remaining: 0s Progress 8298 / 9694 Time remaining: 0s Progress 8299 / 9694 Time remaining: 0s Progress 8300 / 9694 Time remaining: 0s Progress 8301 / 9694 Time remaining: 0s Progress 8302 / 9694 Time remaining: 0s Progress 8303 / 9694 Time remaining: 0s Progress 8304 / 9694 Time remaining: 0s Progress 8305 / 9694 Time remaining: 0s Progress 8306 / 9694 Time remaining: 0s Progress 8307 / 9694 Time remaining: 0s Progress 8308 / 9694 Time remaining: 0s Progress 8309 / 9694 Time remaining: 0s Progress 8310 / 9694 Time remaining: 0s Progress 8311 / 9694 Time remaining: 0s Progress 8312 / 9694 Time remaining: 0s Progress 8313 / 9694 Time remaining: 0s Progress 8314 / 9694 Time remaining: 0s Progress 8315 / 9694 Time remaining: 0s Progress 8316 / 9694 Time remaining: 0s Progress 8317 / 9694 Time remaining: 0s Progress 8318 / 9694 Time remaining: 0s Progress 8319 / 9694 Time remaining: 0s Progress 8320 / 9694 Time remaining: 0s Progress 8321 / 9694 Time remaining: 0s Progress 8322 / 9694 Time remaining: 0s Progress 8323 / 9694 Time remaining: 0s Progress 8324 / 9694 Time remaining: 0s Progress 8325 / 9694 Time remaining: 0s Progress 8326 / 9694 Time remaining: 0s Progress 8327 / 9694 Time remaining: 0s Progress 8328 / 9694 Time remaining: 0s Progress 8329 / 9694 Time remaining: 0s Progress 8330 / 9694 Time remaining: 0s Progress 8331 / 9694 Time remaining: 0s Progress 8332 / 9694 Time remaining: 0s Progress 8333 / 9694 Time remaining: 0s Progress 8334 / 9694 Time remaining: 0s Progress 8335 / 9694 Time remaining: 0s Progress 8336 / 9694 Time remaining: 0s Progress 8337 / 9694 Time remaining: 0s Progress 8338 / 9694 Time remaining: 0s Progress 8339 / 9694 Time remaining: 0s Progress 8340 / 9694 Time remaining: 0s Progress 8341 / 9694 Time remaining: 0s Progress 8342 / 9694 Time remaining: 0s Progress 8343 / 9694 Time remaining: 0s Progress 8344 / 9694 Time remaining: 0s Progress 8345 / 9694 Time remaining: 0s Progress 8346 / 9694 Time remaining: 0s Progress 8347 / 9694 Time remaining: 0s Progress 8348 / 9694 Time remaining: 0s Progress 8349 / 9694 Time remaining: 0s Progress 8350 / 9694 Time remaining: 0s Progress 8351 / 9694 Time remaining: 0s Progress 8352 / 9694 Time remaining: 0s Progress 8353 / 9694 Time remaining: 0s Progress 8354 / 9694 Time remaining: 0s Progress 8355 / 9694 Time remaining: 0s Progress 8356 / 9694 Time remaining: 0s Progress 8357 / 9694 Time remaining: 0s Progress 8358 / 9694 Time remaining: 0s Progress 8359 / 9694 Time remaining: 0s Progress 8360 / 9694 Time remaining: 0s Progress 8361 / 9694 Time remaining: 0s Progress 8362 / 9694 Time remaining: 0s Progress 8363 / 9694 Time remaining: 0s Progress 8364 / 9694 Time remaining: 0s Progress 8365 / 9694 Time remaining: 0s Progress 8366 / 9694 Time remaining: 0s Progress 8367 / 9694 Time remaining: 0s Progress 8368 / 9694 Time remaining: 0s Progress 8369 / 9694 Time remaining: 0s Progress 8370 / 9694 Time remaining: 0s Progress 8371 / 9694 Time remaining: 0s Progress 8372 / 9694 Time remaining: 0s Progress 8373 / 9694 Time remaining: 0s Progress 8374 / 9694 Time remaining: 0s Progress 8375 / 9694 Time remaining: 0s Progress 8376 / 9694 Time remaining: 0s Progress 8377 / 9694 Time remaining: 0s Progress 8378 / 9694 Time remaining: 0s Progress 8379 / 9694 Time remaining: 0s Progress 8380 / 9694 Time remaining: 0s Progress 8381 / 9694 Time remaining: 0s Progress 8382 / 9694 Time remaining: 0s Progress 8383 / 9694 Time remaining: 0s Progress 8384 / 9694 Time remaining: 0s Progress 8385 / 9694 Time remaining: 0s Progress 8386 / 9694 Time remaining: 0s Progress 8387 / 9694 Time remaining: 0s Progress 8388 / 9694 Time remaining: 0s Progress 8389 / 9694 Time remaining: 0s Progress 8390 / 9694 Time remaining: 0s Progress 8391 / 9694 Time remaining: 0s Progress 8392 / 9694 Time remaining: 0s Progress 8393 / 9694 Time remaining: 0s Progress 8394 / 9694 Time remaining: 0s Progress 8395 / 9694 Time remaining: 0s Progress 8396 / 9694 Time remaining: 0s Progress 8397 / 9694 Time remaining: 0s Progress 8398 / 9694 Time remaining: 0s Progress 8399 / 9694 Time remaining: 0s Progress 8400 / 9694 Time remaining: 0s Progress 8401 / 9694 Time remaining: 0s Progress 8402 / 9694 Time remaining: 0s Progress 8403 / 9694 Time remaining: 0s Progress 8404 / 9694 Time remaining: 0s Progress 8405 / 9694 Time remaining: 0s Progress 8406 / 9694 Time remaining: 0s Progress 8407 / 9694 Time remaining: 0s Progress 8408 / 9694 Time remaining: 0s Progress 8409 / 9694 Time remaining: 0s Progress 8410 / 9694 Time remaining: 0s Progress 8411 / 9694 Time remaining: 0s Progress 8412 / 9694 Time remaining: 0s Progress 8413 / 9694 Time remaining: 0s Progress 8414 / 9694 Time remaining: 0s Progress 8415 / 9694 Time remaining: 0s Progress 8416 / 9694 Time remaining: 0s Progress 8417 / 9694 Time remaining: 0s Progress 8418 / 9694 Time remaining: 0s Progress 8419 / 9694 Time remaining: 0s Progress 8420 / 9694 Time remaining: 0s Progress 8421 / 9694 Time remaining: 0s Progress 8422 / 9694 Time remaining: 0s Progress 8423 / 9694 Time remaining: 0s Progress 8424 / 9694 Time remaining: 0s Progress 8425 / 9694 Time remaining: 0s Progress 8426 / 9694 Time remaining: 0s Progress 8427 / 9694 Time remaining: 0s Progress 8428 / 9694 Time remaining: 0s Progress 8429 / 9694 Time remaining: 0s Progress 8430 / 9694 Time remaining: 0s Progress 8431 / 9694 Time remaining: 0s Progress 8432 / 9694 Time remaining: 0s Progress 8433 / 9694 Time remaining: 0s Progress 8434 / 9694 Time remaining: 0s Progress 8435 / 9694 Time remaining: 0s Progress 8436 / 9694 Time remaining: 0s Progress 8437 / 9694 Time remaining: 0s Progress 8438 / 9694 Time remaining: 0s Progress 8439 / 9694 Time remaining: 0s Progress 8440 / 9694 Time remaining: 0s Progress 8441 / 9694 Time remaining: 0s Progress 8442 / 9694 Time remaining: 0s Progress 8443 / 9694 Time remaining: 0s Progress 8444 / 9694 Time remaining: 0s Progress 8445 / 9694 Time remaining: 0s Progress 8446 / 9694 Time remaining: 0s Progress 8447 / 9694 Time remaining: 0s Progress 8448 / 9694 Time remaining: 0s Progress 8449 / 9694 Time remaining: 0s Progress 8450 / 9694 Time remaining: 0s Progress 8451 / 9694 Time remaining: 0s Progress 8452 / 9694 Time remaining: 0s Progress 8453 / 9694 Time remaining: 0s Progress 8454 / 9694 Time remaining: 0s Progress 8455 / 9694 Time remaining: 0s Progress 8456 / 9694 Time remaining: 0s Progress 8457 / 9694 Time remaining: 0s Progress 8458 / 9694 Time remaining: 0s Progress 8459 / 9694 Time remaining: 0s Progress 8460 / 9694 Time remaining: 0s Progress 8461 / 9694 Time remaining: 0s Progress 8462 / 9694 Time remaining: 0s Progress 8463 / 9694 Time remaining: 0s Progress 8464 / 9694 Time remaining: 0s Progress 8465 / 9694 Time remaining: 0s Progress 8466 / 9694 Time remaining: 0s Progress 8467 / 9694 Time remaining: 0s Progress 8468 / 9694 Time remaining: 0s Progress 8469 / 9694 Time remaining: 0s Progress 8470 / 9694 Time remaining: 0s Progress 8471 / 9694 Time remaining: 0s Progress 8472 / 9694 Time remaining: 0s Progress 8473 / 9694 Time remaining: 0s Progress 8474 / 9694 Time remaining: 0s Progress 8475 / 9694 Time remaining: 0s Progress 8476 / 9694 Time remaining: 0s Progress 8477 / 9694 Time remaining: 0s Progress 8478 / 9694 Time remaining: 0s Progress 8479 / 9694 Time remaining: 0s Progress 8480 / 9694 Time remaining: 0s Progress 8481 / 9694 Time remaining: 0s Progress 8482 / 9694 Time remaining: 0s Progress 8483 / 9694 Time remaining: 0s Progress 8484 / 9694 Time remaining: 0s Progress 8485 / 9694 Time remaining: 0s Progress 8486 / 9694 Time remaining: 0s Progress 8487 / 9694 Time remaining: 0s Progress 8488 / 9694 Time remaining: 0s Progress 8489 / 9694 Time remaining: 0s Progress 8490 / 9694 Time remaining: 0s Progress 8491 / 9694 Time remaining: 0s Progress 8492 / 9694 Time remaining: 0s Progress 8493 / 9694 Time remaining: 0s Progress 8494 / 9694 Time remaining: 0s Progress 8495 / 9694 Time remaining: 0s Progress 8496 / 9694 Time remaining: 0s Progress 8497 / 9694 Time remaining: 0s Progress 8498 / 9694 Time remaining: 0s Progress 8499 / 9694 Time remaining: 0s Progress 8500 / 9694 Time remaining: 0s Progress 8501 / 9694 Time remaining: 0s Progress 8502 / 9694 Time remaining: 0s Progress 8503 / 9694 Time remaining: 0s Progress 8504 / 9694 Time remaining: 0s Progress 8505 / 9694 Time remaining: 0s Progress 8506 / 9694 Time remaining: 0s Progress 8507 / 9694 Time remaining: 0s Progress 8508 / 9694 Time remaining: 0s Progress 8509 / 9694 Time remaining: 0s Progress 8510 / 9694 Time remaining: 0s Progress 8511 / 9694 Time remaining: 0s Progress 8512 / 9694 Time remaining: 0s Progress 8513 / 9694 Time remaining: 0s Progress 8514 / 9694 Time remaining: 0s Progress 8515 / 9694 Time remaining: 0s Progress 8516 / 9694 Time remaining: 0s Progress 8517 / 9694 Time remaining: 0s Progress 8518 / 9694 Time remaining: 0s Progress 8519 / 9694 Time remaining: 0s Progress 8520 / 9694 Time remaining: 0s Progress 8521 / 9694 Time remaining: 0s Progress 8522 / 9694 Time remaining: 0s Progress 8523 / 9694 Time remaining: 0s Progress 8524 / 9694 Time remaining: 0s Progress 8525 / 9694 Time remaining: 0s Progress 8526 / 9694 Time remaining: 0s Progress 8527 / 9694 Time remaining: 0s Progress 8528 / 9694 Time remaining: 0s Progress 8529 / 9694 Time remaining: 0s Progress 8530 / 9694 Time remaining: 0s Progress 8531 / 9694 Time remaining: 0s Progress 8532 / 9694 Time remaining: 0s Progress 8533 / 9694 Time remaining: 0s Progress 8534 / 9694 Time remaining: 0s Progress 8535 / 9694 Time remaining: 0s Progress 8536 / 9694 Time remaining: 0s Progress 8537 / 9694 Time remaining: 0s Progress 8538 / 9694 Time remaining: 0s Progress 8539 / 9694 Time remaining: 0s Progress 8540 / 9694 Time remaining: 0s Progress 8541 / 9694 Time remaining: 0s Progress 8542 / 9694 Time remaining: 0s Progress 8543 / 9694 Time remaining: 0s Progress 8544 / 9694 Time remaining: 0s Progress 8545 / 9694 Time remaining: 0s Progress 8546 / 9694 Time remaining: 0s Progress 8547 / 9694 Time remaining: 0s Progress 8548 / 9694 Time remaining: 0s Progress 8549 / 9694 Time remaining: 0s Progress 8550 / 9694 Time remaining: 0s Progress 8551 / 9694 Time remaining: 0s Progress 8552 / 9694 Time remaining: 0s Progress 8553 / 9694 Time remaining: 0s Progress 8554 / 9694 Time remaining: 0s Progress 8555 / 9694 Time remaining: 0s Progress 8556 / 9694 Time remaining: 0s Progress 8557 / 9694 Time remaining: 0s Progress 8558 / 9694 Time remaining: 0s Progress 8559 / 9694 Time remaining: 0s Progress 8560 / 9694 Time remaining: 0s Progress 8561 / 9694 Time remaining: 0s Progress 8562 / 9694 Time remaining: 0s Progress 8563 / 9694 Time remaining: 0s Progress 8564 / 9694 Time remaining: 0s Progress 8565 / 9694 Time remaining: 0s Progress 8566 / 9694 Time remaining: 0s Progress 8567 / 9694 Time remaining: 0s Progress 8568 / 9694 Time remaining: 0s Progress 8569 / 9694 Time remaining: 0s Progress 8570 / 9694 Time remaining: 0s Progress 8571 / 9694 Time remaining: 0s Progress 8572 / 9694 Time remaining: 0s Progress 8573 / 9694 Time remaining: 0s Progress 8574 / 9694 Time remaining: 0s Progress 8575 / 9694 Time remaining: 0s Progress 8576 / 9694 Time remaining: 0s Progress 8577 / 9694 Time remaining: 0s Progress 8578 / 9694 Time remaining: 0s Progress 8579 / 9694 Time remaining: 0s Progress 8580 / 9694 Time remaining: 0s Progress 8581 / 9694 Time remaining: 0s Progress 8582 / 9694 Time remaining: 0s Progress 8583 / 9694 Time remaining: 0s Progress 8584 / 9694 Time remaining: 0s Progress 8585 / 9694 Time remaining: 0s Progress 8586 / 9694 Time remaining: 0s Progress 8587 / 9694 Time remaining: 0s Progress 8588 / 9694 Time remaining: 0s Progress 8589 / 9694 Time remaining: 0s Progress 8590 / 9694 Time remaining: 0s Progress 8591 / 9694 Time remaining: 0s Progress 8592 / 9694 Time remaining: 0s Progress 8593 / 9694 Time remaining: 0s Progress 8594 / 9694 Time remaining: 0s Progress 8595 / 9694 Time remaining: 0s Progress 8596 / 9694 Time remaining: 0s Progress 8597 / 9694 Time remaining: 0s Progress 8598 / 9694 Time remaining: 0s Progress 8599 / 9694 Time remaining: 0s Progress 8600 / 9694 Time remaining: 0s Progress 8601 / 9694 Time remaining: 0s Progress 8602 / 9694 Time remaining: 0s Progress 8603 / 9694 Time remaining: 0s Progress 8604 / 9694 Time remaining: 0s Progress 8605 / 9694 Time remaining: 0s Progress 8606 / 9694 Time remaining: 0s Progress 8607 / 9694 Time remaining: 0s Progress 8608 / 9694 Time remaining: 0s Progress 8609 / 9694 Time remaining: 0s Progress 8610 / 9694 Time remaining: 0s Progress 8611 / 9694 Time remaining: 0s Progress 8612 / 9694 Time remaining: 0s Progress 8613 / 9694 Time remaining: 0s Progress 8614 / 9694 Time remaining: 0s Progress 8615 / 9694 Time remaining: 0s Progress 8616 / 9694 Time remaining: 0s Progress 8617 / 9694 Time remaining: 0s Progress 8618 / 9694 Time remaining: 0s Progress 8619 / 9694 Time remaining: 0s Progress 8620 / 9694 Time remaining: 0s Progress 8621 / 9694 Time remaining: 0s Progress 8622 / 9694 Time remaining: 0s Progress 8623 / 9694 Time remaining: 0s Progress 8624 / 9694 Time remaining: 0s Progress 8625 / 9694 Time remaining: 0s Progress 8626 / 9694 Time remaining: 0s Progress 8627 / 9694 Time remaining: 0s Progress 8628 / 9694 Time remaining: 0s Progress 8629 / 9694 Time remaining: 0s Progress 8630 / 9694 Time remaining: 0s Progress 8631 / 9694 Time remaining: 0s Progress 8632 / 9694 Time remaining: 0s Progress 8633 / 9694 Time remaining: 0s Progress 8634 / 9694 Time remaining: 0s Progress 8635 / 9694 Time remaining: 0s Progress 8636 / 9694 Time remaining: 0s Progress 8637 / 9694 Time remaining: 0s Progress 8638 / 9694 Time remaining: 0s Progress 8639 / 9694 Time remaining: 0s Progress 8640 / 9694 Time remaining: 0s Progress 8641 / 9694 Time remaining: 0s Progress 8642 / 9694 Time remaining: 0s Progress 8643 / 9694 Time remaining: 0s Progress 8644 / 9694 Time remaining: 0s Progress 8645 / 9694 Time remaining: 0s Progress 8646 / 9694 Time remaining: 0s Progress 8647 / 9694 Time remaining: 0s Progress 8648 / 9694 Time remaining: 0s Progress 8649 / 9694 Time remaining: 0s Progress 8650 / 9694 Time remaining: 0s Progress 8651 / 9694 Time remaining: 0s Progress 8652 / 9694 Time remaining: 0s Progress 8653 / 9694 Time remaining: 0s Progress 8654 / 9694 Time remaining: 0s Progress 8655 / 9694 Time remaining: 0s Progress 8656 / 9694 Time remaining: 0s Progress 8657 / 9694 Time remaining: 0s Progress 8658 / 9694 Time remaining: 0s Progress 8659 / 9694 Time remaining: 0s Progress 8660 / 9694 Time remaining: 0s Progress 8661 / 9694 Time remaining: 0s Progress 8662 / 9694 Time remaining: 0s Progress 8663 / 9694 Time remaining: 0s Progress 8664 / 9694 Time remaining: 0s Progress 8665 / 9694 Time remaining: 0s Progress 8666 / 9694 Time remaining: 0s Progress 8667 / 9694 Time remaining: 0s Progress 8668 / 9694 Time remaining: 0s Progress 8669 / 9694 Time remaining: 0s Progress 8670 / 9694 Time remaining: 0s Progress 8671 / 9694 Time remaining: 0s Progress 8672 / 9694 Time remaining: 0s Progress 8673 / 9694 Time remaining: 0s Progress 8674 / 9694 Time remaining: 0s Progress 8675 / 9694 Time remaining: 0s Progress 8676 / 9694 Time remaining: 0s Progress 8677 / 9694 Time remaining: 0s Progress 8678 / 9694 Time remaining: 0s Progress 8679 / 9694 Time remaining: 0s Progress 8680 / 9694 Time remaining: 0s Progress 8681 / 9694 Time remaining: 0s Progress 8682 / 9694 Time remaining: 0s Progress 8683 / 9694 Time remaining: 0s Progress 8684 / 9694 Time remaining: 0s Progress 8685 / 9694 Time remaining: 0s Progress 8686 / 9694 Time remaining: 0s Progress 8687 / 9694 Time remaining: 0s Progress 8688 / 9694 Time remaining: 0s Progress 8689 / 9694 Time remaining: 0s Progress 8690 / 9694 Time remaining: 0s Progress 8691 / 9694 Time remaining: 0s Progress 8692 / 9694 Time remaining: 0s Progress 8693 / 9694 Time remaining: 0s Progress 8694 / 9694 Time remaining: 0s Progress 8695 / 9694 Time remaining: 0s Progress 8696 / 9694 Time remaining: 0s Progress 8697 / 9694 Time remaining: 0s Progress 8698 / 9694 Time remaining: 0s Progress 8699 / 9694 Time remaining: 0s Progress 8700 / 9694 Time remaining: 0s Progress 8701 / 9694 Time remaining: 0s Progress 8702 / 9694 Time remaining: 0s Progress 8703 / 9694 Time remaining: 0s Progress 8704 / 9694 Time remaining: 0s Progress 8705 / 9694 Time remaining: 0s Progress 8706 / 9694 Time remaining: 0s Progress 8707 / 9694 Time remaining: 0s Progress 8708 / 9694 Time remaining: 0s Progress 8709 / 9694 Time remaining: 0s Progress 8710 / 9694 Time remaining: 0s Progress 8711 / 9694 Time remaining: 0s Progress 8712 / 9694 Time remaining: 0s Progress 8713 / 9694 Time remaining: 0s Progress 8714 / 9694 Time remaining: 0s Progress 8715 / 9694 Time remaining: 0s Progress 8716 / 9694 Time remaining: 0s Progress 8717 / 9694 Time remaining: 0s Progress 8718 / 9694 Time remaining: 0s Progress 8719 / 9694 Time remaining: 0s Progress 8720 / 9694 Time remaining: 0s Progress 8721 / 9694 Time remaining: 0s Progress 8722 / 9694 Time remaining: 0s Progress 8723 / 9694 Time remaining: 0s Progress 8724 / 9694 Time remaining: 0s Progress 8725 / 9694 Time remaining: 0s Progress 8726 / 9694 Time remaining: 0s Progress 8727 / 9694 Time remaining: 0s Progress 8728 / 9694 Time remaining: 0s Progress 8729 / 9694 Time remaining: 0s Progress 8730 / 9694 Time remaining: 0s Progress 8731 / 9694 Time remaining: 0s Progress 8732 / 9694 Time remaining: 0s Progress 8733 / 9694 Time remaining: 0s Progress 8734 / 9694 Time remaining: 0s Progress 8735 / 9694 Time remaining: 0s Progress 8736 / 9694 Time remaining: 0s Progress 8737 / 9694 Time remaining: 0s Progress 8738 / 9694 Time remaining: 0s Progress 8739 / 9694 Time remaining: 0s Progress 8740 / 9694 Time remaining: 0s Progress 8741 / 9694 Time remaining: 0s Progress 8742 / 9694 Time remaining: 0s Progress 8743 / 9694 Time remaining: 0s Progress 8744 / 9694 Time remaining: 0s Progress 8745 / 9694 Time remaining: 0s Progress 8746 / 9694 Time remaining: 0s Progress 8747 / 9694 Time remaining: 0s Progress 8748 / 9694 Time remaining: 0s Progress 8749 / 9694 Time remaining: 0s Progress 8750 / 9694 Time remaining: 0s Progress 8751 / 9694 Time remaining: 0s Progress 8752 / 9694 Time remaining: 0s Progress 8753 / 9694 Time remaining: 0s Progress 8754 / 9694 Time remaining: 0s Progress 8755 / 9694 Time remaining: 0s Progress 8756 / 9694 Time remaining: 0s Progress 8757 / 9694 Time remaining: 0s Progress 8758 / 9694 Time remaining: 0s Progress 8759 / 9694 Time remaining: 0s Progress 8760 / 9694 Time remaining: 0s Progress 8761 / 9694 Time remaining: 0s Progress 8762 / 9694 Time remaining: 0s Progress 8763 / 9694 Time remaining: 0s Progress 8764 / 9694 Time remaining: 0s Progress 8765 / 9694 Time remaining: 0s Progress 8766 / 9694 Time remaining: 0s Progress 8767 / 9694 Time remaining: 0s Progress 8768 / 9694 Time remaining: 0s Progress 8769 / 9694 Time remaining: 0s Progress 8770 / 9694 Time remaining: 0s Progress 8771 / 9694 Time remaining: 0s Progress 8772 / 9694 Time remaining: 0s Progress 8773 / 9694 Time remaining: 0s Progress 8774 / 9694 Time remaining: 0s Progress 8775 / 9694 Time remaining: 0s Progress 8776 / 9694 Time remaining: 0s Progress 8777 / 9694 Time remaining: 0s Progress 8778 / 9694 Time remaining: 0s Progress 8779 / 9694 Time remaining: 0s Progress 8780 / 9694 Time remaining: 0s Progress 8781 / 9694 Time remaining: 0s Progress 8782 / 9694 Time remaining: 0s Progress 8783 / 9694 Time remaining: 0s Progress 8784 / 9694 Time remaining: 0s Progress 8785 / 9694 Time remaining: 0s Progress 8786 / 9694 Time remaining: 0s Progress 8787 / 9694 Time remaining: 0s Progress 8788 / 9694 Time remaining: 0s Progress 8789 / 9694 Time remaining: 0s Progress 8790 / 9694 Time remaining: 0s Progress 8791 / 9694 Time remaining: 0s Progress 8792 / 9694 Time remaining: 0s Progress 8793 / 9694 Time remaining: 0s Progress 8794 / 9694 Time remaining: 0s Progress 8795 / 9694 Time remaining: 0s Progress 8796 / 9694 Time remaining: 0s Progress 8797 / 9694 Time remaining: 0s Progress 8798 / 9694 Time remaining: 0s Progress 8799 / 9694 Time remaining: 0s Progress 8800 / 9694 Time remaining: 0s Progress 8801 / 9694 Time remaining: 0s Progress 8802 / 9694 Time remaining: 0s Progress 8803 / 9694 Time remaining: 0s Progress 8804 / 9694 Time remaining: 0s Progress 8805 / 9694 Time remaining: 0s Progress 8806 / 9694 Time remaining: 0s Progress 8807 / 9694 Time remaining: 0s Progress 8808 / 9694 Time remaining: 0s Progress 8809 / 9694 Time remaining: 0s Progress 8810 / 9694 Time remaining: 0s Progress 8811 / 9694 Time remaining: 0s Progress 8812 / 9694 Time remaining: 0s Progress 8813 / 9694 Time remaining: 0s Progress 8814 / 9694 Time remaining: 0s Progress 8815 / 9694 Time remaining: 0s Progress 8816 / 9694 Time remaining: 0s Progress 8817 / 9694 Time remaining: 0s Progress 8818 / 9694 Time remaining: 0s Progress 8819 / 9694 Time remaining: 0s Progress 8820 / 9694 Time remaining: 0s Progress 8821 / 9694 Time remaining: 0s Progress 8822 / 9694 Time remaining: 0s Progress 8823 / 9694 Time remaining: 0s Progress 8824 / 9694 Time remaining: 0s Progress 8825 / 9694 Time remaining: 0s Progress 8826 / 9694 Time remaining: 0s Progress 8827 / 9694 Time remaining: 0s Progress 8828 / 9694 Time remaining: 0s Progress 8829 / 9694 Time remaining: 0s Progress 8830 / 9694 Time remaining: 0s Progress 8831 / 9694 Time remaining: 0s Progress 8832 / 9694 Time remaining: 0s Progress 8833 / 9694 Time remaining: 0s Progress 8834 / 9694 Time remaining: 0s Progress 8835 / 9694 Time remaining: 0s Progress 8836 / 9694 Time remaining: 0s Progress 8837 / 9694 Time remaining: 0s Progress 8838 / 9694 Time remaining: 0s Progress 8839 / 9694 Time remaining: 0s Progress 8840 / 9694 Time remaining: 0s Progress 8841 / 9694 Time remaining: 0s Progress 8842 / 9694 Time remaining: 0s Progress 8843 / 9694 Time remaining: 0s Progress 8844 / 9694 Time remaining: 0s Progress 8845 / 9694 Time remaining: 0s Progress 8846 / 9694 Time remaining: 0s Progress 8847 / 9694 Time remaining: 0s Progress 8848 / 9694 Time remaining: 0s Progress 8849 / 9694 Time remaining: 0s Progress 8850 / 9694 Time remaining: 0s Progress 8851 / 9694 Time remaining: 0s Progress 8852 / 9694 Time remaining: 0s Progress 8853 / 9694 Time remaining: 0s Progress 8854 / 9694 Time remaining: 0s Progress 8855 / 9694 Time remaining: 0s Progress 8856 / 9694 Time remaining: 0s Progress 8857 / 9694 Time remaining: 0s Progress 8858 / 9694 Time remaining: 0s Progress 8859 / 9694 Time remaining: 0s Progress 8860 / 9694 Time remaining: 0s Progress 8861 / 9694 Time remaining: 0s Progress 8862 / 9694 Time remaining: 0s Progress 8863 / 9694 Time remaining: 0s Progress 8864 / 9694 Time remaining: 0s Progress 8865 / 9694 Time remaining: 0s Progress 8866 / 9694 Time remaining: 0s Progress 8867 / 9694 Time remaining: 0s Progress 8868 / 9694 Time remaining: 0s Progress 8869 / 9694 Time remaining: 0s Progress 8870 / 9694 Time remaining: 0s Progress 8871 / 9694 Time remaining: 0s Progress 8872 / 9694 Time remaining: 0s Progress 8873 / 9694 Time remaining: 0s Progress 8874 / 9694 Time remaining: 0s Progress 8875 / 9694 Time remaining: 0s Progress 8876 / 9694 Time remaining: 0s Progress 8877 / 9694 Time remaining: 0s Progress 8878 / 9694 Time remaining: 0s Progress 8879 / 9694 Time remaining: 0s Progress 8880 / 9694 Time remaining: 0s Progress 8881 / 9694 Time remaining: 0s Progress 8882 / 9694 Time remaining: 0s Progress 8883 / 9694 Time remaining: 0s Progress 8884 / 9694 Time remaining: 0s Progress 8885 / 9694 Time remaining: 0s Progress 8886 / 9694 Time remaining: 0s Progress 8887 / 9694 Time remaining: 0s Progress 8888 / 9694 Time remaining: 0s Progress 8889 / 9694 Time remaining: 0s Progress 8890 / 9694 Time remaining: 0s Progress 8891 / 9694 Time remaining: 0s Progress 8892 / 9694 Time remaining: 0s Progress 8893 / 9694 Time remaining: 0s Progress 8894 / 9694 Time remaining: 0s Progress 8895 / 9694 Time remaining: 0s Progress 8896 / 9694 Time remaining: 0s Progress 8897 / 9694 Time remaining: 0s Progress 8898 / 9694 Time remaining: 0s Progress 8899 / 9694 Time remaining: 0s Progress 8900 / 9694 Time remaining: 0s Progress 8901 / 9694 Time remaining: 0s Progress 8902 / 9694 Time remaining: 0s Progress 8903 / 9694 Time remaining: 0s Progress 8904 / 9694 Time remaining: 0s Progress 8905 / 9694 Time remaining: 0s Progress 8906 / 9694 Time remaining: 0s Progress 8907 / 9694 Time remaining: 0s Progress 8908 / 9694 Time remaining: 0s Progress 8909 / 9694 Time remaining: 0s Progress 8910 / 9694 Time remaining: 0s Progress 8911 / 9694 Time remaining: 0s Progress 8912 / 9694 Time remaining: 0s Progress 8913 / 9694 Time remaining: 0s Progress 8914 / 9694 Time remaining: 0s Progress 8915 / 9694 Time remaining: 0s Progress 8916 / 9694 Time remaining: 0s Progress 8917 / 9694 Time remaining: 0s Progress 8918 / 9694 Time remaining: 0s Progress 8919 / 9694 Time remaining: 0s Progress 8920 / 9694 Time remaining: 0s Progress 8921 / 9694 Time remaining: 0s Progress 8922 / 9694 Time remaining: 0s Progress 8923 / 9694 Time remaining: 0s Progress 8924 / 9694 Time remaining: 0s Progress 8925 / 9694 Time remaining: 0s Progress 8926 / 9694 Time remaining: 0s Progress 8927 / 9694 Time remaining: 0s Progress 8928 / 9694 Time remaining: 0s Progress 8929 / 9694 Time remaining: 0s Progress 8930 / 9694 Time remaining: 0s Progress 8931 / 9694 Time remaining: 0s Progress 8932 / 9694 Time remaining: 0s Progress 8933 / 9694 Time remaining: 0s Progress 8934 / 9694 Time remaining: 0s Progress 8935 / 9694 Time remaining: 0s Progress 8936 / 9694 Time remaining: 0s Progress 8937 / 9694 Time remaining: 0s Progress 8938 / 9694 Time remaining: 0s Progress 8939 / 9694 Time remaining: 0s Progress 8940 / 9694 Time remaining: 0s Progress 8941 / 9694 Time remaining: 0s Progress 8942 / 9694 Time remaining: 0s Progress 8943 / 9694 Time remaining: 0s Progress 8944 / 9694 Time remaining: 0s Progress 8945 / 9694 Time remaining: 0s Progress 8946 / 9694 Time remaining: 0s Progress 8947 / 9694 Time remaining: 0s Progress 8948 / 9694 Time remaining: 0s Progress 8949 / 9694 Time remaining: 0s Progress 8950 / 9694 Time remaining: 0s Progress 8951 / 9694 Time remaining: 0s Progress 8952 / 9694 Time remaining: 0s Progress 8953 / 9694 Time remaining: 0s Progress 8954 / 9694 Time remaining: 0s Progress 8955 / 9694 Time remaining: 0s Progress 8956 / 9694 Time remaining: 0s Progress 8957 / 9694 Time remaining: 0s Progress 8958 / 9694 Time remaining: 0s Progress 8959 / 9694 Time remaining: 0s Progress 8960 / 9694 Time remaining: 0s Progress 8961 / 9694 Time remaining: 0s Progress 8962 / 9694 Time remaining: 0s Progress 8963 / 9694 Time remaining: 0s Progress 8964 / 9694 Time remaining: 0s Progress 8965 / 9694 Time remaining: 0s Progress 8966 / 9694 Time remaining: 0s Progress 8967 / 9694 Time remaining: 0s Progress 8968 / 9694 Time remaining: 0s Progress 8969 / 9694 Time remaining: 0s Progress 8970 / 9694 Time remaining: 0s Progress 8971 / 9694 Time remaining: 0s Progress 8972 / 9694 Time remaining: 0s Progress 8973 / 9694 Time remaining: 0s Progress 8974 / 9694 Time remaining: 0s Progress 8975 / 9694 Time remaining: 0s Progress 8976 / 9694 Time remaining: 0s Progress 8977 / 9694 Time remaining: 0s Progress 8978 / 9694 Time remaining: 0s Progress 8979 / 9694 Time remaining: 0s Progress 8980 / 9694 Time remaining: 0s Progress 8981 / 9694 Time remaining: 0s Progress 8982 / 9694 Time remaining: 0s Progress 8983 / 9694 Time remaining: 0s Progress 8984 / 9694 Time remaining: 0s Progress 8985 / 9694 Time remaining: 0s Progress 8986 / 9694 Time remaining: 0s Progress 8987 / 9694 Time remaining: 0s Progress 8988 / 9694 Time remaining: 0s Progress 8989 / 9694 Time remaining: 0s Progress 8990 / 9694 Time remaining: 0s Progress 8991 / 9694 Time remaining: 0s Progress 8992 / 9694 Time remaining: 0s Progress 8993 / 9694 Time remaining: 0s Progress 8994 / 9694 Time remaining: 0s Progress 8995 / 9694 Time remaining: 0s Progress 8996 / 9694 Time remaining: 0s Progress 8997 / 9694 Time remaining: 0s Progress 8998 / 9694 Time remaining: 0s Progress 8999 / 9694 Time remaining: 0s Progress 9000 / 9694 Time remaining: 0s Progress 9001 / 9694 Time remaining: 0s Progress 9002 / 9694 Time remaining: 0s Progress 9003 / 9694 Time remaining: 0s Progress 9004 / 9694 Time remaining: 0s Progress 9005 / 9694 Time remaining: 0s Progress 9006 / 9694 Time remaining: 0s Progress 9007 / 9694 Time remaining: 0s Progress 9008 / 9694 Time remaining: 0s Progress 9009 / 9694 Time remaining: 0s Progress 9010 / 9694 Time remaining: 0s Progress 9011 / 9694 Time remaining: 0s Progress 9012 / 9694 Time remaining: 0s Progress 9013 / 9694 Time remaining: 0s Progress 9014 / 9694 Time remaining: 0s Progress 9015 / 9694 Time remaining: 0s Progress 9016 / 9694 Time remaining: 0s Progress 9017 / 9694 Time remaining: 0s Progress 9018 / 9694 Time remaining: 0s Progress 9019 / 9694 Time remaining: 0s Progress 9020 / 9694 Time remaining: 0s Progress 9021 / 9694 Time remaining: 0s Progress 9022 / 9694 Time remaining: 0s Progress 9023 / 9694 Time remaining: 0s Progress 9024 / 9694 Time remaining: 0s Progress 9025 / 9694 Time remaining: 0s Progress 9026 / 9694 Time remaining: 0s Progress 9027 / 9694 Time remaining: 0s Progress 9028 / 9694 Time remaining: 0s Progress 9029 / 9694 Time remaining: 0s Progress 9030 / 9694 Time remaining: 0s Progress 9031 / 9694 Time remaining: 0s Progress 9032 / 9694 Time remaining: 0s Progress 9033 / 9694 Time remaining: 0s Progress 9034 / 9694 Time remaining: 0s Progress 9035 / 9694 Time remaining: 0s Progress 9036 / 9694 Time remaining: 0s Progress 9037 / 9694 Time remaining: 0s Progress 9038 / 9694 Time remaining: 0s Progress 9039 / 9694 Time remaining: 0s Progress 9040 / 9694 Time remaining: 0s Progress 9041 / 9694 Time remaining: 0s Progress 9042 / 9694 Time remaining: 0s Progress 9043 / 9694 Time remaining: 0s Progress 9044 / 9694 Time remaining: 0s Progress 9045 / 9694 Time remaining: 0s Progress 9046 / 9694 Time remaining: 0s Progress 9047 / 9694 Time remaining: 0s Progress 9048 / 9694 Time remaining: 0s Progress 9049 / 9694 Time remaining: 0s Progress 9050 / 9694 Time remaining: 0s Progress 9051 / 9694 Time remaining: 0s Progress 9052 / 9694 Time remaining: 0s Progress 9053 / 9694 Time remaining: 0s Progress 9054 / 9694 Time remaining: 0s Progress 9055 / 9694 Time remaining: 0s Progress 9056 / 9694 Time remaining: 0s Progress 9057 / 9694 Time remaining: 0s Progress 9058 / 9694 Time remaining: 0s Progress 9059 / 9694 Time remaining: 0s Progress 9060 / 9694 Time remaining: 0s Progress 9061 / 9694 Time remaining: 0s Progress 9062 / 9694 Time remaining: 0s Progress 9063 / 9694 Time remaining: 0s Progress 9064 / 9694 Time remaining: 0s Progress 9065 / 9694 Time remaining: 0s Progress 9066 / 9694 Time remaining: 0s Progress 9067 / 9694 Time remaining: 0s Progress 9068 / 9694 Time remaining: 0s Progress 9069 / 9694 Time remaining: 0s Progress 9070 / 9694 Time remaining: 0s Progress 9071 / 9694 Time remaining: 0s Progress 9072 / 9694 Time remaining: 0s Progress 9073 / 9694 Time remaining: 0s Progress 9074 / 9694 Time remaining: 0s Progress 9075 / 9694 Time remaining: 0s Progress 9076 / 9694 Time remaining: 0s Progress 9077 / 9694 Time remaining: 0s Progress 9078 / 9694 Time remaining: 0s Progress 9079 / 9694 Time remaining: 0s Progress 9080 / 9694 Time remaining: 0s Progress 9081 / 9694 Time remaining: 0s Progress 9082 / 9694 Time remaining: 0s Progress 9083 / 9694 Time remaining: 0s Progress 9084 / 9694 Time remaining: 0s Progress 9085 / 9694 Time remaining: 0s Progress 9086 / 9694 Time remaining: 0s Progress 9087 / 9694 Time remaining: 0s Progress 9088 / 9694 Time remaining: 0s Progress 9089 / 9694 Time remaining: 0s Progress 9090 / 9694 Time remaining: 0s Progress 9091 / 9694 Time remaining: 0s Progress 9092 / 9694 Time remaining: 0s Progress 9093 / 9694 Time remaining: 0s Progress 9094 / 9694 Time remaining: 0s Progress 9095 / 9694 Time remaining: 0s Progress 9096 / 9694 Time remaining: 0s Progress 9097 / 9694 Time remaining: 0s Progress 9098 / 9694 Time remaining: 0s Progress 9099 / 9694 Time remaining: 0s Progress 9100 / 9694 Time remaining: 0s Progress 9101 / 9694 Time remaining: 0s Progress 9102 / 9694 Time remaining: 0s Progress 9103 / 9694 Time remaining: 0s Progress 9104 / 9694 Time remaining: 0s Progress 9105 / 9694 Time remaining: 0s Progress 9106 / 9694 Time remaining: 0s Progress 9107 / 9694 Time remaining: 0s Progress 9108 / 9694 Time remaining: 0s Progress 9109 / 9694 Time remaining: 0s Progress 9110 / 9694 Time remaining: 0s Progress 9111 / 9694 Time remaining: 0s Progress 9112 / 9694 Time remaining: 0s Progress 9113 / 9694 Time remaining: 0s Progress 9114 / 9694 Time remaining: 0s Progress 9115 / 9694 Time remaining: 0s Progress 9116 / 9694 Time remaining: 0s Progress 9117 / 9694 Time remaining: 0s Progress 9118 / 9694 Time remaining: 0s Progress 9119 / 9694 Time remaining: 0s Progress 9120 / 9694 Time remaining: 0s Progress 9121 / 9694 Time remaining: 0s Progress 9122 / 9694 Time remaining: 0s Progress 9123 / 9694 Time remaining: 0s Progress 9124 / 9694 Time remaining: 0s Progress 9125 / 9694 Time remaining: 0s Progress 9126 / 9694 Time remaining: 0s Progress 9127 / 9694 Time remaining: 0s Progress 9128 / 9694 Time remaining: 0s Progress 9129 / 9694 Time remaining: 0s Progress 9130 / 9694 Time remaining: 0s Progress 9131 / 9694 Time remaining: 0s Progress 9132 / 9694 Time remaining: 0s Progress 9133 / 9694 Time remaining: 0s Progress 9134 / 9694 Time remaining: 0s Progress 9135 / 9694 Time remaining: 0s Progress 9136 / 9694 Time remaining: 0s Progress 9137 / 9694 Time remaining: 0s Progress 9138 / 9694 Time remaining: 0s Progress 9139 / 9694 Time remaining: 0s Progress 9140 / 9694 Time remaining: 0s Progress 9141 / 9694 Time remaining: 0s Progress 9142 / 9694 Time remaining: 0s Progress 9143 / 9694 Time remaining: 0s Progress 9144 / 9694 Time remaining: 0s Progress 9145 / 9694 Time remaining: 0s Progress 9146 / 9694 Time remaining: 0s Progress 9147 / 9694 Time remaining: 0s Progress 9148 / 9694 Time remaining: 0s Progress 9149 / 9694 Time remaining: 0s Progress 9150 / 9694 Time remaining: 0s Progress 9151 / 9694 Time remaining: 0s Progress 9152 / 9694 Time remaining: 0s Progress 9153 / 9694 Time remaining: 0s Progress 9154 / 9694 Time remaining: 0s Progress 9155 / 9694 Time remaining: 0s Progress 9156 / 9694 Time remaining: 0s Progress 9157 / 9694 Time remaining: 0s Progress 9158 / 9694 Time remaining: 0s Progress 9159 / 9694 Time remaining: 0s Progress 9160 / 9694 Time remaining: 0s Progress 9161 / 9694 Time remaining: 0s Progress 9162 / 9694 Time remaining: 0s Progress 9163 / 9694 Time remaining: 0s Progress 9164 / 9694 Time remaining: 0s Progress 9165 / 9694 Time remaining: 0s Progress 9166 / 9694 Time remaining: 0s Progress 9167 / 9694 Time remaining: 0s Progress 9168 / 9694 Time remaining: 0s Progress 9169 / 9694 Time remaining: 0s Progress 9170 / 9694 Time remaining: 0s Progress 9171 / 9694 Time remaining: 0s Progress 9172 / 9694 Time remaining: 0s Progress 9173 / 9694 Time remaining: 0s Progress 9174 / 9694 Time remaining: 0s Progress 9175 / 9694 Time remaining: 0s Progress 9176 / 9694 Time remaining: 0s Progress 9177 / 9694 Time remaining: 0s Progress 9178 / 9694 Time remaining: 0s Progress 9179 / 9694 Time remaining: 0s Progress 9180 / 9694 Time remaining: 0s Progress 9181 / 9694 Time remaining: 0s Progress 9182 / 9694 Time remaining: 0s Progress 9183 / 9694 Time remaining: 0s Progress 9184 / 9694 Time remaining: 0s Progress 9185 / 9694 Time remaining: 0s Progress 9186 / 9694 Time remaining: 0s Progress 9187 / 9694 Time remaining: 0s Progress 9188 / 9694 Time remaining: 0s Progress 9189 / 9694 Time remaining: 0s Progress 9190 / 9694 Time remaining: 0s Progress 9191 / 9694 Time remaining: 0s Progress 9192 / 9694 Time remaining: 0s Progress 9193 / 9694 Time remaining: 0s Progress 9194 / 9694 Time remaining: 0s Progress 9195 / 9694 Time remaining: 0s Progress 9196 / 9694 Time remaining: 0s Progress 9197 / 9694 Time remaining: 0s Progress 9198 / 9694 Time remaining: 0s Progress 9199 / 9694 Time remaining: 0s Progress 9200 / 9694 Time remaining: 0s Progress 9201 / 9694 Time remaining: 0s Progress 9202 / 9694 Time remaining: 0s Progress 9203 / 9694 Time remaining: 0s Progress 9204 / 9694 Time remaining: 0s Progress 9205 / 9694 Time remaining: 0s Progress 9206 / 9694 Time remaining: 0s Progress 9207 / 9694 Time remaining: 0s Progress 9208 / 9694 Time remaining: 0s Progress 9209 / 9694 Time remaining: 0s Progress 9210 / 9694 Time remaining: 0s Progress 9211 / 9694 Time remaining: 0s Progress 9212 / 9694 Time remaining: 0s Progress 9213 / 9694 Time remaining: 0s Progress 9214 / 9694 Time remaining: 0s Progress 9215 / 9694 Time remaining: 0s Progress 9216 / 9694 Time remaining: 0s Progress 9217 / 9694 Time remaining: 0s Progress 9218 / 9694 Time remaining: 0s Progress 9219 / 9694 Time remaining: 0s Progress 9220 / 9694 Time remaining: 0s Progress 9221 / 9694 Time remaining: 0s Progress 9222 / 9694 Time remaining: 0s Progress 9223 / 9694 Time remaining: 0s Progress 9224 / 9694 Time remaining: 0s Progress 9225 / 9694 Time remaining: 0s Progress 9226 / 9694 Time remaining: 0s Progress 9227 / 9694 Time remaining: 0s Progress 9228 / 9694 Time remaining: 0s Progress 9229 / 9694 Time remaining: 0s Progress 9230 / 9694 Time remaining: 0s Progress 9231 / 9694 Time remaining: 0s Progress 9232 / 9694 Time remaining: 0s Progress 9233 / 9694 Time remaining: 0s Progress 9234 / 9694 Time remaining: 0s Progress 9235 / 9694 Time remaining: 0s Progress 9236 / 9694 Time remaining: 0s Progress 9237 / 9694 Time remaining: 0s Progress 9238 / 9694 Time remaining: 0s Progress 9239 / 9694 Time remaining: 0s Progress 9240 / 9694 Time remaining: 0s Progress 9241 / 9694 Time remaining: 0s Progress 9242 / 9694 Time remaining: 0s Progress 9243 / 9694 Time remaining: 0s Progress 9244 / 9694 Time remaining: 0s Progress 9245 / 9694 Time remaining: 0s Progress 9246 / 9694 Time remaining: 0s Progress 9247 / 9694 Time remaining: 0s Progress 9248 / 9694 Time remaining: 0s Progress 9249 / 9694 Time remaining: 0s Progress 9250 / 9694 Time remaining: 0s Progress 9251 / 9694 Time remaining: 0s Progress 9252 / 9694 Time remaining: 0s Progress 9253 / 9694 Time remaining: 0s Progress 9254 / 9694 Time remaining: 0s Progress 9255 / 9694 Time remaining: 0s Progress 9256 / 9694 Time remaining: 0s Progress 9257 / 9694 Time remaining: 0s Progress 9258 / 9694 Time remaining: 0s Progress 9259 / 9694 Time remaining: 0s Progress 9260 / 9694 Time remaining: 0s Progress 9261 / 9694 Time remaining: 0s Progress 9262 / 9694 Time remaining: 0s Progress 9263 / 9694 Time remaining: 0s Progress 9264 / 9694 Time remaining: 0s Progress 9265 / 9694 Time remaining: 0s Progress 9266 / 9694 Time remaining: 0s Progress 9267 / 9694 Time remaining: 0s Progress 9268 / 9694 Time remaining: 0s Progress 9269 / 9694 Time remaining: 0s Progress 9270 / 9694 Time remaining: 0s Progress 9271 / 9694 Time remaining: 0s Progress 9272 / 9694 Time remaining: 0s Progress 9273 / 9694 Time remaining: 0s Progress 9274 / 9694 Time remaining: 0s Progress 9275 / 9694 Time remaining: 0s Progress 9276 / 9694 Time remaining: 0s Progress 9277 / 9694 Time remaining: 0s Progress 9278 / 9694 Time remaining: 0s Progress 9279 / 9694 Time remaining: 0s Progress 9280 / 9694 Time remaining: 0s Progress 9281 / 9694 Time remaining: 0s Progress 9282 / 9694 Time remaining: 0s Progress 9283 / 9694 Time remaining: 0s Progress 9284 / 9694 Time remaining: 0s Progress 9285 / 9694 Time remaining: 0s Progress 9286 / 9694 Time remaining: 0s Progress 9287 / 9694 Time remaining: 0s Progress 9288 / 9694 Time remaining: 0s Progress 9289 / 9694 Time remaining: 0s Progress 9290 / 9694 Time remaining: 0s Progress 9291 / 9694 Time remaining: 0s Progress 9292 / 9694 Time remaining: 0s Progress 9293 / 9694 Time remaining: 0s Progress 9294 / 9694 Time remaining: 0s Progress 9295 / 9694 Time remaining: 0s Progress 9296 / 9694 Time remaining: 0s Progress 9297 / 9694 Time remaining: 0s Progress 9298 / 9694 Time remaining: 0s Progress 9299 / 9694 Time remaining: 0s Progress 9300 / 9694 Time remaining: 0s Progress 9301 / 9694 Time remaining: 0s Progress 9302 / 9694 Time remaining: 0s Progress 9303 / 9694 Time remaining: 0s Progress 9304 / 9694 Time remaining: 0s Progress 9305 / 9694 Time remaining: 0s Progress 9306 / 9694 Time remaining: 0s Progress 9307 / 9694 Time remaining: 0s Progress 9308 / 9694 Time remaining: 0s Progress 9309 / 9694 Time remaining: 0s Progress 9310 / 9694 Time remaining: 0s Progress 9311 / 9694 Time remaining: 0s Progress 9312 / 9694 Time remaining: 0s Progress 9313 / 9694 Time remaining: 0s Progress 9314 / 9694 Time remaining: 0s Progress 9315 / 9694 Time remaining: 0s Progress 9316 / 9694 Time remaining: 0s Progress 9317 / 9694 Time remaining: 0s Progress 9318 / 9694 Time remaining: 0s Progress 9319 / 9694 Time remaining: 0s Progress 9320 / 9694 Time remaining: 0s Progress 9321 / 9694 Time remaining: 0s Progress 9322 / 9694 Time remaining: 0s Progress 9323 / 9694 Time remaining: 0s Progress 9324 / 9694 Time remaining: 0s Progress 9325 / 9694 Time remaining: 0s Progress 9326 / 9694 Time remaining: 0s Progress 9327 / 9694 Time remaining: 0s Progress 9328 / 9694 Time remaining: 0s Progress 9329 / 9694 Time remaining: 0s Progress 9330 / 9694 Time remaining: 0s Progress 9331 / 9694 Time remaining: 0s Progress 9332 / 9694 Time remaining: 0s Progress 9333 / 9694 Time remaining: 0s Progress 9334 / 9694 Time remaining: 0s Progress 9335 / 9694 Time remaining: 0s Progress 9336 / 9694 Time remaining: 0s Progress 9337 / 9694 Time remaining: 0s Progress 9338 / 9694 Time remaining: 0s Progress 9339 / 9694 Time remaining: 0s Progress 9340 / 9694 Time remaining: 0s Progress 9341 / 9694 Time remaining: 0s Progress 9342 / 9694 Time remaining: 0s Progress 9343 / 9694 Time remaining: 0s Progress 9344 / 9694 Time remaining: 0s Progress 9345 / 9694 Time remaining: 0s Progress 9346 / 9694 Time remaining: 0s Progress 9347 / 9694 Time remaining: 0s Progress 9348 / 9694 Time remaining: 0s Progress 9349 / 9694 Time remaining: 0s Progress 9350 / 9694 Time remaining: 0s Progress 9351 / 9694 Time remaining: 0s Progress 9352 / 9694 Time remaining: 0s Progress 9353 / 9694 Time remaining: 0s Progress 9354 / 9694 Time remaining: 0s Progress 9355 / 9694 Time remaining: 0s Progress 9356 / 9694 Time remaining: 0s Progress 9357 / 9694 Time remaining: 0s Progress 9358 / 9694 Time remaining: 0s Progress 9359 / 9694 Time remaining: 0s Progress 9360 / 9694 Time remaining: 0s Progress 9361 / 9694 Time remaining: 0s Progress 9362 / 9694 Time remaining: 0s Progress 9363 / 9694 Time remaining: 0s Progress 9364 / 9694 Time remaining: 0s Progress 9365 / 9694 Time remaining: 0s Progress 9366 / 9694 Time remaining: 0s Progress 9367 / 9694 Time remaining: 0s Progress 9368 / 9694 Time remaining: 0s Progress 9369 / 9694 Time remaining: 0s Progress 9370 / 9694 Time remaining: 0s Progress 9371 / 9694 Time remaining: 0s Progress 9372 / 9694 Time remaining: 0s Progress 9373 / 9694 Time remaining: 0s Progress 9374 / 9694 Time remaining: 0s Progress 9375 / 9694 Time remaining: 0s Progress 9376 / 9694 Time remaining: 0s Progress 9377 / 9694 Time remaining: 0s Progress 9378 / 9694 Time remaining: 0s Progress 9379 / 9694 Time remaining: 0s Progress 9380 / 9694 Time remaining: 0s Progress 9381 / 9694 Time remaining: 0s Progress 9382 / 9694 Time remaining: 0s Progress 9383 / 9694 Time remaining: 0s Progress 9384 / 9694 Time remaining: 0s Progress 9385 / 9694 Time remaining: 0s Progress 9386 / 9694 Time remaining: 0s Progress 9387 / 9694 Time remaining: 0s Progress 9388 / 9694 Time remaining: 0s Progress 9389 / 9694 Time remaining: 0s Progress 9390 / 9694 Time remaining: 0s Progress 9391 / 9694 Time remaining: 0s Progress 9392 / 9694 Time remaining: 0s Progress 9393 / 9694 Time remaining: 0s Progress 9394 / 9694 Time remaining: 0s Progress 9395 / 9694 Time remaining: 0s Progress 9396 / 9694 Time remaining: 0s Progress 9397 / 9694 Time remaining: 0s Progress 9398 / 9694 Time remaining: 0s Progress 9399 / 9694 Time remaining: 0s Progress 9400 / 9694 Time remaining: 0s Progress 9401 / 9694 Time remaining: 0s Progress 9402 / 9694 Time remaining: 0s Progress 9403 / 9694 Time remaining: 0s Progress 9404 / 9694 Time remaining: 0s Progress 9405 / 9694 Time remaining: 0s Progress 9406 / 9694 Time remaining: 0s Progress 9407 / 9694 Time remaining: 0s Progress 9408 / 9694 Time remaining: 0s Progress 9409 / 9694 Time remaining: 0s Progress 9410 / 9694 Time remaining: 0s Progress 9411 / 9694 Time remaining: 0s Progress 9412 / 9694 Time remaining: 0s Progress 9413 / 9694 Time remaining: 0s Progress 9414 / 9694 Time remaining: 0s Progress 9415 / 9694 Time remaining: 0s Progress 9416 / 9694 Time remaining: 0s Progress 9417 / 9694 Time remaining: 0s Progress 9418 / 9694 Time remaining: 0s Progress 9419 / 9694 Time remaining: 0s Progress 9420 / 9694 Time remaining: 0s Progress 9421 / 9694 Time remaining: 0s Progress 9422 / 9694 Time remaining: 0s Progress 9423 / 9694 Time remaining: 0s Progress 9424 / 9694 Time remaining: 0s Progress 9425 / 9694 Time remaining: 0s Progress 9426 / 9694 Time remaining: 0s Progress 9427 / 9694 Time remaining: 0s Progress 9428 / 9694 Time remaining: 0s Progress 9429 / 9694 Time remaining: 0s Progress 9430 / 9694 Time remaining: 0s Progress 9431 / 9694 Time remaining: 0s Progress 9432 / 9694 Time remaining: 0s Progress 9433 / 9694 Time remaining: 0s Progress 9434 / 9694 Time remaining: 0s Progress 9435 / 9694 Time remaining: 0s Progress 9436 / 9694 Time remaining: 0s Progress 9437 / 9694 Time remaining: 0s Progress 9438 / 9694 Time remaining: 0s Progress 9439 / 9694 Time remaining: 0s Progress 9440 / 9694 Time remaining: 0s Progress 9441 / 9694 Time remaining: 0s Progress 9442 / 9694 Time remaining: 0s Progress 9443 / 9694 Time remaining: 0s Progress 9444 / 9694 Time remaining: 0s Progress 9445 / 9694 Time remaining: 0s Progress 9446 / 9694 Time remaining: 0s Progress 9447 / 9694 Time remaining: 0s Progress 9448 / 9694 Time remaining: 0s Progress 9449 / 9694 Time remaining: 0s Progress 9450 / 9694 Time remaining: 0s Progress 9451 / 9694 Time remaining: 0s Progress 9452 / 9694 Time remaining: 0s Progress 9453 / 9694 Time remaining: 0s Progress 9454 / 9694 Time remaining: 0s Progress 9455 / 9694 Time remaining: 0s Progress 9456 / 9694 Time remaining: 0s Progress 9457 / 9694 Time remaining: 0s Progress 9458 / 9694 Time remaining: 0s Progress 9459 / 9694 Time remaining: 0s Progress 9460 / 9694 Time remaining: 0s Progress 9461 / 9694 Time remaining: 0s Progress 9462 / 9694 Time remaining: 0s Progress 9463 / 9694 Time remaining: 0s Progress 9464 / 9694 Time remaining: 0s Progress 9465 / 9694 Time remaining: 0s Progress 9466 / 9694 Time remaining: 0s Progress 9467 / 9694 Time remaining: 0s Progress 9468 / 9694 Time remaining: 0s Progress 9469 / 9694 Time remaining: 0s Progress 9470 / 9694 Time remaining: 0s Progress 9471 / 9694 Time remaining: 0s Progress 9472 / 9694 Time remaining: 0s Progress 9473 / 9694 Time remaining: 0s Progress 9474 / 9694 Time remaining: 0s Progress 9475 / 9694 Time remaining: 0s Progress 9476 / 9694 Time remaining: 0s Progress 9477 / 9694 Time remaining: 0s Progress 9478 / 9694 Time remaining: 0s Progress 9479 / 9694 Time remaining: 0s Progress 9480 / 9694 Time remaining: 0s Progress 9481 / 9694 Time remaining: 0s Progress 9482 / 9694 Time remaining: 0s Progress 9483 / 9694 Time remaining: 0s Progress 9484 / 9694 Time remaining: 0s Progress 9485 / 9694 Time remaining: 0s Progress 9486 / 9694 Time remaining: 0s Progress 9487 / 9694 Time remaining: 0s Progress 9488 / 9694 Time remaining: 0s Progress 9489 / 9694 Time remaining: 0s Progress 9490 / 9694 Time remaining: 0s Progress 9491 / 9694 Time remaining: 0s Progress 9492 / 9694 Time remaining: 0s Progress 9493 / 9694 Time remaining: 0s Progress 9494 / 9694 Time remaining: 0s Progress 9495 / 9694 Time remaining: 0s Progress 9496 / 9694 Time remaining: 0s Progress 9497 / 9694 Time remaining: 0s Progress 9498 / 9694 Time remaining: 0s Progress 9499 / 9694 Time remaining: 0s Progress 9500 / 9694 Time remaining: 0s Progress 9501 / 9694 Time remaining: 0s Progress 9502 / 9694 Time remaining: 0s Progress 9503 / 9694 Time remaining: 0s Progress 9504 / 9694 Time remaining: 0s Progress 9505 / 9694 Time remaining: 0s Progress 9506 / 9694 Time remaining: 0s Progress 9507 / 9694 Time remaining: 0s Progress 9508 / 9694 Time remaining: 0s Progress 9509 / 9694 Time remaining: 0s Progress 9510 / 9694 Time remaining: 0s Progress 9511 / 9694 Time remaining: 0s Progress 9512 / 9694 Time remaining: 0s Progress 9513 / 9694 Time remaining: 0s Progress 9514 / 9694 Time remaining: 0s Progress 9515 / 9694 Time remaining: 0s Progress 9516 / 9694 Time remaining: 0s Progress 9517 / 9694 Time remaining: 0s Progress 9518 / 9694 Time remaining: 0s Progress 9519 / 9694 Time remaining: 0s Progress 9520 / 9694 Time remaining: 0s Progress 9521 / 9694 Time remaining: 0s Progress 9522 / 9694 Time remaining: 0s Progress 9523 / 9694 Time remaining: 0s Progress 9524 / 9694 Time remaining: 0s Progress 9525 / 9694 Time remaining: 0s Progress 9526 / 9694 Time remaining: 0s Progress 9527 / 9694 Time remaining: 0s Progress 9528 / 9694 Time remaining: 0s Progress 9529 / 9694 Time remaining: 0s Progress 9530 / 9694 Time remaining: 0s Progress 9531 / 9694 Time remaining: 0s Progress 9532 / 9694 Time remaining: 0s Progress 9533 / 9694 Time remaining: 0s Progress 9534 / 9694 Time remaining: 0s Progress 9535 / 9694 Time remaining: 0s Progress 9536 / 9694 Time remaining: 0s Progress 9537 / 9694 Time remaining: 0s Progress 9538 / 9694 Time remaining: 0s Progress 9539 / 9694 Time remaining: 0s Progress 9540 / 9694 Time remaining: 0s Progress 9541 / 9694 Time remaining: 0s Progress 9542 / 9694 Time remaining: 0s Progress 9543 / 9694 Time remaining: 0s Progress 9544 / 9694 Time remaining: 0s Progress 9545 / 9694 Time remaining: 0s Progress 9546 / 9694 Time remaining: 0s Progress 9547 / 9694 Time remaining: 0s Progress 9548 / 9694 Time remaining: 0s Progress 9549 / 9694 Time remaining: 0s Progress 9550 / 9694 Time remaining: 0s Progress 9551 / 9694 Time remaining: 0s Progress 9552 / 9694 Time remaining: 0s Progress 9553 / 9694 Time remaining: 0s Progress 9554 / 9694 Time remaining: 0s Progress 9555 / 9694 Time remaining: 0s Progress 9556 / 9694 Time remaining: 0s Progress 9557 / 9694 Time remaining: 0s Progress 9558 / 9694 Time remaining: 0s Progress 9559 / 9694 Time remaining: 0s Progress 9560 / 9694 Time remaining: 0s Progress 9561 / 9694 Time remaining: 0s Progress 9562 / 9694 Time remaining: 0s Progress 9563 / 9694 Time remaining: 0s Progress 9564 / 9694 Time remaining: 0s Progress 9565 / 9694 Time remaining: 0s Progress 9566 / 9694 Time remaining: 0s Progress 9567 / 9694 Time remaining: 0s Progress 9568 / 9694 Time remaining: 0s Progress 9569 / 9694 Time remaining: 0s Progress 9570 / 9694 Time remaining: 0s Progress 9571 / 9694 Time remaining: 0s Progress 9572 / 9694 Time remaining: 0s Progress 9573 / 9694 Time remaining: 0s Progress 9574 / 9694 Time remaining: 0s Progress 9575 / 9694 Time remaining: 0s Progress 9576 / 9694 Time remaining: 0s Progress 9577 / 9694 Time remaining: 0s Progress 9578 / 9694 Time remaining: 0s Progress 9579 / 9694 Time remaining: 0s Progress 9580 / 9694 Time remaining: 0s Progress 9581 / 9694 Time remaining: 0s Progress 9582 / 9694 Time remaining: 0s Progress 9583 / 9694 Time remaining: 0s Progress 9584 / 9694 Time remaining: 0s Progress 9585 / 9694 Time remaining: 0s Progress 9586 / 9694 Time remaining: 0s Progress 9587 / 9694 Time remaining: 0s Progress 9588 / 9694 Time remaining: 0s Progress 9589 / 9694 Time remaining: 0s Progress 9590 / 9694 Time remaining: 0s Progress 9591 / 9694 Time remaining: 0s Progress 9592 / 9694 Time remaining: 0s Progress 9593 / 9694 Time remaining: 0s Progress 9594 / 9694 Time remaining: 0s Progress 9595 / 9694 Time remaining: 0s Progress 9596 / 9694 Time remaining: 0s Progress 9597 / 9694 Time remaining: 0s Progress 9598 / 9694 Time remaining: 0s Progress 9599 / 9694 Time remaining: 0s Progress 9600 / 9694 Time remaining: 0s Progress 9601 / 9694 Time remaining: 0s Progress 9602 / 9694 Time remaining: 0s Progress 9603 / 9694 Time remaining: 0s Progress 9604 / 9694 Time remaining: 0s Progress 9605 / 9694 Time remaining: 0s Progress 9606 / 9694 Time remaining: 0s Progress 9607 / 9694 Time remaining: 0s Progress 9608 / 9694 Time remaining: 0s Progress 9609 / 9694 Time remaining: 0s Progress 9610 / 9694 Time remaining: 0s Progress 9611 / 9694 Time remaining: 0s Progress 9612 / 9694 Time remaining: 0s Progress 9613 / 9694 Time remaining: 0s Progress 9614 / 9694 Time remaining: 0s Progress 9615 / 9694 Time remaining: 0s Progress 9616 / 9694 Time remaining: 0s Progress 9617 / 9694 Time remaining: 0s Progress 9618 / 9694 Time remaining: 0s Progress 9619 / 9694 Time remaining: 0s Progress 9620 / 9694 Time remaining: 0s Progress 9621 / 9694 Time remaining: 0s Progress 9622 / 9694 Time remaining: 0s Progress 9623 / 9694 Time remaining: 0s Progress 9624 / 9694 Time remaining: 0s Progress 9625 / 9694 Time remaining: 0s Progress 9626 / 9694 Time remaining: 0s Progress 9627 / 9694 Time remaining: 0s Progress 9628 / 9694 Time remaining: 0s Progress 9629 / 9694 Time remaining: 0s Progress 9630 / 9694 Time remaining: 0s Progress 9631 / 9694 Time remaining: 0s Progress 9632 / 9694 Time remaining: 0s Progress 9633 / 9694 Time remaining: 0s Progress 9634 / 9694 Time remaining: 0s Progress 9635 / 9694 Time remaining: 0s Progress 9636 / 9694 Time remaining: 0s Progress 9637 / 9694 Time remaining: 0s Progress 9638 / 9694 Time remaining: 0s Progress 9639 / 9694 Time remaining: 0s Progress 9640 / 9694 Time remaining: 0s Progress 9641 / 9694 Time remaining: 0s Progress 9642 / 9694 Time remaining: 0s Progress 9643 / 9694 Time remaining: 0s Progress 9644 / 9694 Time remaining: 0s Progress 9645 / 9694 Time remaining: 0s Progress 9646 / 9694 Time remaining: 0s Progress 9647 / 9694 Time remaining: 0s Progress 9648 / 9694 Time remaining: 0s Progress 9649 / 9694 Time remaining: 0s Progress 9650 / 9694 Time remaining: 0s Progress 9651 / 9694 Time remaining: 0s Progress 9652 / 9694 Time remaining: 0s Progress 9653 / 9694 Time remaining: 0s Progress 9654 / 9694 Time remaining: 0s Progress 9655 / 9694 Time remaining: 0s Progress 9656 / 9694 Time remaining: 0s Progress 9657 / 9694 Time remaining: 0s Progress 9658 / 9694 Time remaining: 0s Progress 9659 / 9694 Time remaining: 0s Progress 9660 / 9694 Time remaining: 0s Progress 9661 / 9694 Time remaining: 0s Progress 9662 / 9694 Time remaining: 0s Progress 9663 / 9694 Time remaining: 0s Progress 9664 / 9694 Time remaining: 0s Progress 9665 / 9694 Time remaining: 0s Progress 9666 / 9694 Time remaining: 0s Progress 9667 / 9694 Time remaining: 0s Progress 9668 / 9694 Time remaining: 0s Progress 9669 / 9694 Time remaining: 0s Progress 9670 / 9694 Time remaining: 0s Progress 9671 / 9694 Time remaining: 0s Progress 9672 / 9694 Time remaining: 0s Progress 9673 / 9694 Time remaining: 0s Progress 9674 / 9694 Time remaining: 0s Progress 9675 / 9694 Time remaining: 0s Progress 9676 / 9694 Time remaining: 0s Progress 9677 / 9694 Time remaining: 0s Progress 9678 / 9694 Time remaining: 0s Progress 9679 / 9694 Time remaining: 0s Progress 9680 / 9694 Time remaining: 0s Progress 9681 / 9694 Time remaining: 0s Progress 9682 / 9694 Time remaining: 0s Progress 9683 / 9694 Time remaining: 0s Progress 9684 / 9694 Time remaining: 0s Progress 9685 / 9694 Time remaining: 0s Progress 9686 / 9694 Time remaining: 0s Progress 9687 / 9694 Time remaining: 0s Progress 9688 / 9694 Time remaining: 0s Progress 9689 / 9694 Time remaining: 0s Progress 9690 / 9694 Time remaining: 0s Progress 9691 / 9694 Time remaining: 0s Progress 9692 / 9694 Time remaining: 0s Progress 9693 / 9694 Time remaining: 0s Progress 9694 / 9694 Time remaining: Read 9694 imu readings over 48.6 seconds +Initializing calibration target: + Type: aprilgrid + Tags: + Rows: 6 + Cols: 6 + Size: 0.088 [m] + Spacing 0.0264 [m] +Initializing camera chain: +Camera chain - cam0: + Camera model: pinhole + Focal length: [190.97847715128717, 190.9733070521226] + Principal point: [254.93170605935475, 256.8974428996504] + Distortion model: equidistant + Distortion coefficients: [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, 0.00020293673591811182] + baseline: no data available +Camera chain - cam1: + Camera model: pinhole + Focal length: [190.44236969414825, 190.4344384721956] + Principal point: [252.59949716835982, 254.91723064636983] + Distortion model: equidistant + Distortion coefficients: [0.0034003170790442797, 0.001766278153469831, -0.00266312569781606, 0.0003299517423931039] + baseline: [[ 0.99999945 -0.00082336 -0.00065614 -0.1010611 ] + [ 0.00079169 0.99889946 -0.04689604 -0.00197646] + [ 0.00069403 0.04689549 0.99889956 -0.00117564] + [ 0. 0. 0. 1. ]] +Initializing camera rosbag dataset reader: + Dataset: imucalib.bag + Topic: /cam0/image_raw + Number of images: 972 +Extracting calibration target corners + Progress 9 / 972 Time remaining: 3m 15s Progress 11 / 972 Time remaining: 3m 23s Progress 18 / 972 Time remaining: 3m 23s Progress 119 / 972 Time remaining: 31s Progress 232 / 972 Time remaining: 15s Progress 347 / 972 Time remaining: 9s Progress 461 / 972 Time remaining: 6s Progress 577 / 972 Time remaining: 4s Progress 690 / 972 Time remaining: 2s Progress 807 / 972 Time remaining: 1s Progress 919 / 972 Time remaining: 0s Progress 972 / 972 Time remaining: Extracted corners for 972 images (of 972 images) +Initializing camera rosbag dataset reader: + Dataset: imucalib.bag + Topic: /cam1/image_raw + Number of images: 972 +Extracting calibration target corners + Progress 9 / 972 Time remaining: 2m 59s Progress 11 / 972 Time remaining: 3m 10s Progress 27 / 972 Time remaining: 2m 8s Progress 137 / 972 Time remaining: 25s Progress 252 / 972 Time remaining: 13s Progress 368 / 972 Time remaining: 8s Progress 478 / 972 Time remaining: 5s Progress 595 / 972 Time remaining: 3s Progress 711 / 972 Time remaining: 2s Progress 831 / 972 Time remaining: 1s Progress 950 / 972 Time remaining: 0s Progress 972 / 972 Time remaining: Extracted corners for 972 images (of 972 images) +Baseline between cam0 and cam1 set to: +T= [[ 0.99999945 -0.00082336 -0.00065614 -0.1010611 ] + [ 0.00079169 0.99889946 -0.04689604 -0.00197646] + [ 0.00069403 0.04689549 0.99889956 -0.00117564] + [ 0. 0. 0. 1. ]] +Baseline: 0.101087264328 [m] + +Building the problem + Spline order: 6 + Pose knots per second: 100 + Do pose motion regularization: False + xddot translation variance: 1000000.000000 + xddot rotation variance: 100000.000000 + Bias knots per second: 50 + Do bias motion regularization: True + Blake-Zisserman on reprojection errors -1 + Acceleration Huber width (sigma): -1.000000 + Gyroscope Huber width (sigma): -1.000000 + Do time calibration: False + Max iterations: 30 + Time offset padding: 0.010000 + +Estimating imu-camera rotation prior + +Initializing a pose spline with 4855 knots (100.000000 knots per second over 48.551517 seconds) +Gravity was intialized to [ 0.03697373 -9.69919254 -1.44662361] [m/s^2] + Orientation prior camera-imu found as: (T_i_c) +[[-0.99951271 0.0299736 -0.00871321] + [ 0.00766313 -0.03497177 -0.99935892] + [-0.0302591 -0.99893872 0.03472504]] + Gyro bias prior found as: (b_gyro) +[-0.00012915 -0.00004175 -0.00019334] + +Initializing a pose spline with 4859 knots (100.000000 knots per second over 48.591517 seconds) + +Initializing the bias splines with 2430 knots + +Adding camera error terms (/cam0/image_raw) + Progress 1 / 972 Time remaining: 6s Progress 2 / 972 Time remaining: 6s Progress 3 / 972 Time remaining: 6s Progress 4 / 972 Time remaining: 6s Progress 5 / 972 Time remaining: 5s Progress 6 / 972 Time remaining: 5s Progress 7 / 972 Time remaining: 5s Progress 8 / 972 Time remaining: 4s Progress 9 / 972 Time remaining: 4s Progress 10 / 972 Time remaining: 4s Progress 11 / 972 Time remaining: 4s Progress 12 / 972 Time remaining: 4s Progress 13 / 972 Time remaining: 4s Progress 14 / 972 Time remaining: 4s Progress 15 / 972 Time remaining: 4s Progress 16 / 972 Time remaining: 4s Progress 17 / 972 Time remaining: 4s Progress 18 / 972 Time remaining: 4s Progress 19 / 972 Time remaining: 4s Progress 20 / 972 Time remaining: 4s Progress 21 / 972 Time remaining: 4s Progress 22 / 972 Time remaining: 4s Progress 23 / 972 Time remaining: 4s Progress 24 / 972 Time remaining: 4s Progress 25 / 972 Time remaining: 4s Progress 26 / 972 Time remaining: 4s Progress 27 / 972 Time remaining: 4s Progress 28 / 972 Time remaining: 4s Progress 29 / 972 Time remaining: 4s Progress 30 / 972 Time remaining: 4s Progress 31 / 972 Time remaining: 4s Progress 32 / 972 Time remaining: 4s Progress 33 / 972 Time remaining: 4s Progress 34 / 972 Time remaining: 3s Progress 35 / 972 Time remaining: 3s Progress 36 / 972 Time remaining: 3s Progress 37 / 972 Time remaining: 3s Progress 38 / 972 Time remaining: 3s Progress 39 / 972 Time remaining: 3s Progress 40 / 972 Time remaining: 3s Progress 41 / 972 Time remaining: 3s Progress 42 / 972 Time remaining: 3s Progress 43 / 972 Time remaining: 3s Progress 44 / 972 Time remaining: 3s Progress 45 / 972 Time remaining: 3s Progress 46 / 972 Time remaining: 3s Progress 47 / 972 Time remaining: 3s Progress 48 / 972 Time remaining: 3s Progress 49 / 972 Time remaining: 3s Progress 50 / 972 Time remaining: 3s Progress 51 / 972 Time remaining: 3s Progress 52 / 972 Time remaining: 3s Progress 53 / 972 Time remaining: 3s Progress 54 / 972 Time remaining: 3s Progress 55 / 972 Time remaining: 3s Progress 56 / 972 Time remaining: 3s Progress 57 / 972 Time remaining: 3s Progress 58 / 972 Time remaining: 3s Progress 59 / 972 Time remaining: 3s Progress 60 / 972 Time remaining: 3s Progress 61 / 972 Time remaining: 3s Progress 62 / 972 Time remaining: 3s Progress 63 / 972 Time remaining: 3s Progress 64 / 972 Time remaining: 3s Progress 65 / 972 Time remaining: 3s Progress 66 / 972 Time remaining: 3s Progress 67 / 972 Time remaining: 3s Progress 68 / 972 Time remaining: 3s Progress 69 / 972 Time remaining: 3s Progress 70 / 972 Time remaining: 3s Progress 71 / 972 Time remaining: 3s Progress 72 / 972 Time remaining: 3s Progress 73 / 972 Time remaining: 3s Progress 74 / 972 Time remaining: 3s Progress 75 / 972 Time remaining: 3s Progress 76 / 972 Time remaining: 3s Progress 77 / 972 Time remaining: 3s Progress 78 / 972 Time remaining: 3s Progress 79 / 972 Time remaining: 3s Progress 80 / 972 Time remaining: 3s Progress 81 / 972 Time remaining: 3s Progress 82 / 972 Time remaining: 3s Progress 83 / 972 Time remaining: 3s Progress 84 / 972 Time remaining: 3s Progress 85 / 972 Time remaining: 3s Progress 86 / 972 Time remaining: 3s Progress 87 / 972 Time remaining: 3s Progress 88 / 972 Time remaining: 3s Progress 89 / 972 Time remaining: 3s Progress 90 / 972 Time remaining: 3s Progress 91 / 972 Time remaining: 3s Progress 92 / 972 Time remaining: 3s Progress 93 / 972 Time remaining: 3s Progress 94 / 972 Time remaining: 3s Progress 95 / 972 Time remaining: 3s Progress 96 / 972 Time remaining: 3s Progress 97 / 972 Time remaining: 3s Progress 98 / 972 Time remaining: 3s Progress 99 / 972 Time remaining: 3s Progress 100 / 972 Time remaining: 3s Progress 101 / 972 Time remaining: 3s Progress 102 / 972 Time remaining: 3s Progress 103 / 972 Time remaining: 3s Progress 104 / 972 Time remaining: 3s Progress 105 / 972 Time remaining: 3s Progress 106 / 972 Time remaining: 3s Progress 107 / 972 Time remaining: 3s Progress 108 / 972 Time remaining: 3s Progress 109 / 972 Time remaining: 3s Progress 110 / 972 Time remaining: 3s Progress 111 / 972 Time remaining: 3s Progress 112 / 972 Time remaining: 3s Progress 113 / 972 Time remaining: 3s Progress 114 / 972 Time remaining: 3s Progress 115 / 972 Time remaining: 3s Progress 116 / 972 Time remaining: 3s Progress 117 / 972 Time remaining: 3s Progress 118 / 972 Time remaining: 3s Progress 119 / 972 Time remaining: 3s Progress 120 / 972 Time remaining: 3s Progress 121 / 972 Time remaining: 3s Progress 122 / 972 Time remaining: 3s Progress 123 / 972 Time remaining: 3s Progress 124 / 972 Time remaining: 3s Progress 125 / 972 Time remaining: 3s Progress 126 / 972 Time remaining: 3s Progress 127 / 972 Time remaining: 3s Progress 128 / 972 Time remaining: 3s Progress 129 / 972 Time remaining: 3s Progress 130 / 972 Time remaining: 3s Progress 131 / 972 Time remaining: 3s Progress 132 / 972 Time remaining: 3s Progress 133 / 972 Time remaining: 3s Progress 134 / 972 Time remaining: 3s Progress 135 / 972 Time remaining: 3s Progress 136 / 972 Time remaining: 3s Progress 137 / 972 Time remaining: 3s Progress 138 / 972 Time remaining: 3s Progress 139 / 972 Time remaining: 3s Progress 140 / 972 Time remaining: 3s Progress 141 / 972 Time remaining: 3s Progress 142 / 972 Time remaining: 3s Progress 143 / 972 Time remaining: 3s Progress 144 / 972 Time remaining: 3s Progress 145 / 972 Time remaining: 3s Progress 146 / 972 Time remaining: 3s Progress 147 / 972 Time remaining: 3s Progress 148 / 972 Time remaining: 3s Progress 149 / 972 Time remaining: 3s Progress 150 / 972 Time remaining: 3s Progress 151 / 972 Time remaining: 3s Progress 152 / 972 Time remaining: 3s Progress 153 / 972 Time remaining: 3s Progress 154 / 972 Time remaining: 3s Progress 155 / 972 Time remaining: 3s Progress 156 / 972 Time remaining: 3s Progress 157 / 972 Time remaining: 3s Progress 158 / 972 Time remaining: 3s Progress 159 / 972 Time remaining: 3s Progress 160 / 972 Time remaining: 3s Progress 161 / 972 Time remaining: 3s Progress 162 / 972 Time remaining: 3s Progress 163 / 972 Time remaining: 3s Progress 164 / 972 Time remaining: 3s Progress 165 / 972 Time remaining: 3s Progress 166 / 972 Time remaining: 3s Progress 167 / 972 Time remaining: 3s Progress 168 / 972 Time remaining: 3s Progress 169 / 972 Time remaining: 3s Progress 170 / 972 Time remaining: 3s Progress 171 / 972 Time remaining: 3s Progress 172 / 972 Time remaining: 3s Progress 173 / 972 Time remaining: 3s Progress 174 / 972 Time remaining: 3s Progress 175 / 972 Time remaining: 3s Progress 176 / 972 Time remaining: 3s Progress 177 / 972 Time remaining: 3s Progress 178 / 972 Time remaining: 3s Progress 179 / 972 Time remaining: 3s Progress 180 / 972 Time remaining: 3s Progress 181 / 972 Time remaining: 3s Progress 182 / 972 Time remaining: 3s Progress 183 / 972 Time remaining: 3s Progress 184 / 972 Time remaining: 3s Progress 185 / 972 Time remaining: 3s Progress 186 / 972 Time remaining: 3s Progress 187 / 972 Time remaining: 3s Progress 188 / 972 Time remaining: 3s Progress 189 / 972 Time remaining: 3s Progress 190 / 972 Time remaining: 3s Progress 191 / 972 Time remaining: 3s Progress 192 / 972 Time remaining: 3s Progress 193 / 972 Time remaining: 3s Progress 194 / 972 Time remaining: 3s Progress 195 / 972 Time remaining: 3s Progress 196 / 972 Time remaining: 3s Progress 197 / 972 Time remaining: 3s Progress 198 / 972 Time remaining: 3s Progress 199 / 972 Time remaining: 3s Progress 200 / 972 Time remaining: 3s Progress 201 / 972 Time remaining: 3s Progress 202 / 972 Time remaining: 3s Progress 203 / 972 Time remaining: 3s Progress 204 / 972 Time remaining: 3s Progress 205 / 972 Time remaining: 3s Progress 206 / 972 Time remaining: 3s Progress 207 / 972 Time remaining: 3s Progress 208 / 972 Time remaining: 3s Progress 209 / 972 Time remaining: 3s Progress 210 / 972 Time remaining: 3s Progress 211 / 972 Time remaining: 3s Progress 212 / 972 Time remaining: 3s Progress 213 / 972 Time remaining: 3s Progress 214 / 972 Time remaining: 3s Progress 215 / 972 Time remaining: 3s Progress 216 / 972 Time remaining: 3s Progress 217 / 972 Time remaining: 2s Progress 218 / 972 Time remaining: 2s Progress 219 / 972 Time remaining: 2s Progress 220 / 972 Time remaining: 2s Progress 221 / 972 Time remaining: 2s Progress 222 / 972 Time remaining: 2s Progress 223 / 972 Time remaining: 2s Progress 224 / 972 Time remaining: 2s Progress 225 / 972 Time remaining: 2s Progress 226 / 972 Time remaining: 2s Progress 227 / 972 Time remaining: 2s Progress 228 / 972 Time remaining: 2s Progress 229 / 972 Time remaining: 2s Progress 230 / 972 Time remaining: 2s Progress 231 / 972 Time remaining: 2s Progress 232 / 972 Time remaining: 2s Progress 233 / 972 Time remaining: 2s Progress 234 / 972 Time remaining: 2s Progress 235 / 972 Time remaining: 2s Progress 236 / 972 Time remaining: 2s Progress 237 / 972 Time remaining: 2s Progress 238 / 972 Time remaining: 2s Progress 239 / 972 Time remaining: 2s Progress 240 / 972 Time remaining: 2s Progress 241 / 972 Time remaining: 2s Progress 242 / 972 Time remaining: 2s Progress 243 / 972 Time remaining: 2s Progress 244 / 972 Time remaining: 2s Progress 245 / 972 Time remaining: 2s Progress 246 / 972 Time remaining: 2s Progress 247 / 972 Time remaining: 2s Progress 248 / 972 Time remaining: 2s Progress 249 / 972 Time remaining: 2s Progress 250 / 972 Time remaining: 2s Progress 251 / 972 Time remaining: 2s Progress 252 / 972 Time remaining: 2s Progress 253 / 972 Time remaining: 2s Progress 254 / 972 Time remaining: 2s Progress 255 / 972 Time remaining: 2s Progress 256 / 972 Time remaining: 2s Progress 257 / 972 Time remaining: 2s Progress 258 / 972 Time remaining: 2s Progress 259 / 972 Time remaining: 2s Progress 260 / 972 Time remaining: 2s Progress 261 / 972 Time remaining: 2s Progress 262 / 972 Time remaining: 2s Progress 263 / 972 Time remaining: 2s Progress 264 / 972 Time remaining: 2s Progress 265 / 972 Time remaining: 2s Progress 266 / 972 Time remaining: 2s Progress 267 / 972 Time remaining: 2s Progress 268 / 972 Time remaining: 2s Progress 269 / 972 Time remaining: 2s Progress 270 / 972 Time remaining: 2s Progress 271 / 972 Time remaining: 2s Progress 272 / 972 Time remaining: 2s Progress 273 / 972 Time remaining: 2s Progress 274 / 972 Time remaining: 2s Progress 275 / 972 Time remaining: 2s Progress 276 / 972 Time remaining: 2s Progress 277 / 972 Time remaining: 2s Progress 278 / 972 Time remaining: 2s Progress 279 / 972 Time remaining: 2s Progress 280 / 972 Time remaining: 2s Progress 281 / 972 Time remaining: 2s Progress 282 / 972 Time remaining: 2s Progress 283 / 972 Time remaining: 2s Progress 284 / 972 Time remaining: 2s Progress 285 / 972 Time remaining: 2s Progress 286 / 972 Time remaining: 2s Progress 287 / 972 Time remaining: 2s Progress 288 / 972 Time remaining: 2s Progress 289 / 972 Time remaining: 2s Progress 290 / 972 Time remaining: 2s Progress 291 / 972 Time remaining: 2s Progress 292 / 972 Time remaining: 2s Progress 293 / 972 Time remaining: 2s Progress 294 / 972 Time remaining: 2s Progress 295 / 972 Time remaining: 2s Progress 296 / 972 Time remaining: 2s Progress 297 / 972 Time remaining: 2s Progress 298 / 972 Time remaining: 2s Progress 299 / 972 Time remaining: 2s Progress 300 / 972 Time remaining: 2s Progress 301 / 972 Time remaining: 2s Progress 302 / 972 Time remaining: 2s Progress 303 / 972 Time remaining: 2s Progress 304 / 972 Time remaining: 2s Progress 305 / 972 Time remaining: 2s Progress 306 / 972 Time remaining: 2s Progress 307 / 972 Time remaining: 2s Progress 308 / 972 Time remaining: 2s Progress 309 / 972 Time remaining: 2s Progress 310 / 972 Time remaining: 2s Progress 311 / 972 Time remaining: 2s Progress 312 / 972 Time remaining: 2s Progress 313 / 972 Time remaining: 2s Progress 314 / 972 Time remaining: 2s Progress 315 / 972 Time remaining: 2s Progress 316 / 972 Time remaining: 2s Progress 317 / 972 Time remaining: 2s Progress 318 / 972 Time remaining: 2s Progress 319 / 972 Time remaining: 2s Progress 320 / 972 Time remaining: 2s Progress 321 / 972 Time remaining: 2s Progress 322 / 972 Time remaining: 2s Progress 323 / 972 Time remaining: 2s Progress 324 / 972 Time remaining: 2s Progress 325 / 972 Time remaining: 2s Progress 326 / 972 Time remaining: 2s Progress 327 / 972 Time remaining: 2s Progress 328 / 972 Time remaining: 2s Progress 329 / 972 Time remaining: 2s Progress 330 / 972 Time remaining: 2s Progress 331 / 972 Time remaining: 2s Progress 332 / 972 Time remaining: 2s Progress 333 / 972 Time remaining: 2s Progress 334 / 972 Time remaining: 2s Progress 335 / 972 Time remaining: 2s Progress 336 / 972 Time remaining: 2s Progress 337 / 972 Time remaining: 2s Progress 338 / 972 Time remaining: 2s Progress 339 / 972 Time remaining: 2s Progress 340 / 972 Time remaining: 2s Progress 341 / 972 Time remaining: 2s Progress 342 / 972 Time remaining: 2s Progress 343 / 972 Time remaining: 2s Progress 344 / 972 Time remaining: 2s Progress 345 / 972 Time remaining: 2s Progress 346 / 972 Time remaining: 2s Progress 347 / 972 Time remaining: 2s Progress 348 / 972 Time remaining: 2s Progress 349 / 972 Time remaining: 2s Progress 350 / 972 Time remaining: 2s Progress 351 / 972 Time remaining: 2s Progress 352 / 972 Time remaining: 2s Progress 353 / 972 Time remaining: 2s Progress 354 / 972 Time remaining: 2s Progress 355 / 972 Time remaining: 2s Progress 356 / 972 Time remaining: 2s Progress 357 / 972 Time remaining: 2s Progress 358 / 972 Time remaining: 2s Progress 359 / 972 Time remaining: 2s Progress 360 / 972 Time remaining: 2s Progress 361 / 972 Time remaining: 2s Progress 362 / 972 Time remaining: 2s Progress 363 / 972 Time remaining: 2s Progress 364 / 972 Time remaining: 2s Progress 365 / 972 Time remaining: 2s Progress 366 / 972 Time remaining: 2s Progress 367 / 972 Time remaining: 2s Progress 368 / 972 Time remaining: 2s Progress 369 / 972 Time remaining: 2s Progress 370 / 972 Time remaining: 2s Progress 371 / 972 Time remaining: 2s Progress 372 / 972 Time remaining: 2s Progress 373 / 972 Time remaining: 2s Progress 374 / 972 Time remaining: 2s Progress 375 / 972 Time remaining: 2s Progress 376 / 972 Time remaining: 2s Progress 377 / 972 Time remaining: 2s Progress 378 / 972 Time remaining: 2s Progress 379 / 972 Time remaining: 2s Progress 380 / 972 Time remaining: 2s Progress 381 / 972 Time remaining: 2s Progress 382 / 972 Time remaining: 2s Progress 383 / 972 Time remaining: 2s Progress 384 / 972 Time remaining: 2s Progress 385 / 972 Time remaining: 2s Progress 386 / 972 Time remaining: 2s Progress 387 / 972 Time remaining: 2s Progress 388 / 972 Time remaining: 2s Progress 389 / 972 Time remaining: 2s Progress 390 / 972 Time remaining: 2s Progress 391 / 972 Time remaining: 2s Progress 392 / 972 Time remaining: 2s Progress 393 / 972 Time remaining: 2s Progress 394 / 972 Time remaining: 2s Progress 395 / 972 Time remaining: 2s Progress 396 / 972 Time remaining: 2s Progress 397 / 972 Time remaining: 2s Progress 398 / 972 Time remaining: 2s Progress 399 / 972 Time remaining: 2s Progress 400 / 972 Time remaining: 2s Progress 401 / 972 Time remaining: 2s Progress 402 / 972 Time remaining: 2s Progress 403 / 972 Time remaining: 2s Progress 404 / 972 Time remaining: 2s Progress 405 / 972 Time remaining: 2s Progress 406 / 972 Time remaining: 2s Progress 407 / 972 Time remaining: 2s Progress 408 / 972 Time remaining: 2s Progress 409 / 972 Time remaining: 2s Progress 410 / 972 Time remaining: 2s Progress 411 / 972 Time remaining: 2s Progress 412 / 972 Time remaining: 2s Progress 413 / 972 Time remaining: 2s Progress 414 / 972 Time remaining: 2s Progress 415 / 972 Time remaining: 2s Progress 416 / 972 Time remaining: 2s Progress 417 / 972 Time remaining: 2s Progress 418 / 972 Time remaining: 2s Progress 419 / 972 Time remaining: 2s Progress 420 / 972 Time remaining: 2s Progress 421 / 972 Time remaining: 2s Progress 422 / 972 Time remaining: 2s Progress 423 / 972 Time remaining: 2s Progress 424 / 972 Time remaining: 2s Progress 425 / 972 Time remaining: 2s Progress 426 / 972 Time remaining: 2s Progress 427 / 972 Time remaining: 2s Progress 428 / 972 Time remaining: 2s Progress 429 / 972 Time remaining: 2s Progress 430 / 972 Time remaining: 2s Progress 431 / 972 Time remaining: 2s Progress 432 / 972 Time remaining: 2s Progress 433 / 972 Time remaining: 2s Progress 434 / 972 Time remaining: 2s Progress 435 / 972 Time remaining: 2s Progress 436 / 972 Time remaining: 2s Progress 437 / 972 Time remaining: 2s Progress 438 / 972 Time remaining: 2s Progress 439 / 972 Time remaining: 2s Progress 440 / 972 Time remaining: 2s Progress 441 / 972 Time remaining: 2s Progress 442 / 972 Time remaining: 2s Progress 443 / 972 Time remaining: 2s Progress 444 / 972 Time remaining: 2s Progress 445 / 972 Time remaining: 2s Progress 446 / 972 Time remaining: 2s Progress 447 / 972 Time remaining: 2s Progress 448 / 972 Time remaining: 2s Progress 449 / 972 Time remaining: 2s Progress 450 / 972 Time remaining: 2s Progress 451 / 972 Time remaining: 2s Progress 452 / 972 Time remaining: 2s Progress 453 / 972 Time remaining: 2s Progress 454 / 972 Time remaining: 2s Progress 455 / 972 Time remaining: 2s Progress 456 / 972 Time remaining: 2s Progress 457 / 972 Time remaining: 2s Progress 458 / 972 Time remaining: 2s Progress 459 / 972 Time remaining: 2s Progress 460 / 972 Time remaining: 2s Progress 461 / 972 Time remaining: 2s Progress 462 / 972 Time remaining: 2s Progress 463 / 972 Time remaining: 2s Progress 464 / 972 Time remaining: 2s Progress 465 / 972 Time remaining: 2s Progress 466 / 972 Time remaining: 2s Progress 467 / 972 Time remaining: 2s Progress 468 / 972 Time remaining: 2s Progress 469 / 972 Time remaining: 2s Progress 470 / 972 Time remaining: 2s Progress 471 / 972 Time remaining: 2s Progress 472 / 972 Time remaining: 2s Progress 473 / 972 Time remaining: 2s Progress 474 / 972 Time remaining: 2s Progress 475 / 972 Time remaining: 2s Progress 476 / 972 Time remaining: 2s Progress 477 / 972 Time remaining: 2s Progress 478 / 972 Time remaining: 2s Progress 479 / 972 Time remaining: 2s Progress 480 / 972 Time remaining: 2s Progress 481 / 972 Time remaining: 2s Progress 482 / 972 Time remaining: 2s Progress 483 / 972 Time remaining: 2s Progress 484 / 972 Time remaining: 2s Progress 485 / 972 Time remaining: 2s Progress 486 / 972 Time remaining: 2s Progress 487 / 972 Time remaining: 1s Progress 488 / 972 Time remaining: 1s Progress 489 / 972 Time remaining: 1s Progress 490 / 972 Time remaining: 1s Progress 491 / 972 Time remaining: 1s Progress 492 / 972 Time remaining: 1s Progress 493 / 972 Time remaining: 1s Progress 494 / 972 Time remaining: 1s Progress 495 / 972 Time remaining: 1s Progress 496 / 972 Time remaining: 1s Progress 497 / 972 Time remaining: 1s Progress 498 / 972 Time remaining: 1s Progress 499 / 972 Time remaining: 1s Progress 500 / 972 Time remaining: 1s Progress 501 / 972 Time remaining: 1s Progress 502 / 972 Time remaining: 1s Progress 503 / 972 Time remaining: 1s Progress 504 / 972 Time remaining: 1s Progress 505 / 972 Time remaining: 1s Progress 506 / 972 Time remaining: 1s Progress 507 / 972 Time remaining: 1s Progress 508 / 972 Time remaining: 1s Progress 509 / 972 Time remaining: 1s Progress 510 / 972 Time remaining: 1s Progress 511 / 972 Time remaining: 1s Progress 512 / 972 Time remaining: 1s Progress 513 / 972 Time remaining: 1s Progress 514 / 972 Time remaining: 1s Progress 515 / 972 Time remaining: 1s Progress 516 / 972 Time remaining: 1s Progress 517 / 972 Time remaining: 1s Progress 518 / 972 Time remaining: 1s Progress 519 / 972 Time remaining: 1s Progress 520 / 972 Time remaining: 1s Progress 521 / 972 Time remaining: 1s Progress 522 / 972 Time remaining: 1s Progress 523 / 972 Time remaining: 1s Progress 524 / 972 Time remaining: 1s Progress 525 / 972 Time remaining: 1s Progress 526 / 972 Time remaining: 1s Progress 527 / 972 Time remaining: 1s Progress 528 / 972 Time remaining: 1s Progress 529 / 972 Time remaining: 1s Progress 530 / 972 Time remaining: 1s Progress 531 / 972 Time remaining: 1s Progress 532 / 972 Time remaining: 1s Progress 533 / 972 Time remaining: 1s Progress 534 / 972 Time remaining: 1s Progress 535 / 972 Time remaining: 1s Progress 536 / 972 Time remaining: 1s Progress 537 / 972 Time remaining: 1s Progress 538 / 972 Time remaining: 1s Progress 539 / 972 Time remaining: 1s Progress 540 / 972 Time remaining: 1s Progress 541 / 972 Time remaining: 1s Progress 542 / 972 Time remaining: 1s Progress 543 / 972 Time remaining: 1s Progress 544 / 972 Time remaining: 1s Progress 545 / 972 Time remaining: 1s Progress 546 / 972 Time remaining: 1s Progress 547 / 972 Time remaining: 1s Progress 548 / 972 Time remaining: 1s Progress 549 / 972 Time remaining: 1s Progress 550 / 972 Time remaining: 1s Progress 551 / 972 Time remaining: 1s Progress 552 / 972 Time remaining: 1s Progress 553 / 972 Time remaining: 1s Progress 554 / 972 Time remaining: 1s Progress 555 / 972 Time remaining: 1s Progress 556 / 972 Time remaining: 1s Progress 557 / 972 Time remaining: 1s Progress 558 / 972 Time remaining: 1s Progress 559 / 972 Time remaining: 1s Progress 560 / 972 Time remaining: 1s Progress 561 / 972 Time remaining: 1s Progress 562 / 972 Time remaining: 1s Progress 563 / 972 Time remaining: 1s Progress 564 / 972 Time remaining: 1s Progress 565 / 972 Time remaining: 1s Progress 566 / 972 Time remaining: 1s Progress 567 / 972 Time remaining: 1s Progress 568 / 972 Time remaining: 1s Progress 569 / 972 Time remaining: 1s Progress 570 / 972 Time remaining: 1s Progress 571 / 972 Time remaining: 1s Progress 572 / 972 Time remaining: 1s Progress 573 / 972 Time remaining: 1s Progress 574 / 972 Time remaining: 1s Progress 575 / 972 Time remaining: 1s Progress 576 / 972 Time remaining: 1s Progress 577 / 972 Time remaining: 1s Progress 578 / 972 Time remaining: 1s Progress 579 / 972 Time remaining: 1s Progress 580 / 972 Time remaining: 1s Progress 581 / 972 Time remaining: 1s Progress 582 / 972 Time remaining: 1s Progress 583 / 972 Time remaining: 1s Progress 584 / 972 Time remaining: 1s Progress 585 / 972 Time remaining: 1s Progress 586 / 972 Time remaining: 1s Progress 587 / 972 Time remaining: 1s Progress 588 / 972 Time remaining: 1s Progress 589 / 972 Time remaining: 1s Progress 590 / 972 Time remaining: 1s Progress 591 / 972 Time remaining: 1s Progress 592 / 972 Time remaining: 1s Progress 593 / 972 Time remaining: 1s Progress 594 / 972 Time remaining: 1s Progress 595 / 972 Time remaining: 1s Progress 596 / 972 Time remaining: 1s Progress 597 / 972 Time remaining: 1s Progress 598 / 972 Time remaining: 1s Progress 599 / 972 Time remaining: 1s Progress 600 / 972 Time remaining: 1s Progress 601 / 972 Time remaining: 1s Progress 602 / 972 Time remaining: 1s Progress 603 / 972 Time remaining: 1s Progress 604 / 972 Time remaining: 1s Progress 605 / 972 Time remaining: 1s Progress 606 / 972 Time remaining: 1s Progress 607 / 972 Time remaining: 1s Progress 608 / 972 Time remaining: 1s Progress 609 / 972 Time remaining: 1s Progress 610 / 972 Time remaining: 1s Progress 611 / 972 Time remaining: 1s Progress 612 / 972 Time remaining: 1s Progress 613 / 972 Time remaining: 1s Progress 614 / 972 Time remaining: 1s Progress 615 / 972 Time remaining: 1s Progress 616 / 972 Time remaining: 1s Progress 617 / 972 Time remaining: 1s Progress 618 / 972 Time remaining: 1s Progress 619 / 972 Time remaining: 1s Progress 620 / 972 Time remaining: 1s Progress 621 / 972 Time remaining: 1s Progress 622 / 972 Time remaining: 1s Progress 623 / 972 Time remaining: 1s Progress 624 / 972 Time remaining: 1s Progress 625 / 972 Time remaining: 1s Progress 626 / 972 Time remaining: 1s Progress 627 / 972 Time remaining: 1s Progress 628 / 972 Time remaining: 1s Progress 629 / 972 Time remaining: 1s Progress 630 / 972 Time remaining: 1s Progress 631 / 972 Time remaining: 1s Progress 632 / 972 Time remaining: 1s Progress 633 / 972 Time remaining: 1s Progress 634 / 972 Time remaining: 1s Progress 635 / 972 Time remaining: 1s Progress 636 / 972 Time remaining: 1s Progress 637 / 972 Time remaining: 1s Progress 638 / 972 Time remaining: 1s Progress 639 / 972 Time remaining: 1s Progress 640 / 972 Time remaining: 1s Progress 641 / 972 Time remaining: 1s Progress 642 / 972 Time remaining: 1s Progress 643 / 972 Time remaining: 1s Progress 644 / 972 Time remaining: 1s Progress 645 / 972 Time remaining: 1s Progress 646 / 972 Time remaining: 1s Progress 647 / 972 Time remaining: 1s Progress 648 / 972 Time remaining: 1s Progress 649 / 972 Time remaining: 1s Progress 650 / 972 Time remaining: 1s Progress 651 / 972 Time remaining: 1s Progress 652 / 972 Time remaining: 1s Progress 653 / 972 Time remaining: 1s Progress 654 / 972 Time remaining: 1s Progress 655 / 972 Time remaining: 1s Progress 656 / 972 Time remaining: 1s Progress 657 / 972 Time remaining: 1s Progress 658 / 972 Time remaining: 1s Progress 659 / 972 Time remaining: 1s Progress 660 / 972 Time remaining: 1s Progress 661 / 972 Time remaining: 1s Progress 662 / 972 Time remaining: 1s Progress 663 / 972 Time remaining: 1s Progress 664 / 972 Time remaining: 1s Progress 665 / 972 Time remaining: 1s Progress 666 / 972 Time remaining: 1s Progress 667 / 972 Time remaining: 1s Progress 668 / 972 Time remaining: 1s Progress 669 / 972 Time remaining: 1s Progress 670 / 972 Time remaining: 1s Progress 671 / 972 Time remaining: 1s Progress 672 / 972 Time remaining: 1s Progress 673 / 972 Time remaining: 1s Progress 674 / 972 Time remaining: 1s Progress 675 / 972 Time remaining: 1s Progress 676 / 972 Time remaining: 1s Progress 677 / 972 Time remaining: 1s Progress 678 / 972 Time remaining: 1s Progress 679 / 972 Time remaining: 1s Progress 680 / 972 Time remaining: 1s Progress 681 / 972 Time remaining: 1s Progress 682 / 972 Time remaining: 1s Progress 683 / 972 Time remaining: 1s Progress 684 / 972 Time remaining: 1s Progress 685 / 972 Time remaining: 1s Progress 686 / 972 Time remaining: 1s Progress 687 / 972 Time remaining: 1s Progress 688 / 972 Time remaining: 1s Progress 689 / 972 Time remaining: 1s Progress 690 / 972 Time remaining: 1s Progress 691 / 972 Time remaining: 1s Progress 692 / 972 Time remaining: 1s Progress 693 / 972 Time remaining: 1s Progress 694 / 972 Time remaining: 1s Progress 695 / 972 Time remaining: 1s Progress 696 / 972 Time remaining: 1s Progress 697 / 972 Time remaining: 1s Progress 698 / 972 Time remaining: 1s Progress 699 / 972 Time remaining: 1s Progress 700 / 972 Time remaining: 1s Progress 701 / 972 Time remaining: 1s Progress 702 / 972 Time remaining: 1s Progress 703 / 972 Time remaining: 1s Progress 704 / 972 Time remaining: 1s Progress 705 / 972 Time remaining: 1s Progress 706 / 972 Time remaining: 1s Progress 707 / 972 Time remaining: 1s Progress 708 / 972 Time remaining: 1s Progress 709 / 972 Time remaining: 1s Progress 710 / 972 Time remaining: 1s Progress 711 / 972 Time remaining: 1s Progress 712 / 972 Time remaining: 1s Progress 713 / 972 Time remaining: 1s Progress 714 / 972 Time remaining: 1s Progress 715 / 972 Time remaining: 1s Progress 716 / 972 Time remaining: 1s Progress 717 / 972 Time remaining: 1s Progress 718 / 972 Time remaining: 1s Progress 719 / 972 Time remaining: 1s Progress 720 / 972 Time remaining: 1s Progress 721 / 972 Time remaining: 1s Progress 722 / 972 Time remaining: 1s Progress 723 / 972 Time remaining: 1s Progress 724 / 972 Time remaining: 1s Progress 725 / 972 Time remaining: 1s Progress 726 / 972 Time remaining: 1s Progress 727 / 972 Time remaining: 0s Progress 728 / 972 Time remaining: 0s Progress 729 / 972 Time remaining: 0s Progress 730 / 972 Time remaining: 0s Progress 731 / 972 Time remaining: 0s Progress 732 / 972 Time remaining: 0s Progress 733 / 972 Time remaining: 0s Progress 734 / 972 Time remaining: 0s Progress 735 / 972 Time remaining: 0s Progress 736 / 972 Time remaining: 0s Progress 737 / 972 Time remaining: 0s Progress 738 / 972 Time remaining: 0s Progress 739 / 972 Time remaining: 0s Progress 740 / 972 Time remaining: 0s Progress 741 / 972 Time remaining: 0s Progress 742 / 972 Time remaining: 0s Progress 743 / 972 Time remaining: 0s Progress 744 / 972 Time remaining: 0s Progress 745 / 972 Time remaining: 0s Progress 746 / 972 Time remaining: 0s Progress 747 / 972 Time remaining: 0s Progress 748 / 972 Time remaining: 0s Progress 749 / 972 Time remaining: 0s Progress 750 / 972 Time remaining: 0s Progress 751 / 972 Time remaining: 0s Progress 752 / 972 Time remaining: 0s Progress 753 / 972 Time remaining: 0s Progress 754 / 972 Time remaining: 0s Progress 755 / 972 Time remaining: 0s Progress 756 / 972 Time remaining: 0s Progress 757 / 972 Time remaining: 0s Progress 758 / 972 Time remaining: 0s Progress 759 / 972 Time remaining: 0s Progress 760 / 972 Time remaining: 0s Progress 761 / 972 Time remaining: 0s Progress 762 / 972 Time remaining: 0s Progress 763 / 972 Time remaining: 0s Progress 764 / 972 Time remaining: 0s Progress 765 / 972 Time remaining: 0s Progress 766 / 972 Time remaining: 0s Progress 767 / 972 Time remaining: 0s Progress 768 / 972 Time remaining: 0s Progress 769 / 972 Time remaining: 0s Progress 770 / 972 Time remaining: 0s Progress 771 / 972 Time remaining: 0s Progress 772 / 972 Time remaining: 0s Progress 773 / 972 Time remaining: 0s Progress 774 / 972 Time remaining: 0s Progress 775 / 972 Time remaining: 0s Progress 776 / 972 Time remaining: 0s Progress 777 / 972 Time remaining: 0s Progress 778 / 972 Time remaining: 0s Progress 779 / 972 Time remaining: 0s Progress 780 / 972 Time remaining: 0s Progress 781 / 972 Time remaining: 0s Progress 782 / 972 Time remaining: 0s Progress 783 / 972 Time remaining: 0s Progress 784 / 972 Time remaining: 0s Progress 785 / 972 Time remaining: 0s Progress 786 / 972 Time remaining: 0s Progress 787 / 972 Time remaining: 0s Progress 788 / 972 Time remaining: 0s Progress 789 / 972 Time remaining: 0s Progress 790 / 972 Time remaining: 0s Progress 791 / 972 Time remaining: 0s Progress 792 / 972 Time remaining: 0s Progress 793 / 972 Time remaining: 0s Progress 794 / 972 Time remaining: 0s Progress 795 / 972 Time remaining: 0s Progress 796 / 972 Time remaining: 0s Progress 797 / 972 Time remaining: 0s Progress 798 / 972 Time remaining: 0s Progress 799 / 972 Time remaining: 0s Progress 800 / 972 Time remaining: 0s Progress 801 / 972 Time remaining: 0s Progress 802 / 972 Time remaining: 0s Progress 803 / 972 Time remaining: 0s Progress 804 / 972 Time remaining: 0s Progress 805 / 972 Time remaining: 0s Progress 806 / 972 Time remaining: 0s Progress 807 / 972 Time remaining: 0s Progress 808 / 972 Time remaining: 0s Progress 809 / 972 Time remaining: 0s Progress 810 / 972 Time remaining: 0s Progress 811 / 972 Time remaining: 0s Progress 812 / 972 Time remaining: 0s Progress 813 / 972 Time remaining: 0s Progress 814 / 972 Time remaining: 0s Progress 815 / 972 Time remaining: 0s Progress 816 / 972 Time remaining: 0s Progress 817 / 972 Time remaining: 0s Progress 818 / 972 Time remaining: 0s Progress 819 / 972 Time remaining: 0s Progress 820 / 972 Time remaining: 0s Progress 821 / 972 Time remaining: 0s Progress 822 / 972 Time remaining: 0s Progress 823 / 972 Time remaining: 0s Progress 824 / 972 Time remaining: 0s Progress 825 / 972 Time remaining: 0s Progress 826 / 972 Time remaining: 0s Progress 827 / 972 Time remaining: 0s Progress 828 / 972 Time remaining: 0s Progress 829 / 972 Time remaining: 0s Progress 830 / 972 Time remaining: 0s Progress 831 / 972 Time remaining: 0s Progress 832 / 972 Time remaining: 0s Progress 833 / 972 Time remaining: 0s Progress 834 / 972 Time remaining: 0s Progress 835 / 972 Time remaining: 0s Progress 836 / 972 Time remaining: 0s Progress 837 / 972 Time remaining: 0s Progress 838 / 972 Time remaining: 0s Progress 839 / 972 Time remaining: 0s Progress 840 / 972 Time remaining: 0s Progress 841 / 972 Time remaining: 0s Progress 842 / 972 Time remaining: 0s Progress 843 / 972 Time remaining: 0s Progress 844 / 972 Time remaining: 0s Progress 845 / 972 Time remaining: 0s Progress 846 / 972 Time remaining: 0s Progress 847 / 972 Time remaining: 0s Progress 848 / 972 Time remaining: 0s Progress 849 / 972 Time remaining: 0s Progress 850 / 972 Time remaining: 0s Progress 851 / 972 Time remaining: 0s Progress 852 / 972 Time remaining: 0s Progress 853 / 972 Time remaining: 0s Progress 854 / 972 Time remaining: 0s Progress 855 / 972 Time remaining: 0s Progress 856 / 972 Time remaining: 0s Progress 857 / 972 Time remaining: 0s Progress 858 / 972 Time remaining: 0s Progress 859 / 972 Time remaining: 0s Progress 860 / 972 Time remaining: 0s Progress 861 / 972 Time remaining: 0s Progress 862 / 972 Time remaining: 0s Progress 863 / 972 Time remaining: 0s Progress 864 / 972 Time remaining: 0s Progress 865 / 972 Time remaining: 0s Progress 866 / 972 Time remaining: 0s Progress 867 / 972 Time remaining: 0s Progress 868 / 972 Time remaining: 0s Progress 869 / 972 Time remaining: 0s Progress 870 / 972 Time remaining: 0s Progress 871 / 972 Time remaining: 0s Progress 872 / 972 Time remaining: 0s Progress 873 / 972 Time remaining: 0s Progress 874 / 972 Time remaining: 0s Progress 875 / 972 Time remaining: 0s Progress 876 / 972 Time remaining: 0s Progress 877 / 972 Time remaining: 0s Progress 878 / 972 Time remaining: 0s Progress 879 / 972 Time remaining: 0s Progress 880 / 972 Time remaining: 0s Progress 881 / 972 Time remaining: 0s Progress 882 / 972 Time remaining: 0s Progress 883 / 972 Time remaining: 0s Progress 884 / 972 Time remaining: 0s Progress 885 / 972 Time remaining: 0s Progress 886 / 972 Time remaining: 0s Progress 887 / 972 Time remaining: 0s Progress 888 / 972 Time remaining: 0s Progress 889 / 972 Time remaining: 0s Progress 890 / 972 Time remaining: 0s Progress 891 / 972 Time remaining: 0s Progress 892 / 972 Time remaining: 0s Progress 893 / 972 Time remaining: 0s Progress 894 / 972 Time remaining: 0s Progress 895 / 972 Time remaining: 0s Progress 896 / 972 Time remaining: 0s Progress 897 / 972 Time remaining: 0s Progress 898 / 972 Time remaining: 0s Progress 899 / 972 Time remaining: 0s Progress 900 / 972 Time remaining: 0s Progress 901 / 972 Time remaining: 0s Progress 902 / 972 Time remaining: 0s Progress 903 / 972 Time remaining: 0s Progress 904 / 972 Time remaining: 0s Progress 905 / 972 Time remaining: 0s Progress 906 / 972 Time remaining: 0s Progress 907 / 972 Time remaining: 0s Progress 908 / 972 Time remaining: 0s Progress 909 / 972 Time remaining: 0s Progress 910 / 972 Time remaining: 0s Progress 911 / 972 Time remaining: 0s Progress 912 / 972 Time remaining: 0s Progress 913 / 972 Time remaining: 0s Progress 914 / 972 Time remaining: 0s Progress 915 / 972 Time remaining: 0s Progress 916 / 972 Time remaining: 0s Progress 917 / 972 Time remaining: 0s Progress 918 / 972 Time remaining: 0s Progress 919 / 972 Time remaining: 0s Progress 920 / 972 Time remaining: 0s Progress 921 / 972 Time remaining: 0s Progress 922 / 972 Time remaining: 0s Progress 923 / 972 Time remaining: 0s Progress 924 / 972 Time remaining: 0s Progress 925 / 972 Time remaining: 0s Progress 926 / 972 Time remaining: 0s Progress 927 / 972 Time remaining: 0s Progress 928 / 972 Time remaining: 0s Progress 929 / 972 Time remaining: 0s Progress 930 / 972 Time remaining: 0s Progress 931 / 972 Time remaining: 0s Progress 932 / 972 Time remaining: 0s Progress 933 / 972 Time remaining: 0s Progress 934 / 972 Time remaining: 0s Progress 935 / 972 Time remaining: 0s Progress 936 / 972 Time remaining: 0s Progress 937 / 972 Time remaining: 0s Progress 938 / 972 Time remaining: 0s Progress 939 / 972 Time remaining: 0s Progress 940 / 972 Time remaining: 0s Progress 941 / 972 Time remaining: 0s Progress 942 / 972 Time remaining: 0s Progress 943 / 972 Time remaining: 0s Progress 944 / 972 Time remaining: 0s Progress 945 / 972 Time remaining: 0s Progress 946 / 972 Time remaining: 0s Progress 947 / 972 Time remaining: 0s Progress 948 / 972 Time remaining: 0s Progress 949 / 972 Time remaining: 0s Progress 950 / 972 Time remaining: 0s Progress 951 / 972 Time remaining: 0s Progress 952 / 972 Time remaining: 0s Progress 953 / 972 Time remaining: 0s Progress 954 / 972 Time remaining: 0s Progress 955 / 972 Time remaining: 0s Progress 956 / 972 Time remaining: 0s Progress 957 / 972 Time remaining: 0s Progress 958 / 972 Time remaining: 0s Progress 959 / 972 Time remaining: 0s Progress 960 / 972 Time remaining: 0s Progress 961 / 972 Time remaining: 0s Progress 962 / 972 Time remaining: 0s Progress 963 / 972 Time remaining: 0s Progress 964 / 972 Time remaining: 0s Progress 965 / 972 Time remaining: 0s Progress 966 / 972 Time remaining: 0s Progress 967 / 972 Time remaining: 0s Progress 968 / 972 Time remaining: 0s Progress 969 / 972 Time remaining: 0s Progress 970 / 972 Time remaining: 0s Progress 971 / 972 Time remaining: 0s Progress 972 / 972 Time remaining: Added 972 camera error terms + +Adding camera error terms (/cam1/image_raw) + Progress 1 / 972 Time remaining: 3s Progress 2 / 972 Time remaining: 3s Progress 3 / 972 Time remaining: 3s Progress 4 / 972 Time remaining: 3s Progress 5 / 972 Time remaining: 3s Progress 6 / 972 Time remaining: 3s Progress 7 / 972 Time remaining: 3s Progress 8 / 972 Time remaining: 3s Progress 9 / 972 Time remaining: 3s Progress 10 / 972 Time remaining: 3s Progress 11 / 972 Time remaining: 3s Progress 12 / 972 Time remaining: 3s Progress 13 / 972 Time remaining: 3s Progress 14 / 972 Time remaining: 3s Progress 15 / 972 Time remaining: 3s Progress 16 / 972 Time remaining: 3s Progress 17 / 972 Time remaining: 3s Progress 18 / 972 Time remaining: 3s Progress 19 / 972 Time remaining: 3s Progress 20 / 972 Time remaining: 3s Progress 21 / 972 Time remaining: 3s Progress 22 / 972 Time remaining: 3s Progress 23 / 972 Time remaining: 3s Progress 24 / 972 Time remaining: 3s Progress 25 / 972 Time remaining: 3s Progress 26 / 972 Time remaining: 3s Progress 27 / 972 Time remaining: 3s Progress 28 / 972 Time remaining: 3s Progress 29 / 972 Time remaining: 3s Progress 30 / 972 Time remaining: 3s Progress 31 / 972 Time remaining: 3s Progress 32 / 972 Time remaining: 3s Progress 33 / 972 Time remaining: 3s Progress 34 / 972 Time remaining: 3s Progress 35 / 972 Time remaining: 3s Progress 36 / 972 Time remaining: 3s Progress 37 / 972 Time remaining: 3s Progress 38 / 972 Time remaining: 3s Progress 39 / 972 Time remaining: 3s Progress 40 / 972 Time remaining: 3s Progress 41 / 972 Time remaining: 3s Progress 42 / 972 Time remaining: 3s Progress 43 / 972 Time remaining: 3s Progress 44 / 972 Time remaining: 3s Progress 45 / 972 Time remaining: 3s Progress 46 / 972 Time remaining: 3s Progress 47 / 972 Time remaining: 3s Progress 48 / 972 Time remaining: 3s Progress 49 / 972 Time remaining: 3s Progress 50 / 972 Time remaining: 3s Progress 51 / 972 Time remaining: 3s Progress 52 / 972 Time remaining: 3s Progress 53 / 972 Time remaining: 3s Progress 54 / 972 Time remaining: 3s Progress 55 / 972 Time remaining: 4s Progress 56 / 972 Time remaining: 4s Progress 57 / 972 Time remaining: 4s Progress 58 / 972 Time remaining: 4s Progress 59 / 972 Time remaining: 4s Progress 60 / 972 Time remaining: 4s Progress 61 / 972 Time remaining: 4s Progress 62 / 972 Time remaining: 4s Progress 63 / 972 Time remaining: 4s Progress 64 / 972 Time remaining: 4s Progress 65 / 972 Time remaining: 4s Progress 66 / 972 Time remaining: 4s Progress 67 / 972 Time remaining: 4s Progress 68 / 972 Time remaining: 4s Progress 69 / 972 Time remaining: 4s Progress 70 / 972 Time remaining: 4s Progress 71 / 972 Time remaining: 4s Progress 72 / 972 Time remaining: 4s Progress 73 / 972 Time remaining: 4s Progress 74 / 972 Time remaining: 4s Progress 75 / 972 Time remaining: 4s Progress 76 / 972 Time remaining: 4s Progress 77 / 972 Time remaining: 4s Progress 78 / 972 Time remaining: 4s Progress 79 / 972 Time remaining: 4s Progress 80 / 972 Time remaining: 4s Progress 81 / 972 Time remaining: 4s Progress 82 / 972 Time remaining: 4s Progress 83 / 972 Time remaining: 4s Progress 84 / 972 Time remaining: 4s Progress 85 / 972 Time remaining: 4s Progress 86 / 972 Time remaining: 4s Progress 87 / 972 Time remaining: 4s Progress 88 / 972 Time remaining: 4s Progress 89 / 972 Time remaining: 4s Progress 90 / 972 Time remaining: 4s Progress 91 / 972 Time remaining: 4s Progress 92 / 972 Time remaining: 4s Progress 93 / 972 Time remaining: 4s Progress 94 / 972 Time remaining: 4s Progress 95 / 972 Time remaining: 4s Progress 96 / 972 Time remaining: 4s Progress 97 / 972 Time remaining: 4s Progress 98 / 972 Time remaining: 4s Progress 99 / 972 Time remaining: 4s Progress 100 / 972 Time remaining: 4s Progress 101 / 972 Time remaining: 4s Progress 102 / 972 Time remaining: 4s Progress 103 / 972 Time remaining: 4s Progress 104 / 972 Time remaining: 4s Progress 105 / 972 Time remaining: 4s Progress 106 / 972 Time remaining: 4s Progress 107 / 972 Time remaining: 4s Progress 108 / 972 Time remaining: 4s Progress 109 / 972 Time remaining: 4s Progress 110 / 972 Time remaining: 4s Progress 111 / 972 Time remaining: 4s Progress 112 / 972 Time remaining: 4s Progress 113 / 972 Time remaining: 4s Progress 114 / 972 Time remaining: 4s Progress 115 / 972 Time remaining: 3s Progress 116 / 972 Time remaining: 3s Progress 117 / 972 Time remaining: 3s Progress 118 / 972 Time remaining: 3s Progress 119 / 972 Time remaining: 3s Progress 120 / 972 Time remaining: 3s Progress 121 / 972 Time remaining: 3s Progress 122 / 972 Time remaining: 3s Progress 123 / 972 Time remaining: 3s Progress 124 / 972 Time remaining: 3s Progress 125 / 972 Time remaining: 3s Progress 126 / 972 Time remaining: 3s Progress 127 / 972 Time remaining: 3s Progress 128 / 972 Time remaining: 3s Progress 129 / 972 Time remaining: 3s Progress 130 / 972 Time remaining: 3s Progress 131 / 972 Time remaining: 3s Progress 132 / 972 Time remaining: 3s Progress 133 / 972 Time remaining: 3s Progress 134 / 972 Time remaining: 3s Progress 135 / 972 Time remaining: 3s Progress 136 / 972 Time remaining: 3s Progress 137 / 972 Time remaining: 3s Progress 138 / 972 Time remaining: 3s Progress 139 / 972 Time remaining: 3s Progress 140 / 972 Time remaining: 3s Progress 141 / 972 Time remaining: 3s Progress 142 / 972 Time remaining: 3s Progress 143 / 972 Time remaining: 3s Progress 144 / 972 Time remaining: 3s Progress 145 / 972 Time remaining: 3s Progress 146 / 972 Time remaining: 3s Progress 147 / 972 Time remaining: 3s Progress 148 / 972 Time remaining: 3s Progress 149 / 972 Time remaining: 3s Progress 150 / 972 Time remaining: 3s Progress 151 / 972 Time remaining: 3s Progress 152 / 972 Time remaining: 3s Progress 153 / 972 Time remaining: 3s Progress 154 / 972 Time remaining: 3s Progress 155 / 972 Time remaining: 3s Progress 156 / 972 Time remaining: 3s Progress 157 / 972 Time remaining: 3s Progress 158 / 972 Time remaining: 3s Progress 159 / 972 Time remaining: 3s Progress 160 / 972 Time remaining: 3s Progress 161 / 972 Time remaining: 3s Progress 162 / 972 Time remaining: 3s Progress 163 / 972 Time remaining: 3s Progress 164 / 972 Time remaining: 3s Progress 165 / 972 Time remaining: 3s Progress 166 / 972 Time remaining: 3s Progress 167 / 972 Time remaining: 3s Progress 168 / 972 Time remaining: 3s Progress 169 / 972 Time remaining: 3s Progress 170 / 972 Time remaining: 3s Progress 171 / 972 Time remaining: 3s Progress 172 / 972 Time remaining: 3s Progress 173 / 972 Time remaining: 3s Progress 174 / 972 Time remaining: 3s Progress 175 / 972 Time remaining: 3s Progress 176 / 972 Time remaining: 3s Progress 177 / 972 Time remaining: 3s Progress 178 / 972 Time remaining: 3s Progress 179 / 972 Time remaining: 3s Progress 180 / 972 Time remaining: 3s Progress 181 / 972 Time remaining: 3s Progress 182 / 972 Time remaining: 3s Progress 183 / 972 Time remaining: 3s Progress 184 / 972 Time remaining: 3s Progress 185 / 972 Time remaining: 3s Progress 186 / 972 Time remaining: 3s Progress 187 / 972 Time remaining: 3s Progress 188 / 972 Time remaining: 3s Progress 189 / 972 Time remaining: 3s Progress 190 / 972 Time remaining: 3s Progress 191 / 972 Time remaining: 3s Progress 192 / 972 Time remaining: 3s Progress 193 / 972 Time remaining: 3s Progress 194 / 972 Time remaining: 3s Progress 195 / 972 Time remaining: 3s Progress 196 / 972 Time remaining: 3s Progress 197 / 972 Time remaining: 3s Progress 198 / 972 Time remaining: 3s Progress 199 / 972 Time remaining: 3s Progress 200 / 972 Time remaining: 3s Progress 201 / 972 Time remaining: 3s Progress 202 / 972 Time remaining: 3s Progress 203 / 972 Time remaining: 3s Progress 204 / 972 Time remaining: 3s Progress 205 / 972 Time remaining: 3s Progress 206 / 972 Time remaining: 3s Progress 207 / 972 Time remaining: 3s Progress 208 / 972 Time remaining: 3s Progress 209 / 972 Time remaining: 3s Progress 210 / 972 Time remaining: 3s Progress 211 / 972 Time remaining: 3s Progress 212 / 972 Time remaining: 3s Progress 213 / 972 Time remaining: 3s Progress 214 / 972 Time remaining: 3s Progress 215 / 972 Time remaining: 3s Progress 216 / 972 Time remaining: 3s Progress 217 / 972 Time remaining: 3s Progress 218 / 972 Time remaining: 3s Progress 219 / 972 Time remaining: 3s Progress 220 / 972 Time remaining: 3s Progress 221 / 972 Time remaining: 3s Progress 222 / 972 Time remaining: 3s Progress 223 / 972 Time remaining: 3s Progress 224 / 972 Time remaining: 3s Progress 225 / 972 Time remaining: 3s Progress 226 / 972 Time remaining: 3s Progress 227 / 972 Time remaining: 3s Progress 228 / 972 Time remaining: 3s Progress 229 / 972 Time remaining: 3s Progress 230 / 972 Time remaining: 3s Progress 231 / 972 Time remaining: 3s Progress 232 / 972 Time remaining: 3s Progress 233 / 972 Time remaining: 3s Progress 234 / 972 Time remaining: 3s Progress 235 / 972 Time remaining: 3s Progress 236 / 972 Time remaining: 3s Progress 237 / 972 Time remaining: 3s Progress 238 / 972 Time remaining: 3s Progress 239 / 972 Time remaining: 3s Progress 240 / 972 Time remaining: 3s Progress 241 / 972 Time remaining: 3s Progress 242 / 972 Time remaining: 3s Progress 243 / 972 Time remaining: 3s Progress 244 / 972 Time remaining: 3s Progress 245 / 972 Time remaining: 3s Progress 246 / 972 Time remaining: 3s Progress 247 / 972 Time remaining: 3s Progress 248 / 972 Time remaining: 3s Progress 249 / 972 Time remaining: 3s Progress 250 / 972 Time remaining: 3s Progress 251 / 972 Time remaining: 3s Progress 252 / 972 Time remaining: 3s Progress 253 / 972 Time remaining: 3s Progress 254 / 972 Time remaining: 3s Progress 255 / 972 Time remaining: 3s Progress 256 / 972 Time remaining: 3s Progress 257 / 972 Time remaining: 3s Progress 258 / 972 Time remaining: 3s Progress 259 / 972 Time remaining: 3s Progress 260 / 972 Time remaining: 3s Progress 261 / 972 Time remaining: 3s Progress 262 / 972 Time remaining: 3s Progress 263 / 972 Time remaining: 3s Progress 264 / 972 Time remaining: 3s Progress 265 / 972 Time remaining: 3s Progress 266 / 972 Time remaining: 3s Progress 267 / 972 Time remaining: 3s Progress 268 / 972 Time remaining: 3s Progress 269 / 972 Time remaining: 3s Progress 270 / 972 Time remaining: 3s Progress 271 / 972 Time remaining: 3s Progress 272 / 972 Time remaining: 2s Progress 273 / 972 Time remaining: 2s Progress 274 / 972 Time remaining: 2s Progress 275 / 972 Time remaining: 2s Progress 276 / 972 Time remaining: 2s Progress 277 / 972 Time remaining: 2s Progress 278 / 972 Time remaining: 2s Progress 279 / 972 Time remaining: 2s Progress 280 / 972 Time remaining: 2s Progress 281 / 972 Time remaining: 2s Progress 282 / 972 Time remaining: 2s Progress 283 / 972 Time remaining: 2s Progress 284 / 972 Time remaining: 2s Progress 285 / 972 Time remaining: 2s Progress 286 / 972 Time remaining: 2s Progress 287 / 972 Time remaining: 2s Progress 288 / 972 Time remaining: 2s Progress 289 / 972 Time remaining: 2s Progress 290 / 972 Time remaining: 2s Progress 291 / 972 Time remaining: 2s Progress 292 / 972 Time remaining: 2s Progress 293 / 972 Time remaining: 2s Progress 294 / 972 Time remaining: 2s Progress 295 / 972 Time remaining: 2s Progress 296 / 972 Time remaining: 2s Progress 297 / 972 Time remaining: 2s Progress 298 / 972 Time remaining: 2s Progress 299 / 972 Time remaining: 2s Progress 300 / 972 Time remaining: 2s Progress 301 / 972 Time remaining: 2s Progress 302 / 972 Time remaining: 2s Progress 303 / 972 Time remaining: 2s Progress 304 / 972 Time remaining: 2s Progress 305 / 972 Time remaining: 2s Progress 306 / 972 Time remaining: 2s Progress 307 / 972 Time remaining: 2s Progress 308 / 972 Time remaining: 2s Progress 309 / 972 Time remaining: 2s Progress 310 / 972 Time remaining: 2s Progress 311 / 972 Time remaining: 2s Progress 312 / 972 Time remaining: 2s Progress 313 / 972 Time remaining: 2s Progress 314 / 972 Time remaining: 2s Progress 315 / 972 Time remaining: 2s Progress 316 / 972 Time remaining: 2s Progress 317 / 972 Time remaining: 2s Progress 318 / 972 Time remaining: 2s Progress 319 / 972 Time remaining: 2s Progress 320 / 972 Time remaining: 2s Progress 321 / 972 Time remaining: 2s Progress 322 / 972 Time remaining: 2s Progress 323 / 972 Time remaining: 2s Progress 324 / 972 Time remaining: 2s Progress 325 / 972 Time remaining: 2s Progress 326 / 972 Time remaining: 2s Progress 327 / 972 Time remaining: 2s Progress 328 / 972 Time remaining: 2s Progress 329 / 972 Time remaining: 2s Progress 330 / 972 Time remaining: 2s Progress 331 / 972 Time remaining: 2s Progress 332 / 972 Time remaining: 2s Progress 333 / 972 Time remaining: 2s Progress 334 / 972 Time remaining: 2s Progress 335 / 972 Time remaining: 2s Progress 336 / 972 Time remaining: 2s Progress 337 / 972 Time remaining: 2s Progress 338 / 972 Time remaining: 2s Progress 339 / 972 Time remaining: 2s Progress 340 / 972 Time remaining: 2s Progress 341 / 972 Time remaining: 2s Progress 342 / 972 Time remaining: 2s Progress 343 / 972 Time remaining: 2s Progress 344 / 972 Time remaining: 2s Progress 345 / 972 Time remaining: 2s Progress 346 / 972 Time remaining: 2s Progress 347 / 972 Time remaining: 2s Progress 348 / 972 Time remaining: 2s Progress 349 / 972 Time remaining: 2s Progress 350 / 972 Time remaining: 2s Progress 351 / 972 Time remaining: 2s Progress 352 / 972 Time remaining: 2s Progress 353 / 972 Time remaining: 2s Progress 354 / 972 Time remaining: 2s Progress 355 / 972 Time remaining: 2s Progress 356 / 972 Time remaining: 2s Progress 357 / 972 Time remaining: 2s Progress 358 / 972 Time remaining: 2s Progress 359 / 972 Time remaining: 2s Progress 360 / 972 Time remaining: 2s Progress 361 / 972 Time remaining: 2s Progress 362 / 972 Time remaining: 2s Progress 363 / 972 Time remaining: 2s Progress 364 / 972 Time remaining: 2s Progress 365 / 972 Time remaining: 2s Progress 366 / 972 Time remaining: 2s Progress 367 / 972 Time remaining: 2s Progress 368 / 972 Time remaining: 2s Progress 369 / 972 Time remaining: 2s Progress 370 / 972 Time remaining: 2s Progress 371 / 972 Time remaining: 2s Progress 372 / 972 Time remaining: 2s Progress 373 / 972 Time remaining: 2s Progress 374 / 972 Time remaining: 2s Progress 375 / 972 Time remaining: 2s Progress 376 / 972 Time remaining: 2s Progress 377 / 972 Time remaining: 2s Progress 378 / 972 Time remaining: 2s Progress 379 / 972 Time remaining: 2s Progress 380 / 972 Time remaining: 2s Progress 381 / 972 Time remaining: 2s Progress 382 / 972 Time remaining: 2s Progress 383 / 972 Time remaining: 2s Progress 384 / 972 Time remaining: 2s Progress 385 / 972 Time remaining: 2s Progress 386 / 972 Time remaining: 2s Progress 387 / 972 Time remaining: 2s Progress 388 / 972 Time remaining: 2s Progress 389 / 972 Time remaining: 2s Progress 390 / 972 Time remaining: 2s Progress 391 / 972 Time remaining: 2s Progress 392 / 972 Time remaining: 2s Progress 393 / 972 Time remaining: 2s Progress 394 / 972 Time remaining: 2s Progress 395 / 972 Time remaining: 2s Progress 396 / 972 Time remaining: 2s Progress 397 / 972 Time remaining: 2s Progress 398 / 972 Time remaining: 2s Progress 399 / 972 Time remaining: 2s Progress 400 / 972 Time remaining: 2s Progress 401 / 972 Time remaining: 2s Progress 402 / 972 Time remaining: 2s Progress 403 / 972 Time remaining: 2s Progress 404 / 972 Time remaining: 2s Progress 405 / 972 Time remaining: 2s Progress 406 / 972 Time remaining: 2s Progress 407 / 972 Time remaining: 2s Progress 408 / 972 Time remaining: 2s Progress 409 / 972 Time remaining: 2s Progress 410 / 972 Time remaining: 2s Progress 411 / 972 Time remaining: 2s Progress 412 / 972 Time remaining: 2s Progress 413 / 972 Time remaining: 2s Progress 414 / 972 Time remaining: 2s Progress 415 / 972 Time remaining: 2s Progress 416 / 972 Time remaining: 2s Progress 417 / 972 Time remaining: 2s Progress 418 / 972 Time remaining: 2s Progress 419 / 972 Time remaining: 2s Progress 420 / 972 Time remaining: 2s Progress 421 / 972 Time remaining: 2s Progress 422 / 972 Time remaining: 2s Progress 423 / 972 Time remaining: 2s Progress 424 / 972 Time remaining: 2s Progress 425 / 972 Time remaining: 2s Progress 426 / 972 Time remaining: 2s Progress 427 / 972 Time remaining: 2s Progress 428 / 972 Time remaining: 2s Progress 429 / 972 Time remaining: 2s Progress 430 / 972 Time remaining: 2s Progress 431 / 972 Time remaining: 2s Progress 432 / 972 Time remaining: 2s Progress 433 / 972 Time remaining: 2s Progress 434 / 972 Time remaining: 2s Progress 435 / 972 Time remaining: 2s Progress 436 / 972 Time remaining: 2s Progress 437 / 972 Time remaining: 2s Progress 438 / 972 Time remaining: 2s Progress 439 / 972 Time remaining: 2s Progress 440 / 972 Time remaining: 2s Progress 441 / 972 Time remaining: 2s Progress 442 / 972 Time remaining: 2s Progress 443 / 972 Time remaining: 2s Progress 444 / 972 Time remaining: 2s Progress 445 / 972 Time remaining: 2s Progress 446 / 972 Time remaining: 2s Progress 447 / 972 Time remaining: 2s Progress 448 / 972 Time remaining: 2s Progress 449 / 972 Time remaining: 2s Progress 450 / 972 Time remaining: 2s Progress 451 / 972 Time remaining: 2s Progress 452 / 972 Time remaining: 2s Progress 453 / 972 Time remaining: 2s Progress 454 / 972 Time remaining: 2s Progress 455 / 972 Time remaining: 2s Progress 456 / 972 Time remaining: 2s Progress 457 / 972 Time remaining: 2s Progress 458 / 972 Time remaining: 2s Progress 459 / 972 Time remaining: 2s Progress 460 / 972 Time remaining: 2s Progress 461 / 972 Time remaining: 2s Progress 462 / 972 Time remaining: 2s Progress 463 / 972 Time remaining: 2s Progress 464 / 972 Time remaining: 2s Progress 465 / 972 Time remaining: 2s Progress 466 / 972 Time remaining: 2s Progress 467 / 972 Time remaining: 2s Progress 468 / 972 Time remaining: 2s Progress 469 / 972 Time remaining: 2s Progress 470 / 972 Time remaining: 2s Progress 471 / 972 Time remaining: 2s Progress 472 / 972 Time remaining: 2s Progress 473 / 972 Time remaining: 2s Progress 474 / 972 Time remaining: 2s Progress 475 / 972 Time remaining: 2s Progress 476 / 972 Time remaining: 2s Progress 477 / 972 Time remaining: 2s Progress 478 / 972 Time remaining: 2s Progress 479 / 972 Time remaining: 2s Progress 480 / 972 Time remaining: 2s Progress 481 / 972 Time remaining: 2s Progress 482 / 972 Time remaining: 2s Progress 483 / 972 Time remaining: 2s Progress 484 / 972 Time remaining: 2s Progress 485 / 972 Time remaining: 2s Progress 486 / 972 Time remaining: 2s Progress 487 / 972 Time remaining: 2s Progress 488 / 972 Time remaining: 2s Progress 489 / 972 Time remaining: 2s Progress 490 / 972 Time remaining: 2s Progress 491 / 972 Time remaining: 2s Progress 492 / 972 Time remaining: 1s Progress 493 / 972 Time remaining: 1s Progress 494 / 972 Time remaining: 1s Progress 495 / 972 Time remaining: 1s Progress 496 / 972 Time remaining: 1s Progress 497 / 972 Time remaining: 1s Progress 498 / 972 Time remaining: 1s Progress 499 / 972 Time remaining: 1s Progress 500 / 972 Time remaining: 1s Progress 501 / 972 Time remaining: 1s Progress 502 / 972 Time remaining: 1s Progress 503 / 972 Time remaining: 1s Progress 504 / 972 Time remaining: 1s Progress 505 / 972 Time remaining: 1s Progress 506 / 972 Time remaining: 1s Progress 507 / 972 Time remaining: 1s Progress 508 / 972 Time remaining: 1s Progress 509 / 972 Time remaining: 1s Progress 510 / 972 Time remaining: 1s Progress 511 / 972 Time remaining: 1s Progress 512 / 972 Time remaining: 1s Progress 513 / 972 Time remaining: 1s Progress 514 / 972 Time remaining: 1s Progress 515 / 972 Time remaining: 1s Progress 516 / 972 Time remaining: 1s Progress 517 / 972 Time remaining: 1s Progress 518 / 972 Time remaining: 1s Progress 519 / 972 Time remaining: 1s Progress 520 / 972 Time remaining: 1s Progress 521 / 972 Time remaining: 1s Progress 522 / 972 Time remaining: 1s Progress 523 / 972 Time remaining: 1s Progress 524 / 972 Time remaining: 1s Progress 525 / 972 Time remaining: 1s Progress 526 / 972 Time remaining: 1s Progress 527 / 972 Time remaining: 1s Progress 528 / 972 Time remaining: 1s Progress 529 / 972 Time remaining: 1s Progress 530 / 972 Time remaining: 1s Progress 531 / 972 Time remaining: 1s Progress 532 / 972 Time remaining: 1s Progress 533 / 972 Time remaining: 1s Progress 534 / 972 Time remaining: 1s Progress 535 / 972 Time remaining: 1s Progress 536 / 972 Time remaining: 1s Progress 537 / 972 Time remaining: 1s Progress 538 / 972 Time remaining: 1s Progress 539 / 972 Time remaining: 1s Progress 540 / 972 Time remaining: 1s Progress 541 / 972 Time remaining: 1s Progress 542 / 972 Time remaining: 1s Progress 543 / 972 Time remaining: 1s Progress 544 / 972 Time remaining: 1s Progress 545 / 972 Time remaining: 1s Progress 546 / 972 Time remaining: 1s Progress 547 / 972 Time remaining: 1s Progress 548 / 972 Time remaining: 1s Progress 549 / 972 Time remaining: 1s Progress 550 / 972 Time remaining: 1s Progress 551 / 972 Time remaining: 1s Progress 552 / 972 Time remaining: 1s Progress 553 / 972 Time remaining: 1s Progress 554 / 972 Time remaining: 1s Progress 555 / 972 Time remaining: 1s Progress 556 / 972 Time remaining: 1s Progress 557 / 972 Time remaining: 1s Progress 558 / 972 Time remaining: 1s Progress 559 / 972 Time remaining: 1s Progress 560 / 972 Time remaining: 1s Progress 561 / 972 Time remaining: 1s Progress 562 / 972 Time remaining: 1s Progress 563 / 972 Time remaining: 1s Progress 564 / 972 Time remaining: 1s Progress 565 / 972 Time remaining: 1s Progress 566 / 972 Time remaining: 1s Progress 567 / 972 Time remaining: 1s Progress 568 / 972 Time remaining: 1s Progress 569 / 972 Time remaining: 1s Progress 570 / 972 Time remaining: 1s Progress 571 / 972 Time remaining: 1s Progress 572 / 972 Time remaining: 1s Progress 573 / 972 Time remaining: 1s Progress 574 / 972 Time remaining: 1s Progress 575 / 972 Time remaining: 1s Progress 576 / 972 Time remaining: 1s Progress 577 / 972 Time remaining: 1s Progress 578 / 972 Time remaining: 1s Progress 579 / 972 Time remaining: 1s Progress 580 / 972 Time remaining: 1s Progress 581 / 972 Time remaining: 1s Progress 582 / 972 Time remaining: 1s Progress 583 / 972 Time remaining: 1s Progress 584 / 972 Time remaining: 1s Progress 585 / 972 Time remaining: 1s Progress 586 / 972 Time remaining: 1s Progress 587 / 972 Time remaining: 1s Progress 588 / 972 Time remaining: 1s Progress 589 / 972 Time remaining: 1s Progress 590 / 972 Time remaining: 1s Progress 591 / 972 Time remaining: 1s Progress 592 / 972 Time remaining: 1s Progress 593 / 972 Time remaining: 1s Progress 594 / 972 Time remaining: 1s Progress 595 / 972 Time remaining: 1s Progress 596 / 972 Time remaining: 1s Progress 597 / 972 Time remaining: 1s Progress 598 / 972 Time remaining: 1s Progress 599 / 972 Time remaining: 1s Progress 600 / 972 Time remaining: 1s Progress 601 / 972 Time remaining: 1s Progress 602 / 972 Time remaining: 1s Progress 603 / 972 Time remaining: 1s Progress 604 / 972 Time remaining: 1s Progress 605 / 972 Time remaining: 1s Progress 606 / 972 Time remaining: 1s Progress 607 / 972 Time remaining: 1s Progress 608 / 972 Time remaining: 1s Progress 609 / 972 Time remaining: 1s Progress 610 / 972 Time remaining: 1s Progress 611 / 972 Time remaining: 1s Progress 612 / 972 Time remaining: 1s Progress 613 / 972 Time remaining: 1s Progress 614 / 972 Time remaining: 1s Progress 615 / 972 Time remaining: 1s Progress 616 / 972 Time remaining: 1s Progress 617 / 972 Time remaining: 1s Progress 618 / 972 Time remaining: 1s Progress 619 / 972 Time remaining: 1s Progress 620 / 972 Time remaining: 1s Progress 621 / 972 Time remaining: 1s Progress 622 / 972 Time remaining: 1s Progress 623 / 972 Time remaining: 1s Progress 624 / 972 Time remaining: 1s Progress 625 / 972 Time remaining: 1s Progress 626 / 972 Time remaining: 1s Progress 627 / 972 Time remaining: 1s Progress 628 / 972 Time remaining: 1s Progress 629 / 972 Time remaining: 1s Progress 630 / 972 Time remaining: 1s Progress 631 / 972 Time remaining: 1s Progress 632 / 972 Time remaining: 1s Progress 633 / 972 Time remaining: 1s Progress 634 / 972 Time remaining: 1s Progress 635 / 972 Time remaining: 1s Progress 636 / 972 Time remaining: 1s Progress 637 / 972 Time remaining: 1s Progress 638 / 972 Time remaining: 1s Progress 639 / 972 Time remaining: 1s Progress 640 / 972 Time remaining: 1s Progress 641 / 972 Time remaining: 1s Progress 642 / 972 Time remaining: 1s Progress 643 / 972 Time remaining: 1s Progress 644 / 972 Time remaining: 1s Progress 645 / 972 Time remaining: 1s Progress 646 / 972 Time remaining: 1s Progress 647 / 972 Time remaining: 1s Progress 648 / 972 Time remaining: 1s Progress 649 / 972 Time remaining: 1s Progress 650 / 972 Time remaining: 1s Progress 651 / 972 Time remaining: 1s Progress 652 / 972 Time remaining: 1s Progress 653 / 972 Time remaining: 1s Progress 654 / 972 Time remaining: 1s Progress 655 / 972 Time remaining: 1s Progress 656 / 972 Time remaining: 1s Progress 657 / 972 Time remaining: 1s Progress 658 / 972 Time remaining: 1s Progress 659 / 972 Time remaining: 1s Progress 660 / 972 Time remaining: 1s Progress 661 / 972 Time remaining: 1s Progress 662 / 972 Time remaining: 1s Progress 663 / 972 Time remaining: 1s Progress 664 / 972 Time remaining: 1s Progress 665 / 972 Time remaining: 1s Progress 666 / 972 Time remaining: 1s Progress 667 / 972 Time remaining: 1s Progress 668 / 972 Time remaining: 1s Progress 669 / 972 Time remaining: 1s Progress 670 / 972 Time remaining: 1s Progress 671 / 972 Time remaining: 1s Progress 672 / 972 Time remaining: 1s Progress 673 / 972 Time remaining: 1s Progress 674 / 972 Time remaining: 1s Progress 675 / 972 Time remaining: 1s Progress 676 / 972 Time remaining: 1s Progress 677 / 972 Time remaining: 1s Progress 678 / 972 Time remaining: 1s Progress 679 / 972 Time remaining: 1s Progress 680 / 972 Time remaining: 1s Progress 681 / 972 Time remaining: 1s Progress 682 / 972 Time remaining: 1s Progress 683 / 972 Time remaining: 1s Progress 684 / 972 Time remaining: 1s Progress 685 / 972 Time remaining: 1s Progress 686 / 972 Time remaining: 1s Progress 687 / 972 Time remaining: 1s Progress 688 / 972 Time remaining: 1s Progress 689 / 972 Time remaining: 1s Progress 690 / 972 Time remaining: 1s Progress 691 / 972 Time remaining: 1s Progress 692 / 972 Time remaining: 1s Progress 693 / 972 Time remaining: 1s Progress 694 / 972 Time remaining: 1s Progress 695 / 972 Time remaining: 1s Progress 696 / 972 Time remaining: 1s Progress 697 / 972 Time remaining: 1s Progress 698 / 972 Time remaining: 1s Progress 699 / 972 Time remaining: 1s Progress 700 / 972 Time remaining: 1s Progress 701 / 972 Time remaining: 1s Progress 702 / 972 Time remaining: 1s Progress 703 / 972 Time remaining: 1s Progress 704 / 972 Time remaining: 1s Progress 705 / 972 Time remaining: 1s Progress 706 / 972 Time remaining: 1s Progress 707 / 972 Time remaining: 1s Progress 708 / 972 Time remaining: 1s Progress 709 / 972 Time remaining: 1s Progress 710 / 972 Time remaining: 1s Progress 711 / 972 Time remaining: 1s Progress 712 / 972 Time remaining: 1s Progress 713 / 972 Time remaining: 1s Progress 714 / 972 Time remaining: 1s Progress 715 / 972 Time remaining: 1s Progress 716 / 972 Time remaining: 1s Progress 717 / 972 Time remaining: 1s Progress 718 / 972 Time remaining: 1s Progress 719 / 972 Time remaining: 1s Progress 720 / 972 Time remaining: 1s Progress 721 / 972 Time remaining: 1s Progress 722 / 972 Time remaining: 1s Progress 723 / 972 Time remaining: 1s Progress 724 / 972 Time remaining: 1s Progress 725 / 972 Time remaining: 1s Progress 726 / 972 Time remaining: 1s Progress 727 / 972 Time remaining: 1s Progress 728 / 972 Time remaining: 1s Progress 729 / 972 Time remaining: 1s Progress 730 / 972 Time remaining: 1s Progress 731 / 972 Time remaining: 1s Progress 732 / 972 Time remaining: 1s Progress 733 / 972 Time remaining: 1s Progress 734 / 972 Time remaining: 1s Progress 735 / 972 Time remaining: 1s Progress 736 / 972 Time remaining: 1s Progress 737 / 972 Time remaining: 1s Progress 738 / 972 Time remaining: 1s Progress 739 / 972 Time remaining: 0s Progress 740 / 972 Time remaining: 0s Progress 741 / 972 Time remaining: 0s Progress 742 / 972 Time remaining: 0s Progress 743 / 972 Time remaining: 0s Progress 744 / 972 Time remaining: 0s Progress 745 / 972 Time remaining: 0s Progress 746 / 972 Time remaining: 0s Progress 747 / 972 Time remaining: 0s Progress 748 / 972 Time remaining: 0s Progress 749 / 972 Time remaining: 0s Progress 750 / 972 Time remaining: 0s Progress 751 / 972 Time remaining: 0s Progress 752 / 972 Time remaining: 0s Progress 753 / 972 Time remaining: 0s Progress 754 / 972 Time remaining: 0s Progress 755 / 972 Time remaining: 0s Progress 756 / 972 Time remaining: 0s Progress 757 / 972 Time remaining: 0s Progress 758 / 972 Time remaining: 0s Progress 759 / 972 Time remaining: 0s Progress 760 / 972 Time remaining: 0s Progress 761 / 972 Time remaining: 0s Progress 762 / 972 Time remaining: 0s Progress 763 / 972 Time remaining: 0s Progress 764 / 972 Time remaining: 0s Progress 765 / 972 Time remaining: 0s Progress 766 / 972 Time remaining: 0s Progress 767 / 972 Time remaining: 0s Progress 768 / 972 Time remaining: 0s Progress 769 / 972 Time remaining: 0s Progress 770 / 972 Time remaining: 0s Progress 771 / 972 Time remaining: 0s Progress 772 / 972 Time remaining: 0s Progress 773 / 972 Time remaining: 0s Progress 774 / 972 Time remaining: 0s Progress 775 / 972 Time remaining: 0s Progress 776 / 972 Time remaining: 0s Progress 777 / 972 Time remaining: 0s Progress 778 / 972 Time remaining: 0s Progress 779 / 972 Time remaining: 0s Progress 780 / 972 Time remaining: 0s Progress 781 / 972 Time remaining: 0s Progress 782 / 972 Time remaining: 0s Progress 783 / 972 Time remaining: 0s Progress 784 / 972 Time remaining: 0s Progress 785 / 972 Time remaining: 0s Progress 786 / 972 Time remaining: 0s Progress 787 / 972 Time remaining: 0s Progress 788 / 972 Time remaining: 0s Progress 789 / 972 Time remaining: 0s Progress 790 / 972 Time remaining: 0s Progress 791 / 972 Time remaining: 0s Progress 792 / 972 Time remaining: 0s Progress 793 / 972 Time remaining: 0s Progress 794 / 972 Time remaining: 0s Progress 795 / 972 Time remaining: 0s Progress 796 / 972 Time remaining: 0s Progress 797 / 972 Time remaining: 0s Progress 798 / 972 Time remaining: 0s Progress 799 / 972 Time remaining: 0s Progress 800 / 972 Time remaining: 0s Progress 801 / 972 Time remaining: 0s Progress 802 / 972 Time remaining: 0s Progress 803 / 972 Time remaining: 0s Progress 804 / 972 Time remaining: 0s Progress 805 / 972 Time remaining: 0s Progress 806 / 972 Time remaining: 0s Progress 807 / 972 Time remaining: 0s Progress 808 / 972 Time remaining: 0s Progress 809 / 972 Time remaining: 0s Progress 810 / 972 Time remaining: 0s Progress 811 / 972 Time remaining: 0s Progress 812 / 972 Time remaining: 0s Progress 813 / 972 Time remaining: 0s Progress 814 / 972 Time remaining: 0s Progress 815 / 972 Time remaining: 0s Progress 816 / 972 Time remaining: 0s Progress 817 / 972 Time remaining: 0s Progress 818 / 972 Time remaining: 0s Progress 819 / 972 Time remaining: 0s Progress 820 / 972 Time remaining: 0s Progress 821 / 972 Time remaining: 0s Progress 822 / 972 Time remaining: 0s Progress 823 / 972 Time remaining: 0s Progress 824 / 972 Time remaining: 0s Progress 825 / 972 Time remaining: 0s Progress 826 / 972 Time remaining: 0s Progress 827 / 972 Time remaining: 0s Progress 828 / 972 Time remaining: 0s Progress 829 / 972 Time remaining: 0s Progress 830 / 972 Time remaining: 0s Progress 831 / 972 Time remaining: 0s Progress 832 / 972 Time remaining: 0s Progress 833 / 972 Time remaining: 0s Progress 834 / 972 Time remaining: 0s Progress 835 / 972 Time remaining: 0s Progress 836 / 972 Time remaining: 0s Progress 837 / 972 Time remaining: 0s Progress 838 / 972 Time remaining: 0s Progress 839 / 972 Time remaining: 0s Progress 840 / 972 Time remaining: 0s Progress 841 / 972 Time remaining: 0s Progress 842 / 972 Time remaining: 0s Progress 843 / 972 Time remaining: 0s Progress 844 / 972 Time remaining: 0s Progress 845 / 972 Time remaining: 0s Progress 846 / 972 Time remaining: 0s Progress 847 / 972 Time remaining: 0s Progress 848 / 972 Time remaining: 0s Progress 849 / 972 Time remaining: 0s Progress 850 / 972 Time remaining: 0s Progress 851 / 972 Time remaining: 0s Progress 852 / 972 Time remaining: 0s Progress 853 / 972 Time remaining: 0s Progress 854 / 972 Time remaining: 0s Progress 855 / 972 Time remaining: 0s Progress 856 / 972 Time remaining: 0s Progress 857 / 972 Time remaining: 0s Progress 858 / 972 Time remaining: 0s Progress 859 / 972 Time remaining: 0s Progress 860 / 972 Time remaining: 0s Progress 861 / 972 Time remaining: 0s Progress 862 / 972 Time remaining: 0s Progress 863 / 972 Time remaining: 0s Progress 864 / 972 Time remaining: 0s Progress 865 / 972 Time remaining: 0s Progress 866 / 972 Time remaining: 0s Progress 867 / 972 Time remaining: 0s Progress 868 / 972 Time remaining: 0s Progress 869 / 972 Time remaining: 0s Progress 870 / 972 Time remaining: 0s Progress 871 / 972 Time remaining: 0s Progress 872 / 972 Time remaining: 0s Progress 873 / 972 Time remaining: 0s Progress 874 / 972 Time remaining: 0s Progress 875 / 972 Time remaining: 0s Progress 876 / 972 Time remaining: 0s Progress 877 / 972 Time remaining: 0s Progress 878 / 972 Time remaining: 0s Progress 879 / 972 Time remaining: 0s Progress 880 / 972 Time remaining: 0s Progress 881 / 972 Time remaining: 0s Progress 882 / 972 Time remaining: 0s Progress 883 / 972 Time remaining: 0s Progress 884 / 972 Time remaining: 0s Progress 885 / 972 Time remaining: 0s Progress 886 / 972 Time remaining: 0s Progress 887 / 972 Time remaining: 0s Progress 888 / 972 Time remaining: 0s Progress 889 / 972 Time remaining: 0s Progress 890 / 972 Time remaining: 0s Progress 891 / 972 Time remaining: 0s Progress 892 / 972 Time remaining: 0s Progress 893 / 972 Time remaining: 0s Progress 894 / 972 Time remaining: 0s Progress 895 / 972 Time remaining: 0s Progress 896 / 972 Time remaining: 0s Progress 897 / 972 Time remaining: 0s Progress 898 / 972 Time remaining: 0s Progress 899 / 972 Time remaining: 0s Progress 900 / 972 Time remaining: 0s Progress 901 / 972 Time remaining: 0s Progress 902 / 972 Time remaining: 0s Progress 903 / 972 Time remaining: 0s Progress 904 / 972 Time remaining: 0s Progress 905 / 972 Time remaining: 0s Progress 906 / 972 Time remaining: 0s Progress 907 / 972 Time remaining: 0s Progress 908 / 972 Time remaining: 0s Progress 909 / 972 Time remaining: 0s Progress 910 / 972 Time remaining: 0s Progress 911 / 972 Time remaining: 0s Progress 912 / 972 Time remaining: 0s Progress 913 / 972 Time remaining: 0s Progress 914 / 972 Time remaining: 0s Progress 915 / 972 Time remaining: 0s Progress 916 / 972 Time remaining: 0s Progress 917 / 972 Time remaining: 0s Progress 918 / 972 Time remaining: 0s Progress 919 / 972 Time remaining: 0s Progress 920 / 972 Time remaining: 0s Progress 921 / 972 Time remaining: 0s Progress 922 / 972 Time remaining: 0s Progress 923 / 972 Time remaining: 0s Progress 924 / 972 Time remaining: 0s Progress 925 / 972 Time remaining: 0s Progress 926 / 972 Time remaining: 0s Progress 927 / 972 Time remaining: 0s Progress 928 / 972 Time remaining: 0s Progress 929 / 972 Time remaining: 0s Progress 930 / 972 Time remaining: 0s Progress 931 / 972 Time remaining: 0s Progress 932 / 972 Time remaining: 0s Progress 933 / 972 Time remaining: 0s Progress 934 / 972 Time remaining: 0s Progress 935 / 972 Time remaining: 0s Progress 936 / 972 Time remaining: 0s Progress 937 / 972 Time remaining: 0s Progress 938 / 972 Time remaining: 0s Progress 939 / 972 Time remaining: 0s Progress 940 / 972 Time remaining: 0s Progress 941 / 972 Time remaining: 0s Progress 942 / 972 Time remaining: 0s Progress 943 / 972 Time remaining: 0s Progress 944 / 972 Time remaining: 0s Progress 945 / 972 Time remaining: 0s Progress 946 / 972 Time remaining: 0s Progress 947 / 972 Time remaining: 0s Progress 948 / 972 Time remaining: 0s Progress 949 / 972 Time remaining: 0s Progress 950 / 972 Time remaining: 0s Progress 951 / 972 Time remaining: 0s Progress 952 / 972 Time remaining: 0s Progress 953 / 972 Time remaining: 0s Progress 954 / 972 Time remaining: 0s Progress 955 / 972 Time remaining: 0s Progress 956 / 972 Time remaining: 0s Progress 957 / 972 Time remaining: 0s Progress 958 / 972 Time remaining: 0s Progress 959 / 972 Time remaining: 0s Progress 960 / 972 Time remaining: 0s Progress 961 / 972 Time remaining: 0s Progress 962 / 972 Time remaining: 0s Progress 963 / 972 Time remaining: 0s Progress 964 / 972 Time remaining: 0s Progress 965 / 972 Time remaining: 0s Progress 966 / 972 Time remaining: 0s Progress 967 / 972 Time remaining: 0s Progress 968 / 972 Time remaining: 0s Progress 969 / 972 Time remaining: 0s Progress 970 / 972 Time remaining: 0s Progress 971 / 972 Time remaining: 0s Progress 972 / 972 Time remaining: Added 972 camera error terms + +Adding accelerometer error terms (/imu0) + Progress 1 / 9694 Time remaining: 3s Progress 2 / 9694 Time remaining: 3s Progress 3 / 9694 Time remaining: 3s Progress 4 / 9694 Time remaining: 4s Progress 5 / 9694 Time remaining: 5s Progress 6 / 9694 Time remaining: 5s Progress 7 / 9694 Time remaining: 5s Progress 8 / 9694 Time remaining: 5s Progress 9 / 9694 Time remaining: 5s Progress 10 / 9694 Time remaining: 6s Progress 11 / 9694 Time remaining: 6s Progress 12 / 9694 Time remaining: 6s Progress 13 / 9694 Time remaining: 6s Progress 14 / 9694 Time remaining: 6s Progress 15 / 9694 Time remaining: 6s Progress 16 / 9694 Time remaining: 6s Progress 17 / 9694 Time remaining: 6s Progress 18 / 9694 Time remaining: 6s Progress 19 / 9694 Time remaining: 6s Progress 20 / 9694 Time remaining: 6s Progress 21 / 9694 Time remaining: 6s Progress 22 / 9694 Time remaining: 6s Progress 23 / 9694 Time remaining: 6s Progress 24 / 9694 Time remaining: 6s Progress 25 / 9694 Time remaining: 6s Progress 26 / 9694 Time remaining: 6s Progress 27 / 9694 Time remaining: 6s Progress 28 / 9694 Time remaining: 6s Progress 29 / 9694 Time remaining: 6s Progress 30 / 9694 Time remaining: 6s Progress 31 / 9694 Time remaining: 6s Progress 32 / 9694 Time remaining: 6s Progress 33 / 9694 Time remaining: 6s Progress 34 / 9694 Time remaining: 6s Progress 35 / 9694 Time remaining: 6s Progress 36 / 9694 Time remaining: 6s Progress 37 / 9694 Time remaining: 6s Progress 38 / 9694 Time remaining: 6s Progress 39 / 9694 Time remaining: 6s Progress 40 / 9694 Time remaining: 6s Progress 41 / 9694 Time remaining: 6s Progress 42 / 9694 Time remaining: 6s Progress 43 / 9694 Time remaining: 6s Progress 44 / 9694 Time remaining: 6s Progress 45 / 9694 Time remaining: 6s Progress 46 / 9694 Time remaining: 6s Progress 47 / 9694 Time remaining: 6s Progress 48 / 9694 Time remaining: 6s Progress 49 / 9694 Time remaining: 6s Progress 50 / 9694 Time remaining: 6s Progress 51 / 9694 Time remaining: 6s Progress 52 / 9694 Time remaining: 6s Progress 53 / 9694 Time remaining: 6s Progress 54 / 9694 Time remaining: 6s Progress 55 / 9694 Time remaining: 6s Progress 56 / 9694 Time remaining: 6s Progress 57 / 9694 Time remaining: 6s Progress 58 / 9694 Time remaining: 6s Progress 59 / 9694 Time remaining: 6s Progress 60 / 9694 Time remaining: 6s Progress 61 / 9694 Time remaining: 6s Progress 62 / 9694 Time remaining: 6s Progress 63 / 9694 Time remaining: 6s Progress 64 / 9694 Time remaining: 6s Progress 65 / 9694 Time remaining: 6s Progress 66 / 9694 Time remaining: 6s Progress 67 / 9694 Time remaining: 6s Progress 68 / 9694 Time remaining: 6s Progress 69 / 9694 Time remaining: 6s Progress 70 / 9694 Time remaining: 6s Progress 71 / 9694 Time remaining: 6s Progress 72 / 9694 Time remaining: 6s Progress 73 / 9694 Time remaining: 6s Progress 74 / 9694 Time remaining: 6s Progress 75 / 9694 Time remaining: 6s Progress 76 / 9694 Time remaining: 6s Progress 77 / 9694 Time remaining: 6s Progress 78 / 9694 Time remaining: 6s Progress 79 / 9694 Time remaining: 6s Progress 80 / 9694 Time remaining: 6s Progress 81 / 9694 Time remaining: 6s Progress 82 / 9694 Time remaining: 6s Progress 83 / 9694 Time remaining: 6s Progress 84 / 9694 Time remaining: 6s Progress 85 / 9694 Time remaining: 6s Progress 86 / 9694 Time remaining: 6s Progress 87 / 9694 Time remaining: 6s Progress 88 / 9694 Time remaining: 6s Progress 89 / 9694 Time remaining: 6s Progress 90 / 9694 Time remaining: 6s Progress 91 / 9694 Time remaining: 6s Progress 92 / 9694 Time remaining: 6s Progress 93 / 9694 Time remaining: 6s Progress 94 / 9694 Time remaining: 6s Progress 95 / 9694 Time remaining: 6s Progress 96 / 9694 Time remaining: 6s Progress 97 / 9694 Time remaining: 6s Progress 98 / 9694 Time remaining: 6s Progress 99 / 9694 Time remaining: 6s Progress 100 / 9694 Time remaining: 6s Progress 101 / 9694 Time remaining: 6s Progress 102 / 9694 Time remaining: 6s Progress 103 / 9694 Time remaining: 6s Progress 104 / 9694 Time remaining: 6s Progress 105 / 9694 Time remaining: 6s Progress 106 / 9694 Time remaining: 6s Progress 107 / 9694 Time remaining: 6s Progress 108 / 9694 Time remaining: 6s Progress 109 / 9694 Time remaining: 6s Progress 110 / 9694 Time remaining: 6s Progress 111 / 9694 Time remaining: 6s Progress 112 / 9694 Time remaining: 6s Progress 113 / 9694 Time remaining: 6s Progress 114 / 9694 Time remaining: 6s Progress 115 / 9694 Time remaining: 6s Progress 116 / 9694 Time remaining: 6s Progress 117 / 9694 Time remaining: 6s Progress 118 / 9694 Time remaining: 6s Progress 119 / 9694 Time remaining: 6s Progress 120 / 9694 Time remaining: 6s Progress 121 / 9694 Time remaining: 6s Progress 122 / 9694 Time remaining: 6s Progress 123 / 9694 Time remaining: 6s Progress 124 / 9694 Time remaining: 6s Progress 125 / 9694 Time remaining: 6s Progress 126 / 9694 Time remaining: 6s Progress 127 / 9694 Time remaining: 6s Progress 128 / 9694 Time remaining: 6s Progress 129 / 9694 Time remaining: 6s Progress 130 / 9694 Time remaining: 6s Progress 131 / 9694 Time remaining: 6s Progress 132 / 9694 Time remaining: 6s Progress 133 / 9694 Time remaining: 6s Progress 134 / 9694 Time remaining: 6s Progress 135 / 9694 Time remaining: 6s Progress 136 / 9694 Time remaining: 6s Progress 137 / 9694 Time remaining: 6s Progress 138 / 9694 Time remaining: 6s Progress 139 / 9694 Time remaining: 6s Progress 140 / 9694 Time remaining: 6s Progress 141 / 9694 Time remaining: 6s Progress 142 / 9694 Time remaining: 6s Progress 143 / 9694 Time remaining: 6s Progress 144 / 9694 Time remaining: 6s Progress 145 / 9694 Time remaining: 6s Progress 146 / 9694 Time remaining: 6s Progress 147 / 9694 Time remaining: 6s Progress 148 / 9694 Time remaining: 6s Progress 149 / 9694 Time remaining: 6s Progress 150 / 9694 Time remaining: 6s Progress 151 / 9694 Time remaining: 6s Progress 152 / 9694 Time remaining: 6s Progress 153 / 9694 Time remaining: 6s Progress 154 / 9694 Time remaining: 6s Progress 155 / 9694 Time remaining: 6s Progress 156 / 9694 Time remaining: 6s Progress 157 / 9694 Time remaining: 6s Progress 158 / 9694 Time remaining: 6s Progress 159 / 9694 Time remaining: 6s Progress 160 / 9694 Time remaining: 6s Progress 161 / 9694 Time remaining: 6s Progress 162 / 9694 Time remaining: 6s Progress 163 / 9694 Time remaining: 6s Progress 164 / 9694 Time remaining: 6s Progress 165 / 9694 Time remaining: 6s Progress 166 / 9694 Time remaining: 6s Progress 167 / 9694 Time remaining: 6s Progress 168 / 9694 Time remaining: 6s Progress 169 / 9694 Time remaining: 6s Progress 170 / 9694 Time remaining: 6s Progress 171 / 9694 Time remaining: 6s Progress 172 / 9694 Time remaining: 6s Progress 173 / 9694 Time remaining: 6s Progress 174 / 9694 Time remaining: 6s Progress 175 / 9694 Time remaining: 6s Progress 176 / 9694 Time remaining: 6s Progress 177 / 9694 Time remaining: 6s Progress 178 / 9694 Time remaining: 6s Progress 179 / 9694 Time remaining: 6s Progress 180 / 9694 Time remaining: 6s Progress 181 / 9694 Time remaining: 6s Progress 182 / 9694 Time remaining: 6s Progress 183 / 9694 Time remaining: 6s Progress 184 / 9694 Time remaining: 6s Progress 185 / 9694 Time remaining: 6s Progress 186 / 9694 Time remaining: 6s Progress 187 / 9694 Time remaining: 6s Progress 188 / 9694 Time remaining: 6s Progress 189 / 9694 Time remaining: 6s Progress 190 / 9694 Time remaining: 6s Progress 191 / 9694 Time remaining: 6s Progress 192 / 9694 Time remaining: 6s Progress 193 / 9694 Time remaining: 6s Progress 194 / 9694 Time remaining: 6s Progress 195 / 9694 Time remaining: 6s Progress 196 / 9694 Time remaining: 6s Progress 197 / 9694 Time remaining: 6s Progress 198 / 9694 Time remaining: 6s Progress 199 / 9694 Time remaining: 6s Progress 200 / 9694 Time remaining: 6s Progress 201 / 9694 Time remaining: 6s Progress 202 / 9694 Time remaining: 6s Progress 203 / 9694 Time remaining: 6s Progress 204 / 9694 Time remaining: 6s Progress 205 / 9694 Time remaining: 6s Progress 206 / 9694 Time remaining: 6s Progress 207 / 9694 Time remaining: 6s Progress 208 / 9694 Time remaining: 6s Progress 209 / 9694 Time remaining: 6s Progress 210 / 9694 Time remaining: 6s Progress 211 / 9694 Time remaining: 6s Progress 212 / 9694 Time remaining: 6s Progress 213 / 9694 Time remaining: 6s Progress 214 / 9694 Time remaining: 6s Progress 215 / 9694 Time remaining: 6s Progress 216 / 9694 Time remaining: 6s Progress 217 / 9694 Time remaining: 6s Progress 218 / 9694 Time remaining: 6s Progress 219 / 9694 Time remaining: 6s Progress 220 / 9694 Time remaining: 6s Progress 221 / 9694 Time remaining: 6s Progress 222 / 9694 Time remaining: 6s Progress 223 / 9694 Time remaining: 6s Progress 224 / 9694 Time remaining: 6s Progress 225 / 9694 Time remaining: 6s Progress 226 / 9694 Time remaining: 6s Progress 227 / 9694 Time remaining: 6s Progress 228 / 9694 Time remaining: 6s Progress 229 / 9694 Time remaining: 6s Progress 230 / 9694 Time remaining: 6s Progress 231 / 9694 Time remaining: 6s Progress 232 / 9694 Time remaining: 6s Progress 233 / 9694 Time remaining: 6s Progress 234 / 9694 Time remaining: 6s Progress 235 / 9694 Time remaining: 6s Progress 236 / 9694 Time remaining: 6s Progress 237 / 9694 Time remaining: 6s Progress 238 / 9694 Time remaining: 6s Progress 239 / 9694 Time remaining: 6s Progress 240 / 9694 Time remaining: 6s Progress 241 / 9694 Time remaining: 6s Progress 242 / 9694 Time remaining: 6s Progress 243 / 9694 Time remaining: 6s Progress 244 / 9694 Time remaining: 6s Progress 245 / 9694 Time remaining: 6s Progress 246 / 9694 Time remaining: 6s Progress 247 / 9694 Time remaining: 6s Progress 248 / 9694 Time remaining: 6s Progress 249 / 9694 Time remaining: 6s Progress 250 / 9694 Time remaining: 6s Progress 251 / 9694 Time remaining: 6s Progress 252 / 9694 Time remaining: 6s Progress 253 / 9694 Time remaining: 6s Progress 254 / 9694 Time remaining: 6s Progress 255 / 9694 Time remaining: 6s Progress 256 / 9694 Time remaining: 6s Progress 257 / 9694 Time remaining: 6s Progress 258 / 9694 Time remaining: 6s Progress 259 / 9694 Time remaining: 6s Progress 260 / 9694 Time remaining: 6s Progress 261 / 9694 Time remaining: 6s Progress 262 / 9694 Time remaining: 6s Progress 263 / 9694 Time remaining: 6s Progress 264 / 9694 Time remaining: 6s Progress 265 / 9694 Time remaining: 6s Progress 266 / 9694 Time remaining: 6s Progress 267 / 9694 Time remaining: 6s Progress 268 / 9694 Time remaining: 6s Progress 269 / 9694 Time remaining: 6s Progress 270 / 9694 Time remaining: 6s Progress 271 / 9694 Time remaining: 6s Progress 272 / 9694 Time remaining: 6s Progress 273 / 9694 Time remaining: 6s Progress 274 / 9694 Time remaining: 6s Progress 275 / 9694 Time remaining: 6s Progress 276 / 9694 Time remaining: 6s Progress 277 / 9694 Time remaining: 6s Progress 278 / 9694 Time remaining: 6s Progress 279 / 9694 Time remaining: 6s Progress 280 / 9694 Time remaining: 6s Progress 281 / 9694 Time remaining: 6s Progress 282 / 9694 Time remaining: 6s Progress 283 / 9694 Time remaining: 6s Progress 284 / 9694 Time remaining: 6s Progress 285 / 9694 Time remaining: 6s Progress 286 / 9694 Time remaining: 6s Progress 287 / 9694 Time remaining: 6s Progress 288 / 9694 Time remaining: 6s Progress 289 / 9694 Time remaining: 6s Progress 290 / 9694 Time remaining: 6s Progress 291 / 9694 Time remaining: 6s Progress 292 / 9694 Time remaining: 6s Progress 293 / 9694 Time remaining: 6s Progress 294 / 9694 Time remaining: 6s Progress 295 / 9694 Time remaining: 6s Progress 296 / 9694 Time remaining: 6s Progress 297 / 9694 Time remaining: 6s Progress 298 / 9694 Time remaining: 6s Progress 299 / 9694 Time remaining: 6s Progress 300 / 9694 Time remaining: 6s Progress 301 / 9694 Time remaining: 6s Progress 302 / 9694 Time remaining: 6s Progress 303 / 9694 Time remaining: 6s Progress 304 / 9694 Time remaining: 6s Progress 305 / 9694 Time remaining: 6s Progress 306 / 9694 Time remaining: 6s Progress 307 / 9694 Time remaining: 6s Progress 308 / 9694 Time remaining: 6s Progress 309 / 9694 Time remaining: 6s Progress 310 / 9694 Time remaining: 6s Progress 311 / 9694 Time remaining: 6s Progress 312 / 9694 Time remaining: 6s Progress 313 / 9694 Time remaining: 6s Progress 314 / 9694 Time remaining: 6s Progress 315 / 9694 Time remaining: 6s Progress 316 / 9694 Time remaining: 6s Progress 317 / 9694 Time remaining: 6s Progress 318 / 9694 Time remaining: 6s Progress 319 / 9694 Time remaining: 6s Progress 320 / 9694 Time remaining: 6s Progress 321 / 9694 Time remaining: 6s Progress 322 / 9694 Time remaining: 6s Progress 323 / 9694 Time remaining: 6s Progress 324 / 9694 Time remaining: 6s Progress 325 / 9694 Time remaining: 6s Progress 326 / 9694 Time remaining: 6s Progress 327 / 9694 Time remaining: 6s Progress 328 / 9694 Time remaining: 6s Progress 329 / 9694 Time remaining: 6s Progress 330 / 9694 Time remaining: 6s Progress 331 / 9694 Time remaining: 6s Progress 332 / 9694 Time remaining: 6s Progress 333 / 9694 Time remaining: 6s Progress 334 / 9694 Time remaining: 6s Progress 335 / 9694 Time remaining: 6s Progress 336 / 9694 Time remaining: 6s Progress 337 / 9694 Time remaining: 6s Progress 338 / 9694 Time remaining: 6s Progress 339 / 9694 Time remaining: 6s Progress 340 / 9694 Time remaining: 6s Progress 341 / 9694 Time remaining: 6s Progress 342 / 9694 Time remaining: 6s Progress 343 / 9694 Time remaining: 6s Progress 344 / 9694 Time remaining: 6s Progress 345 / 9694 Time remaining: 6s Progress 346 / 9694 Time remaining: 6s Progress 347 / 9694 Time remaining: 6s Progress 348 / 9694 Time remaining: 6s Progress 349 / 9694 Time remaining: 6s Progress 350 / 9694 Time remaining: 6s Progress 351 / 9694 Time remaining: 6s Progress 352 / 9694 Time remaining: 6s Progress 353 / 9694 Time remaining: 6s Progress 354 / 9694 Time remaining: 6s Progress 355 / 9694 Time remaining: 6s Progress 356 / 9694 Time remaining: 6s Progress 357 / 9694 Time remaining: 6s Progress 358 / 9694 Time remaining: 6s Progress 359 / 9694 Time remaining: 6s Progress 360 / 9694 Time remaining: 6s Progress 361 / 9694 Time remaining: 6s Progress 362 / 9694 Time remaining: 6s Progress 363 / 9694 Time remaining: 6s Progress 364 / 9694 Time remaining: 6s Progress 365 / 9694 Time remaining: 6s Progress 366 / 9694 Time remaining: 6s Progress 367 / 9694 Time remaining: 6s Progress 368 / 9694 Time remaining: 6s Progress 369 / 9694 Time remaining: 6s Progress 370 / 9694 Time remaining: 6s Progress 371 / 9694 Time remaining: 6s Progress 372 / 9694 Time remaining: 6s Progress 373 / 9694 Time remaining: 6s Progress 374 / 9694 Time remaining: 6s Progress 375 / 9694 Time remaining: 6s Progress 376 / 9694 Time remaining: 6s Progress 377 / 9694 Time remaining: 6s Progress 378 / 9694 Time remaining: 6s Progress 379 / 9694 Time remaining: 6s Progress 380 / 9694 Time remaining: 6s Progress 381 / 9694 Time remaining: 6s Progress 382 / 9694 Time remaining: 6s Progress 383 / 9694 Time remaining: 6s Progress 384 / 9694 Time remaining: 6s Progress 385 / 9694 Time remaining: 6s Progress 386 / 9694 Time remaining: 6s Progress 387 / 9694 Time remaining: 6s Progress 388 / 9694 Time remaining: 6s Progress 389 / 9694 Time remaining: 6s Progress 390 / 9694 Time remaining: 6s Progress 391 / 9694 Time remaining: 6s Progress 392 / 9694 Time remaining: 6s Progress 393 / 9694 Time remaining: 6s Progress 394 / 9694 Time remaining: 6s Progress 395 / 9694 Time remaining: 6s Progress 396 / 9694 Time remaining: 6s Progress 397 / 9694 Time remaining: 6s Progress 398 / 9694 Time remaining: 6s Progress 399 / 9694 Time remaining: 6s Progress 400 / 9694 Time remaining: 6s Progress 401 / 9694 Time remaining: 6s Progress 402 / 9694 Time remaining: 6s Progress 403 / 9694 Time remaining: 6s Progress 404 / 9694 Time remaining: 6s Progress 405 / 9694 Time remaining: 6s Progress 406 / 9694 Time remaining: 6s Progress 407 / 9694 Time remaining: 6s Progress 408 / 9694 Time remaining: 6s Progress 409 / 9694 Time remaining: 6s Progress 410 / 9694 Time remaining: 6s Progress 411 / 9694 Time remaining: 6s Progress 412 / 9694 Time remaining: 6s Progress 413 / 9694 Time remaining: 6s Progress 414 / 9694 Time remaining: 6s Progress 415 / 9694 Time remaining: 6s Progress 416 / 9694 Time remaining: 6s Progress 417 / 9694 Time remaining: 6s Progress 418 / 9694 Time remaining: 6s Progress 419 / 9694 Time remaining: 6s Progress 420 / 9694 Time remaining: 6s Progress 421 / 9694 Time remaining: 6s Progress 422 / 9694 Time remaining: 6s Progress 423 / 9694 Time remaining: 6s Progress 424 / 9694 Time remaining: 6s Progress 425 / 9694 Time remaining: 6s Progress 426 / 9694 Time remaining: 6s Progress 427 / 9694 Time remaining: 6s Progress 428 / 9694 Time remaining: 6s Progress 429 / 9694 Time remaining: 6s Progress 430 / 9694 Time remaining: 6s Progress 431 / 9694 Time remaining: 6s Progress 432 / 9694 Time remaining: 6s Progress 433 / 9694 Time remaining: 6s Progress 434 / 9694 Time remaining: 6s Progress 435 / 9694 Time remaining: 6s Progress 436 / 9694 Time remaining: 6s Progress 437 / 9694 Time remaining: 6s Progress 438 / 9694 Time remaining: 6s Progress 439 / 9694 Time remaining: 6s Progress 440 / 9694 Time remaining: 6s Progress 441 / 9694 Time remaining: 6s Progress 442 / 9694 Time remaining: 6s Progress 443 / 9694 Time remaining: 6s Progress 444 / 9694 Time remaining: 6s Progress 445 / 9694 Time remaining: 6s Progress 446 / 9694 Time remaining: 6s Progress 447 / 9694 Time remaining: 6s Progress 448 / 9694 Time remaining: 6s Progress 449 / 9694 Time remaining: 6s Progress 450 / 9694 Time remaining: 6s Progress 451 / 9694 Time remaining: 6s Progress 452 / 9694 Time remaining: 6s Progress 453 / 9694 Time remaining: 6s Progress 454 / 9694 Time remaining: 6s Progress 455 / 9694 Time remaining: 6s Progress 456 / 9694 Time remaining: 6s Progress 457 / 9694 Time remaining: 6s Progress 458 / 9694 Time remaining: 6s Progress 459 / 9694 Time remaining: 6s Progress 460 / 9694 Time remaining: 6s Progress 461 / 9694 Time remaining: 6s Progress 462 / 9694 Time remaining: 6s Progress 463 / 9694 Time remaining: 6s Progress 464 / 9694 Time remaining: 6s Progress 465 / 9694 Time remaining: 6s Progress 466 / 9694 Time remaining: 6s Progress 467 / 9694 Time remaining: 6s Progress 468 / 9694 Time remaining: 6s Progress 469 / 9694 Time remaining: 6s Progress 470 / 9694 Time remaining: 6s Progress 471 / 9694 Time remaining: 6s Progress 472 / 9694 Time remaining: 6s Progress 473 / 9694 Time remaining: 6s Progress 474 / 9694 Time remaining: 6s Progress 475 / 9694 Time remaining: 6s Progress 476 / 9694 Time remaining: 6s Progress 477 / 9694 Time remaining: 6s Progress 478 / 9694 Time remaining: 6s Progress 479 / 9694 Time remaining: 6s Progress 480 / 9694 Time remaining: 6s Progress 481 / 9694 Time remaining: 6s Progress 482 / 9694 Time remaining: 6s Progress 483 / 9694 Time remaining: 6s Progress 484 / 9694 Time remaining: 6s Progress 485 / 9694 Time remaining: 6s Progress 486 / 9694 Time remaining: 6s Progress 487 / 9694 Time remaining: 6s Progress 488 / 9694 Time remaining: 6s Progress 489 / 9694 Time remaining: 6s Progress 490 / 9694 Time remaining: 6s Progress 491 / 9694 Time remaining: 6s Progress 492 / 9694 Time remaining: 6s Progress 493 / 9694 Time remaining: 6s Progress 494 / 9694 Time remaining: 6s Progress 495 / 9694 Time remaining: 6s Progress 496 / 9694 Time remaining: 6s Progress 497 / 9694 Time remaining: 6s Progress 498 / 9694 Time remaining: 6s Progress 499 / 9694 Time remaining: 6s Progress 500 / 9694 Time remaining: 6s Progress 501 / 9694 Time remaining: 6s Progress 502 / 9694 Time remaining: 6s Progress 503 / 9694 Time remaining: 6s Progress 504 / 9694 Time remaining: 6s Progress 505 / 9694 Time remaining: 6s Progress 506 / 9694 Time remaining: 6s Progress 507 / 9694 Time remaining: 6s Progress 508 / 9694 Time remaining: 6s Progress 509 / 9694 Time remaining: 6s Progress 510 / 9694 Time remaining: 6s Progress 511 / 9694 Time remaining: 6s Progress 512 / 9694 Time remaining: 6s Progress 513 / 9694 Time remaining: 6s Progress 514 / 9694 Time remaining: 6s Progress 515 / 9694 Time remaining: 6s Progress 516 / 9694 Time remaining: 6s Progress 517 / 9694 Time remaining: 6s Progress 518 / 9694 Time remaining: 6s Progress 519 / 9694 Time remaining: 6s Progress 520 / 9694 Time remaining: 6s Progress 521 / 9694 Time remaining: 6s Progress 522 / 9694 Time remaining: 6s Progress 523 / 9694 Time remaining: 6s Progress 524 / 9694 Time remaining: 6s Progress 525 / 9694 Time remaining: 6s Progress 526 / 9694 Time remaining: 6s Progress 527 / 9694 Time remaining: 6s Progress 528 / 9694 Time remaining: 6s Progress 529 / 9694 Time remaining: 6s Progress 530 / 9694 Time remaining: 6s Progress 531 / 9694 Time remaining: 6s Progress 532 / 9694 Time remaining: 6s Progress 533 / 9694 Time remaining: 6s Progress 534 / 9694 Time remaining: 6s Progress 535 / 9694 Time remaining: 6s Progress 536 / 9694 Time remaining: 6s Progress 537 / 9694 Time remaining: 6s Progress 538 / 9694 Time remaining: 6s Progress 539 / 9694 Time remaining: 6s Progress 540 / 9694 Time remaining: 6s Progress 541 / 9694 Time remaining: 6s Progress 542 / 9694 Time remaining: 6s Progress 543 / 9694 Time remaining: 6s Progress 544 / 9694 Time remaining: 6s Progress 545 / 9694 Time remaining: 6s Progress 546 / 9694 Time remaining: 6s Progress 547 / 9694 Time remaining: 6s Progress 548 / 9694 Time remaining: 6s Progress 549 / 9694 Time remaining: 6s Progress 550 / 9694 Time remaining: 6s Progress 551 / 9694 Time remaining: 6s Progress 552 / 9694 Time remaining: 6s Progress 553 / 9694 Time remaining: 6s Progress 554 / 9694 Time remaining: 6s Progress 555 / 9694 Time remaining: 6s Progress 556 / 9694 Time remaining: 6s Progress 557 / 9694 Time remaining: 6s Progress 558 / 9694 Time remaining: 6s Progress 559 / 9694 Time remaining: 6s Progress 560 / 9694 Time remaining: 6s Progress 561 / 9694 Time remaining: 6s Progress 562 / 9694 Time remaining: 6s Progress 563 / 9694 Time remaining: 6s Progress 564 / 9694 Time remaining: 6s Progress 565 / 9694 Time remaining: 6s Progress 566 / 9694 Time remaining: 6s Progress 567 / 9694 Time remaining: 6s Progress 568 / 9694 Time remaining: 6s Progress 569 / 9694 Time remaining: 6s Progress 570 / 9694 Time remaining: 6s Progress 571 / 9694 Time remaining: 6s Progress 572 / 9694 Time remaining: 6s Progress 573 / 9694 Time remaining: 6s Progress 574 / 9694 Time remaining: 6s Progress 575 / 9694 Time remaining: 6s Progress 576 / 9694 Time remaining: 6s Progress 577 / 9694 Time remaining: 6s Progress 578 / 9694 Time remaining: 6s Progress 579 / 9694 Time remaining: 6s Progress 580 / 9694 Time remaining: 6s Progress 581 / 9694 Time remaining: 6s Progress 582 / 9694 Time remaining: 6s Progress 583 / 9694 Time remaining: 6s Progress 584 / 9694 Time remaining: 6s Progress 585 / 9694 Time remaining: 6s Progress 586 / 9694 Time remaining: 6s Progress 587 / 9694 Time remaining: 6s Progress 588 / 9694 Time remaining: 6s Progress 589 / 9694 Time remaining: 6s Progress 590 / 9694 Time remaining: 6s Progress 591 / 9694 Time remaining: 6s Progress 592 / 9694 Time remaining: 6s Progress 593 / 9694 Time remaining: 6s Progress 594 / 9694 Time remaining: 6s Progress 595 / 9694 Time remaining: 6s Progress 596 / 9694 Time remaining: 6s Progress 597 / 9694 Time remaining: 6s Progress 598 / 9694 Time remaining: 6s Progress 599 / 9694 Time remaining: 6s Progress 600 / 9694 Time remaining: 6s Progress 601 / 9694 Time remaining: 6s Progress 602 / 9694 Time remaining: 6s Progress 603 / 9694 Time remaining: 6s Progress 604 / 9694 Time remaining: 6s Progress 605 / 9694 Time remaining: 6s Progress 606 / 9694 Time remaining: 6s Progress 607 / 9694 Time remaining: 6s Progress 608 / 9694 Time remaining: 6s Progress 609 / 9694 Time remaining: 6s Progress 610 / 9694 Time remaining: 6s Progress 611 / 9694 Time remaining: 6s Progress 612 / 9694 Time remaining: 6s Progress 613 / 9694 Time remaining: 6s Progress 614 / 9694 Time remaining: 6s Progress 615 / 9694 Time remaining: 6s Progress 616 / 9694 Time remaining: 6s Progress 617 / 9694 Time remaining: 6s Progress 618 / 9694 Time remaining: 6s Progress 619 / 9694 Time remaining: 6s Progress 620 / 9694 Time remaining: 6s Progress 621 / 9694 Time remaining: 6s Progress 622 / 9694 Time remaining: 6s Progress 623 / 9694 Time remaining: 6s Progress 624 / 9694 Time remaining: 6s Progress 625 / 9694 Time remaining: 6s Progress 626 / 9694 Time remaining: 6s Progress 627 / 9694 Time remaining: 6s Progress 628 / 9694 Time remaining: 6s Progress 629 / 9694 Time remaining: 6s Progress 630 / 9694 Time remaining: 6s Progress 631 / 9694 Time remaining: 6s Progress 632 / 9694 Time remaining: 6s Progress 633 / 9694 Time remaining: 6s Progress 634 / 9694 Time remaining: 6s Progress 635 / 9694 Time remaining: 6s Progress 636 / 9694 Time remaining: 6s Progress 637 / 9694 Time remaining: 6s Progress 638 / 9694 Time remaining: 6s Progress 639 / 9694 Time remaining: 6s Progress 640 / 9694 Time remaining: 6s Progress 641 / 9694 Time remaining: 6s Progress 642 / 9694 Time remaining: 6s Progress 643 / 9694 Time remaining: 6s Progress 644 / 9694 Time remaining: 6s Progress 645 / 9694 Time remaining: 6s Progress 646 / 9694 Time remaining: 6s Progress 647 / 9694 Time remaining: 6s Progress 648 / 9694 Time remaining: 6s Progress 649 / 9694 Time remaining: 6s Progress 650 / 9694 Time remaining: 6s Progress 651 / 9694 Time remaining: 6s Progress 652 / 9694 Time remaining: 6s Progress 653 / 9694 Time remaining: 6s Progress 654 / 9694 Time remaining: 6s Progress 655 / 9694 Time remaining: 6s Progress 656 / 9694 Time remaining: 6s Progress 657 / 9694 Time remaining: 6s Progress 658 / 9694 Time remaining: 6s Progress 659 / 9694 Time remaining: 6s Progress 660 / 9694 Time remaining: 6s Progress 661 / 9694 Time remaining: 6s Progress 662 / 9694 Time remaining: 6s Progress 663 / 9694 Time remaining: 6s Progress 664 / 9694 Time remaining: 6s Progress 665 / 9694 Time remaining: 6s Progress 666 / 9694 Time remaining: 6s Progress 667 / 9694 Time remaining: 6s Progress 668 / 9694 Time remaining: 6s Progress 669 / 9694 Time remaining: 6s Progress 670 / 9694 Time remaining: 6s Progress 671 / 9694 Time remaining: 6s Progress 672 / 9694 Time remaining: 6s Progress 673 / 9694 Time remaining: 6s Progress 674 / 9694 Time remaining: 6s Progress 675 / 9694 Time remaining: 6s Progress 676 / 9694 Time remaining: 6s Progress 677 / 9694 Time remaining: 6s Progress 678 / 9694 Time remaining: 6s Progress 679 / 9694 Time remaining: 6s Progress 680 / 9694 Time remaining: 6s Progress 681 / 9694 Time remaining: 6s Progress 682 / 9694 Time remaining: 6s Progress 683 / 9694 Time remaining: 6s Progress 684 / 9694 Time remaining: 6s Progress 685 / 9694 Time remaining: 6s Progress 686 / 9694 Time remaining: 6s Progress 687 / 9694 Time remaining: 6s Progress 688 / 9694 Time remaining: 6s Progress 689 / 9694 Time remaining: 6s Progress 690 / 9694 Time remaining: 6s Progress 691 / 9694 Time remaining: 6s Progress 692 / 9694 Time remaining: 6s Progress 693 / 9694 Time remaining: 6s Progress 694 / 9694 Time remaining: 6s Progress 695 / 9694 Time remaining: 6s Progress 696 / 9694 Time remaining: 6s Progress 697 / 9694 Time remaining: 6s Progress 698 / 9694 Time remaining: 6s Progress 699 / 9694 Time remaining: 6s Progress 700 / 9694 Time remaining: 6s Progress 701 / 9694 Time remaining: 6s Progress 702 / 9694 Time remaining: 6s Progress 703 / 9694 Time remaining: 6s Progress 704 / 9694 Time remaining: 6s Progress 705 / 9694 Time remaining: 6s Progress 706 / 9694 Time remaining: 6s Progress 707 / 9694 Time remaining: 6s Progress 708 / 9694 Time remaining: 6s Progress 709 / 9694 Time remaining: 6s Progress 710 / 9694 Time remaining: 6s Progress 711 / 9694 Time remaining: 6s Progress 712 / 9694 Time remaining: 6s Progress 713 / 9694 Time remaining: 6s Progress 714 / 9694 Time remaining: 6s Progress 715 / 9694 Time remaining: 6s Progress 716 / 9694 Time remaining: 6s Progress 717 / 9694 Time remaining: 6s Progress 718 / 9694 Time remaining: 6s Progress 719 / 9694 Time remaining: 6s Progress 720 / 9694 Time remaining: 6s Progress 721 / 9694 Time remaining: 6s Progress 722 / 9694 Time remaining: 6s Progress 723 / 9694 Time remaining: 6s Progress 724 / 9694 Time remaining: 6s Progress 725 / 9694 Time remaining: 6s Progress 726 / 9694 Time remaining: 6s Progress 727 / 9694 Time remaining: 6s Progress 728 / 9694 Time remaining: 6s Progress 729 / 9694 Time remaining: 6s Progress 730 / 9694 Time remaining: 6s Progress 731 / 9694 Time remaining: 6s Progress 732 / 9694 Time remaining: 6s Progress 733 / 9694 Time remaining: 6s Progress 734 / 9694 Time remaining: 6s Progress 735 / 9694 Time remaining: 6s Progress 736 / 9694 Time remaining: 6s Progress 737 / 9694 Time remaining: 6s Progress 738 / 9694 Time remaining: 6s Progress 739 / 9694 Time remaining: 6s Progress 740 / 9694 Time remaining: 6s Progress 741 / 9694 Time remaining: 6s Progress 742 / 9694 Time remaining: 6s Progress 743 / 9694 Time remaining: 6s Progress 744 / 9694 Time remaining: 6s Progress 745 / 9694 Time remaining: 6s Progress 746 / 9694 Time remaining: 6s Progress 747 / 9694 Time remaining: 6s Progress 748 / 9694 Time remaining: 6s Progress 749 / 9694 Time remaining: 6s Progress 750 / 9694 Time remaining: 6s Progress 751 / 9694 Time remaining: 6s Progress 752 / 9694 Time remaining: 6s Progress 753 / 9694 Time remaining: 6s Progress 754 / 9694 Time remaining: 6s Progress 755 / 9694 Time remaining: 6s Progress 756 / 9694 Time remaining: 6s Progress 757 / 9694 Time remaining: 6s Progress 758 / 9694 Time remaining: 6s Progress 759 / 9694 Time remaining: 6s Progress 760 / 9694 Time remaining: 6s Progress 761 / 9694 Time remaining: 6s Progress 762 / 9694 Time remaining: 6s Progress 763 / 9694 Time remaining: 6s Progress 764 / 9694 Time remaining: 6s Progress 765 / 9694 Time remaining: 6s Progress 766 / 9694 Time remaining: 6s Progress 767 / 9694 Time remaining: 6s Progress 768 / 9694 Time remaining: 6s Progress 769 / 9694 Time remaining: 6s Progress 770 / 9694 Time remaining: 6s Progress 771 / 9694 Time remaining: 6s Progress 772 / 9694 Time remaining: 6s Progress 773 / 9694 Time remaining: 6s Progress 774 / 9694 Time remaining: 6s Progress 775 / 9694 Time remaining: 6s Progress 776 / 9694 Time remaining: 6s Progress 777 / 9694 Time remaining: 6s Progress 778 / 9694 Time remaining: 6s Progress 779 / 9694 Time remaining: 6s Progress 780 / 9694 Time remaining: 6s Progress 781 / 9694 Time remaining: 6s Progress 782 / 9694 Time remaining: 6s Progress 783 / 9694 Time remaining: 6s Progress 784 / 9694 Time remaining: 6s Progress 785 / 9694 Time remaining: 6s Progress 786 / 9694 Time remaining: 6s Progress 787 / 9694 Time remaining: 6s Progress 788 / 9694 Time remaining: 6s Progress 789 / 9694 Time remaining: 6s Progress 790 / 9694 Time remaining: 6s Progress 791 / 9694 Time remaining: 6s Progress 792 / 9694 Time remaining: 6s Progress 793 / 9694 Time remaining: 6s Progress 794 / 9694 Time remaining: 6s Progress 795 / 9694 Time remaining: 6s Progress 796 / 9694 Time remaining: 6s Progress 797 / 9694 Time remaining: 6s Progress 798 / 9694 Time remaining: 6s Progress 799 / 9694 Time remaining: 6s Progress 800 / 9694 Time remaining: 6s Progress 801 / 9694 Time remaining: 6s Progress 802 / 9694 Time remaining: 6s Progress 803 / 9694 Time remaining: 6s Progress 804 / 9694 Time remaining: 6s Progress 805 / 9694 Time remaining: 6s Progress 806 / 9694 Time remaining: 6s Progress 807 / 9694 Time remaining: 6s Progress 808 / 9694 Time remaining: 6s Progress 809 / 9694 Time remaining: 6s Progress 810 / 9694 Time remaining: 6s Progress 811 / 9694 Time remaining: 6s Progress 812 / 9694 Time remaining: 6s Progress 813 / 9694 Time remaining: 6s Progress 814 / 9694 Time remaining: 6s Progress 815 / 9694 Time remaining: 6s Progress 816 / 9694 Time remaining: 6s Progress 817 / 9694 Time remaining: 6s Progress 818 / 9694 Time remaining: 6s Progress 819 / 9694 Time remaining: 6s Progress 820 / 9694 Time remaining: 6s Progress 821 / 9694 Time remaining: 6s Progress 822 / 9694 Time remaining: 6s Progress 823 / 9694 Time remaining: 6s Progress 824 / 9694 Time remaining: 6s Progress 825 / 9694 Time remaining: 6s Progress 826 / 9694 Time remaining: 6s Progress 827 / 9694 Time remaining: 6s Progress 828 / 9694 Time remaining: 6s Progress 829 / 9694 Time remaining: 6s Progress 830 / 9694 Time remaining: 6s Progress 831 / 9694 Time remaining: 6s Progress 832 / 9694 Time remaining: 6s Progress 833 / 9694 Time remaining: 6s Progress 834 / 9694 Time remaining: 6s Progress 835 / 9694 Time remaining: 6s Progress 836 / 9694 Time remaining: 6s Progress 837 / 9694 Time remaining: 6s Progress 838 / 9694 Time remaining: 6s Progress 839 / 9694 Time remaining: 6s Progress 840 / 9694 Time remaining: 6s Progress 841 / 9694 Time remaining: 6s Progress 842 / 9694 Time remaining: 6s Progress 843 / 9694 Time remaining: 6s Progress 844 / 9694 Time remaining: 6s Progress 845 / 9694 Time remaining: 6s Progress 846 / 9694 Time remaining: 6s Progress 847 / 9694 Time remaining: 6s Progress 848 / 9694 Time remaining: 6s Progress 849 / 9694 Time remaining: 6s Progress 850 / 9694 Time remaining: 6s Progress 851 / 9694 Time remaining: 6s Progress 852 / 9694 Time remaining: 6s Progress 853 / 9694 Time remaining: 6s Progress 854 / 9694 Time remaining: 6s Progress 855 / 9694 Time remaining: 6s Progress 856 / 9694 Time remaining: 6s Progress 857 / 9694 Time remaining: 6s Progress 858 / 9694 Time remaining: 6s Progress 859 / 9694 Time remaining: 6s Progress 860 / 9694 Time remaining: 6s Progress 861 / 9694 Time remaining: 6s Progress 862 / 9694 Time remaining: 6s Progress 863 / 9694 Time remaining: 6s Progress 864 / 9694 Time remaining: 6s Progress 865 / 9694 Time remaining: 6s Progress 866 / 9694 Time remaining: 6s Progress 867 / 9694 Time remaining: 6s Progress 868 / 9694 Time remaining: 6s Progress 869 / 9694 Time remaining: 6s Progress 870 / 9694 Time remaining: 6s Progress 871 / 9694 Time remaining: 6s Progress 872 / 9694 Time remaining: 6s Progress 873 / 9694 Time remaining: 6s Progress 874 / 9694 Time remaining: 6s Progress 875 / 9694 Time remaining: 6s Progress 876 / 9694 Time remaining: 6s Progress 877 / 9694 Time remaining: 6s Progress 878 / 9694 Time remaining: 6s Progress 879 / 9694 Time remaining: 6s Progress 880 / 9694 Time remaining: 6s Progress 881 / 9694 Time remaining: 6s Progress 882 / 9694 Time remaining: 6s Progress 883 / 9694 Time remaining: 6s Progress 884 / 9694 Time remaining: 6s Progress 885 / 9694 Time remaining: 6s Progress 886 / 9694 Time remaining: 6s Progress 887 / 9694 Time remaining: 6s Progress 888 / 9694 Time remaining: 6s Progress 889 / 9694 Time remaining: 6s Progress 890 / 9694 Time remaining: 6s Progress 891 / 9694 Time remaining: 6s Progress 892 / 9694 Time remaining: 6s Progress 893 / 9694 Time remaining: 6s Progress 894 / 9694 Time remaining: 6s Progress 895 / 9694 Time remaining: 6s Progress 896 / 9694 Time remaining: 6s Progress 897 / 9694 Time remaining: 6s Progress 898 / 9694 Time remaining: 6s Progress 899 / 9694 Time remaining: 6s Progress 900 / 9694 Time remaining: 6s Progress 901 / 9694 Time remaining: 6s Progress 902 / 9694 Time remaining: 6s Progress 903 / 9694 Time remaining: 6s Progress 904 / 9694 Time remaining: 6s Progress 905 / 9694 Time remaining: 6s Progress 906 / 9694 Time remaining: 6s Progress 907 / 9694 Time remaining: 6s Progress 908 / 9694 Time remaining: 6s Progress 909 / 9694 Time remaining: 6s Progress 910 / 9694 Time remaining: 6s Progress 911 / 9694 Time remaining: 6s Progress 912 / 9694 Time remaining: 6s Progress 913 / 9694 Time remaining: 6s Progress 914 / 9694 Time remaining: 6s Progress 915 / 9694 Time remaining: 6s Progress 916 / 9694 Time remaining: 6s Progress 917 / 9694 Time remaining: 6s Progress 918 / 9694 Time remaining: 6s Progress 919 / 9694 Time remaining: 6s Progress 920 / 9694 Time remaining: 6s Progress 921 / 9694 Time remaining: 6s Progress 922 / 9694 Time remaining: 6s Progress 923 / 9694 Time remaining: 6s Progress 924 / 9694 Time remaining: 6s Progress 925 / 9694 Time remaining: 6s Progress 926 / 9694 Time remaining: 6s Progress 927 / 9694 Time remaining: 6s Progress 928 / 9694 Time remaining: 6s Progress 929 / 9694 Time remaining: 6s Progress 930 / 9694 Time remaining: 6s Progress 931 / 9694 Time remaining: 6s Progress 932 / 9694 Time remaining: 6s Progress 933 / 9694 Time remaining: 6s Progress 934 / 9694 Time remaining: 6s Progress 935 / 9694 Time remaining: 6s Progress 936 / 9694 Time remaining: 6s Progress 937 / 9694 Time remaining: 6s Progress 938 / 9694 Time remaining: 6s Progress 939 / 9694 Time remaining: 6s Progress 940 / 9694 Time remaining: 6s Progress 941 / 9694 Time remaining: 6s Progress 942 / 9694 Time remaining: 6s Progress 943 / 9694 Time remaining: 6s Progress 944 / 9694 Time remaining: 6s Progress 945 / 9694 Time remaining: 6s Progress 946 / 9694 Time remaining: 6s Progress 947 / 9694 Time remaining: 6s Progress 948 / 9694 Time remaining: 6s Progress 949 / 9694 Time remaining: 6s Progress 950 / 9694 Time remaining: 6s Progress 951 / 9694 Time remaining: 6s Progress 952 / 9694 Time remaining: 6s Progress 953 / 9694 Time remaining: 6s Progress 954 / 9694 Time remaining: 6s Progress 955 / 9694 Time remaining: 6s Progress 956 / 9694 Time remaining: 6s Progress 957 / 9694 Time remaining: 6s Progress 958 / 9694 Time remaining: 6s Progress 959 / 9694 Time remaining: 6s Progress 960 / 9694 Time remaining: 6s Progress 961 / 9694 Time remaining: 6s Progress 962 / 9694 Time remaining: 6s Progress 963 / 9694 Time remaining: 6s Progress 964 / 9694 Time remaining: 6s Progress 965 / 9694 Time remaining: 6s Progress 966 / 9694 Time remaining: 6s Progress 967 / 9694 Time remaining: 6s Progress 968 / 9694 Time remaining: 6s Progress 969 / 9694 Time remaining: 6s Progress 970 / 9694 Time remaining: 6s Progress 971 / 9694 Time remaining: 6s Progress 972 / 9694 Time remaining: 6s Progress 973 / 9694 Time remaining: 6s Progress 974 / 9694 Time remaining: 6s Progress 975 / 9694 Time remaining: 6s Progress 976 / 9694 Time remaining: 6s Progress 977 / 9694 Time remaining: 6s Progress 978 / 9694 Time remaining: 6s Progress 979 / 9694 Time remaining: 6s Progress 980 / 9694 Time remaining: 6s Progress 981 / 9694 Time remaining: 6s Progress 982 / 9694 Time remaining: 6s Progress 983 / 9694 Time remaining: 6s Progress 984 / 9694 Time remaining: 6s Progress 985 / 9694 Time remaining: 6s Progress 986 / 9694 Time remaining: 6s Progress 987 / 9694 Time remaining: 6s Progress 988 / 9694 Time remaining: 6s Progress 989 / 9694 Time remaining: 6s Progress 990 / 9694 Time remaining: 6s Progress 991 / 9694 Time remaining: 6s Progress 992 / 9694 Time remaining: 6s Progress 993 / 9694 Time remaining: 6s Progress 994 / 9694 Time remaining: 6s Progress 995 / 9694 Time remaining: 6s Progress 996 / 9694 Time remaining: 6s Progress 997 / 9694 Time remaining: 6s Progress 998 / 9694 Time remaining: 6s Progress 999 / 9694 Time remaining: 6s Progress 1000 / 9694 Time remaining: 6s Progress 1001 / 9694 Time remaining: 6s Progress 1002 / 9694 Time remaining: 6s Progress 1003 / 9694 Time remaining: 6s Progress 1004 / 9694 Time remaining: 6s Progress 1005 / 9694 Time remaining: 6s Progress 1006 / 9694 Time remaining: 6s Progress 1007 / 9694 Time remaining: 6s Progress 1008 / 9694 Time remaining: 6s Progress 1009 / 9694 Time remaining: 6s Progress 1010 / 9694 Time remaining: 6s Progress 1011 / 9694 Time remaining: 6s Progress 1012 / 9694 Time remaining: 6s Progress 1013 / 9694 Time remaining: 6s Progress 1014 / 9694 Time remaining: 6s Progress 1015 / 9694 Time remaining: 6s Progress 1016 / 9694 Time remaining: 6s Progress 1017 / 9694 Time remaining: 6s Progress 1018 / 9694 Time remaining: 6s Progress 1019 / 9694 Time remaining: 6s Progress 1020 / 9694 Time remaining: 6s Progress 1021 / 9694 Time remaining: 6s Progress 1022 / 9694 Time remaining: 6s Progress 1023 / 9694 Time remaining: 6s Progress 1024 / 9694 Time remaining: 6s Progress 1025 / 9694 Time remaining: 6s Progress 1026 / 9694 Time remaining: 6s Progress 1027 / 9694 Time remaining: 6s Progress 1028 / 9694 Time remaining: 6s Progress 1029 / 9694 Time remaining: 6s Progress 1030 / 9694 Time remaining: 6s Progress 1031 / 9694 Time remaining: 6s Progress 1032 / 9694 Time remaining: 6s Progress 1033 / 9694 Time remaining: 6s Progress 1034 / 9694 Time remaining: 6s Progress 1035 / 9694 Time remaining: 6s Progress 1036 / 9694 Time remaining: 6s Progress 1037 / 9694 Time remaining: 6s Progress 1038 / 9694 Time remaining: 6s Progress 1039 / 9694 Time remaining: 6s Progress 1040 / 9694 Time remaining: 6s Progress 1041 / 9694 Time remaining: 6s Progress 1042 / 9694 Time remaining: 6s Progress 1043 / 9694 Time remaining: 6s Progress 1044 / 9694 Time remaining: 6s Progress 1045 / 9694 Time remaining: 6s Progress 1046 / 9694 Time remaining: 6s Progress 1047 / 9694 Time remaining: 6s Progress 1048 / 9694 Time remaining: 6s Progress 1049 / 9694 Time remaining: 6s Progress 1050 / 9694 Time remaining: 6s Progress 1051 / 9694 Time remaining: 6s Progress 1052 / 9694 Time remaining: 6s Progress 1053 / 9694 Time remaining: 6s Progress 1054 / 9694 Time remaining: 6s Progress 1055 / 9694 Time remaining: 6s Progress 1056 / 9694 Time remaining: 6s Progress 1057 / 9694 Time remaining: 6s Progress 1058 / 9694 Time remaining: 6s Progress 1059 / 9694 Time remaining: 6s Progress 1060 / 9694 Time remaining: 6s Progress 1061 / 9694 Time remaining: 6s Progress 1062 / 9694 Time remaining: 6s Progress 1063 / 9694 Time remaining: 6s Progress 1064 / 9694 Time remaining: 6s Progress 1065 / 9694 Time remaining: 6s Progress 1066 / 9694 Time remaining: 6s Progress 1067 / 9694 Time remaining: 6s Progress 1068 / 9694 Time remaining: 6s Progress 1069 / 9694 Time remaining: 6s Progress 1070 / 9694 Time remaining: 6s Progress 1071 / 9694 Time remaining: 6s Progress 1072 / 9694 Time remaining: 6s Progress 1073 / 9694 Time remaining: 6s Progress 1074 / 9694 Time remaining: 6s Progress 1075 / 9694 Time remaining: 6s Progress 1076 / 9694 Time remaining: 6s Progress 1077 / 9694 Time remaining: 6s Progress 1078 / 9694 Time remaining: 6s Progress 1079 / 9694 Time remaining: 6s Progress 1080 / 9694 Time remaining: 6s Progress 1081 / 9694 Time remaining: 6s Progress 1082 / 9694 Time remaining: 6s Progress 1083 / 9694 Time remaining: 6s Progress 1084 / 9694 Time remaining: 6s Progress 1085 / 9694 Time remaining: 6s Progress 1086 / 9694 Time remaining: 6s Progress 1087 / 9694 Time remaining: 6s Progress 1088 / 9694 Time remaining: 6s Progress 1089 / 9694 Time remaining: 6s Progress 1090 / 9694 Time remaining: 6s Progress 1091 / 9694 Time remaining: 6s Progress 1092 / 9694 Time remaining: 6s Progress 1093 / 9694 Time remaining: 6s Progress 1094 / 9694 Time remaining: 6s Progress 1095 / 9694 Time remaining: 6s Progress 1096 / 9694 Time remaining: 6s Progress 1097 / 9694 Time remaining: 6s Progress 1098 / 9694 Time remaining: 6s Progress 1099 / 9694 Time remaining: 6s Progress 1100 / 9694 Time remaining: 6s Progress 1101 / 9694 Time remaining: 6s Progress 1102 / 9694 Time remaining: 6s Progress 1103 / 9694 Time remaining: 6s Progress 1104 / 9694 Time remaining: 6s Progress 1105 / 9694 Time remaining: 6s Progress 1106 / 9694 Time remaining: 6s Progress 1107 / 9694 Time remaining: 6s Progress 1108 / 9694 Time remaining: 6s Progress 1109 / 9694 Time remaining: 6s Progress 1110 / 9694 Time remaining: 6s Progress 1111 / 9694 Time remaining: 6s Progress 1112 / 9694 Time remaining: 6s Progress 1113 / 9694 Time remaining: 6s Progress 1114 / 9694 Time remaining: 6s Progress 1115 / 9694 Time remaining: 6s Progress 1116 / 9694 Time remaining: 6s Progress 1117 / 9694 Time remaining: 6s Progress 1118 / 9694 Time remaining: 6s Progress 1119 / 9694 Time remaining: 6s Progress 1120 / 9694 Time remaining: 6s Progress 1121 / 9694 Time remaining: 6s Progress 1122 / 9694 Time remaining: 6s Progress 1123 / 9694 Time remaining: 6s Progress 1124 / 9694 Time remaining: 6s Progress 1125 / 9694 Time remaining: 6s Progress 1126 / 9694 Time remaining: 6s Progress 1127 / 9694 Time remaining: 6s Progress 1128 / 9694 Time remaining: 6s Progress 1129 / 9694 Time remaining: 6s Progress 1130 / 9694 Time remaining: 6s Progress 1131 / 9694 Time remaining: 6s Progress 1132 / 9694 Time remaining: 6s Progress 1133 / 9694 Time remaining: 6s Progress 1134 / 9694 Time remaining: 6s Progress 1135 / 9694 Time remaining: 6s Progress 1136 / 9694 Time remaining: 6s Progress 1137 / 9694 Time remaining: 6s Progress 1138 / 9694 Time remaining: 6s Progress 1139 / 9694 Time remaining: 6s Progress 1140 / 9694 Time remaining: 6s Progress 1141 / 9694 Time remaining: 6s Progress 1142 / 9694 Time remaining: 6s Progress 1143 / 9694 Time remaining: 6s Progress 1144 / 9694 Time remaining: 6s Progress 1145 / 9694 Time remaining: 6s Progress 1146 / 9694 Time remaining: 6s Progress 1147 / 9694 Time remaining: 6s Progress 1148 / 9694 Time remaining: 6s Progress 1149 / 9694 Time remaining: 6s Progress 1150 / 9694 Time remaining: 6s Progress 1151 / 9694 Time remaining: 6s Progress 1152 / 9694 Time remaining: 6s Progress 1153 / 9694 Time remaining: 6s Progress 1154 / 9694 Time remaining: 6s Progress 1155 / 9694 Time remaining: 6s Progress 1156 / 9694 Time remaining: 6s Progress 1157 / 9694 Time remaining: 6s Progress 1158 / 9694 Time remaining: 6s Progress 1159 / 9694 Time remaining: 6s Progress 1160 / 9694 Time remaining: 6s Progress 1161 / 9694 Time remaining: 6s Progress 1162 / 9694 Time remaining: 6s Progress 1163 / 9694 Time remaining: 6s Progress 1164 / 9694 Time remaining: 6s Progress 1165 / 9694 Time remaining: 6s Progress 1166 / 9694 Time remaining: 6s Progress 1167 / 9694 Time remaining: 6s Progress 1168 / 9694 Time remaining: 6s Progress 1169 / 9694 Time remaining: 6s Progress 1170 / 9694 Time remaining: 6s Progress 1171 / 9694 Time remaining: 6s Progress 1172 / 9694 Time remaining: 6s Progress 1173 / 9694 Time remaining: 6s Progress 1174 / 9694 Time remaining: 6s Progress 1175 / 9694 Time remaining: 6s Progress 1176 / 9694 Time remaining: 6s Progress 1177 / 9694 Time remaining: 6s Progress 1178 / 9694 Time remaining: 6s Progress 1179 / 9694 Time remaining: 6s Progress 1180 / 9694 Time remaining: 6s Progress 1181 / 9694 Time remaining: 6s Progress 1182 / 9694 Time remaining: 6s Progress 1183 / 9694 Time remaining: 6s Progress 1184 / 9694 Time remaining: 6s Progress 1185 / 9694 Time remaining: 6s Progress 1186 / 9694 Time remaining: 6s Progress 1187 / 9694 Time remaining: 6s Progress 1188 / 9694 Time remaining: 6s Progress 1189 / 9694 Time remaining: 6s Progress 1190 / 9694 Time remaining: 6s Progress 1191 / 9694 Time remaining: 6s Progress 1192 / 9694 Time remaining: 6s Progress 1193 / 9694 Time remaining: 6s Progress 1194 / 9694 Time remaining: 6s Progress 1195 / 9694 Time remaining: 6s Progress 1196 / 9694 Time remaining: 6s Progress 1197 / 9694 Time remaining: 6s Progress 1198 / 9694 Time remaining: 6s Progress 1199 / 9694 Time remaining: 6s Progress 1200 / 9694 Time remaining: 6s Progress 1201 / 9694 Time remaining: 6s Progress 1202 / 9694 Time remaining: 6s Progress 1203 / 9694 Time remaining: 6s Progress 1204 / 9694 Time remaining: 6s Progress 1205 / 9694 Time remaining: 6s Progress 1206 / 9694 Time remaining: 6s Progress 1207 / 9694 Time remaining: 6s Progress 1208 / 9694 Time remaining: 6s Progress 1209 / 9694 Time remaining: 6s Progress 1210 / 9694 Time remaining: 6s Progress 1211 / 9694 Time remaining: 6s Progress 1212 / 9694 Time remaining: 6s Progress 1213 / 9694 Time remaining: 6s Progress 1214 / 9694 Time remaining: 6s Progress 1215 / 9694 Time remaining: 6s Progress 1216 / 9694 Time remaining: 6s Progress 1217 / 9694 Time remaining: 6s Progress 1218 / 9694 Time remaining: 6s Progress 1219 / 9694 Time remaining: 6s Progress 1220 / 9694 Time remaining: 6s Progress 1221 / 9694 Time remaining: 6s Progress 1222 / 9694 Time remaining: 6s Progress 1223 / 9694 Time remaining: 6s Progress 1224 / 9694 Time remaining: 6s Progress 1225 / 9694 Time remaining: 6s Progress 1226 / 9694 Time remaining: 6s Progress 1227 / 9694 Time remaining: 6s Progress 1228 / 9694 Time remaining: 6s Progress 1229 / 9694 Time remaining: 6s Progress 1230 / 9694 Time remaining: 6s Progress 1231 / 9694 Time remaining: 6s Progress 1232 / 9694 Time remaining: 6s Progress 1233 / 9694 Time remaining: 6s Progress 1234 / 9694 Time remaining: 6s Progress 1235 / 9694 Time remaining: 6s Progress 1236 / 9694 Time remaining: 6s Progress 1237 / 9694 Time remaining: 6s Progress 1238 / 9694 Time remaining: 6s Progress 1239 / 9694 Time remaining: 6s Progress 1240 / 9694 Time remaining: 6s Progress 1241 / 9694 Time remaining: 6s Progress 1242 / 9694 Time remaining: 6s Progress 1243 / 9694 Time remaining: 6s Progress 1244 / 9694 Time remaining: 6s Progress 1245 / 9694 Time remaining: 6s Progress 1246 / 9694 Time remaining: 6s Progress 1247 / 9694 Time remaining: 6s Progress 1248 / 9694 Time remaining: 6s Progress 1249 / 9694 Time remaining: 6s Progress 1250 / 9694 Time remaining: 6s Progress 1251 / 9694 Time remaining: 6s Progress 1252 / 9694 Time remaining: 6s Progress 1253 / 9694 Time remaining: 6s Progress 1254 / 9694 Time remaining: 6s Progress 1255 / 9694 Time remaining: 6s Progress 1256 / 9694 Time remaining: 6s Progress 1257 / 9694 Time remaining: 6s Progress 1258 / 9694 Time remaining: 6s Progress 1259 / 9694 Time remaining: 6s Progress 1260 / 9694 Time remaining: 6s Progress 1261 / 9694 Time remaining: 6s Progress 1262 / 9694 Time remaining: 6s Progress 1263 / 9694 Time remaining: 6s Progress 1264 / 9694 Time remaining: 6s Progress 1265 / 9694 Time remaining: 6s Progress 1266 / 9694 Time remaining: 6s Progress 1267 / 9694 Time remaining: 6s Progress 1268 / 9694 Time remaining: 6s Progress 1269 / 9694 Time remaining: 6s Progress 1270 / 9694 Time remaining: 6s Progress 1271 / 9694 Time remaining: 6s Progress 1272 / 9694 Time remaining: 6s Progress 1273 / 9694 Time remaining: 6s Progress 1274 / 9694 Time remaining: 6s Progress 1275 / 9694 Time remaining: 6s Progress 1276 / 9694 Time remaining: 6s Progress 1277 / 9694 Time remaining: 6s Progress 1278 / 9694 Time remaining: 6s Progress 1279 / 9694 Time remaining: 6s Progress 1280 / 9694 Time remaining: 6s Progress 1281 / 9694 Time remaining: 6s Progress 1282 / 9694 Time remaining: 6s Progress 1283 / 9694 Time remaining: 6s Progress 1284 / 9694 Time remaining: 6s Progress 1285 / 9694 Time remaining: 6s Progress 1286 / 9694 Time remaining: 6s Progress 1287 / 9694 Time remaining: 6s Progress 1288 / 9694 Time remaining: 6s Progress 1289 / 9694 Time remaining: 6s Progress 1290 / 9694 Time remaining: 6s Progress 1291 / 9694 Time remaining: 6s Progress 1292 / 9694 Time remaining: 6s Progress 1293 / 9694 Time remaining: 6s Progress 1294 / 9694 Time remaining: 6s Progress 1295 / 9694 Time remaining: 6s Progress 1296 / 9694 Time remaining: 6s Progress 1297 / 9694 Time remaining: 6s Progress 1298 / 9694 Time remaining: 6s Progress 1299 / 9694 Time remaining: 6s Progress 1300 / 9694 Time remaining: 6s Progress 1301 / 9694 Time remaining: 6s Progress 1302 / 9694 Time remaining: 6s Progress 1303 / 9694 Time remaining: 6s Progress 1304 / 9694 Time remaining: 6s Progress 1305 / 9694 Time remaining: 6s Progress 1306 / 9694 Time remaining: 6s Progress 1307 / 9694 Time remaining: 6s Progress 1308 / 9694 Time remaining: 6s Progress 1309 / 9694 Time remaining: 6s Progress 1310 / 9694 Time remaining: 6s Progress 1311 / 9694 Time remaining: 6s Progress 1312 / 9694 Time remaining: 6s Progress 1313 / 9694 Time remaining: 6s Progress 1314 / 9694 Time remaining: 6s Progress 1315 / 9694 Time remaining: 6s Progress 1316 / 9694 Time remaining: 6s Progress 1317 / 9694 Time remaining: 6s Progress 1318 / 9694 Time remaining: 6s Progress 1319 / 9694 Time remaining: 6s Progress 1320 / 9694 Time remaining: 6s Progress 1321 / 9694 Time remaining: 6s Progress 1322 / 9694 Time remaining: 6s Progress 1323 / 9694 Time remaining: 6s Progress 1324 / 9694 Time remaining: 6s Progress 1325 / 9694 Time remaining: 6s Progress 1326 / 9694 Time remaining: 6s Progress 1327 / 9694 Time remaining: 6s Progress 1328 / 9694 Time remaining: 6s Progress 1329 / 9694 Time remaining: 6s Progress 1330 / 9694 Time remaining: 6s Progress 1331 / 9694 Time remaining: 6s Progress 1332 / 9694 Time remaining: 6s Progress 1333 / 9694 Time remaining: 6s Progress 1334 / 9694 Time remaining: 6s Progress 1335 / 9694 Time remaining: 6s Progress 1336 / 9694 Time remaining: 6s Progress 1337 / 9694 Time remaining: 6s Progress 1338 / 9694 Time remaining: 6s Progress 1339 / 9694 Time remaining: 6s Progress 1340 / 9694 Time remaining: 6s Progress 1341 / 9694 Time remaining: 6s Progress 1342 / 9694 Time remaining: 6s Progress 1343 / 9694 Time remaining: 6s Progress 1344 / 9694 Time remaining: 6s Progress 1345 / 9694 Time remaining: 6s Progress 1346 / 9694 Time remaining: 6s Progress 1347 / 9694 Time remaining: 6s Progress 1348 / 9694 Time remaining: 6s Progress 1349 / 9694 Time remaining: 6s Progress 1350 / 9694 Time remaining: 6s Progress 1351 / 9694 Time remaining: 6s Progress 1352 / 9694 Time remaining: 6s Progress 1353 / 9694 Time remaining: 6s Progress 1354 / 9694 Time remaining: 6s Progress 1355 / 9694 Time remaining: 6s Progress 1356 / 9694 Time remaining: 6s Progress 1357 / 9694 Time remaining: 6s Progress 1358 / 9694 Time remaining: 6s Progress 1359 / 9694 Time remaining: 6s Progress 1360 / 9694 Time remaining: 6s Progress 1361 / 9694 Time remaining: 6s Progress 1362 / 9694 Time remaining: 6s Progress 1363 / 9694 Time remaining: 6s Progress 1364 / 9694 Time remaining: 6s Progress 1365 / 9694 Time remaining: 6s Progress 1366 / 9694 Time remaining: 6s Progress 1367 / 9694 Time remaining: 6s Progress 1368 / 9694 Time remaining: 6s Progress 1369 / 9694 Time remaining: 6s Progress 1370 / 9694 Time remaining: 6s Progress 1371 / 9694 Time remaining: 6s Progress 1372 / 9694 Time remaining: 6s Progress 1373 / 9694 Time remaining: 6s Progress 1374 / 9694 Time remaining: 6s Progress 1375 / 9694 Time remaining: 6s Progress 1376 / 9694 Time remaining: 6s Progress 1377 / 9694 Time remaining: 6s Progress 1378 / 9694 Time remaining: 6s Progress 1379 / 9694 Time remaining: 6s Progress 1380 / 9694 Time remaining: 6s Progress 1381 / 9694 Time remaining: 6s Progress 1382 / 9694 Time remaining: 6s Progress 1383 / 9694 Time remaining: 6s Progress 1384 / 9694 Time remaining: 6s Progress 1385 / 9694 Time remaining: 6s Progress 1386 / 9694 Time remaining: 6s Progress 1387 / 9694 Time remaining: 6s Progress 1388 / 9694 Time remaining: 6s Progress 1389 / 9694 Time remaining: 6s Progress 1390 / 9694 Time remaining: 6s Progress 1391 / 9694 Time remaining: 6s Progress 1392 / 9694 Time remaining: 6s Progress 1393 / 9694 Time remaining: 6s Progress 1394 / 9694 Time remaining: 6s Progress 1395 / 9694 Time remaining: 6s Progress 1396 / 9694 Time remaining: 6s Progress 1397 / 9694 Time remaining: 6s Progress 1398 / 9694 Time remaining: 6s Progress 1399 / 9694 Time remaining: 6s Progress 1400 / 9694 Time remaining: 6s Progress 1401 / 9694 Time remaining: 6s Progress 1402 / 9694 Time remaining: 6s Progress 1403 / 9694 Time remaining: 6s Progress 1404 / 9694 Time remaining: 6s Progress 1405 / 9694 Time remaining: 6s Progress 1406 / 9694 Time remaining: 6s Progress 1407 / 9694 Time remaining: 6s Progress 1408 / 9694 Time remaining: 6s Progress 1409 / 9694 Time remaining: 6s Progress 1410 / 9694 Time remaining: 6s Progress 1411 / 9694 Time remaining: 6s Progress 1412 / 9694 Time remaining: 6s Progress 1413 / 9694 Time remaining: 6s Progress 1414 / 9694 Time remaining: 6s Progress 1415 / 9694 Time remaining: 6s Progress 1416 / 9694 Time remaining: 6s Progress 1417 / 9694 Time remaining: 6s Progress 1418 / 9694 Time remaining: 6s Progress 1419 / 9694 Time remaining: 6s Progress 1420 / 9694 Time remaining: 6s Progress 1421 / 9694 Time remaining: 6s Progress 1422 / 9694 Time remaining: 6s Progress 1423 / 9694 Time remaining: 6s Progress 1424 / 9694 Time remaining: 6s Progress 1425 / 9694 Time remaining: 6s Progress 1426 / 9694 Time remaining: 6s Progress 1427 / 9694 Time remaining: 6s Progress 1428 / 9694 Time remaining: 6s Progress 1429 / 9694 Time remaining: 6s Progress 1430 / 9694 Time remaining: 6s Progress 1431 / 9694 Time remaining: 6s Progress 1432 / 9694 Time remaining: 6s Progress 1433 / 9694 Time remaining: 6s Progress 1434 / 9694 Time remaining: 6s Progress 1435 / 9694 Time remaining: 6s Progress 1436 / 9694 Time remaining: 6s Progress 1437 / 9694 Time remaining: 6s Progress 1438 / 9694 Time remaining: 6s Progress 1439 / 9694 Time remaining: 6s Progress 1440 / 9694 Time remaining: 6s Progress 1441 / 9694 Time remaining: 6s Progress 1442 / 9694 Time remaining: 6s Progress 1443 / 9694 Time remaining: 6s Progress 1444 / 9694 Time remaining: 6s Progress 1445 / 9694 Time remaining: 6s Progress 1446 / 9694 Time remaining: 6s Progress 1447 / 9694 Time remaining: 6s Progress 1448 / 9694 Time remaining: 6s Progress 1449 / 9694 Time remaining: 6s Progress 1450 / 9694 Time remaining: 6s Progress 1451 / 9694 Time remaining: 6s Progress 1452 / 9694 Time remaining: 6s Progress 1453 / 9694 Time remaining: 6s Progress 1454 / 9694 Time remaining: 6s Progress 1455 / 9694 Time remaining: 6s Progress 1456 / 9694 Time remaining: 6s Progress 1457 / 9694 Time remaining: 6s Progress 1458 / 9694 Time remaining: 6s Progress 1459 / 9694 Time remaining: 6s Progress 1460 / 9694 Time remaining: 6s Progress 1461 / 9694 Time remaining: 6s Progress 1462 / 9694 Time remaining: 6s Progress 1463 / 9694 Time remaining: 6s Progress 1464 / 9694 Time remaining: 6s Progress 1465 / 9694 Time remaining: 6s Progress 1466 / 9694 Time remaining: 6s Progress 1467 / 9694 Time remaining: 6s Progress 1468 / 9694 Time remaining: 6s Progress 1469 / 9694 Time remaining: 6s Progress 1470 / 9694 Time remaining: 6s Progress 1471 / 9694 Time remaining: 6s Progress 1472 / 9694 Time remaining: 6s Progress 1473 / 9694 Time remaining: 6s Progress 1474 / 9694 Time remaining: 6s Progress 1475 / 9694 Time remaining: 6s Progress 1476 / 9694 Time remaining: 6s Progress 1477 / 9694 Time remaining: 6s Progress 1478 / 9694 Time remaining: 6s Progress 1479 / 9694 Time remaining: 6s Progress 1480 / 9694 Time remaining: 6s Progress 1481 / 9694 Time remaining: 6s Progress 1482 / 9694 Time remaining: 6s Progress 1483 / 9694 Time remaining: 6s Progress 1484 / 9694 Time remaining: 6s Progress 1485 / 9694 Time remaining: 6s Progress 1486 / 9694 Time remaining: 6s Progress 1487 / 9694 Time remaining: 6s Progress 1488 / 9694 Time remaining: 6s Progress 1489 / 9694 Time remaining: 6s Progress 1490 / 9694 Time remaining: 6s Progress 1491 / 9694 Time remaining: 6s Progress 1492 / 9694 Time remaining: 6s Progress 1493 / 9694 Time remaining: 6s Progress 1494 / 9694 Time remaining: 6s Progress 1495 / 9694 Time remaining: 6s Progress 1496 / 9694 Time remaining: 6s Progress 1497 / 9694 Time remaining: 6s Progress 1498 / 9694 Time remaining: 6s Progress 1499 / 9694 Time remaining: 6s Progress 1500 / 9694 Time remaining: 6s Progress 1501 / 9694 Time remaining: 6s Progress 1502 / 9694 Time remaining: 6s Progress 1503 / 9694 Time remaining: 6s Progress 1504 / 9694 Time remaining: 6s Progress 1505 / 9694 Time remaining: 6s Progress 1506 / 9694 Time remaining: 6s Progress 1507 / 9694 Time remaining: 6s Progress 1508 / 9694 Time remaining: 6s Progress 1509 / 9694 Time remaining: 6s Progress 1510 / 9694 Time remaining: 6s Progress 1511 / 9694 Time remaining: 6s Progress 1512 / 9694 Time remaining: 6s Progress 1513 / 9694 Time remaining: 6s Progress 1514 / 9694 Time remaining: 6s Progress 1515 / 9694 Time remaining: 6s Progress 1516 / 9694 Time remaining: 6s Progress 1517 / 9694 Time remaining: 6s Progress 1518 / 9694 Time remaining: 6s Progress 1519 / 9694 Time remaining: 6s Progress 1520 / 9694 Time remaining: 6s Progress 1521 / 9694 Time remaining: 6s Progress 1522 / 9694 Time remaining: 6s Progress 1523 / 9694 Time remaining: 6s Progress 1524 / 9694 Time remaining: 6s Progress 1525 / 9694 Time remaining: 6s Progress 1526 / 9694 Time remaining: 6s Progress 1527 / 9694 Time remaining: 6s Progress 1528 / 9694 Time remaining: 5s Progress 1529 / 9694 Time remaining: 5s Progress 1530 / 9694 Time remaining: 5s Progress 1531 / 9694 Time remaining: 5s Progress 1532 / 9694 Time remaining: 5s Progress 1533 / 9694 Time remaining: 5s Progress 1534 / 9694 Time remaining: 5s Progress 1535 / 9694 Time remaining: 5s Progress 1536 / 9694 Time remaining: 5s Progress 1537 / 9694 Time remaining: 5s Progress 1538 / 9694 Time remaining: 5s Progress 1539 / 9694 Time remaining: 5s Progress 1540 / 9694 Time remaining: 5s Progress 1541 / 9694 Time remaining: 5s Progress 1542 / 9694 Time remaining: 5s Progress 1543 / 9694 Time remaining: 5s Progress 1544 / 9694 Time remaining: 5s Progress 1545 / 9694 Time remaining: 5s Progress 1546 / 9694 Time remaining: 5s Progress 1547 / 9694 Time remaining: 5s Progress 1548 / 9694 Time remaining: 5s Progress 1549 / 9694 Time remaining: 5s Progress 1550 / 9694 Time remaining: 5s Progress 1551 / 9694 Time remaining: 5s Progress 1552 / 9694 Time remaining: 5s Progress 1553 / 9694 Time remaining: 5s Progress 1554 / 9694 Time remaining: 5s Progress 1555 / 9694 Time remaining: 5s Progress 1556 / 9694 Time remaining: 5s Progress 1557 / 9694 Time remaining: 5s Progress 1558 / 9694 Time remaining: 5s Progress 1559 / 9694 Time remaining: 5s Progress 1560 / 9694 Time remaining: 5s Progress 1561 / 9694 Time remaining: 5s Progress 1562 / 9694 Time remaining: 5s Progress 1563 / 9694 Time remaining: 5s Progress 1564 / 9694 Time remaining: 5s Progress 1565 / 9694 Time remaining: 5s Progress 1566 / 9694 Time remaining: 5s Progress 1567 / 9694 Time remaining: 5s Progress 1568 / 9694 Time remaining: 5s Progress 1569 / 9694 Time remaining: 5s Progress 1570 / 9694 Time remaining: 5s Progress 1571 / 9694 Time remaining: 5s Progress 1572 / 9694 Time remaining: 5s Progress 1573 / 9694 Time remaining: 5s Progress 1574 / 9694 Time remaining: 5s Progress 1575 / 9694 Time remaining: 5s Progress 1576 / 9694 Time remaining: 5s Progress 1577 / 9694 Time remaining: 5s Progress 1578 / 9694 Time remaining: 5s Progress 1579 / 9694 Time remaining: 5s Progress 1580 / 9694 Time remaining: 5s Progress 1581 / 9694 Time remaining: 5s Progress 1582 / 9694 Time remaining: 5s Progress 1583 / 9694 Time remaining: 5s Progress 1584 / 9694 Time remaining: 5s Progress 1585 / 9694 Time remaining: 5s Progress 1586 / 9694 Time remaining: 5s Progress 1587 / 9694 Time remaining: 5s Progress 1588 / 9694 Time remaining: 5s Progress 1589 / 9694 Time remaining: 5s Progress 1590 / 9694 Time remaining: 5s Progress 1591 / 9694 Time remaining: 5s Progress 1592 / 9694 Time remaining: 5s Progress 1593 / 9694 Time remaining: 5s Progress 1594 / 9694 Time remaining: 5s Progress 1595 / 9694 Time remaining: 5s Progress 1596 / 9694 Time remaining: 5s Progress 1597 / 9694 Time remaining: 5s Progress 1598 / 9694 Time remaining: 5s Progress 1599 / 9694 Time remaining: 5s Progress 1600 / 9694 Time remaining: 5s Progress 1601 / 9694 Time remaining: 5s Progress 1602 / 9694 Time remaining: 5s Progress 1603 / 9694 Time remaining: 5s Progress 1604 / 9694 Time remaining: 5s Progress 1605 / 9694 Time remaining: 5s Progress 1606 / 9694 Time remaining: 5s Progress 1607 / 9694 Time remaining: 5s Progress 1608 / 9694 Time remaining: 5s Progress 1609 / 9694 Time remaining: 5s Progress 1610 / 9694 Time remaining: 5s Progress 1611 / 9694 Time remaining: 5s Progress 1612 / 9694 Time remaining: 5s Progress 1613 / 9694 Time remaining: 5s Progress 1614 / 9694 Time remaining: 5s Progress 1615 / 9694 Time remaining: 5s Progress 1616 / 9694 Time remaining: 5s Progress 1617 / 9694 Time remaining: 5s Progress 1618 / 9694 Time remaining: 5s Progress 1619 / 9694 Time remaining: 5s Progress 1620 / 9694 Time remaining: 5s Progress 1621 / 9694 Time remaining: 5s Progress 1622 / 9694 Time remaining: 5s Progress 1623 / 9694 Time remaining: 5s Progress 1624 / 9694 Time remaining: 5s Progress 1625 / 9694 Time remaining: 5s Progress 1626 / 9694 Time remaining: 5s Progress 1627 / 9694 Time remaining: 5s Progress 1628 / 9694 Time remaining: 5s Progress 1629 / 9694 Time remaining: 5s Progress 1630 / 9694 Time remaining: 5s Progress 1631 / 9694 Time remaining: 5s Progress 1632 / 9694 Time remaining: 5s Progress 1633 / 9694 Time remaining: 5s Progress 1634 / 9694 Time remaining: 5s Progress 1635 / 9694 Time remaining: 5s Progress 1636 / 9694 Time remaining: 5s Progress 1637 / 9694 Time remaining: 5s Progress 1638 / 9694 Time remaining: 5s Progress 1639 / 9694 Time remaining: 5s Progress 1640 / 9694 Time remaining: 5s Progress 1641 / 9694 Time remaining: 5s Progress 1642 / 9694 Time remaining: 5s Progress 1643 / 9694 Time remaining: 5s Progress 1644 / 9694 Time remaining: 5s Progress 1645 / 9694 Time remaining: 5s Progress 1646 / 9694 Time remaining: 5s Progress 1647 / 9694 Time remaining: 5s Progress 1648 / 9694 Time remaining: 5s Progress 1649 / 9694 Time remaining: 5s Progress 1650 / 9694 Time remaining: 5s Progress 1651 / 9694 Time remaining: 5s Progress 1652 / 9694 Time remaining: 5s Progress 1653 / 9694 Time remaining: 5s Progress 1654 / 9694 Time remaining: 5s Progress 1655 / 9694 Time remaining: 5s Progress 1656 / 9694 Time remaining: 5s Progress 1657 / 9694 Time remaining: 5s Progress 1658 / 9694 Time remaining: 5s Progress 1659 / 9694 Time remaining: 5s Progress 1660 / 9694 Time remaining: 5s Progress 1661 / 9694 Time remaining: 5s Progress 1662 / 9694 Time remaining: 5s Progress 1663 / 9694 Time remaining: 5s Progress 1664 / 9694 Time remaining: 5s Progress 1665 / 9694 Time remaining: 5s Progress 1666 / 9694 Time remaining: 5s Progress 1667 / 9694 Time remaining: 5s Progress 1668 / 9694 Time remaining: 5s Progress 1669 / 9694 Time remaining: 5s Progress 1670 / 9694 Time remaining: 5s Progress 1671 / 9694 Time remaining: 5s Progress 1672 / 9694 Time remaining: 5s Progress 1673 / 9694 Time remaining: 5s Progress 1674 / 9694 Time remaining: 5s Progress 1675 / 9694 Time remaining: 5s Progress 1676 / 9694 Time remaining: 5s Progress 1677 / 9694 Time remaining: 5s Progress 1678 / 9694 Time remaining: 5s Progress 1679 / 9694 Time remaining: 5s Progress 1680 / 9694 Time remaining: 5s Progress 1681 / 9694 Time remaining: 5s Progress 1682 / 9694 Time remaining: 5s Progress 1683 / 9694 Time remaining: 5s Progress 1684 / 9694 Time remaining: 5s Progress 1685 / 9694 Time remaining: 5s Progress 1686 / 9694 Time remaining: 5s Progress 1687 / 9694 Time remaining: 5s Progress 1688 / 9694 Time remaining: 5s Progress 1689 / 9694 Time remaining: 5s Progress 1690 / 9694 Time remaining: 5s Progress 1691 / 9694 Time remaining: 5s Progress 1692 / 9694 Time remaining: 5s Progress 1693 / 9694 Time remaining: 5s Progress 1694 / 9694 Time remaining: 5s Progress 1695 / 9694 Time remaining: 5s Progress 1696 / 9694 Time remaining: 5s Progress 1697 / 9694 Time remaining: 5s Progress 1698 / 9694 Time remaining: 5s Progress 1699 / 9694 Time remaining: 5s Progress 1700 / 9694 Time remaining: 5s Progress 1701 / 9694 Time remaining: 5s Progress 1702 / 9694 Time remaining: 5s Progress 1703 / 9694 Time remaining: 5s Progress 1704 / 9694 Time remaining: 5s Progress 1705 / 9694 Time remaining: 5s Progress 1706 / 9694 Time remaining: 5s Progress 1707 / 9694 Time remaining: 5s Progress 1708 / 9694 Time remaining: 5s Progress 1709 / 9694 Time remaining: 5s Progress 1710 / 9694 Time remaining: 5s Progress 1711 / 9694 Time remaining: 5s Progress 1712 / 9694 Time remaining: 5s Progress 1713 / 9694 Time remaining: 5s Progress 1714 / 9694 Time remaining: 5s Progress 1715 / 9694 Time remaining: 5s Progress 1716 / 9694 Time remaining: 5s Progress 1717 / 9694 Time remaining: 5s Progress 1718 / 9694 Time remaining: 5s Progress 1719 / 9694 Time remaining: 5s Progress 1720 / 9694 Time remaining: 5s Progress 1721 / 9694 Time remaining: 5s Progress 1722 / 9694 Time remaining: 5s Progress 1723 / 9694 Time remaining: 5s Progress 1724 / 9694 Time remaining: 5s Progress 1725 / 9694 Time remaining: 5s Progress 1726 / 9694 Time remaining: 5s Progress 1727 / 9694 Time remaining: 5s Progress 1728 / 9694 Time remaining: 5s Progress 1729 / 9694 Time remaining: 5s Progress 1730 / 9694 Time remaining: 5s Progress 1731 / 9694 Time remaining: 5s Progress 1732 / 9694 Time remaining: 5s Progress 1733 / 9694 Time remaining: 5s Progress 1734 / 9694 Time remaining: 5s Progress 1735 / 9694 Time remaining: 5s Progress 1736 / 9694 Time remaining: 5s Progress 1737 / 9694 Time remaining: 5s Progress 1738 / 9694 Time remaining: 5s Progress 1739 / 9694 Time remaining: 5s Progress 1740 / 9694 Time remaining: 5s Progress 1741 / 9694 Time remaining: 5s Progress 1742 / 9694 Time remaining: 5s Progress 1743 / 9694 Time remaining: 5s Progress 1744 / 9694 Time remaining: 5s Progress 1745 / 9694 Time remaining: 5s Progress 1746 / 9694 Time remaining: 5s Progress 1747 / 9694 Time remaining: 5s Progress 1748 / 9694 Time remaining: 5s Progress 1749 / 9694 Time remaining: 5s Progress 1750 / 9694 Time remaining: 5s Progress 1751 / 9694 Time remaining: 5s Progress 1752 / 9694 Time remaining: 5s Progress 1753 / 9694 Time remaining: 5s Progress 1754 / 9694 Time remaining: 5s Progress 1755 / 9694 Time remaining: 5s Progress 1756 / 9694 Time remaining: 5s Progress 1757 / 9694 Time remaining: 5s Progress 1758 / 9694 Time remaining: 5s Progress 1759 / 9694 Time remaining: 5s Progress 1760 / 9694 Time remaining: 5s Progress 1761 / 9694 Time remaining: 5s Progress 1762 / 9694 Time remaining: 5s Progress 1763 / 9694 Time remaining: 5s Progress 1764 / 9694 Time remaining: 5s Progress 1765 / 9694 Time remaining: 5s Progress 1766 / 9694 Time remaining: 5s Progress 1767 / 9694 Time remaining: 5s Progress 1768 / 9694 Time remaining: 5s Progress 1769 / 9694 Time remaining: 5s Progress 1770 / 9694 Time remaining: 5s Progress 1771 / 9694 Time remaining: 5s Progress 1772 / 9694 Time remaining: 5s Progress 1773 / 9694 Time remaining: 5s Progress 1774 / 9694 Time remaining: 5s Progress 1775 / 9694 Time remaining: 5s Progress 1776 / 9694 Time remaining: 5s Progress 1777 / 9694 Time remaining: 5s Progress 1778 / 9694 Time remaining: 5s Progress 1779 / 9694 Time remaining: 5s Progress 1780 / 9694 Time remaining: 5s Progress 1781 / 9694 Time remaining: 5s Progress 1782 / 9694 Time remaining: 5s Progress 1783 / 9694 Time remaining: 5s Progress 1784 / 9694 Time remaining: 5s Progress 1785 / 9694 Time remaining: 5s Progress 1786 / 9694 Time remaining: 5s Progress 1787 / 9694 Time remaining: 5s Progress 1788 / 9694 Time remaining: 5s Progress 1789 / 9694 Time remaining: 5s Progress 1790 / 9694 Time remaining: 5s Progress 1791 / 9694 Time remaining: 5s Progress 1792 / 9694 Time remaining: 5s Progress 1793 / 9694 Time remaining: 5s Progress 1794 / 9694 Time remaining: 5s Progress 1795 / 9694 Time remaining: 5s Progress 1796 / 9694 Time remaining: 5s Progress 1797 / 9694 Time remaining: 5s Progress 1798 / 9694 Time remaining: 5s Progress 1799 / 9694 Time remaining: 5s Progress 1800 / 9694 Time remaining: 5s Progress 1801 / 9694 Time remaining: 5s Progress 1802 / 9694 Time remaining: 5s Progress 1803 / 9694 Time remaining: 5s Progress 1804 / 9694 Time remaining: 5s Progress 1805 / 9694 Time remaining: 5s Progress 1806 / 9694 Time remaining: 5s Progress 1807 / 9694 Time remaining: 5s Progress 1808 / 9694 Time remaining: 5s Progress 1809 / 9694 Time remaining: 5s Progress 1810 / 9694 Time remaining: 5s Progress 1811 / 9694 Time remaining: 5s Progress 1812 / 9694 Time remaining: 5s Progress 1813 / 9694 Time remaining: 5s Progress 1814 / 9694 Time remaining: 5s Progress 1815 / 9694 Time remaining: 5s Progress 1816 / 9694 Time remaining: 5s Progress 1817 / 9694 Time remaining: 5s Progress 1818 / 9694 Time remaining: 5s Progress 1819 / 9694 Time remaining: 5s Progress 1820 / 9694 Time remaining: 5s Progress 1821 / 9694 Time remaining: 5s Progress 1822 / 9694 Time remaining: 5s Progress 1823 / 9694 Time remaining: 5s Progress 1824 / 9694 Time remaining: 5s Progress 1825 / 9694 Time remaining: 5s Progress 1826 / 9694 Time remaining: 5s Progress 1827 / 9694 Time remaining: 5s Progress 1828 / 9694 Time remaining: 5s Progress 1829 / 9694 Time remaining: 5s Progress 1830 / 9694 Time remaining: 5s Progress 1831 / 9694 Time remaining: 5s Progress 1832 / 9694 Time remaining: 5s Progress 1833 / 9694 Time remaining: 5s Progress 1834 / 9694 Time remaining: 5s Progress 1835 / 9694 Time remaining: 5s Progress 1836 / 9694 Time remaining: 5s Progress 1837 / 9694 Time remaining: 5s Progress 1838 / 9694 Time remaining: 5s Progress 1839 / 9694 Time remaining: 5s Progress 1840 / 9694 Time remaining: 5s Progress 1841 / 9694 Time remaining: 5s Progress 1842 / 9694 Time remaining: 5s Progress 1843 / 9694 Time remaining: 5s Progress 1844 / 9694 Time remaining: 5s Progress 1845 / 9694 Time remaining: 5s Progress 1846 / 9694 Time remaining: 5s Progress 1847 / 9694 Time remaining: 5s Progress 1848 / 9694 Time remaining: 5s Progress 1849 / 9694 Time remaining: 5s Progress 1850 / 9694 Time remaining: 5s Progress 1851 / 9694 Time remaining: 5s Progress 1852 / 9694 Time remaining: 5s Progress 1853 / 9694 Time remaining: 5s Progress 1854 / 9694 Time remaining: 5s Progress 1855 / 9694 Time remaining: 5s Progress 1856 / 9694 Time remaining: 5s Progress 1857 / 9694 Time remaining: 5s Progress 1858 / 9694 Time remaining: 5s Progress 1859 / 9694 Time remaining: 5s Progress 1860 / 9694 Time remaining: 5s Progress 1861 / 9694 Time remaining: 5s Progress 1862 / 9694 Time remaining: 5s Progress 1863 / 9694 Time remaining: 5s Progress 1864 / 9694 Time remaining: 5s Progress 1865 / 9694 Time remaining: 5s Progress 1866 / 9694 Time remaining: 5s Progress 1867 / 9694 Time remaining: 5s Progress 1868 / 9694 Time remaining: 5s Progress 1869 / 9694 Time remaining: 5s Progress 1870 / 9694 Time remaining: 5s Progress 1871 / 9694 Time remaining: 5s Progress 1872 / 9694 Time remaining: 5s Progress 1873 / 9694 Time remaining: 5s Progress 1874 / 9694 Time remaining: 5s Progress 1875 / 9694 Time remaining: 5s Progress 1876 / 9694 Time remaining: 5s Progress 1877 / 9694 Time remaining: 5s Progress 1878 / 9694 Time remaining: 5s Progress 1879 / 9694 Time remaining: 5s Progress 1880 / 9694 Time remaining: 5s Progress 1881 / 9694 Time remaining: 5s Progress 1882 / 9694 Time remaining: 5s Progress 1883 / 9694 Time remaining: 5s Progress 1884 / 9694 Time remaining: 5s Progress 1885 / 9694 Time remaining: 5s Progress 1886 / 9694 Time remaining: 5s Progress 1887 / 9694 Time remaining: 5s Progress 1888 / 9694 Time remaining: 5s Progress 1889 / 9694 Time remaining: 5s Progress 1890 / 9694 Time remaining: 5s Progress 1891 / 9694 Time remaining: 5s Progress 1892 / 9694 Time remaining: 5s Progress 1893 / 9694 Time remaining: 5s Progress 1894 / 9694 Time remaining: 5s Progress 1895 / 9694 Time remaining: 5s Progress 1896 / 9694 Time remaining: 5s Progress 1897 / 9694 Time remaining: 5s Progress 1898 / 9694 Time remaining: 5s Progress 1899 / 9694 Time remaining: 5s Progress 1900 / 9694 Time remaining: 5s Progress 1901 / 9694 Time remaining: 5s Progress 1902 / 9694 Time remaining: 5s Progress 1903 / 9694 Time remaining: 5s Progress 1904 / 9694 Time remaining: 5s Progress 1905 / 9694 Time remaining: 5s Progress 1906 / 9694 Time remaining: 5s Progress 1907 / 9694 Time remaining: 5s Progress 1908 / 9694 Time remaining: 5s Progress 1909 / 9694 Time remaining: 5s Progress 1910 / 9694 Time remaining: 5s Progress 1911 / 9694 Time remaining: 5s Progress 1912 / 9694 Time remaining: 5s Progress 1913 / 9694 Time remaining: 5s Progress 1914 / 9694 Time remaining: 5s Progress 1915 / 9694 Time remaining: 5s Progress 1916 / 9694 Time remaining: 5s Progress 1917 / 9694 Time remaining: 5s Progress 1918 / 9694 Time remaining: 5s Progress 1919 / 9694 Time remaining: 5s Progress 1920 / 9694 Time remaining: 5s Progress 1921 / 9694 Time remaining: 5s Progress 1922 / 9694 Time remaining: 5s Progress 1923 / 9694 Time remaining: 5s Progress 1924 / 9694 Time remaining: 5s Progress 1925 / 9694 Time remaining: 5s Progress 1926 / 9694 Time remaining: 5s Progress 1927 / 9694 Time remaining: 5s Progress 1928 / 9694 Time remaining: 5s Progress 1929 / 9694 Time remaining: 5s Progress 1930 / 9694 Time remaining: 5s Progress 1931 / 9694 Time remaining: 5s Progress 1932 / 9694 Time remaining: 5s Progress 1933 / 9694 Time remaining: 5s Progress 1934 / 9694 Time remaining: 5s Progress 1935 / 9694 Time remaining: 5s Progress 1936 / 9694 Time remaining: 5s Progress 1937 / 9694 Time remaining: 5s Progress 1938 / 9694 Time remaining: 5s Progress 1939 / 9694 Time remaining: 5s Progress 1940 / 9694 Time remaining: 5s Progress 1941 / 9694 Time remaining: 5s Progress 1942 / 9694 Time remaining: 5s Progress 1943 / 9694 Time remaining: 5s Progress 1944 / 9694 Time remaining: 5s Progress 1945 / 9694 Time remaining: 5s Progress 1946 / 9694 Time remaining: 5s Progress 1947 / 9694 Time remaining: 5s Progress 1948 / 9694 Time remaining: 5s Progress 1949 / 9694 Time remaining: 5s Progress 1950 / 9694 Time remaining: 5s Progress 1951 / 9694 Time remaining: 5s Progress 1952 / 9694 Time remaining: 5s Progress 1953 / 9694 Time remaining: 5s Progress 1954 / 9694 Time remaining: 5s Progress 1955 / 9694 Time remaining: 5s Progress 1956 / 9694 Time remaining: 5s Progress 1957 / 9694 Time remaining: 5s Progress 1958 / 9694 Time remaining: 5s Progress 1959 / 9694 Time remaining: 5s Progress 1960 / 9694 Time remaining: 5s Progress 1961 / 9694 Time remaining: 5s Progress 1962 / 9694 Time remaining: 5s Progress 1963 / 9694 Time remaining: 5s Progress 1964 / 9694 Time remaining: 5s Progress 1965 / 9694 Time remaining: 5s Progress 1966 / 9694 Time remaining: 5s Progress 1967 / 9694 Time remaining: 5s Progress 1968 / 9694 Time remaining: 5s Progress 1969 / 9694 Time remaining: 5s Progress 1970 / 9694 Time remaining: 5s Progress 1971 / 9694 Time remaining: 5s Progress 1972 / 9694 Time remaining: 5s Progress 1973 / 9694 Time remaining: 5s Progress 1974 / 9694 Time remaining: 5s Progress 1975 / 9694 Time remaining: 5s Progress 1976 / 9694 Time remaining: 5s Progress 1977 / 9694 Time remaining: 5s Progress 1978 / 9694 Time remaining: 5s Progress 1979 / 9694 Time remaining: 5s Progress 1980 / 9694 Time remaining: 5s Progress 1981 / 9694 Time remaining: 5s Progress 1982 / 9694 Time remaining: 5s Progress 1983 / 9694 Time remaining: 5s Progress 1984 / 9694 Time remaining: 5s Progress 1985 / 9694 Time remaining: 5s Progress 1986 / 9694 Time remaining: 5s Progress 1987 / 9694 Time remaining: 5s Progress 1988 / 9694 Time remaining: 5s Progress 1989 / 9694 Time remaining: 5s Progress 1990 / 9694 Time remaining: 5s Progress 1991 / 9694 Time remaining: 5s Progress 1992 / 9694 Time remaining: 5s Progress 1993 / 9694 Time remaining: 5s Progress 1994 / 9694 Time remaining: 5s Progress 1995 / 9694 Time remaining: 5s Progress 1996 / 9694 Time remaining: 5s Progress 1997 / 9694 Time remaining: 5s Progress 1998 / 9694 Time remaining: 5s Progress 1999 / 9694 Time remaining: 5s Progress 2000 / 9694 Time remaining: 5s Progress 2001 / 9694 Time remaining: 5s Progress 2002 / 9694 Time remaining: 5s Progress 2003 / 9694 Time remaining: 5s Progress 2004 / 9694 Time remaining: 5s Progress 2005 / 9694 Time remaining: 5s Progress 2006 / 9694 Time remaining: 5s Progress 2007 / 9694 Time remaining: 5s Progress 2008 / 9694 Time remaining: 5s Progress 2009 / 9694 Time remaining: 5s Progress 2010 / 9694 Time remaining: 5s Progress 2011 / 9694 Time remaining: 5s Progress 2012 / 9694 Time remaining: 5s Progress 2013 / 9694 Time remaining: 5s Progress 2014 / 9694 Time remaining: 5s Progress 2015 / 9694 Time remaining: 5s Progress 2016 / 9694 Time remaining: 5s Progress 2017 / 9694 Time remaining: 5s Progress 2018 / 9694 Time remaining: 5s Progress 2019 / 9694 Time remaining: 5s Progress 2020 / 9694 Time remaining: 5s Progress 2021 / 9694 Time remaining: 5s Progress 2022 / 9694 Time remaining: 5s Progress 2023 / 9694 Time remaining: 5s Progress 2024 / 9694 Time remaining: 5s Progress 2025 / 9694 Time remaining: 5s Progress 2026 / 9694 Time remaining: 5s Progress 2027 / 9694 Time remaining: 5s Progress 2028 / 9694 Time remaining: 5s Progress 2029 / 9694 Time remaining: 5s Progress 2030 / 9694 Time remaining: 5s Progress 2031 / 9694 Time remaining: 5s Progress 2032 / 9694 Time remaining: 5s Progress 2033 / 9694 Time remaining: 5s Progress 2034 / 9694 Time remaining: 5s Progress 2035 / 9694 Time remaining: 5s Progress 2036 / 9694 Time remaining: 5s Progress 2037 / 9694 Time remaining: 5s Progress 2038 / 9694 Time remaining: 5s Progress 2039 / 9694 Time remaining: 5s Progress 2040 / 9694 Time remaining: 5s Progress 2041 / 9694 Time remaining: 5s Progress 2042 / 9694 Time remaining: 5s Progress 2043 / 9694 Time remaining: 5s Progress 2044 / 9694 Time remaining: 5s Progress 2045 / 9694 Time remaining: 5s Progress 2046 / 9694 Time remaining: 5s Progress 2047 / 9694 Time remaining: 5s Progress 2048 / 9694 Time remaining: 5s Progress 2049 / 9694 Time remaining: 5s Progress 2050 / 9694 Time remaining: 5s Progress 2051 / 9694 Time remaining: 5s Progress 2052 / 9694 Time remaining: 5s Progress 2053 / 9694 Time remaining: 5s Progress 2054 / 9694 Time remaining: 5s Progress 2055 / 9694 Time remaining: 5s Progress 2056 / 9694 Time remaining: 5s Progress 2057 / 9694 Time remaining: 5s Progress 2058 / 9694 Time remaining: 5s Progress 2059 / 9694 Time remaining: 5s Progress 2060 / 9694 Time remaining: 5s Progress 2061 / 9694 Time remaining: 5s Progress 2062 / 9694 Time remaining: 5s Progress 2063 / 9694 Time remaining: 5s Progress 2064 / 9694 Time remaining: 5s Progress 2065 / 9694 Time remaining: 5s Progress 2066 / 9694 Time remaining: 5s Progress 2067 / 9694 Time remaining: 5s Progress 2068 / 9694 Time remaining: 5s Progress 2069 / 9694 Time remaining: 5s Progress 2070 / 9694 Time remaining: 5s Progress 2071 / 9694 Time remaining: 5s Progress 2072 / 9694 Time remaining: 5s Progress 2073 / 9694 Time remaining: 5s Progress 2074 / 9694 Time remaining: 5s Progress 2075 / 9694 Time remaining: 5s Progress 2076 / 9694 Time remaining: 5s Progress 2077 / 9694 Time remaining: 5s Progress 2078 / 9694 Time remaining: 5s Progress 2079 / 9694 Time remaining: 5s Progress 2080 / 9694 Time remaining: 5s Progress 2081 / 9694 Time remaining: 5s Progress 2082 / 9694 Time remaining: 5s Progress 2083 / 9694 Time remaining: 5s Progress 2084 / 9694 Time remaining: 5s Progress 2085 / 9694 Time remaining: 5s Progress 2086 / 9694 Time remaining: 5s Progress 2087 / 9694 Time remaining: 5s Progress 2088 / 9694 Time remaining: 5s Progress 2089 / 9694 Time remaining: 5s Progress 2090 / 9694 Time remaining: 5s Progress 2091 / 9694 Time remaining: 5s Progress 2092 / 9694 Time remaining: 5s Progress 2093 / 9694 Time remaining: 5s Progress 2094 / 9694 Time remaining: 5s Progress 2095 / 9694 Time remaining: 5s Progress 2096 / 9694 Time remaining: 5s Progress 2097 / 9694 Time remaining: 5s Progress 2098 / 9694 Time remaining: 5s Progress 2099 / 9694 Time remaining: 5s Progress 2100 / 9694 Time remaining: 5s Progress 2101 / 9694 Time remaining: 5s Progress 2102 / 9694 Time remaining: 5s Progress 2103 / 9694 Time remaining: 5s Progress 2104 / 9694 Time remaining: 5s Progress 2105 / 9694 Time remaining: 5s Progress 2106 / 9694 Time remaining: 5s Progress 2107 / 9694 Time remaining: 5s Progress 2108 / 9694 Time remaining: 5s Progress 2109 / 9694 Time remaining: 5s Progress 2110 / 9694 Time remaining: 5s Progress 2111 / 9694 Time remaining: 5s Progress 2112 / 9694 Time remaining: 5s Progress 2113 / 9694 Time remaining: 5s Progress 2114 / 9694 Time remaining: 5s Progress 2115 / 9694 Time remaining: 5s Progress 2116 / 9694 Time remaining: 5s Progress 2117 / 9694 Time remaining: 5s Progress 2118 / 9694 Time remaining: 5s Progress 2119 / 9694 Time remaining: 5s Progress 2120 / 9694 Time remaining: 5s Progress 2121 / 9694 Time remaining: 5s Progress 2122 / 9694 Time remaining: 5s Progress 2123 / 9694 Time remaining: 5s Progress 2124 / 9694 Time remaining: 5s Progress 2125 / 9694 Time remaining: 5s Progress 2126 / 9694 Time remaining: 5s Progress 2127 / 9694 Time remaining: 5s Progress 2128 / 9694 Time remaining: 5s Progress 2129 / 9694 Time remaining: 5s Progress 2130 / 9694 Time remaining: 5s Progress 2131 / 9694 Time remaining: 5s Progress 2132 / 9694 Time remaining: 5s Progress 2133 / 9694 Time remaining: 5s Progress 2134 / 9694 Time remaining: 5s Progress 2135 / 9694 Time remaining: 5s Progress 2136 / 9694 Time remaining: 5s Progress 2137 / 9694 Time remaining: 5s Progress 2138 / 9694 Time remaining: 5s Progress 2139 / 9694 Time remaining: 5s Progress 2140 / 9694 Time remaining: 5s Progress 2141 / 9694 Time remaining: 5s Progress 2142 / 9694 Time remaining: 5s Progress 2143 / 9694 Time remaining: 5s Progress 2144 / 9694 Time remaining: 5s Progress 2145 / 9694 Time remaining: 5s Progress 2146 / 9694 Time remaining: 5s Progress 2147 / 9694 Time remaining: 5s Progress 2148 / 9694 Time remaining: 5s Progress 2149 / 9694 Time remaining: 5s Progress 2150 / 9694 Time remaining: 5s Progress 2151 / 9694 Time remaining: 5s Progress 2152 / 9694 Time remaining: 5s Progress 2153 / 9694 Time remaining: 5s Progress 2154 / 9694 Time remaining: 5s Progress 2155 / 9694 Time remaining: 5s Progress 2156 / 9694 Time remaining: 5s Progress 2157 / 9694 Time remaining: 5s Progress 2158 / 9694 Time remaining: 5s Progress 2159 / 9694 Time remaining: 5s Progress 2160 / 9694 Time remaining: 5s Progress 2161 / 9694 Time remaining: 5s Progress 2162 / 9694 Time remaining: 5s Progress 2163 / 9694 Time remaining: 5s Progress 2164 / 9694 Time remaining: 5s Progress 2165 / 9694 Time remaining: 5s Progress 2166 / 9694 Time remaining: 5s Progress 2167 / 9694 Time remaining: 5s Progress 2168 / 9694 Time remaining: 5s Progress 2169 / 9694 Time remaining: 5s Progress 2170 / 9694 Time remaining: 5s Progress 2171 / 9694 Time remaining: 5s Progress 2172 / 9694 Time remaining: 5s Progress 2173 / 9694 Time remaining: 5s Progress 2174 / 9694 Time remaining: 5s Progress 2175 / 9694 Time remaining: 5s Progress 2176 / 9694 Time remaining: 5s Progress 2177 / 9694 Time remaining: 5s Progress 2178 / 9694 Time remaining: 5s Progress 2179 / 9694 Time remaining: 5s Progress 2180 / 9694 Time remaining: 5s Progress 2181 / 9694 Time remaining: 5s Progress 2182 / 9694 Time remaining: 5s Progress 2183 / 9694 Time remaining: 5s Progress 2184 / 9694 Time remaining: 5s Progress 2185 / 9694 Time remaining: 5s Progress 2186 / 9694 Time remaining: 5s Progress 2187 / 9694 Time remaining: 5s Progress 2188 / 9694 Time remaining: 5s Progress 2189 / 9694 Time remaining: 5s Progress 2190 / 9694 Time remaining: 5s Progress 2191 / 9694 Time remaining: 5s Progress 2192 / 9694 Time remaining: 5s Progress 2193 / 9694 Time remaining: 5s Progress 2194 / 9694 Time remaining: 5s Progress 2195 / 9694 Time remaining: 5s Progress 2196 / 9694 Time remaining: 5s Progress 2197 / 9694 Time remaining: 5s Progress 2198 / 9694 Time remaining: 5s Progress 2199 / 9694 Time remaining: 5s Progress 2200 / 9694 Time remaining: 5s Progress 2201 / 9694 Time remaining: 5s Progress 2202 / 9694 Time remaining: 5s Progress 2203 / 9694 Time remaining: 5s Progress 2204 / 9694 Time remaining: 5s Progress 2205 / 9694 Time remaining: 5s Progress 2206 / 9694 Time remaining: 5s Progress 2207 / 9694 Time remaining: 5s Progress 2208 / 9694 Time remaining: 5s Progress 2209 / 9694 Time remaining: 5s Progress 2210 / 9694 Time remaining: 5s Progress 2211 / 9694 Time remaining: 5s Progress 2212 / 9694 Time remaining: 5s Progress 2213 / 9694 Time remaining: 5s Progress 2214 / 9694 Time remaining: 5s Progress 2215 / 9694 Time remaining: 5s Progress 2216 / 9694 Time remaining: 5s Progress 2217 / 9694 Time remaining: 5s Progress 2218 / 9694 Time remaining: 5s Progress 2219 / 9694 Time remaining: 5s Progress 2220 / 9694 Time remaining: 5s Progress 2221 / 9694 Time remaining: 5s Progress 2222 / 9694 Time remaining: 5s Progress 2223 / 9694 Time remaining: 5s Progress 2224 / 9694 Time remaining: 5s Progress 2225 / 9694 Time remaining: 5s Progress 2226 / 9694 Time remaining: 5s Progress 2227 / 9694 Time remaining: 5s Progress 2228 / 9694 Time remaining: 5s Progress 2229 / 9694 Time remaining: 5s Progress 2230 / 9694 Time remaining: 5s Progress 2231 / 9694 Time remaining: 5s Progress 2232 / 9694 Time remaining: 5s Progress 2233 / 9694 Time remaining: 5s Progress 2234 / 9694 Time remaining: 5s Progress 2235 / 9694 Time remaining: 5s Progress 2236 / 9694 Time remaining: 5s Progress 2237 / 9694 Time remaining: 5s Progress 2238 / 9694 Time remaining: 5s Progress 2239 / 9694 Time remaining: 5s Progress 2240 / 9694 Time remaining: 5s Progress 2241 / 9694 Time remaining: 5s Progress 2242 / 9694 Time remaining: 5s Progress 2243 / 9694 Time remaining: 5s Progress 2244 / 9694 Time remaining: 5s Progress 2245 / 9694 Time remaining: 5s Progress 2246 / 9694 Time remaining: 5s Progress 2247 / 9694 Time remaining: 5s Progress 2248 / 9694 Time remaining: 5s Progress 2249 / 9694 Time remaining: 5s Progress 2250 / 9694 Time remaining: 5s Progress 2251 / 9694 Time remaining: 5s Progress 2252 / 9694 Time remaining: 5s Progress 2253 / 9694 Time remaining: 5s Progress 2254 / 9694 Time remaining: 5s Progress 2255 / 9694 Time remaining: 5s Progress 2256 / 9694 Time remaining: 5s Progress 2257 / 9694 Time remaining: 5s Progress 2258 / 9694 Time remaining: 5s Progress 2259 / 9694 Time remaining: 5s Progress 2260 / 9694 Time remaining: 5s Progress 2261 / 9694 Time remaining: 5s Progress 2262 / 9694 Time remaining: 5s Progress 2263 / 9694 Time remaining: 5s Progress 2264 / 9694 Time remaining: 5s Progress 2265 / 9694 Time remaining: 5s Progress 2266 / 9694 Time remaining: 5s Progress 2267 / 9694 Time remaining: 5s Progress 2268 / 9694 Time remaining: 5s Progress 2269 / 9694 Time remaining: 5s Progress 2270 / 9694 Time remaining: 5s Progress 2271 / 9694 Time remaining: 5s Progress 2272 / 9694 Time remaining: 5s Progress 2273 / 9694 Time remaining: 5s Progress 2274 / 9694 Time remaining: 5s Progress 2275 / 9694 Time remaining: 5s Progress 2276 / 9694 Time remaining: 5s Progress 2277 / 9694 Time remaining: 5s Progress 2278 / 9694 Time remaining: 5s Progress 2279 / 9694 Time remaining: 5s Progress 2280 / 9694 Time remaining: 5s Progress 2281 / 9694 Time remaining: 5s Progress 2282 / 9694 Time remaining: 5s Progress 2283 / 9694 Time remaining: 5s Progress 2284 / 9694 Time remaining: 5s Progress 2285 / 9694 Time remaining: 5s Progress 2286 / 9694 Time remaining: 5s Progress 2287 / 9694 Time remaining: 5s Progress 2288 / 9694 Time remaining: 5s Progress 2289 / 9694 Time remaining: 5s Progress 2290 / 9694 Time remaining: 5s Progress 2291 / 9694 Time remaining: 5s Progress 2292 / 9694 Time remaining: 5s Progress 2293 / 9694 Time remaining: 5s Progress 2294 / 9694 Time remaining: 5s Progress 2295 / 9694 Time remaining: 5s Progress 2296 / 9694 Time remaining: 5s Progress 2297 / 9694 Time remaining: 5s Progress 2298 / 9694 Time remaining: 5s Progress 2299 / 9694 Time remaining: 5s Progress 2300 / 9694 Time remaining: 5s Progress 2301 / 9694 Time remaining: 5s Progress 2302 / 9694 Time remaining: 5s Progress 2303 / 9694 Time remaining: 5s Progress 2304 / 9694 Time remaining: 5s Progress 2305 / 9694 Time remaining: 5s Progress 2306 / 9694 Time remaining: 5s Progress 2307 / 9694 Time remaining: 5s Progress 2308 / 9694 Time remaining: 5s Progress 2309 / 9694 Time remaining: 5s Progress 2310 / 9694 Time remaining: 5s Progress 2311 / 9694 Time remaining: 5s Progress 2312 / 9694 Time remaining: 5s Progress 2313 / 9694 Time remaining: 5s Progress 2314 / 9694 Time remaining: 5s Progress 2315 / 9694 Time remaining: 5s Progress 2316 / 9694 Time remaining: 5s Progress 2317 / 9694 Time remaining: 5s Progress 2318 / 9694 Time remaining: 5s Progress 2319 / 9694 Time remaining: 5s Progress 2320 / 9694 Time remaining: 5s Progress 2321 / 9694 Time remaining: 5s Progress 2322 / 9694 Time remaining: 5s Progress 2323 / 9694 Time remaining: 5s Progress 2324 / 9694 Time remaining: 5s Progress 2325 / 9694 Time remaining: 5s Progress 2326 / 9694 Time remaining: 5s Progress 2327 / 9694 Time remaining: 5s Progress 2328 / 9694 Time remaining: 5s Progress 2329 / 9694 Time remaining: 5s Progress 2330 / 9694 Time remaining: 5s Progress 2331 / 9694 Time remaining: 5s Progress 2332 / 9694 Time remaining: 5s Progress 2333 / 9694 Time remaining: 5s Progress 2334 / 9694 Time remaining: 5s Progress 2335 / 9694 Time remaining: 5s Progress 2336 / 9694 Time remaining: 5s Progress 2337 / 9694 Time remaining: 5s Progress 2338 / 9694 Time remaining: 5s Progress 2339 / 9694 Time remaining: 5s Progress 2340 / 9694 Time remaining: 5s Progress 2341 / 9694 Time remaining: 5s Progress 2342 / 9694 Time remaining: 5s Progress 2343 / 9694 Time remaining: 5s Progress 2344 / 9694 Time remaining: 5s Progress 2345 / 9694 Time remaining: 5s Progress 2346 / 9694 Time remaining: 5s Progress 2347 / 9694 Time remaining: 5s Progress 2348 / 9694 Time remaining: 5s Progress 2349 / 9694 Time remaining: 5s Progress 2350 / 9694 Time remaining: 5s Progress 2351 / 9694 Time remaining: 5s Progress 2352 / 9694 Time remaining: 5s Progress 2353 / 9694 Time remaining: 5s Progress 2354 / 9694 Time remaining: 5s Progress 2355 / 9694 Time remaining: 5s Progress 2356 / 9694 Time remaining: 5s Progress 2357 / 9694 Time remaining: 5s Progress 2358 / 9694 Time remaining: 5s Progress 2359 / 9694 Time remaining: 5s Progress 2360 / 9694 Time remaining: 5s Progress 2361 / 9694 Time remaining: 5s Progress 2362 / 9694 Time remaining: 5s Progress 2363 / 9694 Time remaining: 5s Progress 2364 / 9694 Time remaining: 5s Progress 2365 / 9694 Time remaining: 5s Progress 2366 / 9694 Time remaining: 5s Progress 2367 / 9694 Time remaining: 5s Progress 2368 / 9694 Time remaining: 5s Progress 2369 / 9694 Time remaining: 5s Progress 2370 / 9694 Time remaining: 5s Progress 2371 / 9694 Time remaining: 5s Progress 2372 / 9694 Time remaining: 5s Progress 2373 / 9694 Time remaining: 5s Progress 2374 / 9694 Time remaining: 5s Progress 2375 / 9694 Time remaining: 5s Progress 2376 / 9694 Time remaining: 5s Progress 2377 / 9694 Time remaining: 5s Progress 2378 / 9694 Time remaining: 5s Progress 2379 / 9694 Time remaining: 5s Progress 2380 / 9694 Time remaining: 5s Progress 2381 / 9694 Time remaining: 5s Progress 2382 / 9694 Time remaining: 5s Progress 2383 / 9694 Time remaining: 5s Progress 2384 / 9694 Time remaining: 5s Progress 2385 / 9694 Time remaining: 5s Progress 2386 / 9694 Time remaining: 5s Progress 2387 / 9694 Time remaining: 5s Progress 2388 / 9694 Time remaining: 5s Progress 2389 / 9694 Time remaining: 5s Progress 2390 / 9694 Time remaining: 5s Progress 2391 / 9694 Time remaining: 5s Progress 2392 / 9694 Time remaining: 5s Progress 2393 / 9694 Time remaining: 5s Progress 2394 / 9694 Time remaining: 5s Progress 2395 / 9694 Time remaining: 5s Progress 2396 / 9694 Time remaining: 5s Progress 2397 / 9694 Time remaining: 5s Progress 2398 / 9694 Time remaining: 5s Progress 2399 / 9694 Time remaining: 5s Progress 2400 / 9694 Time remaining: 5s Progress 2401 / 9694 Time remaining: 5s Progress 2402 / 9694 Time remaining: 5s Progress 2403 / 9694 Time remaining: 5s Progress 2404 / 9694 Time remaining: 5s Progress 2405 / 9694 Time remaining: 5s Progress 2406 / 9694 Time remaining: 5s Progress 2407 / 9694 Time remaining: 5s Progress 2408 / 9694 Time remaining: 5s Progress 2409 / 9694 Time remaining: 5s Progress 2410 / 9694 Time remaining: 5s Progress 2411 / 9694 Time remaining: 5s Progress 2412 / 9694 Time remaining: 5s Progress 2413 / 9694 Time remaining: 5s Progress 2414 / 9694 Time remaining: 5s Progress 2415 / 9694 Time remaining: 5s Progress 2416 / 9694 Time remaining: 5s Progress 2417 / 9694 Time remaining: 5s Progress 2418 / 9694 Time remaining: 5s Progress 2419 / 9694 Time remaining: 5s Progress 2420 / 9694 Time remaining: 5s Progress 2421 / 9694 Time remaining: 5s Progress 2422 / 9694 Time remaining: 5s Progress 2423 / 9694 Time remaining: 5s Progress 2424 / 9694 Time remaining: 5s Progress 2425 / 9694 Time remaining: 5s Progress 2426 / 9694 Time remaining: 5s Progress 2427 / 9694 Time remaining: 5s Progress 2428 / 9694 Time remaining: 5s Progress 2429 / 9694 Time remaining: 5s Progress 2430 / 9694 Time remaining: 5s Progress 2431 / 9694 Time remaining: 5s Progress 2432 / 9694 Time remaining: 5s Progress 2433 / 9694 Time remaining: 5s Progress 2434 / 9694 Time remaining: 5s Progress 2435 / 9694 Time remaining: 5s Progress 2436 / 9694 Time remaining: 5s Progress 2437 / 9694 Time remaining: 5s Progress 2438 / 9694 Time remaining: 5s Progress 2439 / 9694 Time remaining: 5s Progress 2440 / 9694 Time remaining: 5s Progress 2441 / 9694 Time remaining: 5s Progress 2442 / 9694 Time remaining: 5s Progress 2443 / 9694 Time remaining: 5s Progress 2444 / 9694 Time remaining: 5s Progress 2445 / 9694 Time remaining: 5s Progress 2446 / 9694 Time remaining: 5s Progress 2447 / 9694 Time remaining: 5s Progress 2448 / 9694 Time remaining: 5s Progress 2449 / 9694 Time remaining: 5s Progress 2450 / 9694 Time remaining: 5s Progress 2451 / 9694 Time remaining: 5s Progress 2452 / 9694 Time remaining: 5s Progress 2453 / 9694 Time remaining: 5s Progress 2454 / 9694 Time remaining: 5s Progress 2455 / 9694 Time remaining: 5s Progress 2456 / 9694 Time remaining: 5s Progress 2457 / 9694 Time remaining: 5s Progress 2458 / 9694 Time remaining: 5s Progress 2459 / 9694 Time remaining: 5s Progress 2460 / 9694 Time remaining: 5s Progress 2461 / 9694 Time remaining: 5s Progress 2462 / 9694 Time remaining: 5s Progress 2463 / 9694 Time remaining: 5s Progress 2464 / 9694 Time remaining: 5s Progress 2465 / 9694 Time remaining: 5s Progress 2466 / 9694 Time remaining: 5s Progress 2467 / 9694 Time remaining: 5s Progress 2468 / 9694 Time remaining: 5s Progress 2469 / 9694 Time remaining: 5s Progress 2470 / 9694 Time remaining: 5s Progress 2471 / 9694 Time remaining: 5s Progress 2472 / 9694 Time remaining: 5s Progress 2473 / 9694 Time remaining: 5s Progress 2474 / 9694 Time remaining: 5s Progress 2475 / 9694 Time remaining: 5s Progress 2476 / 9694 Time remaining: 5s Progress 2477 / 9694 Time remaining: 5s Progress 2478 / 9694 Time remaining: 5s Progress 2479 / 9694 Time remaining: 5s Progress 2480 / 9694 Time remaining: 5s Progress 2481 / 9694 Time remaining: 5s Progress 2482 / 9694 Time remaining: 5s Progress 2483 / 9694 Time remaining: 5s Progress 2484 / 9694 Time remaining: 5s Progress 2485 / 9694 Time remaining: 5s Progress 2486 / 9694 Time remaining: 5s Progress 2487 / 9694 Time remaining: 5s Progress 2488 / 9694 Time remaining: 5s Progress 2489 / 9694 Time remaining: 5s Progress 2490 / 9694 Time remaining: 5s Progress 2491 / 9694 Time remaining: 5s Progress 2492 / 9694 Time remaining: 5s Progress 2493 / 9694 Time remaining: 5s Progress 2494 / 9694 Time remaining: 5s Progress 2495 / 9694 Time remaining: 5s Progress 2496 / 9694 Time remaining: 5s Progress 2497 / 9694 Time remaining: 5s Progress 2498 / 9694 Time remaining: 5s Progress 2499 / 9694 Time remaining: 5s Progress 2500 / 9694 Time remaining: 5s Progress 2501 / 9694 Time remaining: 5s Progress 2502 / 9694 Time remaining: 5s Progress 2503 / 9694 Time remaining: 5s Progress 2504 / 9694 Time remaining: 5s Progress 2505 / 9694 Time remaining: 5s Progress 2506 / 9694 Time remaining: 5s Progress 2507 / 9694 Time remaining: 5s Progress 2508 / 9694 Time remaining: 5s Progress 2509 / 9694 Time remaining: 5s Progress 2510 / 9694 Time remaining: 5s Progress 2511 / 9694 Time remaining: 5s Progress 2512 / 9694 Time remaining: 5s Progress 2513 / 9694 Time remaining: 5s Progress 2514 / 9694 Time remaining: 5s Progress 2515 / 9694 Time remaining: 5s Progress 2516 / 9694 Time remaining: 5s Progress 2517 / 9694 Time remaining: 5s Progress 2518 / 9694 Time remaining: 5s Progress 2519 / 9694 Time remaining: 5s Progress 2520 / 9694 Time remaining: 5s Progress 2521 / 9694 Time remaining: 5s Progress 2522 / 9694 Time remaining: 5s Progress 2523 / 9694 Time remaining: 5s Progress 2524 / 9694 Time remaining: 5s Progress 2525 / 9694 Time remaining: 5s Progress 2526 / 9694 Time remaining: 5s Progress 2527 / 9694 Time remaining: 5s Progress 2528 / 9694 Time remaining: 5s Progress 2529 / 9694 Time remaining: 5s Progress 2530 / 9694 Time remaining: 5s Progress 2531 / 9694 Time remaining: 5s Progress 2532 / 9694 Time remaining: 5s Progress 2533 / 9694 Time remaining: 5s Progress 2534 / 9694 Time remaining: 5s Progress 2535 / 9694 Time remaining: 5s Progress 2536 / 9694 Time remaining: 5s Progress 2537 / 9694 Time remaining: 5s Progress 2538 / 9694 Time remaining: 5s Progress 2539 / 9694 Time remaining: 5s Progress 2540 / 9694 Time remaining: 5s Progress 2541 / 9694 Time remaining: 5s Progress 2542 / 9694 Time remaining: 5s Progress 2543 / 9694 Time remaining: 5s Progress 2544 / 9694 Time remaining: 5s Progress 2545 / 9694 Time remaining: 5s Progress 2546 / 9694 Time remaining: 5s Progress 2547 / 9694 Time remaining: 5s Progress 2548 / 9694 Time remaining: 5s Progress 2549 / 9694 Time remaining: 5s Progress 2550 / 9694 Time remaining: 5s Progress 2551 / 9694 Time remaining: 5s Progress 2552 / 9694 Time remaining: 5s Progress 2553 / 9694 Time remaining: 5s Progress 2554 / 9694 Time remaining: 5s Progress 2555 / 9694 Time remaining: 5s Progress 2556 / 9694 Time remaining: 5s Progress 2557 / 9694 Time remaining: 5s Progress 2558 / 9694 Time remaining: 5s Progress 2559 / 9694 Time remaining: 5s Progress 2560 / 9694 Time remaining: 5s Progress 2561 / 9694 Time remaining: 5s Progress 2562 / 9694 Time remaining: 5s Progress 2563 / 9694 Time remaining: 5s Progress 2564 / 9694 Time remaining: 5s Progress 2565 / 9694 Time remaining: 5s Progress 2566 / 9694 Time remaining: 5s Progress 2567 / 9694 Time remaining: 5s Progress 2568 / 9694 Time remaining: 5s Progress 2569 / 9694 Time remaining: 5s Progress 2570 / 9694 Time remaining: 5s Progress 2571 / 9694 Time remaining: 5s Progress 2572 / 9694 Time remaining: 5s Progress 2573 / 9694 Time remaining: 5s Progress 2574 / 9694 Time remaining: 5s Progress 2575 / 9694 Time remaining: 5s Progress 2576 / 9694 Time remaining: 5s Progress 2577 / 9694 Time remaining: 5s Progress 2578 / 9694 Time remaining: 5s Progress 2579 / 9694 Time remaining: 5s Progress 2580 / 9694 Time remaining: 5s Progress 2581 / 9694 Time remaining: 5s Progress 2582 / 9694 Time remaining: 5s Progress 2583 / 9694 Time remaining: 5s Progress 2584 / 9694 Time remaining: 5s Progress 2585 / 9694 Time remaining: 5s Progress 2586 / 9694 Time remaining: 5s Progress 2587 / 9694 Time remaining: 5s Progress 2588 / 9694 Time remaining: 5s Progress 2589 / 9694 Time remaining: 5s Progress 2590 / 9694 Time remaining: 5s Progress 2591 / 9694 Time remaining: 5s Progress 2592 / 9694 Time remaining: 5s Progress 2593 / 9694 Time remaining: 5s Progress 2594 / 9694 Time remaining: 5s Progress 2595 / 9694 Time remaining: 5s Progress 2596 / 9694 Time remaining: 5s Progress 2597 / 9694 Time remaining: 5s Progress 2598 / 9694 Time remaining: 5s Progress 2599 / 9694 Time remaining: 5s Progress 2600 / 9694 Time remaining: 5s Progress 2601 / 9694 Time remaining: 5s Progress 2602 / 9694 Time remaining: 5s Progress 2603 / 9694 Time remaining: 5s Progress 2604 / 9694 Time remaining: 5s Progress 2605 / 9694 Time remaining: 5s Progress 2606 / 9694 Time remaining: 5s Progress 2607 / 9694 Time remaining: 5s Progress 2608 / 9694 Time remaining: 5s Progress 2609 / 9694 Time remaining: 5s Progress 2610 / 9694 Time remaining: 5s Progress 2611 / 9694 Time remaining: 5s Progress 2612 / 9694 Time remaining: 5s Progress 2613 / 9694 Time remaining: 5s Progress 2614 / 9694 Time remaining: 5s Progress 2615 / 9694 Time remaining: 5s Progress 2616 / 9694 Time remaining: 5s Progress 2617 / 9694 Time remaining: 5s Progress 2618 / 9694 Time remaining: 5s Progress 2619 / 9694 Time remaining: 5s Progress 2620 / 9694 Time remaining: 5s Progress 2621 / 9694 Time remaining: 5s Progress 2622 / 9694 Time remaining: 5s Progress 2623 / 9694 Time remaining: 5s Progress 2624 / 9694 Time remaining: 5s Progress 2625 / 9694 Time remaining: 5s Progress 2626 / 9694 Time remaining: 5s Progress 2627 / 9694 Time remaining: 5s Progress 2628 / 9694 Time remaining: 5s Progress 2629 / 9694 Time remaining: 5s Progress 2630 / 9694 Time remaining: 5s Progress 2631 / 9694 Time remaining: 5s Progress 2632 / 9694 Time remaining: 5s Progress 2633 / 9694 Time remaining: 5s Progress 2634 / 9694 Time remaining: 5s Progress 2635 / 9694 Time remaining: 5s Progress 2636 / 9694 Time remaining: 5s Progress 2637 / 9694 Time remaining: 5s Progress 2638 / 9694 Time remaining: 5s Progress 2639 / 9694 Time remaining: 5s Progress 2640 / 9694 Time remaining: 5s Progress 2641 / 9694 Time remaining: 5s Progress 2642 / 9694 Time remaining: 5s Progress 2643 / 9694 Time remaining: 5s Progress 2644 / 9694 Time remaining: 5s Progress 2645 / 9694 Time remaining: 5s Progress 2646 / 9694 Time remaining: 5s Progress 2647 / 9694 Time remaining: 5s Progress 2648 / 9694 Time remaining: 5s Progress 2649 / 9694 Time remaining: 5s Progress 2650 / 9694 Time remaining: 5s Progress 2651 / 9694 Time remaining: 5s Progress 2652 / 9694 Time remaining: 5s Progress 2653 / 9694 Time remaining: 5s Progress 2654 / 9694 Time remaining: 5s Progress 2655 / 9694 Time remaining: 5s Progress 2656 / 9694 Time remaining: 5s Progress 2657 / 9694 Time remaining: 5s Progress 2658 / 9694 Time remaining: 5s Progress 2659 / 9694 Time remaining: 5s Progress 2660 / 9694 Time remaining: 5s Progress 2661 / 9694 Time remaining: 5s Progress 2662 / 9694 Time remaining: 5s Progress 2663 / 9694 Time remaining: 5s Progress 2664 / 9694 Time remaining: 5s Progress 2665 / 9694 Time remaining: 5s Progress 2666 / 9694 Time remaining: 5s Progress 2667 / 9694 Time remaining: 5s Progress 2668 / 9694 Time remaining: 5s Progress 2669 / 9694 Time remaining: 5s Progress 2670 / 9694 Time remaining: 5s Progress 2671 / 9694 Time remaining: 5s Progress 2672 / 9694 Time remaining: 5s Progress 2673 / 9694 Time remaining: 5s Progress 2674 / 9694 Time remaining: 5s Progress 2675 / 9694 Time remaining: 5s Progress 2676 / 9694 Time remaining: 5s Progress 2677 / 9694 Time remaining: 5s Progress 2678 / 9694 Time remaining: 5s Progress 2679 / 9694 Time remaining: 5s Progress 2680 / 9694 Time remaining: 5s Progress 2681 / 9694 Time remaining: 5s Progress 2682 / 9694 Time remaining: 5s Progress 2683 / 9694 Time remaining: 5s Progress 2684 / 9694 Time remaining: 5s Progress 2685 / 9694 Time remaining: 5s Progress 2686 / 9694 Time remaining: 5s Progress 2687 / 9694 Time remaining: 5s Progress 2688 / 9694 Time remaining: 5s Progress 2689 / 9694 Time remaining: 5s Progress 2690 / 9694 Time remaining: 5s Progress 2691 / 9694 Time remaining: 5s Progress 2692 / 9694 Time remaining: 5s Progress 2693 / 9694 Time remaining: 5s Progress 2694 / 9694 Time remaining: 5s Progress 2695 / 9694 Time remaining: 5s Progress 2696 / 9694 Time remaining: 5s Progress 2697 / 9694 Time remaining: 5s Progress 2698 / 9694 Time remaining: 5s Progress 2699 / 9694 Time remaining: 5s Progress 2700 / 9694 Time remaining: 5s Progress 2701 / 9694 Time remaining: 5s Progress 2702 / 9694 Time remaining: 5s Progress 2703 / 9694 Time remaining: 5s Progress 2704 / 9694 Time remaining: 5s Progress 2705 / 9694 Time remaining: 5s Progress 2706 / 9694 Time remaining: 5s Progress 2707 / 9694 Time remaining: 5s Progress 2708 / 9694 Time remaining: 5s Progress 2709 / 9694 Time remaining: 5s Progress 2710 / 9694 Time remaining: 5s Progress 2711 / 9694 Time remaining: 5s Progress 2712 / 9694 Time remaining: 5s Progress 2713 / 9694 Time remaining: 5s Progress 2714 / 9694 Time remaining: 5s Progress 2715 / 9694 Time remaining: 5s Progress 2716 / 9694 Time remaining: 5s Progress 2717 / 9694 Time remaining: 5s Progress 2718 / 9694 Time remaining: 5s Progress 2719 / 9694 Time remaining: 5s Progress 2720 / 9694 Time remaining: 5s Progress 2721 / 9694 Time remaining: 5s Progress 2722 / 9694 Time remaining: 5s Progress 2723 / 9694 Time remaining: 5s Progress 2724 / 9694 Time remaining: 5s Progress 2725 / 9694 Time remaining: 5s Progress 2726 / 9694 Time remaining: 5s Progress 2727 / 9694 Time remaining: 5s Progress 2728 / 9694 Time remaining: 5s Progress 2729 / 9694 Time remaining: 5s Progress 2730 / 9694 Time remaining: 5s Progress 2731 / 9694 Time remaining: 5s Progress 2732 / 9694 Time remaining: 5s Progress 2733 / 9694 Time remaining: 5s Progress 2734 / 9694 Time remaining: 5s Progress 2735 / 9694 Time remaining: 5s Progress 2736 / 9694 Time remaining: 5s Progress 2737 / 9694 Time remaining: 5s Progress 2738 / 9694 Time remaining: 5s Progress 2739 / 9694 Time remaining: 5s Progress 2740 / 9694 Time remaining: 5s Progress 2741 / 9694 Time remaining: 5s Progress 2742 / 9694 Time remaining: 5s Progress 2743 / 9694 Time remaining: 5s Progress 2744 / 9694 Time remaining: 5s Progress 2745 / 9694 Time remaining: 5s Progress 2746 / 9694 Time remaining: 5s Progress 2747 / 9694 Time remaining: 5s Progress 2748 / 9694 Time remaining: 5s Progress 2749 / 9694 Time remaining: 5s Progress 2750 / 9694 Time remaining: 5s Progress 2751 / 9694 Time remaining: 5s Progress 2752 / 9694 Time remaining: 5s Progress 2753 / 9694 Time remaining: 5s Progress 2754 / 9694 Time remaining: 5s Progress 2755 / 9694 Time remaining: 5s Progress 2756 / 9694 Time remaining: 5s Progress 2757 / 9694 Time remaining: 5s Progress 2758 / 9694 Time remaining: 5s Progress 2759 / 9694 Time remaining: 5s Progress 2760 / 9694 Time remaining: 5s Progress 2761 / 9694 Time remaining: 5s Progress 2762 / 9694 Time remaining: 5s Progress 2763 / 9694 Time remaining: 5s Progress 2764 / 9694 Time remaining: 5s Progress 2765 / 9694 Time remaining: 5s Progress 2766 / 9694 Time remaining: 5s Progress 2767 / 9694 Time remaining: 5s Progress 2768 / 9694 Time remaining: 5s Progress 2769 / 9694 Time remaining: 5s Progress 2770 / 9694 Time remaining: 5s Progress 2771 / 9694 Time remaining: 5s Progress 2772 / 9694 Time remaining: 5s Progress 2773 / 9694 Time remaining: 5s Progress 2774 / 9694 Time remaining: 5s Progress 2775 / 9694 Time remaining: 5s Progress 2776 / 9694 Time remaining: 5s Progress 2777 / 9694 Time remaining: 5s Progress 2778 / 9694 Time remaining: 5s Progress 2779 / 9694 Time remaining: 5s Progress 2780 / 9694 Time remaining: 5s Progress 2781 / 9694 Time remaining: 5s Progress 2782 / 9694 Time remaining: 5s Progress 2783 / 9694 Time remaining: 5s Progress 2784 / 9694 Time remaining: 5s Progress 2785 / 9694 Time remaining: 5s Progress 2786 / 9694 Time remaining: 5s Progress 2787 / 9694 Time remaining: 5s Progress 2788 / 9694 Time remaining: 5s Progress 2789 / 9694 Time remaining: 5s Progress 2790 / 9694 Time remaining: 5s Progress 2791 / 9694 Time remaining: 5s Progress 2792 / 9694 Time remaining: 5s Progress 2793 / 9694 Time remaining: 5s Progress 2794 / 9694 Time remaining: 5s Progress 2795 / 9694 Time remaining: 5s Progress 2796 / 9694 Time remaining: 5s Progress 2797 / 9694 Time remaining: 5s Progress 2798 / 9694 Time remaining: 5s Progress 2799 / 9694 Time remaining: 5s Progress 2800 / 9694 Time remaining: 5s Progress 2801 / 9694 Time remaining: 5s Progress 2802 / 9694 Time remaining: 5s Progress 2803 / 9694 Time remaining: 5s Progress 2804 / 9694 Time remaining: 5s Progress 2805 / 9694 Time remaining: 5s Progress 2806 / 9694 Time remaining: 5s Progress 2807 / 9694 Time remaining: 5s Progress 2808 / 9694 Time remaining: 5s Progress 2809 / 9694 Time remaining: 5s Progress 2810 / 9694 Time remaining: 5s Progress 2811 / 9694 Time remaining: 5s Progress 2812 / 9694 Time remaining: 5s Progress 2813 / 9694 Time remaining: 5s Progress 2814 / 9694 Time remaining: 5s Progress 2815 / 9694 Time remaining: 5s Progress 2816 / 9694 Time remaining: 5s Progress 2817 / 9694 Time remaining: 5s Progress 2818 / 9694 Time remaining: 5s Progress 2819 / 9694 Time remaining: 5s Progress 2820 / 9694 Time remaining: 5s Progress 2821 / 9694 Time remaining: 5s Progress 2822 / 9694 Time remaining: 5s Progress 2823 / 9694 Time remaining: 5s Progress 2824 / 9694 Time remaining: 5s Progress 2825 / 9694 Time remaining: 5s Progress 2826 / 9694 Time remaining: 5s Progress 2827 / 9694 Time remaining: 5s Progress 2828 / 9694 Time remaining: 5s Progress 2829 / 9694 Time remaining: 5s Progress 2830 / 9694 Time remaining: 5s Progress 2831 / 9694 Time remaining: 5s Progress 2832 / 9694 Time remaining: 5s Progress 2833 / 9694 Time remaining: 5s Progress 2834 / 9694 Time remaining: 5s Progress 2835 / 9694 Time remaining: 5s Progress 2836 / 9694 Time remaining: 5s Progress 2837 / 9694 Time remaining: 5s Progress 2838 / 9694 Time remaining: 5s Progress 2839 / 9694 Time remaining: 5s Progress 2840 / 9694 Time remaining: 5s Progress 2841 / 9694 Time remaining: 5s Progress 2842 / 9694 Time remaining: 5s Progress 2843 / 9694 Time remaining: 5s Progress 2844 / 9694 Time remaining: 5s Progress 2845 / 9694 Time remaining: 5s Progress 2846 / 9694 Time remaining: 5s Progress 2847 / 9694 Time remaining: 5s Progress 2848 / 9694 Time remaining: 5s Progress 2849 / 9694 Time remaining: 5s Progress 2850 / 9694 Time remaining: 5s Progress 2851 / 9694 Time remaining: 5s Progress 2852 / 9694 Time remaining: 5s Progress 2853 / 9694 Time remaining: 5s Progress 2854 / 9694 Time remaining: 5s Progress 2855 / 9694 Time remaining: 5s Progress 2856 / 9694 Time remaining: 5s Progress 2857 / 9694 Time remaining: 5s Progress 2858 / 9694 Time remaining: 5s Progress 2859 / 9694 Time remaining: 5s Progress 2860 / 9694 Time remaining: 5s Progress 2861 / 9694 Time remaining: 5s Progress 2862 / 9694 Time remaining: 5s Progress 2863 / 9694 Time remaining: 5s Progress 2864 / 9694 Time remaining: 5s Progress 2865 / 9694 Time remaining: 5s Progress 2866 / 9694 Time remaining: 5s Progress 2867 / 9694 Time remaining: 5s Progress 2868 / 9694 Time remaining: 5s Progress 2869 / 9694 Time remaining: 5s Progress 2870 / 9694 Time remaining: 5s Progress 2871 / 9694 Time remaining: 5s Progress 2872 / 9694 Time remaining: 5s Progress 2873 / 9694 Time remaining: 5s Progress 2874 / 9694 Time remaining: 5s Progress 2875 / 9694 Time remaining: 5s Progress 2876 / 9694 Time remaining: 5s Progress 2877 / 9694 Time remaining: 5s Progress 2878 / 9694 Time remaining: 5s Progress 2879 / 9694 Time remaining: 5s Progress 2880 / 9694 Time remaining: 5s Progress 2881 / 9694 Time remaining: 5s Progress 2882 / 9694 Time remaining: 4s Progress 2883 / 9694 Time remaining: 4s Progress 2884 / 9694 Time remaining: 4s Progress 2885 / 9694 Time remaining: 4s Progress 2886 / 9694 Time remaining: 4s Progress 2887 / 9694 Time remaining: 4s Progress 2888 / 9694 Time remaining: 4s Progress 2889 / 9694 Time remaining: 4s Progress 2890 / 9694 Time remaining: 4s Progress 2891 / 9694 Time remaining: 4s Progress 2892 / 9694 Time remaining: 4s Progress 2893 / 9694 Time remaining: 4s Progress 2894 / 9694 Time remaining: 4s Progress 2895 / 9694 Time remaining: 4s Progress 2896 / 9694 Time remaining: 4s Progress 2897 / 9694 Time remaining: 4s Progress 2898 / 9694 Time remaining: 4s Progress 2899 / 9694 Time remaining: 4s Progress 2900 / 9694 Time remaining: 4s Progress 2901 / 9694 Time remaining: 4s Progress 2902 / 9694 Time remaining: 4s Progress 2903 / 9694 Time remaining: 4s Progress 2904 / 9694 Time remaining: 4s Progress 2905 / 9694 Time remaining: 4s Progress 2906 / 9694 Time remaining: 4s Progress 2907 / 9694 Time remaining: 4s Progress 2908 / 9694 Time remaining: 4s Progress 2909 / 9694 Time remaining: 4s Progress 2910 / 9694 Time remaining: 4s Progress 2911 / 9694 Time remaining: 4s Progress 2912 / 9694 Time remaining: 4s Progress 2913 / 9694 Time remaining: 4s Progress 2914 / 9694 Time remaining: 4s Progress 2915 / 9694 Time remaining: 4s Progress 2916 / 9694 Time remaining: 4s Progress 2917 / 9694 Time remaining: 4s Progress 2918 / 9694 Time remaining: 4s Progress 2919 / 9694 Time remaining: 4s Progress 2920 / 9694 Time remaining: 4s Progress 2921 / 9694 Time remaining: 4s Progress 2922 / 9694 Time remaining: 4s Progress 2923 / 9694 Time remaining: 4s Progress 2924 / 9694 Time remaining: 4s Progress 2925 / 9694 Time remaining: 4s Progress 2926 / 9694 Time remaining: 4s Progress 2927 / 9694 Time remaining: 4s Progress 2928 / 9694 Time remaining: 4s Progress 2929 / 9694 Time remaining: 4s Progress 2930 / 9694 Time remaining: 4s Progress 2931 / 9694 Time remaining: 4s Progress 2932 / 9694 Time remaining: 4s Progress 2933 / 9694 Time remaining: 4s Progress 2934 / 9694 Time remaining: 4s Progress 2935 / 9694 Time remaining: 4s Progress 2936 / 9694 Time remaining: 4s Progress 2937 / 9694 Time remaining: 4s Progress 2938 / 9694 Time remaining: 4s Progress 2939 / 9694 Time remaining: 4s Progress 2940 / 9694 Time remaining: 4s Progress 2941 / 9694 Time remaining: 4s Progress 2942 / 9694 Time remaining: 4s Progress 2943 / 9694 Time remaining: 4s Progress 2944 / 9694 Time remaining: 4s Progress 2945 / 9694 Time remaining: 4s Progress 2946 / 9694 Time remaining: 4s Progress 2947 / 9694 Time remaining: 4s Progress 2948 / 9694 Time remaining: 4s Progress 2949 / 9694 Time remaining: 4s Progress 2950 / 9694 Time remaining: 4s Progress 2951 / 9694 Time remaining: 4s Progress 2952 / 9694 Time remaining: 4s Progress 2953 / 9694 Time remaining: 4s Progress 2954 / 9694 Time remaining: 4s Progress 2955 / 9694 Time remaining: 4s Progress 2956 / 9694 Time remaining: 4s Progress 2957 / 9694 Time remaining: 4s Progress 2958 / 9694 Time remaining: 4s Progress 2959 / 9694 Time remaining: 4s Progress 2960 / 9694 Time remaining: 4s Progress 2961 / 9694 Time remaining: 4s Progress 2962 / 9694 Time remaining: 4s Progress 2963 / 9694 Time remaining: 4s Progress 2964 / 9694 Time remaining: 4s Progress 2965 / 9694 Time remaining: 4s Progress 2966 / 9694 Time remaining: 4s Progress 2967 / 9694 Time remaining: 4s Progress 2968 / 9694 Time remaining: 4s Progress 2969 / 9694 Time remaining: 4s Progress 2970 / 9694 Time remaining: 4s Progress 2971 / 9694 Time remaining: 4s Progress 2972 / 9694 Time remaining: 4s Progress 2973 / 9694 Time remaining: 4s Progress 2974 / 9694 Time remaining: 4s Progress 2975 / 9694 Time remaining: 4s Progress 2976 / 9694 Time remaining: 4s Progress 2977 / 9694 Time remaining: 4s Progress 2978 / 9694 Time remaining: 4s Progress 2979 / 9694 Time remaining: 4s Progress 2980 / 9694 Time remaining: 4s Progress 2981 / 9694 Time remaining: 4s Progress 2982 / 9694 Time remaining: 4s Progress 2983 / 9694 Time remaining: 4s Progress 2984 / 9694 Time remaining: 4s Progress 2985 / 9694 Time remaining: 4s Progress 2986 / 9694 Time remaining: 4s Progress 2987 / 9694 Time remaining: 4s Progress 2988 / 9694 Time remaining: 4s Progress 2989 / 9694 Time remaining: 4s Progress 2990 / 9694 Time remaining: 4s Progress 2991 / 9694 Time remaining: 4s Progress 2992 / 9694 Time remaining: 4s Progress 2993 / 9694 Time remaining: 4s Progress 2994 / 9694 Time remaining: 4s Progress 2995 / 9694 Time remaining: 4s Progress 2996 / 9694 Time remaining: 4s Progress 2997 / 9694 Time remaining: 4s Progress 2998 / 9694 Time remaining: 4s Progress 2999 / 9694 Time remaining: 4s Progress 3000 / 9694 Time remaining: 4s Progress 3001 / 9694 Time remaining: 4s Progress 3002 / 9694 Time remaining: 4s Progress 3003 / 9694 Time remaining: 4s Progress 3004 / 9694 Time remaining: 4s Progress 3005 / 9694 Time remaining: 4s Progress 3006 / 9694 Time remaining: 4s Progress 3007 / 9694 Time remaining: 4s Progress 3008 / 9694 Time remaining: 4s Progress 3009 / 9694 Time remaining: 4s Progress 3010 / 9694 Time remaining: 4s Progress 3011 / 9694 Time remaining: 4s Progress 3012 / 9694 Time remaining: 4s Progress 3013 / 9694 Time remaining: 4s Progress 3014 / 9694 Time remaining: 4s Progress 3015 / 9694 Time remaining: 4s Progress 3016 / 9694 Time remaining: 4s Progress 3017 / 9694 Time remaining: 4s Progress 3018 / 9694 Time remaining: 4s Progress 3019 / 9694 Time remaining: 4s Progress 3020 / 9694 Time remaining: 4s Progress 3021 / 9694 Time remaining: 4s Progress 3022 / 9694 Time remaining: 4s Progress 3023 / 9694 Time remaining: 4s Progress 3024 / 9694 Time remaining: 4s Progress 3025 / 9694 Time remaining: 4s Progress 3026 / 9694 Time remaining: 4s Progress 3027 / 9694 Time remaining: 4s Progress 3028 / 9694 Time remaining: 4s Progress 3029 / 9694 Time remaining: 4s Progress 3030 / 9694 Time remaining: 4s Progress 3031 / 9694 Time remaining: 4s Progress 3032 / 9694 Time remaining: 4s Progress 3033 / 9694 Time remaining: 4s Progress 3034 / 9694 Time remaining: 4s Progress 3035 / 9694 Time remaining: 4s Progress 3036 / 9694 Time remaining: 4s Progress 3037 / 9694 Time remaining: 4s Progress 3038 / 9694 Time remaining: 4s Progress 3039 / 9694 Time remaining: 4s Progress 3040 / 9694 Time remaining: 4s Progress 3041 / 9694 Time remaining: 4s Progress 3042 / 9694 Time remaining: 4s Progress 3043 / 9694 Time remaining: 4s Progress 3044 / 9694 Time remaining: 4s Progress 3045 / 9694 Time remaining: 4s Progress 3046 / 9694 Time remaining: 4s Progress 3047 / 9694 Time remaining: 4s Progress 3048 / 9694 Time remaining: 4s Progress 3049 / 9694 Time remaining: 4s Progress 3050 / 9694 Time remaining: 4s Progress 3051 / 9694 Time remaining: 4s Progress 3052 / 9694 Time remaining: 4s Progress 3053 / 9694 Time remaining: 4s Progress 3054 / 9694 Time remaining: 4s Progress 3055 / 9694 Time remaining: 4s Progress 3056 / 9694 Time remaining: 4s Progress 3057 / 9694 Time remaining: 4s Progress 3058 / 9694 Time remaining: 4s Progress 3059 / 9694 Time remaining: 4s Progress 3060 / 9694 Time remaining: 4s Progress 3061 / 9694 Time remaining: 4s Progress 3062 / 9694 Time remaining: 4s Progress 3063 / 9694 Time remaining: 4s Progress 3064 / 9694 Time remaining: 4s Progress 3065 / 9694 Time remaining: 4s Progress 3066 / 9694 Time remaining: 4s Progress 3067 / 9694 Time remaining: 4s Progress 3068 / 9694 Time remaining: 4s Progress 3069 / 9694 Time remaining: 4s Progress 3070 / 9694 Time remaining: 4s Progress 3071 / 9694 Time remaining: 4s Progress 3072 / 9694 Time remaining: 4s Progress 3073 / 9694 Time remaining: 4s Progress 3074 / 9694 Time remaining: 4s Progress 3075 / 9694 Time remaining: 4s Progress 3076 / 9694 Time remaining: 4s Progress 3077 / 9694 Time remaining: 4s Progress 3078 / 9694 Time remaining: 4s Progress 3079 / 9694 Time remaining: 4s Progress 3080 / 9694 Time remaining: 4s Progress 3081 / 9694 Time remaining: 4s Progress 3082 / 9694 Time remaining: 4s Progress 3083 / 9694 Time remaining: 4s Progress 3084 / 9694 Time remaining: 4s Progress 3085 / 9694 Time remaining: 4s Progress 3086 / 9694 Time remaining: 4s Progress 3087 / 9694 Time remaining: 4s Progress 3088 / 9694 Time remaining: 4s Progress 3089 / 9694 Time remaining: 4s Progress 3090 / 9694 Time remaining: 4s Progress 3091 / 9694 Time remaining: 4s Progress 3092 / 9694 Time remaining: 4s Progress 3093 / 9694 Time remaining: 4s Progress 3094 / 9694 Time remaining: 4s Progress 3095 / 9694 Time remaining: 4s Progress 3096 / 9694 Time remaining: 4s Progress 3097 / 9694 Time remaining: 4s Progress 3098 / 9694 Time remaining: 4s Progress 3099 / 9694 Time remaining: 4s Progress 3100 / 9694 Time remaining: 4s Progress 3101 / 9694 Time remaining: 4s Progress 3102 / 9694 Time remaining: 4s Progress 3103 / 9694 Time remaining: 4s Progress 3104 / 9694 Time remaining: 4s Progress 3105 / 9694 Time remaining: 4s Progress 3106 / 9694 Time remaining: 4s Progress 3107 / 9694 Time remaining: 4s Progress 3108 / 9694 Time remaining: 4s Progress 3109 / 9694 Time remaining: 4s Progress 3110 / 9694 Time remaining: 4s Progress 3111 / 9694 Time remaining: 4s Progress 3112 / 9694 Time remaining: 4s Progress 3113 / 9694 Time remaining: 4s Progress 3114 / 9694 Time remaining: 4s Progress 3115 / 9694 Time remaining: 4s Progress 3116 / 9694 Time remaining: 4s Progress 3117 / 9694 Time remaining: 4s Progress 3118 / 9694 Time remaining: 4s Progress 3119 / 9694 Time remaining: 4s Progress 3120 / 9694 Time remaining: 4s Progress 3121 / 9694 Time remaining: 4s Progress 3122 / 9694 Time remaining: 4s Progress 3123 / 9694 Time remaining: 4s Progress 3124 / 9694 Time remaining: 4s Progress 3125 / 9694 Time remaining: 4s Progress 3126 / 9694 Time remaining: 4s Progress 3127 / 9694 Time remaining: 4s Progress 3128 / 9694 Time remaining: 4s Progress 3129 / 9694 Time remaining: 4s Progress 3130 / 9694 Time remaining: 4s Progress 3131 / 9694 Time remaining: 4s Progress 3132 / 9694 Time remaining: 4s Progress 3133 / 9694 Time remaining: 4s Progress 3134 / 9694 Time remaining: 4s Progress 3135 / 9694 Time remaining: 4s Progress 3136 / 9694 Time remaining: 4s Progress 3137 / 9694 Time remaining: 4s Progress 3138 / 9694 Time remaining: 4s Progress 3139 / 9694 Time remaining: 4s Progress 3140 / 9694 Time remaining: 4s Progress 3141 / 9694 Time remaining: 4s Progress 3142 / 9694 Time remaining: 4s Progress 3143 / 9694 Time remaining: 4s Progress 3144 / 9694 Time remaining: 4s Progress 3145 / 9694 Time remaining: 4s Progress 3146 / 9694 Time remaining: 4s Progress 3147 / 9694 Time remaining: 4s Progress 3148 / 9694 Time remaining: 4s Progress 3149 / 9694 Time remaining: 4s Progress 3150 / 9694 Time remaining: 4s Progress 3151 / 9694 Time remaining: 4s Progress 3152 / 9694 Time remaining: 4s Progress 3153 / 9694 Time remaining: 4s Progress 3154 / 9694 Time remaining: 4s Progress 3155 / 9694 Time remaining: 4s Progress 3156 / 9694 Time remaining: 4s Progress 3157 / 9694 Time remaining: 4s Progress 3158 / 9694 Time remaining: 4s Progress 3159 / 9694 Time remaining: 4s Progress 3160 / 9694 Time remaining: 4s Progress 3161 / 9694 Time remaining: 4s Progress 3162 / 9694 Time remaining: 4s Progress 3163 / 9694 Time remaining: 4s Progress 3164 / 9694 Time remaining: 4s Progress 3165 / 9694 Time remaining: 4s Progress 3166 / 9694 Time remaining: 4s Progress 3167 / 9694 Time remaining: 4s Progress 3168 / 9694 Time remaining: 4s Progress 3169 / 9694 Time remaining: 4s Progress 3170 / 9694 Time remaining: 4s Progress 3171 / 9694 Time remaining: 4s Progress 3172 / 9694 Time remaining: 4s Progress 3173 / 9694 Time remaining: 4s Progress 3174 / 9694 Time remaining: 4s Progress 3175 / 9694 Time remaining: 4s Progress 3176 / 9694 Time remaining: 4s Progress 3177 / 9694 Time remaining: 4s Progress 3178 / 9694 Time remaining: 4s Progress 3179 / 9694 Time remaining: 4s Progress 3180 / 9694 Time remaining: 4s Progress 3181 / 9694 Time remaining: 4s Progress 3182 / 9694 Time remaining: 4s Progress 3183 / 9694 Time remaining: 4s Progress 3184 / 9694 Time remaining: 4s Progress 3185 / 9694 Time remaining: 4s Progress 3186 / 9694 Time remaining: 4s Progress 3187 / 9694 Time remaining: 4s Progress 3188 / 9694 Time remaining: 4s Progress 3189 / 9694 Time remaining: 4s Progress 3190 / 9694 Time remaining: 4s Progress 3191 / 9694 Time remaining: 4s Progress 3192 / 9694 Time remaining: 4s Progress 3193 / 9694 Time remaining: 4s Progress 3194 / 9694 Time remaining: 4s Progress 3195 / 9694 Time remaining: 4s Progress 3196 / 9694 Time remaining: 4s Progress 3197 / 9694 Time remaining: 4s Progress 3198 / 9694 Time remaining: 4s Progress 3199 / 9694 Time remaining: 4s Progress 3200 / 9694 Time remaining: 4s Progress 3201 / 9694 Time remaining: 4s Progress 3202 / 9694 Time remaining: 4s Progress 3203 / 9694 Time remaining: 4s Progress 3204 / 9694 Time remaining: 4s Progress 3205 / 9694 Time remaining: 4s Progress 3206 / 9694 Time remaining: 4s Progress 3207 / 9694 Time remaining: 4s Progress 3208 / 9694 Time remaining: 4s Progress 3209 / 9694 Time remaining: 4s Progress 3210 / 9694 Time remaining: 4s Progress 3211 / 9694 Time remaining: 4s Progress 3212 / 9694 Time remaining: 4s Progress 3213 / 9694 Time remaining: 4s Progress 3214 / 9694 Time remaining: 4s Progress 3215 / 9694 Time remaining: 4s Progress 3216 / 9694 Time remaining: 4s Progress 3217 / 9694 Time remaining: 4s Progress 3218 / 9694 Time remaining: 4s Progress 3219 / 9694 Time remaining: 4s Progress 3220 / 9694 Time remaining: 4s Progress 3221 / 9694 Time remaining: 4s Progress 3222 / 9694 Time remaining: 4s Progress 3223 / 9694 Time remaining: 4s Progress 3224 / 9694 Time remaining: 4s Progress 3225 / 9694 Time remaining: 4s Progress 3226 / 9694 Time remaining: 4s Progress 3227 / 9694 Time remaining: 4s Progress 3228 / 9694 Time remaining: 4s Progress 3229 / 9694 Time remaining: 4s Progress 3230 / 9694 Time remaining: 4s Progress 3231 / 9694 Time remaining: 4s Progress 3232 / 9694 Time remaining: 4s Progress 3233 / 9694 Time remaining: 4s Progress 3234 / 9694 Time remaining: 4s Progress 3235 / 9694 Time remaining: 4s Progress 3236 / 9694 Time remaining: 4s Progress 3237 / 9694 Time remaining: 4s Progress 3238 / 9694 Time remaining: 4s Progress 3239 / 9694 Time remaining: 4s Progress 3240 / 9694 Time remaining: 4s Progress 3241 / 9694 Time remaining: 4s Progress 3242 / 9694 Time remaining: 4s Progress 3243 / 9694 Time remaining: 4s Progress 3244 / 9694 Time remaining: 4s Progress 3245 / 9694 Time remaining: 4s Progress 3246 / 9694 Time remaining: 4s Progress 3247 / 9694 Time remaining: 4s Progress 3248 / 9694 Time remaining: 4s Progress 3249 / 9694 Time remaining: 4s Progress 3250 / 9694 Time remaining: 4s Progress 3251 / 9694 Time remaining: 4s Progress 3252 / 9694 Time remaining: 4s Progress 3253 / 9694 Time remaining: 4s Progress 3254 / 9694 Time remaining: 4s Progress 3255 / 9694 Time remaining: 4s Progress 3256 / 9694 Time remaining: 4s Progress 3257 / 9694 Time remaining: 4s Progress 3258 / 9694 Time remaining: 4s Progress 3259 / 9694 Time remaining: 4s Progress 3260 / 9694 Time remaining: 4s Progress 3261 / 9694 Time remaining: 4s Progress 3262 / 9694 Time remaining: 4s Progress 3263 / 9694 Time remaining: 4s Progress 3264 / 9694 Time remaining: 4s Progress 3265 / 9694 Time remaining: 4s Progress 3266 / 9694 Time remaining: 4s Progress 3267 / 9694 Time remaining: 4s Progress 3268 / 9694 Time remaining: 4s Progress 3269 / 9694 Time remaining: 4s Progress 3270 / 9694 Time remaining: 4s Progress 3271 / 9694 Time remaining: 4s Progress 3272 / 9694 Time remaining: 4s Progress 3273 / 9694 Time remaining: 4s Progress 3274 / 9694 Time remaining: 4s Progress 3275 / 9694 Time remaining: 4s Progress 3276 / 9694 Time remaining: 4s Progress 3277 / 9694 Time remaining: 4s Progress 3278 / 9694 Time remaining: 4s Progress 3279 / 9694 Time remaining: 4s Progress 3280 / 9694 Time remaining: 4s Progress 3281 / 9694 Time remaining: 4s Progress 3282 / 9694 Time remaining: 4s Progress 3283 / 9694 Time remaining: 4s Progress 3284 / 9694 Time remaining: 4s Progress 3285 / 9694 Time remaining: 4s Progress 3286 / 9694 Time remaining: 4s Progress 3287 / 9694 Time remaining: 4s Progress 3288 / 9694 Time remaining: 4s Progress 3289 / 9694 Time remaining: 4s Progress 3290 / 9694 Time remaining: 4s Progress 3291 / 9694 Time remaining: 4s Progress 3292 / 9694 Time remaining: 4s Progress 3293 / 9694 Time remaining: 4s Progress 3294 / 9694 Time remaining: 4s Progress 3295 / 9694 Time remaining: 4s Progress 3296 / 9694 Time remaining: 4s Progress 3297 / 9694 Time remaining: 4s Progress 3298 / 9694 Time remaining: 4s Progress 3299 / 9694 Time remaining: 4s Progress 3300 / 9694 Time remaining: 4s Progress 3301 / 9694 Time remaining: 4s Progress 3302 / 9694 Time remaining: 4s Progress 3303 / 9694 Time remaining: 4s Progress 3304 / 9694 Time remaining: 4s Progress 3305 / 9694 Time remaining: 4s Progress 3306 / 9694 Time remaining: 4s Progress 3307 / 9694 Time remaining: 4s Progress 3308 / 9694 Time remaining: 4s Progress 3309 / 9694 Time remaining: 4s Progress 3310 / 9694 Time remaining: 4s Progress 3311 / 9694 Time remaining: 4s Progress 3312 / 9694 Time remaining: 4s Progress 3313 / 9694 Time remaining: 4s Progress 3314 / 9694 Time remaining: 4s Progress 3315 / 9694 Time remaining: 4s Progress 3316 / 9694 Time remaining: 4s Progress 3317 / 9694 Time remaining: 4s Progress 3318 / 9694 Time remaining: 4s Progress 3319 / 9694 Time remaining: 4s Progress 3320 / 9694 Time remaining: 4s Progress 3321 / 9694 Time remaining: 4s Progress 3322 / 9694 Time remaining: 4s Progress 3323 / 9694 Time remaining: 4s Progress 3324 / 9694 Time remaining: 4s Progress 3325 / 9694 Time remaining: 4s Progress 3326 / 9694 Time remaining: 4s Progress 3327 / 9694 Time remaining: 4s Progress 3328 / 9694 Time remaining: 4s Progress 3329 / 9694 Time remaining: 4s Progress 3330 / 9694 Time remaining: 4s Progress 3331 / 9694 Time remaining: 4s Progress 3332 / 9694 Time remaining: 4s Progress 3333 / 9694 Time remaining: 4s Progress 3334 / 9694 Time remaining: 4s Progress 3335 / 9694 Time remaining: 4s Progress 3336 / 9694 Time remaining: 4s Progress 3337 / 9694 Time remaining: 4s Progress 3338 / 9694 Time remaining: 4s Progress 3339 / 9694 Time remaining: 4s Progress 3340 / 9694 Time remaining: 4s Progress 3341 / 9694 Time remaining: 4s Progress 3342 / 9694 Time remaining: 4s Progress 3343 / 9694 Time remaining: 4s Progress 3344 / 9694 Time remaining: 4s Progress 3345 / 9694 Time remaining: 4s Progress 3346 / 9694 Time remaining: 4s Progress 3347 / 9694 Time remaining: 4s Progress 3348 / 9694 Time remaining: 4s Progress 3349 / 9694 Time remaining: 4s Progress 3350 / 9694 Time remaining: 4s Progress 3351 / 9694 Time remaining: 4s Progress 3352 / 9694 Time remaining: 4s Progress 3353 / 9694 Time remaining: 4s Progress 3354 / 9694 Time remaining: 4s Progress 3355 / 9694 Time remaining: 4s Progress 3356 / 9694 Time remaining: 4s Progress 3357 / 9694 Time remaining: 4s Progress 3358 / 9694 Time remaining: 4s Progress 3359 / 9694 Time remaining: 4s Progress 3360 / 9694 Time remaining: 4s Progress 3361 / 9694 Time remaining: 4s Progress 3362 / 9694 Time remaining: 4s Progress 3363 / 9694 Time remaining: 4s Progress 3364 / 9694 Time remaining: 4s Progress 3365 / 9694 Time remaining: 4s Progress 3366 / 9694 Time remaining: 4s Progress 3367 / 9694 Time remaining: 4s Progress 3368 / 9694 Time remaining: 4s Progress 3369 / 9694 Time remaining: 4s Progress 3370 / 9694 Time remaining: 4s Progress 3371 / 9694 Time remaining: 4s Progress 3372 / 9694 Time remaining: 4s Progress 3373 / 9694 Time remaining: 4s Progress 3374 / 9694 Time remaining: 4s Progress 3375 / 9694 Time remaining: 4s Progress 3376 / 9694 Time remaining: 4s Progress 3377 / 9694 Time remaining: 4s Progress 3378 / 9694 Time remaining: 4s Progress 3379 / 9694 Time remaining: 4s Progress 3380 / 9694 Time remaining: 4s Progress 3381 / 9694 Time remaining: 4s Progress 3382 / 9694 Time remaining: 4s Progress 3383 / 9694 Time remaining: 4s Progress 3384 / 9694 Time remaining: 4s Progress 3385 / 9694 Time remaining: 4s Progress 3386 / 9694 Time remaining: 4s Progress 3387 / 9694 Time remaining: 4s Progress 3388 / 9694 Time remaining: 4s Progress 3389 / 9694 Time remaining: 4s Progress 3390 / 9694 Time remaining: 4s Progress 3391 / 9694 Time remaining: 4s Progress 3392 / 9694 Time remaining: 4s Progress 3393 / 9694 Time remaining: 4s Progress 3394 / 9694 Time remaining: 4s Progress 3395 / 9694 Time remaining: 4s Progress 3396 / 9694 Time remaining: 4s Progress 3397 / 9694 Time remaining: 4s Progress 3398 / 9694 Time remaining: 4s Progress 3399 / 9694 Time remaining: 4s Progress 3400 / 9694 Time remaining: 4s Progress 3401 / 9694 Time remaining: 4s Progress 3402 / 9694 Time remaining: 4s Progress 3403 / 9694 Time remaining: 4s Progress 3404 / 9694 Time remaining: 4s Progress 3405 / 9694 Time remaining: 4s Progress 3406 / 9694 Time remaining: 4s Progress 3407 / 9694 Time remaining: 4s Progress 3408 / 9694 Time remaining: 4s Progress 3409 / 9694 Time remaining: 4s Progress 3410 / 9694 Time remaining: 4s Progress 3411 / 9694 Time remaining: 4s Progress 3412 / 9694 Time remaining: 4s Progress 3413 / 9694 Time remaining: 4s Progress 3414 / 9694 Time remaining: 4s Progress 3415 / 9694 Time remaining: 4s Progress 3416 / 9694 Time remaining: 4s Progress 3417 / 9694 Time remaining: 4s Progress 3418 / 9694 Time remaining: 4s Progress 3419 / 9694 Time remaining: 4s Progress 3420 / 9694 Time remaining: 4s Progress 3421 / 9694 Time remaining: 4s Progress 3422 / 9694 Time remaining: 4s Progress 3423 / 9694 Time remaining: 4s Progress 3424 / 9694 Time remaining: 4s Progress 3425 / 9694 Time remaining: 4s Progress 3426 / 9694 Time remaining: 4s Progress 3427 / 9694 Time remaining: 4s Progress 3428 / 9694 Time remaining: 4s Progress 3429 / 9694 Time remaining: 4s Progress 3430 / 9694 Time remaining: 4s Progress 3431 / 9694 Time remaining: 4s Progress 3432 / 9694 Time remaining: 4s Progress 3433 / 9694 Time remaining: 4s Progress 3434 / 9694 Time remaining: 4s Progress 3435 / 9694 Time remaining: 4s Progress 3436 / 9694 Time remaining: 4s Progress 3437 / 9694 Time remaining: 4s Progress 3438 / 9694 Time remaining: 4s Progress 3439 / 9694 Time remaining: 4s Progress 3440 / 9694 Time remaining: 4s Progress 3441 / 9694 Time remaining: 4s Progress 3442 / 9694 Time remaining: 4s Progress 3443 / 9694 Time remaining: 4s Progress 3444 / 9694 Time remaining: 4s Progress 3445 / 9694 Time remaining: 4s Progress 3446 / 9694 Time remaining: 4s Progress 3447 / 9694 Time remaining: 4s Progress 3448 / 9694 Time remaining: 4s Progress 3449 / 9694 Time remaining: 4s Progress 3450 / 9694 Time remaining: 4s Progress 3451 / 9694 Time remaining: 4s Progress 3452 / 9694 Time remaining: 4s Progress 3453 / 9694 Time remaining: 4s Progress 3454 / 9694 Time remaining: 4s Progress 3455 / 9694 Time remaining: 4s Progress 3456 / 9694 Time remaining: 4s Progress 3457 / 9694 Time remaining: 4s Progress 3458 / 9694 Time remaining: 4s Progress 3459 / 9694 Time remaining: 4s Progress 3460 / 9694 Time remaining: 4s Progress 3461 / 9694 Time remaining: 4s Progress 3462 / 9694 Time remaining: 4s Progress 3463 / 9694 Time remaining: 4s Progress 3464 / 9694 Time remaining: 4s Progress 3465 / 9694 Time remaining: 4s Progress 3466 / 9694 Time remaining: 4s Progress 3467 / 9694 Time remaining: 4s Progress 3468 / 9694 Time remaining: 4s Progress 3469 / 9694 Time remaining: 4s Progress 3470 / 9694 Time remaining: 4s Progress 3471 / 9694 Time remaining: 4s Progress 3472 / 9694 Time remaining: 4s Progress 3473 / 9694 Time remaining: 4s Progress 3474 / 9694 Time remaining: 4s Progress 3475 / 9694 Time remaining: 4s Progress 3476 / 9694 Time remaining: 4s Progress 3477 / 9694 Time remaining: 4s Progress 3478 / 9694 Time remaining: 4s Progress 3479 / 9694 Time remaining: 4s Progress 3480 / 9694 Time remaining: 4s Progress 3481 / 9694 Time remaining: 4s Progress 3482 / 9694 Time remaining: 4s Progress 3483 / 9694 Time remaining: 4s Progress 3484 / 9694 Time remaining: 4s Progress 3485 / 9694 Time remaining: 4s Progress 3486 / 9694 Time remaining: 4s Progress 3487 / 9694 Time remaining: 4s Progress 3488 / 9694 Time remaining: 4s Progress 3489 / 9694 Time remaining: 4s Progress 3490 / 9694 Time remaining: 4s Progress 3491 / 9694 Time remaining: 4s Progress 3492 / 9694 Time remaining: 4s Progress 3493 / 9694 Time remaining: 4s Progress 3494 / 9694 Time remaining: 4s Progress 3495 / 9694 Time remaining: 4s Progress 3496 / 9694 Time remaining: 4s Progress 3497 / 9694 Time remaining: 4s Progress 3498 / 9694 Time remaining: 4s Progress 3499 / 9694 Time remaining: 4s Progress 3500 / 9694 Time remaining: 4s Progress 3501 / 9694 Time remaining: 4s Progress 3502 / 9694 Time remaining: 4s Progress 3503 / 9694 Time remaining: 4s Progress 3504 / 9694 Time remaining: 4s Progress 3505 / 9694 Time remaining: 4s Progress 3506 / 9694 Time remaining: 4s Progress 3507 / 9694 Time remaining: 4s Progress 3508 / 9694 Time remaining: 4s Progress 3509 / 9694 Time remaining: 4s Progress 3510 / 9694 Time remaining: 4s Progress 3511 / 9694 Time remaining: 4s Progress 3512 / 9694 Time remaining: 4s Progress 3513 / 9694 Time remaining: 4s Progress 3514 / 9694 Time remaining: 4s Progress 3515 / 9694 Time remaining: 4s Progress 3516 / 9694 Time remaining: 4s Progress 3517 / 9694 Time remaining: 4s Progress 3518 / 9694 Time remaining: 4s Progress 3519 / 9694 Time remaining: 4s Progress 3520 / 9694 Time remaining: 4s Progress 3521 / 9694 Time remaining: 4s Progress 3522 / 9694 Time remaining: 4s Progress 3523 / 9694 Time remaining: 4s Progress 3524 / 9694 Time remaining: 4s Progress 3525 / 9694 Time remaining: 4s Progress 3526 / 9694 Time remaining: 4s Progress 3527 / 9694 Time remaining: 4s Progress 3528 / 9694 Time remaining: 4s Progress 3529 / 9694 Time remaining: 4s Progress 3530 / 9694 Time remaining: 4s Progress 3531 / 9694 Time remaining: 4s Progress 3532 / 9694 Time remaining: 4s Progress 3533 / 9694 Time remaining: 4s Progress 3534 / 9694 Time remaining: 4s Progress 3535 / 9694 Time remaining: 4s Progress 3536 / 9694 Time remaining: 4s Progress 3537 / 9694 Time remaining: 4s Progress 3538 / 9694 Time remaining: 4s Progress 3539 / 9694 Time remaining: 4s Progress 3540 / 9694 Time remaining: 4s Progress 3541 / 9694 Time remaining: 4s Progress 3542 / 9694 Time remaining: 4s Progress 3543 / 9694 Time remaining: 4s Progress 3544 / 9694 Time remaining: 4s Progress 3545 / 9694 Time remaining: 4s Progress 3546 / 9694 Time remaining: 4s Progress 3547 / 9694 Time remaining: 4s Progress 3548 / 9694 Time remaining: 4s Progress 3549 / 9694 Time remaining: 4s Progress 3550 / 9694 Time remaining: 4s Progress 3551 / 9694 Time remaining: 4s Progress 3552 / 9694 Time remaining: 4s Progress 3553 / 9694 Time remaining: 4s Progress 3554 / 9694 Time remaining: 4s Progress 3555 / 9694 Time remaining: 4s Progress 3556 / 9694 Time remaining: 4s Progress 3557 / 9694 Time remaining: 4s Progress 3558 / 9694 Time remaining: 4s Progress 3559 / 9694 Time remaining: 4s Progress 3560 / 9694 Time remaining: 4s Progress 3561 / 9694 Time remaining: 4s Progress 3562 / 9694 Time remaining: 4s Progress 3563 / 9694 Time remaining: 4s Progress 3564 / 9694 Time remaining: 4s Progress 3565 / 9694 Time remaining: 4s Progress 3566 / 9694 Time remaining: 4s Progress 3567 / 9694 Time remaining: 4s Progress 3568 / 9694 Time remaining: 4s Progress 3569 / 9694 Time remaining: 4s Progress 3570 / 9694 Time remaining: 4s Progress 3571 / 9694 Time remaining: 4s Progress 3572 / 9694 Time remaining: 4s Progress 3573 / 9694 Time remaining: 4s Progress 3574 / 9694 Time remaining: 4s Progress 3575 / 9694 Time remaining: 4s Progress 3576 / 9694 Time remaining: 4s Progress 3577 / 9694 Time remaining: 4s Progress 3578 / 9694 Time remaining: 4s Progress 3579 / 9694 Time remaining: 4s Progress 3580 / 9694 Time remaining: 4s Progress 3581 / 9694 Time remaining: 4s Progress 3582 / 9694 Time remaining: 4s Progress 3583 / 9694 Time remaining: 4s Progress 3584 / 9694 Time remaining: 4s Progress 3585 / 9694 Time remaining: 4s Progress 3586 / 9694 Time remaining: 4s Progress 3587 / 9694 Time remaining: 4s Progress 3588 / 9694 Time remaining: 4s Progress 3589 / 9694 Time remaining: 4s Progress 3590 / 9694 Time remaining: 4s Progress 3591 / 9694 Time remaining: 4s Progress 3592 / 9694 Time remaining: 4s Progress 3593 / 9694 Time remaining: 4s Progress 3594 / 9694 Time remaining: 4s Progress 3595 / 9694 Time remaining: 4s Progress 3596 / 9694 Time remaining: 4s Progress 3597 / 9694 Time remaining: 4s Progress 3598 / 9694 Time remaining: 4s Progress 3599 / 9694 Time remaining: 4s Progress 3600 / 9694 Time remaining: 4s Progress 3601 / 9694 Time remaining: 4s Progress 3602 / 9694 Time remaining: 4s Progress 3603 / 9694 Time remaining: 4s Progress 3604 / 9694 Time remaining: 4s Progress 3605 / 9694 Time remaining: 4s Progress 3606 / 9694 Time remaining: 4s Progress 3607 / 9694 Time remaining: 4s Progress 3608 / 9694 Time remaining: 4s Progress 3609 / 9694 Time remaining: 4s Progress 3610 / 9694 Time remaining: 4s Progress 3611 / 9694 Time remaining: 4s Progress 3612 / 9694 Time remaining: 4s Progress 3613 / 9694 Time remaining: 4s Progress 3614 / 9694 Time remaining: 4s Progress 3615 / 9694 Time remaining: 4s Progress 3616 / 9694 Time remaining: 4s Progress 3617 / 9694 Time remaining: 4s Progress 3618 / 9694 Time remaining: 4s Progress 3619 / 9694 Time remaining: 4s Progress 3620 / 9694 Time remaining: 4s Progress 3621 / 9694 Time remaining: 4s Progress 3622 / 9694 Time remaining: 4s Progress 3623 / 9694 Time remaining: 4s Progress 3624 / 9694 Time remaining: 4s Progress 3625 / 9694 Time remaining: 4s Progress 3626 / 9694 Time remaining: 4s Progress 3627 / 9694 Time remaining: 4s Progress 3628 / 9694 Time remaining: 4s Progress 3629 / 9694 Time remaining: 4s Progress 3630 / 9694 Time remaining: 4s Progress 3631 / 9694 Time remaining: 4s Progress 3632 / 9694 Time remaining: 4s Progress 3633 / 9694 Time remaining: 4s Progress 3634 / 9694 Time remaining: 4s Progress 3635 / 9694 Time remaining: 4s Progress 3636 / 9694 Time remaining: 4s Progress 3637 / 9694 Time remaining: 4s Progress 3638 / 9694 Time remaining: 4s Progress 3639 / 9694 Time remaining: 4s Progress 3640 / 9694 Time remaining: 4s Progress 3641 / 9694 Time remaining: 4s Progress 3642 / 9694 Time remaining: 4s Progress 3643 / 9694 Time remaining: 4s Progress 3644 / 9694 Time remaining: 4s Progress 3645 / 9694 Time remaining: 4s Progress 3646 / 9694 Time remaining: 4s Progress 3647 / 9694 Time remaining: 4s Progress 3648 / 9694 Time remaining: 4s Progress 3649 / 9694 Time remaining: 4s Progress 3650 / 9694 Time remaining: 4s Progress 3651 / 9694 Time remaining: 4s Progress 3652 / 9694 Time remaining: 4s Progress 3653 / 9694 Time remaining: 4s Progress 3654 / 9694 Time remaining: 4s Progress 3655 / 9694 Time remaining: 4s Progress 3656 / 9694 Time remaining: 4s Progress 3657 / 9694 Time remaining: 4s Progress 3658 / 9694 Time remaining: 4s Progress 3659 / 9694 Time remaining: 4s Progress 3660 / 9694 Time remaining: 4s Progress 3661 / 9694 Time remaining: 4s Progress 3662 / 9694 Time remaining: 4s Progress 3663 / 9694 Time remaining: 4s Progress 3664 / 9694 Time remaining: 4s Progress 3665 / 9694 Time remaining: 4s Progress 3666 / 9694 Time remaining: 4s Progress 3667 / 9694 Time remaining: 4s Progress 3668 / 9694 Time remaining: 4s Progress 3669 / 9694 Time remaining: 4s Progress 3670 / 9694 Time remaining: 4s Progress 3671 / 9694 Time remaining: 4s Progress 3672 / 9694 Time remaining: 4s Progress 3673 / 9694 Time remaining: 4s Progress 3674 / 9694 Time remaining: 4s Progress 3675 / 9694 Time remaining: 4s Progress 3676 / 9694 Time remaining: 4s Progress 3677 / 9694 Time remaining: 4s Progress 3678 / 9694 Time remaining: 4s Progress 3679 / 9694 Time remaining: 4s Progress 3680 / 9694 Time remaining: 4s Progress 3681 / 9694 Time remaining: 4s Progress 3682 / 9694 Time remaining: 4s Progress 3683 / 9694 Time remaining: 4s Progress 3684 / 9694 Time remaining: 4s Progress 3685 / 9694 Time remaining: 4s Progress 3686 / 9694 Time remaining: 4s Progress 3687 / 9694 Time remaining: 4s Progress 3688 / 9694 Time remaining: 4s Progress 3689 / 9694 Time remaining: 4s Progress 3690 / 9694 Time remaining: 4s Progress 3691 / 9694 Time remaining: 4s Progress 3692 / 9694 Time remaining: 4s Progress 3693 / 9694 Time remaining: 4s Progress 3694 / 9694 Time remaining: 4s Progress 3695 / 9694 Time remaining: 4s Progress 3696 / 9694 Time remaining: 4s Progress 3697 / 9694 Time remaining: 4s Progress 3698 / 9694 Time remaining: 4s Progress 3699 / 9694 Time remaining: 4s Progress 3700 / 9694 Time remaining: 4s Progress 3701 / 9694 Time remaining: 4s Progress 3702 / 9694 Time remaining: 4s Progress 3703 / 9694 Time remaining: 4s Progress 3704 / 9694 Time remaining: 4s Progress 3705 / 9694 Time remaining: 4s Progress 3706 / 9694 Time remaining: 4s Progress 3707 / 9694 Time remaining: 4s Progress 3708 / 9694 Time remaining: 4s Progress 3709 / 9694 Time remaining: 4s Progress 3710 / 9694 Time remaining: 4s Progress 3711 / 9694 Time remaining: 4s Progress 3712 / 9694 Time remaining: 4s Progress 3713 / 9694 Time remaining: 4s Progress 3714 / 9694 Time remaining: 4s Progress 3715 / 9694 Time remaining: 4s Progress 3716 / 9694 Time remaining: 4s Progress 3717 / 9694 Time remaining: 4s Progress 3718 / 9694 Time remaining: 4s Progress 3719 / 9694 Time remaining: 4s Progress 3720 / 9694 Time remaining: 4s Progress 3721 / 9694 Time remaining: 4s Progress 3722 / 9694 Time remaining: 4s Progress 3723 / 9694 Time remaining: 4s Progress 3724 / 9694 Time remaining: 4s Progress 3725 / 9694 Time remaining: 4s Progress 3726 / 9694 Time remaining: 4s Progress 3727 / 9694 Time remaining: 4s Progress 3728 / 9694 Time remaining: 4s Progress 3729 / 9694 Time remaining: 4s Progress 3730 / 9694 Time remaining: 4s Progress 3731 / 9694 Time remaining: 4s Progress 3732 / 9694 Time remaining: 4s Progress 3733 / 9694 Time remaining: 4s Progress 3734 / 9694 Time remaining: 4s Progress 3735 / 9694 Time remaining: 4s Progress 3736 / 9694 Time remaining: 4s Progress 3737 / 9694 Time remaining: 4s Progress 3738 / 9694 Time remaining: 4s Progress 3739 / 9694 Time remaining: 4s Progress 3740 / 9694 Time remaining: 4s Progress 3741 / 9694 Time remaining: 4s Progress 3742 / 9694 Time remaining: 4s Progress 3743 / 9694 Time remaining: 4s Progress 3744 / 9694 Time remaining: 4s Progress 3745 / 9694 Time remaining: 4s Progress 3746 / 9694 Time remaining: 4s Progress 3747 / 9694 Time remaining: 4s Progress 3748 / 9694 Time remaining: 4s Progress 3749 / 9694 Time remaining: 4s Progress 3750 / 9694 Time remaining: 4s Progress 3751 / 9694 Time remaining: 4s Progress 3752 / 9694 Time remaining: 4s Progress 3753 / 9694 Time remaining: 4s Progress 3754 / 9694 Time remaining: 4s Progress 3755 / 9694 Time remaining: 4s Progress 3756 / 9694 Time remaining: 4s Progress 3757 / 9694 Time remaining: 4s Progress 3758 / 9694 Time remaining: 4s Progress 3759 / 9694 Time remaining: 4s Progress 3760 / 9694 Time remaining: 4s Progress 3761 / 9694 Time remaining: 4s Progress 3762 / 9694 Time remaining: 4s Progress 3763 / 9694 Time remaining: 4s Progress 3764 / 9694 Time remaining: 4s Progress 3765 / 9694 Time remaining: 4s Progress 3766 / 9694 Time remaining: 4s Progress 3767 / 9694 Time remaining: 4s Progress 3768 / 9694 Time remaining: 4s Progress 3769 / 9694 Time remaining: 4s Progress 3770 / 9694 Time remaining: 4s Progress 3771 / 9694 Time remaining: 4s Progress 3772 / 9694 Time remaining: 4s Progress 3773 / 9694 Time remaining: 4s Progress 3774 / 9694 Time remaining: 4s Progress 3775 / 9694 Time remaining: 4s Progress 3776 / 9694 Time remaining: 4s Progress 3777 / 9694 Time remaining: 4s Progress 3778 / 9694 Time remaining: 4s Progress 3779 / 9694 Time remaining: 4s Progress 3780 / 9694 Time remaining: 4s Progress 3781 / 9694 Time remaining: 4s Progress 3782 / 9694 Time remaining: 4s Progress 3783 / 9694 Time remaining: 4s Progress 3784 / 9694 Time remaining: 4s Progress 3785 / 9694 Time remaining: 4s Progress 3786 / 9694 Time remaining: 4s Progress 3787 / 9694 Time remaining: 4s Progress 3788 / 9694 Time remaining: 4s Progress 3789 / 9694 Time remaining: 4s Progress 3790 / 9694 Time remaining: 4s Progress 3791 / 9694 Time remaining: 4s Progress 3792 / 9694 Time remaining: 4s Progress 3793 / 9694 Time remaining: 4s Progress 3794 / 9694 Time remaining: 4s Progress 3795 / 9694 Time remaining: 4s Progress 3796 / 9694 Time remaining: 4s Progress 3797 / 9694 Time remaining: 4s Progress 3798 / 9694 Time remaining: 4s Progress 3799 / 9694 Time remaining: 4s Progress 3800 / 9694 Time remaining: 4s Progress 3801 / 9694 Time remaining: 4s Progress 3802 / 9694 Time remaining: 4s Progress 3803 / 9694 Time remaining: 4s Progress 3804 / 9694 Time remaining: 4s Progress 3805 / 9694 Time remaining: 4s Progress 3806 / 9694 Time remaining: 4s Progress 3807 / 9694 Time remaining: 4s Progress 3808 / 9694 Time remaining: 4s Progress 3809 / 9694 Time remaining: 4s Progress 3810 / 9694 Time remaining: 4s Progress 3811 / 9694 Time remaining: 4s Progress 3812 / 9694 Time remaining: 4s Progress 3813 / 9694 Time remaining: 4s Progress 3814 / 9694 Time remaining: 4s Progress 3815 / 9694 Time remaining: 4s Progress 3816 / 9694 Time remaining: 4s Progress 3817 / 9694 Time remaining: 4s Progress 3818 / 9694 Time remaining: 4s Progress 3819 / 9694 Time remaining: 4s Progress 3820 / 9694 Time remaining: 4s Progress 3821 / 9694 Time remaining: 4s Progress 3822 / 9694 Time remaining: 4s Progress 3823 / 9694 Time remaining: 4s Progress 3824 / 9694 Time remaining: 4s Progress 3825 / 9694 Time remaining: 4s Progress 3826 / 9694 Time remaining: 4s Progress 3827 / 9694 Time remaining: 4s Progress 3828 / 9694 Time remaining: 4s Progress 3829 / 9694 Time remaining: 4s Progress 3830 / 9694 Time remaining: 4s Progress 3831 / 9694 Time remaining: 4s Progress 3832 / 9694 Time remaining: 4s Progress 3833 / 9694 Time remaining: 4s Progress 3834 / 9694 Time remaining: 4s Progress 3835 / 9694 Time remaining: 4s Progress 3836 / 9694 Time remaining: 4s Progress 3837 / 9694 Time remaining: 4s Progress 3838 / 9694 Time remaining: 4s Progress 3839 / 9694 Time remaining: 4s Progress 3840 / 9694 Time remaining: 4s Progress 3841 / 9694 Time remaining: 4s Progress 3842 / 9694 Time remaining: 4s Progress 3843 / 9694 Time remaining: 4s Progress 3844 / 9694 Time remaining: 4s Progress 3845 / 9694 Time remaining: 4s Progress 3846 / 9694 Time remaining: 4s Progress 3847 / 9694 Time remaining: 4s Progress 3848 / 9694 Time remaining: 4s Progress 3849 / 9694 Time remaining: 4s Progress 3850 / 9694 Time remaining: 4s Progress 3851 / 9694 Time remaining: 4s Progress 3852 / 9694 Time remaining: 4s Progress 3853 / 9694 Time remaining: 4s Progress 3854 / 9694 Time remaining: 4s Progress 3855 / 9694 Time remaining: 4s Progress 3856 / 9694 Time remaining: 4s Progress 3857 / 9694 Time remaining: 4s Progress 3858 / 9694 Time remaining: 4s Progress 3859 / 9694 Time remaining: 4s Progress 3860 / 9694 Time remaining: 4s Progress 3861 / 9694 Time remaining: 4s Progress 3862 / 9694 Time remaining: 4s Progress 3863 / 9694 Time remaining: 4s Progress 3864 / 9694 Time remaining: 4s Progress 3865 / 9694 Time remaining: 4s Progress 3866 / 9694 Time remaining: 4s Progress 3867 / 9694 Time remaining: 4s Progress 3868 / 9694 Time remaining: 4s Progress 3869 / 9694 Time remaining: 4s Progress 3870 / 9694 Time remaining: 4s Progress 3871 / 9694 Time remaining: 4s Progress 3872 / 9694 Time remaining: 4s Progress 3873 / 9694 Time remaining: 4s Progress 3874 / 9694 Time remaining: 4s Progress 3875 / 9694 Time remaining: 4s Progress 3876 / 9694 Time remaining: 4s Progress 3877 / 9694 Time remaining: 4s Progress 3878 / 9694 Time remaining: 4s Progress 3879 / 9694 Time remaining: 4s Progress 3880 / 9694 Time remaining: 4s Progress 3881 / 9694 Time remaining: 4s Progress 3882 / 9694 Time remaining: 4s Progress 3883 / 9694 Time remaining: 4s Progress 3884 / 9694 Time remaining: 4s Progress 3885 / 9694 Time remaining: 4s Progress 3886 / 9694 Time remaining: 4s Progress 3887 / 9694 Time remaining: 4s Progress 3888 / 9694 Time remaining: 4s Progress 3889 / 9694 Time remaining: 4s Progress 3890 / 9694 Time remaining: 4s Progress 3891 / 9694 Time remaining: 4s Progress 3892 / 9694 Time remaining: 4s Progress 3893 / 9694 Time remaining: 4s Progress 3894 / 9694 Time remaining: 4s Progress 3895 / 9694 Time remaining: 4s Progress 3896 / 9694 Time remaining: 4s Progress 3897 / 9694 Time remaining: 4s Progress 3898 / 9694 Time remaining: 4s Progress 3899 / 9694 Time remaining: 4s Progress 3900 / 9694 Time remaining: 4s Progress 3901 / 9694 Time remaining: 4s Progress 3902 / 9694 Time remaining: 4s Progress 3903 / 9694 Time remaining: 4s Progress 3904 / 9694 Time remaining: 4s Progress 3905 / 9694 Time remaining: 4s Progress 3906 / 9694 Time remaining: 4s Progress 3907 / 9694 Time remaining: 4s Progress 3908 / 9694 Time remaining: 4s Progress 3909 / 9694 Time remaining: 4s Progress 3910 / 9694 Time remaining: 4s Progress 3911 / 9694 Time remaining: 4s Progress 3912 / 9694 Time remaining: 4s Progress 3913 / 9694 Time remaining: 4s Progress 3914 / 9694 Time remaining: 4s Progress 3915 / 9694 Time remaining: 4s Progress 3916 / 9694 Time remaining: 4s Progress 3917 / 9694 Time remaining: 4s Progress 3918 / 9694 Time remaining: 4s Progress 3919 / 9694 Time remaining: 4s Progress 3920 / 9694 Time remaining: 4s Progress 3921 / 9694 Time remaining: 4s Progress 3922 / 9694 Time remaining: 4s Progress 3923 / 9694 Time remaining: 4s Progress 3924 / 9694 Time remaining: 4s Progress 3925 / 9694 Time remaining: 4s Progress 3926 / 9694 Time remaining: 4s Progress 3927 / 9694 Time remaining: 4s Progress 3928 / 9694 Time remaining: 4s Progress 3929 / 9694 Time remaining: 4s Progress 3930 / 9694 Time remaining: 4s Progress 3931 / 9694 Time remaining: 4s Progress 3932 / 9694 Time remaining: 4s Progress 3933 / 9694 Time remaining: 4s Progress 3934 / 9694 Time remaining: 4s Progress 3935 / 9694 Time remaining: 4s Progress 3936 / 9694 Time remaining: 4s Progress 3937 / 9694 Time remaining: 4s Progress 3938 / 9694 Time remaining: 4s Progress 3939 / 9694 Time remaining: 4s Progress 3940 / 9694 Time remaining: 4s Progress 3941 / 9694 Time remaining: 4s Progress 3942 / 9694 Time remaining: 4s Progress 3943 / 9694 Time remaining: 4s Progress 3944 / 9694 Time remaining: 4s Progress 3945 / 9694 Time remaining: 4s Progress 3946 / 9694 Time remaining: 4s Progress 3947 / 9694 Time remaining: 4s Progress 3948 / 9694 Time remaining: 4s Progress 3949 / 9694 Time remaining: 4s Progress 3950 / 9694 Time remaining: 4s Progress 3951 / 9694 Time remaining: 4s Progress 3952 / 9694 Time remaining: 4s Progress 3953 / 9694 Time remaining: 4s Progress 3954 / 9694 Time remaining: 4s Progress 3955 / 9694 Time remaining: 4s Progress 3956 / 9694 Time remaining: 4s Progress 3957 / 9694 Time remaining: 4s Progress 3958 / 9694 Time remaining: 4s Progress 3959 / 9694 Time remaining: 4s Progress 3960 / 9694 Time remaining: 4s Progress 3961 / 9694 Time remaining: 4s Progress 3962 / 9694 Time remaining: 4s Progress 3963 / 9694 Time remaining: 4s Progress 3964 / 9694 Time remaining: 4s Progress 3965 / 9694 Time remaining: 4s Progress 3966 / 9694 Time remaining: 4s Progress 3967 / 9694 Time remaining: 4s Progress 3968 / 9694 Time remaining: 4s Progress 3969 / 9694 Time remaining: 4s Progress 3970 / 9694 Time remaining: 4s Progress 3971 / 9694 Time remaining: 4s Progress 3972 / 9694 Time remaining: 4s Progress 3973 / 9694 Time remaining: 4s Progress 3974 / 9694 Time remaining: 4s Progress 3975 / 9694 Time remaining: 4s Progress 3976 / 9694 Time remaining: 4s Progress 3977 / 9694 Time remaining: 4s Progress 3978 / 9694 Time remaining: 4s Progress 3979 / 9694 Time remaining: 4s Progress 3980 / 9694 Time remaining: 4s Progress 3981 / 9694 Time remaining: 4s Progress 3982 / 9694 Time remaining: 4s Progress 3983 / 9694 Time remaining: 4s Progress 3984 / 9694 Time remaining: 4s Progress 3985 / 9694 Time remaining: 4s Progress 3986 / 9694 Time remaining: 4s Progress 3987 / 9694 Time remaining: 4s Progress 3988 / 9694 Time remaining: 4s Progress 3989 / 9694 Time remaining: 4s Progress 3990 / 9694 Time remaining: 4s Progress 3991 / 9694 Time remaining: 4s Progress 3992 / 9694 Time remaining: 4s Progress 3993 / 9694 Time remaining: 4s Progress 3994 / 9694 Time remaining: 4s Progress 3995 / 9694 Time remaining: 4s Progress 3996 / 9694 Time remaining: 4s Progress 3997 / 9694 Time remaining: 4s Progress 3998 / 9694 Time remaining: 4s Progress 3999 / 9694 Time remaining: 4s Progress 4000 / 9694 Time remaining: 4s Progress 4001 / 9694 Time remaining: 4s Progress 4002 / 9694 Time remaining: 4s Progress 4003 / 9694 Time remaining: 4s Progress 4004 / 9694 Time remaining: 4s Progress 4005 / 9694 Time remaining: 4s Progress 4006 / 9694 Time remaining: 4s Progress 4007 / 9694 Time remaining: 4s Progress 4008 / 9694 Time remaining: 4s Progress 4009 / 9694 Time remaining: 4s Progress 4010 / 9694 Time remaining: 4s Progress 4011 / 9694 Time remaining: 4s Progress 4012 / 9694 Time remaining: 4s Progress 4013 / 9694 Time remaining: 4s Progress 4014 / 9694 Time remaining: 4s Progress 4015 / 9694 Time remaining: 4s Progress 4016 / 9694 Time remaining: 4s Progress 4017 / 9694 Time remaining: 4s Progress 4018 / 9694 Time remaining: 4s Progress 4019 / 9694 Time remaining: 4s Progress 4020 / 9694 Time remaining: 4s Progress 4021 / 9694 Time remaining: 4s Progress 4022 / 9694 Time remaining: 4s Progress 4023 / 9694 Time remaining: 4s Progress 4024 / 9694 Time remaining: 4s Progress 4025 / 9694 Time remaining: 4s Progress 4026 / 9694 Time remaining: 4s Progress 4027 / 9694 Time remaining: 4s Progress 4028 / 9694 Time remaining: 4s Progress 4029 / 9694 Time remaining: 4s Progress 4030 / 9694 Time remaining: 4s Progress 4031 / 9694 Time remaining: 4s Progress 4032 / 9694 Time remaining: 4s Progress 4033 / 9694 Time remaining: 4s Progress 4034 / 9694 Time remaining: 4s Progress 4035 / 9694 Time remaining: 4s Progress 4036 / 9694 Time remaining: 4s Progress 4037 / 9694 Time remaining: 4s Progress 4038 / 9694 Time remaining: 4s Progress 4039 / 9694 Time remaining: 4s Progress 4040 / 9694 Time remaining: 4s Progress 4041 / 9694 Time remaining: 4s Progress 4042 / 9694 Time remaining: 4s Progress 4043 / 9694 Time remaining: 4s Progress 4044 / 9694 Time remaining: 4s Progress 4045 / 9694 Time remaining: 4s Progress 4046 / 9694 Time remaining: 4s Progress 4047 / 9694 Time remaining: 4s Progress 4048 / 9694 Time remaining: 4s Progress 4049 / 9694 Time remaining: 4s Progress 4050 / 9694 Time remaining: 4s Progress 4051 / 9694 Time remaining: 4s Progress 4052 / 9694 Time remaining: 4s Progress 4053 / 9694 Time remaining: 4s Progress 4054 / 9694 Time remaining: 4s Progress 4055 / 9694 Time remaining: 4s Progress 4056 / 9694 Time remaining: 4s Progress 4057 / 9694 Time remaining: 4s Progress 4058 / 9694 Time remaining: 4s Progress 4059 / 9694 Time remaining: 4s Progress 4060 / 9694 Time remaining: 4s Progress 4061 / 9694 Time remaining: 4s Progress 4062 / 9694 Time remaining: 4s Progress 4063 / 9694 Time remaining: 4s Progress 4064 / 9694 Time remaining: 4s Progress 4065 / 9694 Time remaining: 4s Progress 4066 / 9694 Time remaining: 4s Progress 4067 / 9694 Time remaining: 4s Progress 4068 / 9694 Time remaining: 4s Progress 4069 / 9694 Time remaining: 4s Progress 4070 / 9694 Time remaining: 4s Progress 4071 / 9694 Time remaining: 4s Progress 4072 / 9694 Time remaining: 4s Progress 4073 / 9694 Time remaining: 4s Progress 4074 / 9694 Time remaining: 4s Progress 4075 / 9694 Time remaining: 4s Progress 4076 / 9694 Time remaining: 4s Progress 4077 / 9694 Time remaining: 4s Progress 4078 / 9694 Time remaining: 4s Progress 4079 / 9694 Time remaining: 4s Progress 4080 / 9694 Time remaining: 4s Progress 4081 / 9694 Time remaining: 4s Progress 4082 / 9694 Time remaining: 4s Progress 4083 / 9694 Time remaining: 4s Progress 4084 / 9694 Time remaining: 4s Progress 4085 / 9694 Time remaining: 4s Progress 4086 / 9694 Time remaining: 4s Progress 4087 / 9694 Time remaining: 4s Progress 4088 / 9694 Time remaining: 4s Progress 4089 / 9694 Time remaining: 4s Progress 4090 / 9694 Time remaining: 4s Progress 4091 / 9694 Time remaining: 4s Progress 4092 / 9694 Time remaining: 4s Progress 4093 / 9694 Time remaining: 4s Progress 4094 / 9694 Time remaining: 4s Progress 4095 / 9694 Time remaining: 4s Progress 4096 / 9694 Time remaining: 4s Progress 4097 / 9694 Time remaining: 4s Progress 4098 / 9694 Time remaining: 4s Progress 4099 / 9694 Time remaining: 4s Progress 4100 / 9694 Time remaining: 4s Progress 4101 / 9694 Time remaining: 4s Progress 4102 / 9694 Time remaining: 4s Progress 4103 / 9694 Time remaining: 4s Progress 4104 / 9694 Time remaining: 4s Progress 4105 / 9694 Time remaining: 4s Progress 4106 / 9694 Time remaining: 4s Progress 4107 / 9694 Time remaining: 4s Progress 4108 / 9694 Time remaining: 4s Progress 4109 / 9694 Time remaining: 4s Progress 4110 / 9694 Time remaining: 4s Progress 4111 / 9694 Time remaining: 4s Progress 4112 / 9694 Time remaining: 4s Progress 4113 / 9694 Time remaining: 4s Progress 4114 / 9694 Time remaining: 4s Progress 4115 / 9694 Time remaining: 4s Progress 4116 / 9694 Time remaining: 4s Progress 4117 / 9694 Time remaining: 4s Progress 4118 / 9694 Time remaining: 4s Progress 4119 / 9694 Time remaining: 4s Progress 4120 / 9694 Time remaining: 4s Progress 4121 / 9694 Time remaining: 4s Progress 4122 / 9694 Time remaining: 4s Progress 4123 / 9694 Time remaining: 4s Progress 4124 / 9694 Time remaining: 4s Progress 4125 / 9694 Time remaining: 4s Progress 4126 / 9694 Time remaining: 4s Progress 4127 / 9694 Time remaining: 4s Progress 4128 / 9694 Time remaining: 4s Progress 4129 / 9694 Time remaining: 4s Progress 4130 / 9694 Time remaining: 4s Progress 4131 / 9694 Time remaining: 4s Progress 4132 / 9694 Time remaining: 4s Progress 4133 / 9694 Time remaining: 4s Progress 4134 / 9694 Time remaining: 4s Progress 4135 / 9694 Time remaining: 4s Progress 4136 / 9694 Time remaining: 4s Progress 4137 / 9694 Time remaining: 4s Progress 4138 / 9694 Time remaining: 4s Progress 4139 / 9694 Time remaining: 4s Progress 4140 / 9694 Time remaining: 4s Progress 4141 / 9694 Time remaining: 4s Progress 4142 / 9694 Time remaining: 4s Progress 4143 / 9694 Time remaining: 4s Progress 4144 / 9694 Time remaining: 4s Progress 4145 / 9694 Time remaining: 4s Progress 4146 / 9694 Time remaining: 4s Progress 4147 / 9694 Time remaining: 4s Progress 4148 / 9694 Time remaining: 4s Progress 4149 / 9694 Time remaining: 4s Progress 4150 / 9694 Time remaining: 4s Progress 4151 / 9694 Time remaining: 4s Progress 4152 / 9694 Time remaining: 4s Progress 4153 / 9694 Time remaining: 4s Progress 4154 / 9694 Time remaining: 4s Progress 4155 / 9694 Time remaining: 4s Progress 4156 / 9694 Time remaining: 4s Progress 4157 / 9694 Time remaining: 4s Progress 4158 / 9694 Time remaining: 4s Progress 4159 / 9694 Time remaining: 4s Progress 4160 / 9694 Time remaining: 4s Progress 4161 / 9694 Time remaining: 4s Progress 4162 / 9694 Time remaining: 4s Progress 4163 / 9694 Time remaining: 4s Progress 4164 / 9694 Time remaining: 4s Progress 4165 / 9694 Time remaining: 4s Progress 4166 / 9694 Time remaining: 4s Progress 4167 / 9694 Time remaining: 4s Progress 4168 / 9694 Time remaining: 4s Progress 4169 / 9694 Time remaining: 4s Progress 4170 / 9694 Time remaining: 4s Progress 4171 / 9694 Time remaining: 4s Progress 4172 / 9694 Time remaining: 4s Progress 4173 / 9694 Time remaining: 4s Progress 4174 / 9694 Time remaining: 4s Progress 4175 / 9694 Time remaining: 4s Progress 4176 / 9694 Time remaining: 4s Progress 4177 / 9694 Time remaining: 4s Progress 4178 / 9694 Time remaining: 4s Progress 4179 / 9694 Time remaining: 4s Progress 4180 / 9694 Time remaining: 4s Progress 4181 / 9694 Time remaining: 4s Progress 4182 / 9694 Time remaining: 4s Progress 4183 / 9694 Time remaining: 4s Progress 4184 / 9694 Time remaining: 4s Progress 4185 / 9694 Time remaining: 4s Progress 4186 / 9694 Time remaining: 4s Progress 4187 / 9694 Time remaining: 4s Progress 4188 / 9694 Time remaining: 4s Progress 4189 / 9694 Time remaining: 4s Progress 4190 / 9694 Time remaining: 4s Progress 4191 / 9694 Time remaining: 4s Progress 4192 / 9694 Time remaining: 4s Progress 4193 / 9694 Time remaining: 4s Progress 4194 / 9694 Time remaining: 4s Progress 4195 / 9694 Time remaining: 4s Progress 4196 / 9694 Time remaining: 4s Progress 4197 / 9694 Time remaining: 4s Progress 4198 / 9694 Time remaining: 4s Progress 4199 / 9694 Time remaining: 4s Progress 4200 / 9694 Time remaining: 4s Progress 4201 / 9694 Time remaining: 4s Progress 4202 / 9694 Time remaining: 4s Progress 4203 / 9694 Time remaining: 4s Progress 4204 / 9694 Time remaining: 4s Progress 4205 / 9694 Time remaining: 4s Progress 4206 / 9694 Time remaining: 4s Progress 4207 / 9694 Time remaining: 4s Progress 4208 / 9694 Time remaining: 4s Progress 4209 / 9694 Time remaining: 4s Progress 4210 / 9694 Time remaining: 4s Progress 4211 / 9694 Time remaining: 4s Progress 4212 / 9694 Time remaining: 4s Progress 4213 / 9694 Time remaining: 4s Progress 4214 / 9694 Time remaining: 4s Progress 4215 / 9694 Time remaining: 4s Progress 4216 / 9694 Time remaining: 4s Progress 4217 / 9694 Time remaining: 4s Progress 4218 / 9694 Time remaining: 4s Progress 4219 / 9694 Time remaining: 4s Progress 4220 / 9694 Time remaining: 4s Progress 4221 / 9694 Time remaining: 4s Progress 4222 / 9694 Time remaining: 4s Progress 4223 / 9694 Time remaining: 4s Progress 4224 / 9694 Time remaining: 4s Progress 4225 / 9694 Time remaining: 4s Progress 4226 / 9694 Time remaining: 4s Progress 4227 / 9694 Time remaining: 4s Progress 4228 / 9694 Time remaining: 4s Progress 4229 / 9694 Time remaining: 4s Progress 4230 / 9694 Time remaining: 4s Progress 4231 / 9694 Time remaining: 4s Progress 4232 / 9694 Time remaining: 4s Progress 4233 / 9694 Time remaining: 4s Progress 4234 / 9694 Time remaining: 4s Progress 4235 / 9694 Time remaining: 4s Progress 4236 / 9694 Time remaining: 4s Progress 4237 / 9694 Time remaining: 4s Progress 4238 / 9694 Time remaining: 3s Progress 4239 / 9694 Time remaining: 3s Progress 4240 / 9694 Time remaining: 3s Progress 4241 / 9694 Time remaining: 3s Progress 4242 / 9694 Time remaining: 3s Progress 4243 / 9694 Time remaining: 3s Progress 4244 / 9694 Time remaining: 3s Progress 4245 / 9694 Time remaining: 3s Progress 4246 / 9694 Time remaining: 3s Progress 4247 / 9694 Time remaining: 3s Progress 4248 / 9694 Time remaining: 3s Progress 4249 / 9694 Time remaining: 3s Progress 4250 / 9694 Time remaining: 3s Progress 4251 / 9694 Time remaining: 3s Progress 4252 / 9694 Time remaining: 3s Progress 4253 / 9694 Time remaining: 3s Progress 4254 / 9694 Time remaining: 3s Progress 4255 / 9694 Time remaining: 3s Progress 4256 / 9694 Time remaining: 3s Progress 4257 / 9694 Time remaining: 3s Progress 4258 / 9694 Time remaining: 3s Progress 4259 / 9694 Time remaining: 3s Progress 4260 / 9694 Time remaining: 3s Progress 4261 / 9694 Time remaining: 3s Progress 4262 / 9694 Time remaining: 3s Progress 4263 / 9694 Time remaining: 3s Progress 4264 / 9694 Time remaining: 3s Progress 4265 / 9694 Time remaining: 3s Progress 4266 / 9694 Time remaining: 3s Progress 4267 / 9694 Time remaining: 3s Progress 4268 / 9694 Time remaining: 3s Progress 4269 / 9694 Time remaining: 3s Progress 4270 / 9694 Time remaining: 3s Progress 4271 / 9694 Time remaining: 3s Progress 4272 / 9694 Time remaining: 3s Progress 4273 / 9694 Time remaining: 3s Progress 4274 / 9694 Time remaining: 3s Progress 4275 / 9694 Time remaining: 3s Progress 4276 / 9694 Time remaining: 3s Progress 4277 / 9694 Time remaining: 3s Progress 4278 / 9694 Time remaining: 3s Progress 4279 / 9694 Time remaining: 3s Progress 4280 / 9694 Time remaining: 3s Progress 4281 / 9694 Time remaining: 3s Progress 4282 / 9694 Time remaining: 3s Progress 4283 / 9694 Time remaining: 3s Progress 4284 / 9694 Time remaining: 3s Progress 4285 / 9694 Time remaining: 3s Progress 4286 / 9694 Time remaining: 3s Progress 4287 / 9694 Time remaining: 3s Progress 4288 / 9694 Time remaining: 3s Progress 4289 / 9694 Time remaining: 3s Progress 4290 / 9694 Time remaining: 3s Progress 4291 / 9694 Time remaining: 3s Progress 4292 / 9694 Time remaining: 3s Progress 4293 / 9694 Time remaining: 3s Progress 4294 / 9694 Time remaining: 3s Progress 4295 / 9694 Time remaining: 3s Progress 4296 / 9694 Time remaining: 3s Progress 4297 / 9694 Time remaining: 3s Progress 4298 / 9694 Time remaining: 3s Progress 4299 / 9694 Time remaining: 3s Progress 4300 / 9694 Time remaining: 3s Progress 4301 / 9694 Time remaining: 3s Progress 4302 / 9694 Time remaining: 3s Progress 4303 / 9694 Time remaining: 3s Progress 4304 / 9694 Time remaining: 3s Progress 4305 / 9694 Time remaining: 3s Progress 4306 / 9694 Time remaining: 3s Progress 4307 / 9694 Time remaining: 3s Progress 4308 / 9694 Time remaining: 3s Progress 4309 / 9694 Time remaining: 3s Progress 4310 / 9694 Time remaining: 3s Progress 4311 / 9694 Time remaining: 3s Progress 4312 / 9694 Time remaining: 3s Progress 4313 / 9694 Time remaining: 3s Progress 4314 / 9694 Time remaining: 3s Progress 4315 / 9694 Time remaining: 3s Progress 4316 / 9694 Time remaining: 3s Progress 4317 / 9694 Time remaining: 3s Progress 4318 / 9694 Time remaining: 3s Progress 4319 / 9694 Time remaining: 3s Progress 4320 / 9694 Time remaining: 3s Progress 4321 / 9694 Time remaining: 3s Progress 4322 / 9694 Time remaining: 3s Progress 4323 / 9694 Time remaining: 3s Progress 4324 / 9694 Time remaining: 3s Progress 4325 / 9694 Time remaining: 3s Progress 4326 / 9694 Time remaining: 3s Progress 4327 / 9694 Time remaining: 3s Progress 4328 / 9694 Time remaining: 3s Progress 4329 / 9694 Time remaining: 3s Progress 4330 / 9694 Time remaining: 3s Progress 4331 / 9694 Time remaining: 3s Progress 4332 / 9694 Time remaining: 3s Progress 4333 / 9694 Time remaining: 3s Progress 4334 / 9694 Time remaining: 3s Progress 4335 / 9694 Time remaining: 3s Progress 4336 / 9694 Time remaining: 3s Progress 4337 / 9694 Time remaining: 3s Progress 4338 / 9694 Time remaining: 3s Progress 4339 / 9694 Time remaining: 3s Progress 4340 / 9694 Time remaining: 3s Progress 4341 / 9694 Time remaining: 3s Progress 4342 / 9694 Time remaining: 3s Progress 4343 / 9694 Time remaining: 3s Progress 4344 / 9694 Time remaining: 3s Progress 4345 / 9694 Time remaining: 3s Progress 4346 / 9694 Time remaining: 3s Progress 4347 / 9694 Time remaining: 3s Progress 4348 / 9694 Time remaining: 3s Progress 4349 / 9694 Time remaining: 3s Progress 4350 / 9694 Time remaining: 3s Progress 4351 / 9694 Time remaining: 3s Progress 4352 / 9694 Time remaining: 3s Progress 4353 / 9694 Time remaining: 3s Progress 4354 / 9694 Time remaining: 3s Progress 4355 / 9694 Time remaining: 3s Progress 4356 / 9694 Time remaining: 3s Progress 4357 / 9694 Time remaining: 3s Progress 4358 / 9694 Time remaining: 3s Progress 4359 / 9694 Time remaining: 3s Progress 4360 / 9694 Time remaining: 3s Progress 4361 / 9694 Time remaining: 3s Progress 4362 / 9694 Time remaining: 3s Progress 4363 / 9694 Time remaining: 3s Progress 4364 / 9694 Time remaining: 3s Progress 4365 / 9694 Time remaining: 3s Progress 4366 / 9694 Time remaining: 3s Progress 4367 / 9694 Time remaining: 3s Progress 4368 / 9694 Time remaining: 3s Progress 4369 / 9694 Time remaining: 3s Progress 4370 / 9694 Time remaining: 3s Progress 4371 / 9694 Time remaining: 3s Progress 4372 / 9694 Time remaining: 3s Progress 4373 / 9694 Time remaining: 3s Progress 4374 / 9694 Time remaining: 3s Progress 4375 / 9694 Time remaining: 3s Progress 4376 / 9694 Time remaining: 3s Progress 4377 / 9694 Time remaining: 3s Progress 4378 / 9694 Time remaining: 3s Progress 4379 / 9694 Time remaining: 3s Progress 4380 / 9694 Time remaining: 3s Progress 4381 / 9694 Time remaining: 3s Progress 4382 / 9694 Time remaining: 3s Progress 4383 / 9694 Time remaining: 3s Progress 4384 / 9694 Time remaining: 3s Progress 4385 / 9694 Time remaining: 3s Progress 4386 / 9694 Time remaining: 3s Progress 4387 / 9694 Time remaining: 3s Progress 4388 / 9694 Time remaining: 3s Progress 4389 / 9694 Time remaining: 3s Progress 4390 / 9694 Time remaining: 3s Progress 4391 / 9694 Time remaining: 3s Progress 4392 / 9694 Time remaining: 3s Progress 4393 / 9694 Time remaining: 3s Progress 4394 / 9694 Time remaining: 3s Progress 4395 / 9694 Time remaining: 3s Progress 4396 / 9694 Time remaining: 3s Progress 4397 / 9694 Time remaining: 3s Progress 4398 / 9694 Time remaining: 3s Progress 4399 / 9694 Time remaining: 3s Progress 4400 / 9694 Time remaining: 3s Progress 4401 / 9694 Time remaining: 3s Progress 4402 / 9694 Time remaining: 3s Progress 4403 / 9694 Time remaining: 3s Progress 4404 / 9694 Time remaining: 3s Progress 4405 / 9694 Time remaining: 3s Progress 4406 / 9694 Time remaining: 3s Progress 4407 / 9694 Time remaining: 3s Progress 4408 / 9694 Time remaining: 3s Progress 4409 / 9694 Time remaining: 3s Progress 4410 / 9694 Time remaining: 3s Progress 4411 / 9694 Time remaining: 3s Progress 4412 / 9694 Time remaining: 3s Progress 4413 / 9694 Time remaining: 3s Progress 4414 / 9694 Time remaining: 3s Progress 4415 / 9694 Time remaining: 3s Progress 4416 / 9694 Time remaining: 3s Progress 4417 / 9694 Time remaining: 3s Progress 4418 / 9694 Time remaining: 3s Progress 4419 / 9694 Time remaining: 3s Progress 4420 / 9694 Time remaining: 3s Progress 4421 / 9694 Time remaining: 3s Progress 4422 / 9694 Time remaining: 3s Progress 4423 / 9694 Time remaining: 3s Progress 4424 / 9694 Time remaining: 3s Progress 4425 / 9694 Time remaining: 3s Progress 4426 / 9694 Time remaining: 3s Progress 4427 / 9694 Time remaining: 3s Progress 4428 / 9694 Time remaining: 3s Progress 4429 / 9694 Time remaining: 3s Progress 4430 / 9694 Time remaining: 3s Progress 4431 / 9694 Time remaining: 3s Progress 4432 / 9694 Time remaining: 3s Progress 4433 / 9694 Time remaining: 3s Progress 4434 / 9694 Time remaining: 3s Progress 4435 / 9694 Time remaining: 3s Progress 4436 / 9694 Time remaining: 3s Progress 4437 / 9694 Time remaining: 3s Progress 4438 / 9694 Time remaining: 3s Progress 4439 / 9694 Time remaining: 3s Progress 4440 / 9694 Time remaining: 3s Progress 4441 / 9694 Time remaining: 3s Progress 4442 / 9694 Time remaining: 3s Progress 4443 / 9694 Time remaining: 3s Progress 4444 / 9694 Time remaining: 3s Progress 4445 / 9694 Time remaining: 3s Progress 4446 / 9694 Time remaining: 3s Progress 4447 / 9694 Time remaining: 3s Progress 4448 / 9694 Time remaining: 3s Progress 4449 / 9694 Time remaining: 3s Progress 4450 / 9694 Time remaining: 3s Progress 4451 / 9694 Time remaining: 3s Progress 4452 / 9694 Time remaining: 3s Progress 4453 / 9694 Time remaining: 3s Progress 4454 / 9694 Time remaining: 3s Progress 4455 / 9694 Time remaining: 3s Progress 4456 / 9694 Time remaining: 3s Progress 4457 / 9694 Time remaining: 3s Progress 4458 / 9694 Time remaining: 3s Progress 4459 / 9694 Time remaining: 3s Progress 4460 / 9694 Time remaining: 3s Progress 4461 / 9694 Time remaining: 3s Progress 4462 / 9694 Time remaining: 3s Progress 4463 / 9694 Time remaining: 3s Progress 4464 / 9694 Time remaining: 3s Progress 4465 / 9694 Time remaining: 3s Progress 4466 / 9694 Time remaining: 3s Progress 4467 / 9694 Time remaining: 3s Progress 4468 / 9694 Time remaining: 3s Progress 4469 / 9694 Time remaining: 3s Progress 4470 / 9694 Time remaining: 3s Progress 4471 / 9694 Time remaining: 3s Progress 4472 / 9694 Time remaining: 3s Progress 4473 / 9694 Time remaining: 3s Progress 4474 / 9694 Time remaining: 3s Progress 4475 / 9694 Time remaining: 3s Progress 4476 / 9694 Time remaining: 3s Progress 4477 / 9694 Time remaining: 3s Progress 4478 / 9694 Time remaining: 3s Progress 4479 / 9694 Time remaining: 3s Progress 4480 / 9694 Time remaining: 3s Progress 4481 / 9694 Time remaining: 3s Progress 4482 / 9694 Time remaining: 3s Progress 4483 / 9694 Time remaining: 3s Progress 4484 / 9694 Time remaining: 3s Progress 4485 / 9694 Time remaining: 3s Progress 4486 / 9694 Time remaining: 3s Progress 4487 / 9694 Time remaining: 3s Progress 4488 / 9694 Time remaining: 3s Progress 4489 / 9694 Time remaining: 3s Progress 4490 / 9694 Time remaining: 3s Progress 4491 / 9694 Time remaining: 3s Progress 4492 / 9694 Time remaining: 3s Progress 4493 / 9694 Time remaining: 3s Progress 4494 / 9694 Time remaining: 3s Progress 4495 / 9694 Time remaining: 3s Progress 4496 / 9694 Time remaining: 3s Progress 4497 / 9694 Time remaining: 3s Progress 4498 / 9694 Time remaining: 3s Progress 4499 / 9694 Time remaining: 3s Progress 4500 / 9694 Time remaining: 3s Progress 4501 / 9694 Time remaining: 3s Progress 4502 / 9694 Time remaining: 3s Progress 4503 / 9694 Time remaining: 3s Progress 4504 / 9694 Time remaining: 3s Progress 4505 / 9694 Time remaining: 3s Progress 4506 / 9694 Time remaining: 3s Progress 4507 / 9694 Time remaining: 3s Progress 4508 / 9694 Time remaining: 3s Progress 4509 / 9694 Time remaining: 3s Progress 4510 / 9694 Time remaining: 3s Progress 4511 / 9694 Time remaining: 3s Progress 4512 / 9694 Time remaining: 3s Progress 4513 / 9694 Time remaining: 3s Progress 4514 / 9694 Time remaining: 3s Progress 4515 / 9694 Time remaining: 3s Progress 4516 / 9694 Time remaining: 3s Progress 4517 / 9694 Time remaining: 3s Progress 4518 / 9694 Time remaining: 3s Progress 4519 / 9694 Time remaining: 3s Progress 4520 / 9694 Time remaining: 3s Progress 4521 / 9694 Time remaining: 3s Progress 4522 / 9694 Time remaining: 3s Progress 4523 / 9694 Time remaining: 3s Progress 4524 / 9694 Time remaining: 3s Progress 4525 / 9694 Time remaining: 3s Progress 4526 / 9694 Time remaining: 3s Progress 4527 / 9694 Time remaining: 3s Progress 4528 / 9694 Time remaining: 3s Progress 4529 / 9694 Time remaining: 3s Progress 4530 / 9694 Time remaining: 3s Progress 4531 / 9694 Time remaining: 3s Progress 4532 / 9694 Time remaining: 3s Progress 4533 / 9694 Time remaining: 3s Progress 4534 / 9694 Time remaining: 3s Progress 4535 / 9694 Time remaining: 3s Progress 4536 / 9694 Time remaining: 3s Progress 4537 / 9694 Time remaining: 3s Progress 4538 / 9694 Time remaining: 3s Progress 4539 / 9694 Time remaining: 3s Progress 4540 / 9694 Time remaining: 3s Progress 4541 / 9694 Time remaining: 3s Progress 4542 / 9694 Time remaining: 3s Progress 4543 / 9694 Time remaining: 3s Progress 4544 / 9694 Time remaining: 3s Progress 4545 / 9694 Time remaining: 3s Progress 4546 / 9694 Time remaining: 3s Progress 4547 / 9694 Time remaining: 3s Progress 4548 / 9694 Time remaining: 3s Progress 4549 / 9694 Time remaining: 3s Progress 4550 / 9694 Time remaining: 3s Progress 4551 / 9694 Time remaining: 3s Progress 4552 / 9694 Time remaining: 3s Progress 4553 / 9694 Time remaining: 3s Progress 4554 / 9694 Time remaining: 3s Progress 4555 / 9694 Time remaining: 3s Progress 4556 / 9694 Time remaining: 3s Progress 4557 / 9694 Time remaining: 3s Progress 4558 / 9694 Time remaining: 3s Progress 4559 / 9694 Time remaining: 3s Progress 4560 / 9694 Time remaining: 3s Progress 4561 / 9694 Time remaining: 3s Progress 4562 / 9694 Time remaining: 3s Progress 4563 / 9694 Time remaining: 3s Progress 4564 / 9694 Time remaining: 3s Progress 4565 / 9694 Time remaining: 3s Progress 4566 / 9694 Time remaining: 3s Progress 4567 / 9694 Time remaining: 3s Progress 4568 / 9694 Time remaining: 3s Progress 4569 / 9694 Time remaining: 3s Progress 4570 / 9694 Time remaining: 3s Progress 4571 / 9694 Time remaining: 3s Progress 4572 / 9694 Time remaining: 3s Progress 4573 / 9694 Time remaining: 3s Progress 4574 / 9694 Time remaining: 3s Progress 4575 / 9694 Time remaining: 3s Progress 4576 / 9694 Time remaining: 3s Progress 4577 / 9694 Time remaining: 3s Progress 4578 / 9694 Time remaining: 3s Progress 4579 / 9694 Time remaining: 3s Progress 4580 / 9694 Time remaining: 3s Progress 4581 / 9694 Time remaining: 3s Progress 4582 / 9694 Time remaining: 3s Progress 4583 / 9694 Time remaining: 3s Progress 4584 / 9694 Time remaining: 3s Progress 4585 / 9694 Time remaining: 3s Progress 4586 / 9694 Time remaining: 3s Progress 4587 / 9694 Time remaining: 3s Progress 4588 / 9694 Time remaining: 3s Progress 4589 / 9694 Time remaining: 3s Progress 4590 / 9694 Time remaining: 3s Progress 4591 / 9694 Time remaining: 3s Progress 4592 / 9694 Time remaining: 3s Progress 4593 / 9694 Time remaining: 3s Progress 4594 / 9694 Time remaining: 3s Progress 4595 / 9694 Time remaining: 3s Progress 4596 / 9694 Time remaining: 3s Progress 4597 / 9694 Time remaining: 3s Progress 4598 / 9694 Time remaining: 3s Progress 4599 / 9694 Time remaining: 3s Progress 4600 / 9694 Time remaining: 3s Progress 4601 / 9694 Time remaining: 3s Progress 4602 / 9694 Time remaining: 3s Progress 4603 / 9694 Time remaining: 3s Progress 4604 / 9694 Time remaining: 3s Progress 4605 / 9694 Time remaining: 3s Progress 4606 / 9694 Time remaining: 3s Progress 4607 / 9694 Time remaining: 3s Progress 4608 / 9694 Time remaining: 3s Progress 4609 / 9694 Time remaining: 3s Progress 4610 / 9694 Time remaining: 3s Progress 4611 / 9694 Time remaining: 3s Progress 4612 / 9694 Time remaining: 3s Progress 4613 / 9694 Time remaining: 3s Progress 4614 / 9694 Time remaining: 3s Progress 4615 / 9694 Time remaining: 3s Progress 4616 / 9694 Time remaining: 3s Progress 4617 / 9694 Time remaining: 3s Progress 4618 / 9694 Time remaining: 3s Progress 4619 / 9694 Time remaining: 3s Progress 4620 / 9694 Time remaining: 3s Progress 4621 / 9694 Time remaining: 3s Progress 4622 / 9694 Time remaining: 3s Progress 4623 / 9694 Time remaining: 3s Progress 4624 / 9694 Time remaining: 3s Progress 4625 / 9694 Time remaining: 3s Progress 4626 / 9694 Time remaining: 3s Progress 4627 / 9694 Time remaining: 3s Progress 4628 / 9694 Time remaining: 3s Progress 4629 / 9694 Time remaining: 3s Progress 4630 / 9694 Time remaining: 3s Progress 4631 / 9694 Time remaining: 3s Progress 4632 / 9694 Time remaining: 3s Progress 4633 / 9694 Time remaining: 3s Progress 4634 / 9694 Time remaining: 3s Progress 4635 / 9694 Time remaining: 3s Progress 4636 / 9694 Time remaining: 3s Progress 4637 / 9694 Time remaining: 3s Progress 4638 / 9694 Time remaining: 3s Progress 4639 / 9694 Time remaining: 3s Progress 4640 / 9694 Time remaining: 3s Progress 4641 / 9694 Time remaining: 3s Progress 4642 / 9694 Time remaining: 3s Progress 4643 / 9694 Time remaining: 3s Progress 4644 / 9694 Time remaining: 3s Progress 4645 / 9694 Time remaining: 3s Progress 4646 / 9694 Time remaining: 3s Progress 4647 / 9694 Time remaining: 3s Progress 4648 / 9694 Time remaining: 3s Progress 4649 / 9694 Time remaining: 3s Progress 4650 / 9694 Time remaining: 3s Progress 4651 / 9694 Time remaining: 3s Progress 4652 / 9694 Time remaining: 3s Progress 4653 / 9694 Time remaining: 3s Progress 4654 / 9694 Time remaining: 3s Progress 4655 / 9694 Time remaining: 3s Progress 4656 / 9694 Time remaining: 3s Progress 4657 / 9694 Time remaining: 3s Progress 4658 / 9694 Time remaining: 3s Progress 4659 / 9694 Time remaining: 3s Progress 4660 / 9694 Time remaining: 3s Progress 4661 / 9694 Time remaining: 3s Progress 4662 / 9694 Time remaining: 3s Progress 4663 / 9694 Time remaining: 3s Progress 4664 / 9694 Time remaining: 3s Progress 4665 / 9694 Time remaining: 3s Progress 4666 / 9694 Time remaining: 3s Progress 4667 / 9694 Time remaining: 3s Progress 4668 / 9694 Time remaining: 3s Progress 4669 / 9694 Time remaining: 3s Progress 4670 / 9694 Time remaining: 3s Progress 4671 / 9694 Time remaining: 3s Progress 4672 / 9694 Time remaining: 3s Progress 4673 / 9694 Time remaining: 3s Progress 4674 / 9694 Time remaining: 3s Progress 4675 / 9694 Time remaining: 3s Progress 4676 / 9694 Time remaining: 3s Progress 4677 / 9694 Time remaining: 3s Progress 4678 / 9694 Time remaining: 3s Progress 4679 / 9694 Time remaining: 3s Progress 4680 / 9694 Time remaining: 3s Progress 4681 / 9694 Time remaining: 3s Progress 4682 / 9694 Time remaining: 3s Progress 4683 / 9694 Time remaining: 3s Progress 4684 / 9694 Time remaining: 3s Progress 4685 / 9694 Time remaining: 3s Progress 4686 / 9694 Time remaining: 3s Progress 4687 / 9694 Time remaining: 3s Progress 4688 / 9694 Time remaining: 3s Progress 4689 / 9694 Time remaining: 3s Progress 4690 / 9694 Time remaining: 3s Progress 4691 / 9694 Time remaining: 3s Progress 4692 / 9694 Time remaining: 3s Progress 4693 / 9694 Time remaining: 3s Progress 4694 / 9694 Time remaining: 3s Progress 4695 / 9694 Time remaining: 3s Progress 4696 / 9694 Time remaining: 3s Progress 4697 / 9694 Time remaining: 3s Progress 4698 / 9694 Time remaining: 3s Progress 4699 / 9694 Time remaining: 3s Progress 4700 / 9694 Time remaining: 3s Progress 4701 / 9694 Time remaining: 3s Progress 4702 / 9694 Time remaining: 3s Progress 4703 / 9694 Time remaining: 3s Progress 4704 / 9694 Time remaining: 3s Progress 4705 / 9694 Time remaining: 3s Progress 4706 / 9694 Time remaining: 3s Progress 4707 / 9694 Time remaining: 3s Progress 4708 / 9694 Time remaining: 3s Progress 4709 / 9694 Time remaining: 3s Progress 4710 / 9694 Time remaining: 3s Progress 4711 / 9694 Time remaining: 3s Progress 4712 / 9694 Time remaining: 3s Progress 4713 / 9694 Time remaining: 3s Progress 4714 / 9694 Time remaining: 3s Progress 4715 / 9694 Time remaining: 3s Progress 4716 / 9694 Time remaining: 3s Progress 4717 / 9694 Time remaining: 3s Progress 4718 / 9694 Time remaining: 3s Progress 4719 / 9694 Time remaining: 3s Progress 4720 / 9694 Time remaining: 3s Progress 4721 / 9694 Time remaining: 3s Progress 4722 / 9694 Time remaining: 3s Progress 4723 / 9694 Time remaining: 3s Progress 4724 / 9694 Time remaining: 3s Progress 4725 / 9694 Time remaining: 3s Progress 4726 / 9694 Time remaining: 3s Progress 4727 / 9694 Time remaining: 3s Progress 4728 / 9694 Time remaining: 3s Progress 4729 / 9694 Time remaining: 3s Progress 4730 / 9694 Time remaining: 3s Progress 4731 / 9694 Time remaining: 3s Progress 4732 / 9694 Time remaining: 3s Progress 4733 / 9694 Time remaining: 3s Progress 4734 / 9694 Time remaining: 3s Progress 4735 / 9694 Time remaining: 3s Progress 4736 / 9694 Time remaining: 3s Progress 4737 / 9694 Time remaining: 3s Progress 4738 / 9694 Time remaining: 3s Progress 4739 / 9694 Time remaining: 3s Progress 4740 / 9694 Time remaining: 3s Progress 4741 / 9694 Time remaining: 3s Progress 4742 / 9694 Time remaining: 3s Progress 4743 / 9694 Time remaining: 3s Progress 4744 / 9694 Time remaining: 3s Progress 4745 / 9694 Time remaining: 3s Progress 4746 / 9694 Time remaining: 3s Progress 4747 / 9694 Time remaining: 3s Progress 4748 / 9694 Time remaining: 3s Progress 4749 / 9694 Time remaining: 3s Progress 4750 / 9694 Time remaining: 3s Progress 4751 / 9694 Time remaining: 3s Progress 4752 / 9694 Time remaining: 3s Progress 4753 / 9694 Time remaining: 3s Progress 4754 / 9694 Time remaining: 3s Progress 4755 / 9694 Time remaining: 3s Progress 4756 / 9694 Time remaining: 3s Progress 4757 / 9694 Time remaining: 3s Progress 4758 / 9694 Time remaining: 3s Progress 4759 / 9694 Time remaining: 3s Progress 4760 / 9694 Time remaining: 3s Progress 4761 / 9694 Time remaining: 3s Progress 4762 / 9694 Time remaining: 3s Progress 4763 / 9694 Time remaining: 3s Progress 4764 / 9694 Time remaining: 3s Progress 4765 / 9694 Time remaining: 3s Progress 4766 / 9694 Time remaining: 3s Progress 4767 / 9694 Time remaining: 3s Progress 4768 / 9694 Time remaining: 3s Progress 4769 / 9694 Time remaining: 3s Progress 4770 / 9694 Time remaining: 3s Progress 4771 / 9694 Time remaining: 3s Progress 4772 / 9694 Time remaining: 3s Progress 4773 / 9694 Time remaining: 3s Progress 4774 / 9694 Time remaining: 3s Progress 4775 / 9694 Time remaining: 3s Progress 4776 / 9694 Time remaining: 3s Progress 4777 / 9694 Time remaining: 3s Progress 4778 / 9694 Time remaining: 3s Progress 4779 / 9694 Time remaining: 3s Progress 4780 / 9694 Time remaining: 3s Progress 4781 / 9694 Time remaining: 3s Progress 4782 / 9694 Time remaining: 3s Progress 4783 / 9694 Time remaining: 3s Progress 4784 / 9694 Time remaining: 3s Progress 4785 / 9694 Time remaining: 3s Progress 4786 / 9694 Time remaining: 3s Progress 4787 / 9694 Time remaining: 3s Progress 4788 / 9694 Time remaining: 3s Progress 4789 / 9694 Time remaining: 3s Progress 4790 / 9694 Time remaining: 3s Progress 4791 / 9694 Time remaining: 3s Progress 4792 / 9694 Time remaining: 3s Progress 4793 / 9694 Time remaining: 3s Progress 4794 / 9694 Time remaining: 3s Progress 4795 / 9694 Time remaining: 3s Progress 4796 / 9694 Time remaining: 3s Progress 4797 / 9694 Time remaining: 3s Progress 4798 / 9694 Time remaining: 3s Progress 4799 / 9694 Time remaining: 3s Progress 4800 / 9694 Time remaining: 3s Progress 4801 / 9694 Time remaining: 3s Progress 4802 / 9694 Time remaining: 3s Progress 4803 / 9694 Time remaining: 3s Progress 4804 / 9694 Time remaining: 3s Progress 4805 / 9694 Time remaining: 3s Progress 4806 / 9694 Time remaining: 3s Progress 4807 / 9694 Time remaining: 3s Progress 4808 / 9694 Time remaining: 3s Progress 4809 / 9694 Time remaining: 3s Progress 4810 / 9694 Time remaining: 3s Progress 4811 / 9694 Time remaining: 3s Progress 4812 / 9694 Time remaining: 3s Progress 4813 / 9694 Time remaining: 3s Progress 4814 / 9694 Time remaining: 3s Progress 4815 / 9694 Time remaining: 3s Progress 4816 / 9694 Time remaining: 3s Progress 4817 / 9694 Time remaining: 3s Progress 4818 / 9694 Time remaining: 3s Progress 4819 / 9694 Time remaining: 3s Progress 4820 / 9694 Time remaining: 3s Progress 4821 / 9694 Time remaining: 3s Progress 4822 / 9694 Time remaining: 3s Progress 4823 / 9694 Time remaining: 3s Progress 4824 / 9694 Time remaining: 3s Progress 4825 / 9694 Time remaining: 3s Progress 4826 / 9694 Time remaining: 3s Progress 4827 / 9694 Time remaining: 3s Progress 4828 / 9694 Time remaining: 3s Progress 4829 / 9694 Time remaining: 3s Progress 4830 / 9694 Time remaining: 3s Progress 4831 / 9694 Time remaining: 3s Progress 4832 / 9694 Time remaining: 3s Progress 4833 / 9694 Time remaining: 3s Progress 4834 / 9694 Time remaining: 3s Progress 4835 / 9694 Time remaining: 3s Progress 4836 / 9694 Time remaining: 3s Progress 4837 / 9694 Time remaining: 3s Progress 4838 / 9694 Time remaining: 3s Progress 4839 / 9694 Time remaining: 3s Progress 4840 / 9694 Time remaining: 3s Progress 4841 / 9694 Time remaining: 3s Progress 4842 / 9694 Time remaining: 3s Progress 4843 / 9694 Time remaining: 3s Progress 4844 / 9694 Time remaining: 3s Progress 4845 / 9694 Time remaining: 3s Progress 4846 / 9694 Time remaining: 3s Progress 4847 / 9694 Time remaining: 3s Progress 4848 / 9694 Time remaining: 3s Progress 4849 / 9694 Time remaining: 3s Progress 4850 / 9694 Time remaining: 3s Progress 4851 / 9694 Time remaining: 3s Progress 4852 / 9694 Time remaining: 3s Progress 4853 / 9694 Time remaining: 3s Progress 4854 / 9694 Time remaining: 3s Progress 4855 / 9694 Time remaining: 3s Progress 4856 / 9694 Time remaining: 3s Progress 4857 / 9694 Time remaining: 3s Progress 4858 / 9694 Time remaining: 3s Progress 4859 / 9694 Time remaining: 3s Progress 4860 / 9694 Time remaining: 3s Progress 4861 / 9694 Time remaining: 3s Progress 4862 / 9694 Time remaining: 3s Progress 4863 / 9694 Time remaining: 3s Progress 4864 / 9694 Time remaining: 3s Progress 4865 / 9694 Time remaining: 3s Progress 4866 / 9694 Time remaining: 3s Progress 4867 / 9694 Time remaining: 3s Progress 4868 / 9694 Time remaining: 3s Progress 4869 / 9694 Time remaining: 3s Progress 4870 / 9694 Time remaining: 3s Progress 4871 / 9694 Time remaining: 3s Progress 4872 / 9694 Time remaining: 3s Progress 4873 / 9694 Time remaining: 3s Progress 4874 / 9694 Time remaining: 3s Progress 4875 / 9694 Time remaining: 3s Progress 4876 / 9694 Time remaining: 3s Progress 4877 / 9694 Time remaining: 3s Progress 4878 / 9694 Time remaining: 3s Progress 4879 / 9694 Time remaining: 3s Progress 4880 / 9694 Time remaining: 3s Progress 4881 / 9694 Time remaining: 3s Progress 4882 / 9694 Time remaining: 3s Progress 4883 / 9694 Time remaining: 3s Progress 4884 / 9694 Time remaining: 3s Progress 4885 / 9694 Time remaining: 3s Progress 4886 / 9694 Time remaining: 3s Progress 4887 / 9694 Time remaining: 3s Progress 4888 / 9694 Time remaining: 3s Progress 4889 / 9694 Time remaining: 3s Progress 4890 / 9694 Time remaining: 3s Progress 4891 / 9694 Time remaining: 3s Progress 4892 / 9694 Time remaining: 3s Progress 4893 / 9694 Time remaining: 3s Progress 4894 / 9694 Time remaining: 3s Progress 4895 / 9694 Time remaining: 3s Progress 4896 / 9694 Time remaining: 3s Progress 4897 / 9694 Time remaining: 3s Progress 4898 / 9694 Time remaining: 3s Progress 4899 / 9694 Time remaining: 3s Progress 4900 / 9694 Time remaining: 3s Progress 4901 / 9694 Time remaining: 3s Progress 4902 / 9694 Time remaining: 3s Progress 4903 / 9694 Time remaining: 3s Progress 4904 / 9694 Time remaining: 3s Progress 4905 / 9694 Time remaining: 3s Progress 4906 / 9694 Time remaining: 3s Progress 4907 / 9694 Time remaining: 3s Progress 4908 / 9694 Time remaining: 3s Progress 4909 / 9694 Time remaining: 3s Progress 4910 / 9694 Time remaining: 3s Progress 4911 / 9694 Time remaining: 3s Progress 4912 / 9694 Time remaining: 3s Progress 4913 / 9694 Time remaining: 3s Progress 4914 / 9694 Time remaining: 3s Progress 4915 / 9694 Time remaining: 3s Progress 4916 / 9694 Time remaining: 3s Progress 4917 / 9694 Time remaining: 3s Progress 4918 / 9694 Time remaining: 3s Progress 4919 / 9694 Time remaining: 3s Progress 4920 / 9694 Time remaining: 3s Progress 4921 / 9694 Time remaining: 3s Progress 4922 / 9694 Time remaining: 3s Progress 4923 / 9694 Time remaining: 3s Progress 4924 / 9694 Time remaining: 3s Progress 4925 / 9694 Time remaining: 3s Progress 4926 / 9694 Time remaining: 3s Progress 4927 / 9694 Time remaining: 3s Progress 4928 / 9694 Time remaining: 3s Progress 4929 / 9694 Time remaining: 3s Progress 4930 / 9694 Time remaining: 3s Progress 4931 / 9694 Time remaining: 3s Progress 4932 / 9694 Time remaining: 3s Progress 4933 / 9694 Time remaining: 3s Progress 4934 / 9694 Time remaining: 3s Progress 4935 / 9694 Time remaining: 3s Progress 4936 / 9694 Time remaining: 3s Progress 4937 / 9694 Time remaining: 3s Progress 4938 / 9694 Time remaining: 3s Progress 4939 / 9694 Time remaining: 3s Progress 4940 / 9694 Time remaining: 3s Progress 4941 / 9694 Time remaining: 3s Progress 4942 / 9694 Time remaining: 3s Progress 4943 / 9694 Time remaining: 3s Progress 4944 / 9694 Time remaining: 3s Progress 4945 / 9694 Time remaining: 3s Progress 4946 / 9694 Time remaining: 3s Progress 4947 / 9694 Time remaining: 3s Progress 4948 / 9694 Time remaining: 3s Progress 4949 / 9694 Time remaining: 3s Progress 4950 / 9694 Time remaining: 3s Progress 4951 / 9694 Time remaining: 3s Progress 4952 / 9694 Time remaining: 3s Progress 4953 / 9694 Time remaining: 3s Progress 4954 / 9694 Time remaining: 3s Progress 4955 / 9694 Time remaining: 3s Progress 4956 / 9694 Time remaining: 3s Progress 4957 / 9694 Time remaining: 3s Progress 4958 / 9694 Time remaining: 3s Progress 4959 / 9694 Time remaining: 3s Progress 4960 / 9694 Time remaining: 3s Progress 4961 / 9694 Time remaining: 3s Progress 4962 / 9694 Time remaining: 3s Progress 4963 / 9694 Time remaining: 3s Progress 4964 / 9694 Time remaining: 3s Progress 4965 / 9694 Time remaining: 3s Progress 4966 / 9694 Time remaining: 3s Progress 4967 / 9694 Time remaining: 3s Progress 4968 / 9694 Time remaining: 3s Progress 4969 / 9694 Time remaining: 3s Progress 4970 / 9694 Time remaining: 3s Progress 4971 / 9694 Time remaining: 3s Progress 4972 / 9694 Time remaining: 3s Progress 4973 / 9694 Time remaining: 3s Progress 4974 / 9694 Time remaining: 3s Progress 4975 / 9694 Time remaining: 3s Progress 4976 / 9694 Time remaining: 3s Progress 4977 / 9694 Time remaining: 3s Progress 4978 / 9694 Time remaining: 3s Progress 4979 / 9694 Time remaining: 3s Progress 4980 / 9694 Time remaining: 3s Progress 4981 / 9694 Time remaining: 3s Progress 4982 / 9694 Time remaining: 3s Progress 4983 / 9694 Time remaining: 3s Progress 4984 / 9694 Time remaining: 3s Progress 4985 / 9694 Time remaining: 3s Progress 4986 / 9694 Time remaining: 3s Progress 4987 / 9694 Time remaining: 3s Progress 4988 / 9694 Time remaining: 3s Progress 4989 / 9694 Time remaining: 3s Progress 4990 / 9694 Time remaining: 3s Progress 4991 / 9694 Time remaining: 3s Progress 4992 / 9694 Time remaining: 3s Progress 4993 / 9694 Time remaining: 3s Progress 4994 / 9694 Time remaining: 3s Progress 4995 / 9694 Time remaining: 3s Progress 4996 / 9694 Time remaining: 3s Progress 4997 / 9694 Time remaining: 3s Progress 4998 / 9694 Time remaining: 3s Progress 4999 / 9694 Time remaining: 3s Progress 5000 / 9694 Time remaining: 3s Progress 5001 / 9694 Time remaining: 3s Progress 5002 / 9694 Time remaining: 3s Progress 5003 / 9694 Time remaining: 3s Progress 5004 / 9694 Time remaining: 3s Progress 5005 / 9694 Time remaining: 3s Progress 5006 / 9694 Time remaining: 3s Progress 5007 / 9694 Time remaining: 3s Progress 5008 / 9694 Time remaining: 3s Progress 5009 / 9694 Time remaining: 3s Progress 5010 / 9694 Time remaining: 3s Progress 5011 / 9694 Time remaining: 3s Progress 5012 / 9694 Time remaining: 3s Progress 5013 / 9694 Time remaining: 3s Progress 5014 / 9694 Time remaining: 3s Progress 5015 / 9694 Time remaining: 3s Progress 5016 / 9694 Time remaining: 3s Progress 5017 / 9694 Time remaining: 3s Progress 5018 / 9694 Time remaining: 3s Progress 5019 / 9694 Time remaining: 3s Progress 5020 / 9694 Time remaining: 3s Progress 5021 / 9694 Time remaining: 3s Progress 5022 / 9694 Time remaining: 3s Progress 5023 / 9694 Time remaining: 3s Progress 5024 / 9694 Time remaining: 3s Progress 5025 / 9694 Time remaining: 3s Progress 5026 / 9694 Time remaining: 3s Progress 5027 / 9694 Time remaining: 3s Progress 5028 / 9694 Time remaining: 3s Progress 5029 / 9694 Time remaining: 3s Progress 5030 / 9694 Time remaining: 3s Progress 5031 / 9694 Time remaining: 3s Progress 5032 / 9694 Time remaining: 3s Progress 5033 / 9694 Time remaining: 3s Progress 5034 / 9694 Time remaining: 3s Progress 5035 / 9694 Time remaining: 3s Progress 5036 / 9694 Time remaining: 3s Progress 5037 / 9694 Time remaining: 3s Progress 5038 / 9694 Time remaining: 3s Progress 5039 / 9694 Time remaining: 3s Progress 5040 / 9694 Time remaining: 3s Progress 5041 / 9694 Time remaining: 3s Progress 5042 / 9694 Time remaining: 3s Progress 5043 / 9694 Time remaining: 3s Progress 5044 / 9694 Time remaining: 3s Progress 5045 / 9694 Time remaining: 3s Progress 5046 / 9694 Time remaining: 3s Progress 5047 / 9694 Time remaining: 3s Progress 5048 / 9694 Time remaining: 3s Progress 5049 / 9694 Time remaining: 3s Progress 5050 / 9694 Time remaining: 3s Progress 5051 / 9694 Time remaining: 3s Progress 5052 / 9694 Time remaining: 3s Progress 5053 / 9694 Time remaining: 3s Progress 5054 / 9694 Time remaining: 3s Progress 5055 / 9694 Time remaining: 3s Progress 5056 / 9694 Time remaining: 3s Progress 5057 / 9694 Time remaining: 3s Progress 5058 / 9694 Time remaining: 3s Progress 5059 / 9694 Time remaining: 3s Progress 5060 / 9694 Time remaining: 3s Progress 5061 / 9694 Time remaining: 3s Progress 5062 / 9694 Time remaining: 3s Progress 5063 / 9694 Time remaining: 3s Progress 5064 / 9694 Time remaining: 3s Progress 5065 / 9694 Time remaining: 3s Progress 5066 / 9694 Time remaining: 3s Progress 5067 / 9694 Time remaining: 3s Progress 5068 / 9694 Time remaining: 3s Progress 5069 / 9694 Time remaining: 3s Progress 5070 / 9694 Time remaining: 3s Progress 5071 / 9694 Time remaining: 3s Progress 5072 / 9694 Time remaining: 3s Progress 5073 / 9694 Time remaining: 3s Progress 5074 / 9694 Time remaining: 3s Progress 5075 / 9694 Time remaining: 3s Progress 5076 / 9694 Time remaining: 3s Progress 5077 / 9694 Time remaining: 3s Progress 5078 / 9694 Time remaining: 3s Progress 5079 / 9694 Time remaining: 3s Progress 5080 / 9694 Time remaining: 3s Progress 5081 / 9694 Time remaining: 3s Progress 5082 / 9694 Time remaining: 3s Progress 5083 / 9694 Time remaining: 3s Progress 5084 / 9694 Time remaining: 3s Progress 5085 / 9694 Time remaining: 3s Progress 5086 / 9694 Time remaining: 3s Progress 5087 / 9694 Time remaining: 3s Progress 5088 / 9694 Time remaining: 3s Progress 5089 / 9694 Time remaining: 3s Progress 5090 / 9694 Time remaining: 3s Progress 5091 / 9694 Time remaining: 3s Progress 5092 / 9694 Time remaining: 3s Progress 5093 / 9694 Time remaining: 3s Progress 5094 / 9694 Time remaining: 3s Progress 5095 / 9694 Time remaining: 3s Progress 5096 / 9694 Time remaining: 3s Progress 5097 / 9694 Time remaining: 3s Progress 5098 / 9694 Time remaining: 3s Progress 5099 / 9694 Time remaining: 3s Progress 5100 / 9694 Time remaining: 3s Progress 5101 / 9694 Time remaining: 3s Progress 5102 / 9694 Time remaining: 3s Progress 5103 / 9694 Time remaining: 3s Progress 5104 / 9694 Time remaining: 3s Progress 5105 / 9694 Time remaining: 3s Progress 5106 / 9694 Time remaining: 3s Progress 5107 / 9694 Time remaining: 3s Progress 5108 / 9694 Time remaining: 3s Progress 5109 / 9694 Time remaining: 3s Progress 5110 / 9694 Time remaining: 3s Progress 5111 / 9694 Time remaining: 3s Progress 5112 / 9694 Time remaining: 3s Progress 5113 / 9694 Time remaining: 3s Progress 5114 / 9694 Time remaining: 3s Progress 5115 / 9694 Time remaining: 3s Progress 5116 / 9694 Time remaining: 3s Progress 5117 / 9694 Time remaining: 3s Progress 5118 / 9694 Time remaining: 3s Progress 5119 / 9694 Time remaining: 3s Progress 5120 / 9694 Time remaining: 3s Progress 5121 / 9694 Time remaining: 3s Progress 5122 / 9694 Time remaining: 3s Progress 5123 / 9694 Time remaining: 3s Progress 5124 / 9694 Time remaining: 3s Progress 5125 / 9694 Time remaining: 3s Progress 5126 / 9694 Time remaining: 3s Progress 5127 / 9694 Time remaining: 3s Progress 5128 / 9694 Time remaining: 3s Progress 5129 / 9694 Time remaining: 3s Progress 5130 / 9694 Time remaining: 3s Progress 5131 / 9694 Time remaining: 3s Progress 5132 / 9694 Time remaining: 3s Progress 5133 / 9694 Time remaining: 3s Progress 5134 / 9694 Time remaining: 3s Progress 5135 / 9694 Time remaining: 3s Progress 5136 / 9694 Time remaining: 3s Progress 5137 / 9694 Time remaining: 3s Progress 5138 / 9694 Time remaining: 3s Progress 5139 / 9694 Time remaining: 3s Progress 5140 / 9694 Time remaining: 3s Progress 5141 / 9694 Time remaining: 3s Progress 5142 / 9694 Time remaining: 3s Progress 5143 / 9694 Time remaining: 3s Progress 5144 / 9694 Time remaining: 3s Progress 5145 / 9694 Time remaining: 3s Progress 5146 / 9694 Time remaining: 3s Progress 5147 / 9694 Time remaining: 3s Progress 5148 / 9694 Time remaining: 3s Progress 5149 / 9694 Time remaining: 3s Progress 5150 / 9694 Time remaining: 3s Progress 5151 / 9694 Time remaining: 3s Progress 5152 / 9694 Time remaining: 3s Progress 5153 / 9694 Time remaining: 3s Progress 5154 / 9694 Time remaining: 3s Progress 5155 / 9694 Time remaining: 3s Progress 5156 / 9694 Time remaining: 3s Progress 5157 / 9694 Time remaining: 3s Progress 5158 / 9694 Time remaining: 3s Progress 5159 / 9694 Time remaining: 3s Progress 5160 / 9694 Time remaining: 3s Progress 5161 / 9694 Time remaining: 3s Progress 5162 / 9694 Time remaining: 3s Progress 5163 / 9694 Time remaining: 3s Progress 5164 / 9694 Time remaining: 3s Progress 5165 / 9694 Time remaining: 3s Progress 5166 / 9694 Time remaining: 3s Progress 5167 / 9694 Time remaining: 3s Progress 5168 / 9694 Time remaining: 3s Progress 5169 / 9694 Time remaining: 3s Progress 5170 / 9694 Time remaining: 3s Progress 5171 / 9694 Time remaining: 3s Progress 5172 / 9694 Time remaining: 3s Progress 5173 / 9694 Time remaining: 3s Progress 5174 / 9694 Time remaining: 3s Progress 5175 / 9694 Time remaining: 3s Progress 5176 / 9694 Time remaining: 3s Progress 5177 / 9694 Time remaining: 3s Progress 5178 / 9694 Time remaining: 3s Progress 5179 / 9694 Time remaining: 3s Progress 5180 / 9694 Time remaining: 3s Progress 5181 / 9694 Time remaining: 3s Progress 5182 / 9694 Time remaining: 3s Progress 5183 / 9694 Time remaining: 3s Progress 5184 / 9694 Time remaining: 3s Progress 5185 / 9694 Time remaining: 3s Progress 5186 / 9694 Time remaining: 3s Progress 5187 / 9694 Time remaining: 3s Progress 5188 / 9694 Time remaining: 3s Progress 5189 / 9694 Time remaining: 3s Progress 5190 / 9694 Time remaining: 3s Progress 5191 / 9694 Time remaining: 3s Progress 5192 / 9694 Time remaining: 3s Progress 5193 / 9694 Time remaining: 3s Progress 5194 / 9694 Time remaining: 3s Progress 5195 / 9694 Time remaining: 3s Progress 5196 / 9694 Time remaining: 3s Progress 5197 / 9694 Time remaining: 3s Progress 5198 / 9694 Time remaining: 3s Progress 5199 / 9694 Time remaining: 3s Progress 5200 / 9694 Time remaining: 3s Progress 5201 / 9694 Time remaining: 3s Progress 5202 / 9694 Time remaining: 3s Progress 5203 / 9694 Time remaining: 3s Progress 5204 / 9694 Time remaining: 3s Progress 5205 / 9694 Time remaining: 3s Progress 5206 / 9694 Time remaining: 3s Progress 5207 / 9694 Time remaining: 3s Progress 5208 / 9694 Time remaining: 3s Progress 5209 / 9694 Time remaining: 3s Progress 5210 / 9694 Time remaining: 3s Progress 5211 / 9694 Time remaining: 3s Progress 5212 / 9694 Time remaining: 3s Progress 5213 / 9694 Time remaining: 3s Progress 5214 / 9694 Time remaining: 3s Progress 5215 / 9694 Time remaining: 3s Progress 5216 / 9694 Time remaining: 3s Progress 5217 / 9694 Time remaining: 3s Progress 5218 / 9694 Time remaining: 3s Progress 5219 / 9694 Time remaining: 3s Progress 5220 / 9694 Time remaining: 3s Progress 5221 / 9694 Time remaining: 3s Progress 5222 / 9694 Time remaining: 3s Progress 5223 / 9694 Time remaining: 3s Progress 5224 / 9694 Time remaining: 3s Progress 5225 / 9694 Time remaining: 3s Progress 5226 / 9694 Time remaining: 3s Progress 5227 / 9694 Time remaining: 3s Progress 5228 / 9694 Time remaining: 3s Progress 5229 / 9694 Time remaining: 3s Progress 5230 / 9694 Time remaining: 3s Progress 5231 / 9694 Time remaining: 3s Progress 5232 / 9694 Time remaining: 3s Progress 5233 / 9694 Time remaining: 3s Progress 5234 / 9694 Time remaining: 3s Progress 5235 / 9694 Time remaining: 3s Progress 5236 / 9694 Time remaining: 3s Progress 5237 / 9694 Time remaining: 3s Progress 5238 / 9694 Time remaining: 3s Progress 5239 / 9694 Time remaining: 3s Progress 5240 / 9694 Time remaining: 3s Progress 5241 / 9694 Time remaining: 3s Progress 5242 / 9694 Time remaining: 3s Progress 5243 / 9694 Time remaining: 3s Progress 5244 / 9694 Time remaining: 3s Progress 5245 / 9694 Time remaining: 3s Progress 5246 / 9694 Time remaining: 3s Progress 5247 / 9694 Time remaining: 3s Progress 5248 / 9694 Time remaining: 3s Progress 5249 / 9694 Time remaining: 3s Progress 5250 / 9694 Time remaining: 3s Progress 5251 / 9694 Time remaining: 3s Progress 5252 / 9694 Time remaining: 3s Progress 5253 / 9694 Time remaining: 3s Progress 5254 / 9694 Time remaining: 3s Progress 5255 / 9694 Time remaining: 3s Progress 5256 / 9694 Time remaining: 3s Progress 5257 / 9694 Time remaining: 3s Progress 5258 / 9694 Time remaining: 3s Progress 5259 / 9694 Time remaining: 3s Progress 5260 / 9694 Time remaining: 3s Progress 5261 / 9694 Time remaining: 3s Progress 5262 / 9694 Time remaining: 3s Progress 5263 / 9694 Time remaining: 3s Progress 5264 / 9694 Time remaining: 3s Progress 5265 / 9694 Time remaining: 3s Progress 5266 / 9694 Time remaining: 3s Progress 5267 / 9694 Time remaining: 3s Progress 5268 / 9694 Time remaining: 3s Progress 5269 / 9694 Time remaining: 3s Progress 5270 / 9694 Time remaining: 3s Progress 5271 / 9694 Time remaining: 3s Progress 5272 / 9694 Time remaining: 3s Progress 5273 / 9694 Time remaining: 3s Progress 5274 / 9694 Time remaining: 3s Progress 5275 / 9694 Time remaining: 3s Progress 5276 / 9694 Time remaining: 3s Progress 5277 / 9694 Time remaining: 3s Progress 5278 / 9694 Time remaining: 3s Progress 5279 / 9694 Time remaining: 3s Progress 5280 / 9694 Time remaining: 3s Progress 5281 / 9694 Time remaining: 3s Progress 5282 / 9694 Time remaining: 3s Progress 5283 / 9694 Time remaining: 3s Progress 5284 / 9694 Time remaining: 3s Progress 5285 / 9694 Time remaining: 3s Progress 5286 / 9694 Time remaining: 3s Progress 5287 / 9694 Time remaining: 3s Progress 5288 / 9694 Time remaining: 3s Progress 5289 / 9694 Time remaining: 3s Progress 5290 / 9694 Time remaining: 3s Progress 5291 / 9694 Time remaining: 3s Progress 5292 / 9694 Time remaining: 3s Progress 5293 / 9694 Time remaining: 3s Progress 5294 / 9694 Time remaining: 3s Progress 5295 / 9694 Time remaining: 3s Progress 5296 / 9694 Time remaining: 3s Progress 5297 / 9694 Time remaining: 3s Progress 5298 / 9694 Time remaining: 3s Progress 5299 / 9694 Time remaining: 3s Progress 5300 / 9694 Time remaining: 3s Progress 5301 / 9694 Time remaining: 3s Progress 5302 / 9694 Time remaining: 3s Progress 5303 / 9694 Time remaining: 3s Progress 5304 / 9694 Time remaining: 3s Progress 5305 / 9694 Time remaining: 3s Progress 5306 / 9694 Time remaining: 3s Progress 5307 / 9694 Time remaining: 3s Progress 5308 / 9694 Time remaining: 3s Progress 5309 / 9694 Time remaining: 3s Progress 5310 / 9694 Time remaining: 3s Progress 5311 / 9694 Time remaining: 3s Progress 5312 / 9694 Time remaining: 3s Progress 5313 / 9694 Time remaining: 3s Progress 5314 / 9694 Time remaining: 3s Progress 5315 / 9694 Time remaining: 3s Progress 5316 / 9694 Time remaining: 3s Progress 5317 / 9694 Time remaining: 3s Progress 5318 / 9694 Time remaining: 3s Progress 5319 / 9694 Time remaining: 3s Progress 5320 / 9694 Time remaining: 3s Progress 5321 / 9694 Time remaining: 3s Progress 5322 / 9694 Time remaining: 3s Progress 5323 / 9694 Time remaining: 3s Progress 5324 / 9694 Time remaining: 3s Progress 5325 / 9694 Time remaining: 3s Progress 5326 / 9694 Time remaining: 3s Progress 5327 / 9694 Time remaining: 3s Progress 5328 / 9694 Time remaining: 3s Progress 5329 / 9694 Time remaining: 3s Progress 5330 / 9694 Time remaining: 3s Progress 5331 / 9694 Time remaining: 3s Progress 5332 / 9694 Time remaining: 3s Progress 5333 / 9694 Time remaining: 3s Progress 5334 / 9694 Time remaining: 3s Progress 5335 / 9694 Time remaining: 3s Progress 5336 / 9694 Time remaining: 3s Progress 5337 / 9694 Time remaining: 3s Progress 5338 / 9694 Time remaining: 3s Progress 5339 / 9694 Time remaining: 3s Progress 5340 / 9694 Time remaining: 3s Progress 5341 / 9694 Time remaining: 3s Progress 5342 / 9694 Time remaining: 3s Progress 5343 / 9694 Time remaining: 3s Progress 5344 / 9694 Time remaining: 3s Progress 5345 / 9694 Time remaining: 3s Progress 5346 / 9694 Time remaining: 3s Progress 5347 / 9694 Time remaining: 3s Progress 5348 / 9694 Time remaining: 3s Progress 5349 / 9694 Time remaining: 3s Progress 5350 / 9694 Time remaining: 3s Progress 5351 / 9694 Time remaining: 3s Progress 5352 / 9694 Time remaining: 3s Progress 5353 / 9694 Time remaining: 3s Progress 5354 / 9694 Time remaining: 3s Progress 5355 / 9694 Time remaining: 3s Progress 5356 / 9694 Time remaining: 3s Progress 5357 / 9694 Time remaining: 3s Progress 5358 / 9694 Time remaining: 3s Progress 5359 / 9694 Time remaining: 3s Progress 5360 / 9694 Time remaining: 3s Progress 5361 / 9694 Time remaining: 3s Progress 5362 / 9694 Time remaining: 3s Progress 5363 / 9694 Time remaining: 3s Progress 5364 / 9694 Time remaining: 3s Progress 5365 / 9694 Time remaining: 3s Progress 5366 / 9694 Time remaining: 3s Progress 5367 / 9694 Time remaining: 3s Progress 5368 / 9694 Time remaining: 3s Progress 5369 / 9694 Time remaining: 3s Progress 5370 / 9694 Time remaining: 3s Progress 5371 / 9694 Time remaining: 3s Progress 5372 / 9694 Time remaining: 3s Progress 5373 / 9694 Time remaining: 3s Progress 5374 / 9694 Time remaining: 3s Progress 5375 / 9694 Time remaining: 3s Progress 5376 / 9694 Time remaining: 3s Progress 5377 / 9694 Time remaining: 3s Progress 5378 / 9694 Time remaining: 3s Progress 5379 / 9694 Time remaining: 3s Progress 5380 / 9694 Time remaining: 3s Progress 5381 / 9694 Time remaining: 3s Progress 5382 / 9694 Time remaining: 3s Progress 5383 / 9694 Time remaining: 3s Progress 5384 / 9694 Time remaining: 3s Progress 5385 / 9694 Time remaining: 3s Progress 5386 / 9694 Time remaining: 3s Progress 5387 / 9694 Time remaining: 3s Progress 5388 / 9694 Time remaining: 3s Progress 5389 / 9694 Time remaining: 3s Progress 5390 / 9694 Time remaining: 3s Progress 5391 / 9694 Time remaining: 3s Progress 5392 / 9694 Time remaining: 3s Progress 5393 / 9694 Time remaining: 3s Progress 5394 / 9694 Time remaining: 3s Progress 5395 / 9694 Time remaining: 3s Progress 5396 / 9694 Time remaining: 3s Progress 5397 / 9694 Time remaining: 3s Progress 5398 / 9694 Time remaining: 3s Progress 5399 / 9694 Time remaining: 3s Progress 5400 / 9694 Time remaining: 3s Progress 5401 / 9694 Time remaining: 3s Progress 5402 / 9694 Time remaining: 3s Progress 5403 / 9694 Time remaining: 3s Progress 5404 / 9694 Time remaining: 3s Progress 5405 / 9694 Time remaining: 3s Progress 5406 / 9694 Time remaining: 3s Progress 5407 / 9694 Time remaining: 3s Progress 5408 / 9694 Time remaining: 3s Progress 5409 / 9694 Time remaining: 3s Progress 5410 / 9694 Time remaining: 3s Progress 5411 / 9694 Time remaining: 3s Progress 5412 / 9694 Time remaining: 3s Progress 5413 / 9694 Time remaining: 3s Progress 5414 / 9694 Time remaining: 3s Progress 5415 / 9694 Time remaining: 3s Progress 5416 / 9694 Time remaining: 3s Progress 5417 / 9694 Time remaining: 3s Progress 5418 / 9694 Time remaining: 3s Progress 5419 / 9694 Time remaining: 3s Progress 5420 / 9694 Time remaining: 3s Progress 5421 / 9694 Time remaining: 3s Progress 5422 / 9694 Time remaining: 3s Progress 5423 / 9694 Time remaining: 3s Progress 5424 / 9694 Time remaining: 3s Progress 5425 / 9694 Time remaining: 3s Progress 5426 / 9694 Time remaining: 3s Progress 5427 / 9694 Time remaining: 3s Progress 5428 / 9694 Time remaining: 3s Progress 5429 / 9694 Time remaining: 3s Progress 5430 / 9694 Time remaining: 3s Progress 5431 / 9694 Time remaining: 3s Progress 5432 / 9694 Time remaining: 3s Progress 5433 / 9694 Time remaining: 3s Progress 5434 / 9694 Time remaining: 3s Progress 5435 / 9694 Time remaining: 3s Progress 5436 / 9694 Time remaining: 3s Progress 5437 / 9694 Time remaining: 3s Progress 5438 / 9694 Time remaining: 3s Progress 5439 / 9694 Time remaining: 3s Progress 5440 / 9694 Time remaining: 3s Progress 5441 / 9694 Time remaining: 3s Progress 5442 / 9694 Time remaining: 3s Progress 5443 / 9694 Time remaining: 3s Progress 5444 / 9694 Time remaining: 3s Progress 5445 / 9694 Time remaining: 3s Progress 5446 / 9694 Time remaining: 3s Progress 5447 / 9694 Time remaining: 3s Progress 5448 / 9694 Time remaining: 3s Progress 5449 / 9694 Time remaining: 3s Progress 5450 / 9694 Time remaining: 3s Progress 5451 / 9694 Time remaining: 3s Progress 5452 / 9694 Time remaining: 3s Progress 5453 / 9694 Time remaining: 3s Progress 5454 / 9694 Time remaining: 3s Progress 5455 / 9694 Time remaining: 3s Progress 5456 / 9694 Time remaining: 3s Progress 5457 / 9694 Time remaining: 3s Progress 5458 / 9694 Time remaining: 3s Progress 5459 / 9694 Time remaining: 3s Progress 5460 / 9694 Time remaining: 3s Progress 5461 / 9694 Time remaining: 3s Progress 5462 / 9694 Time remaining: 3s Progress 5463 / 9694 Time remaining: 3s Progress 5464 / 9694 Time remaining: 3s Progress 5465 / 9694 Time remaining: 3s Progress 5466 / 9694 Time remaining: 3s Progress 5467 / 9694 Time remaining: 3s Progress 5468 / 9694 Time remaining: 3s Progress 5469 / 9694 Time remaining: 3s Progress 5470 / 9694 Time remaining: 3s Progress 5471 / 9694 Time remaining: 3s Progress 5472 / 9694 Time remaining: 3s Progress 5473 / 9694 Time remaining: 3s Progress 5474 / 9694 Time remaining: 3s Progress 5475 / 9694 Time remaining: 3s Progress 5476 / 9694 Time remaining: 3s Progress 5477 / 9694 Time remaining: 3s Progress 5478 / 9694 Time remaining: 3s Progress 5479 / 9694 Time remaining: 3s Progress 5480 / 9694 Time remaining: 3s Progress 5481 / 9694 Time remaining: 3s Progress 5482 / 9694 Time remaining: 3s Progress 5483 / 9694 Time remaining: 3s Progress 5484 / 9694 Time remaining: 3s Progress 5485 / 9694 Time remaining: 3s Progress 5486 / 9694 Time remaining: 3s Progress 5487 / 9694 Time remaining: 3s Progress 5488 / 9694 Time remaining: 3s Progress 5489 / 9694 Time remaining: 3s Progress 5490 / 9694 Time remaining: 3s Progress 5491 / 9694 Time remaining: 3s Progress 5492 / 9694 Time remaining: 3s Progress 5493 / 9694 Time remaining: 3s Progress 5494 / 9694 Time remaining: 3s Progress 5495 / 9694 Time remaining: 3s Progress 5496 / 9694 Time remaining: 3s Progress 5497 / 9694 Time remaining: 3s Progress 5498 / 9694 Time remaining: 3s Progress 5499 / 9694 Time remaining: 3s Progress 5500 / 9694 Time remaining: 3s Progress 5501 / 9694 Time remaining: 3s Progress 5502 / 9694 Time remaining: 3s Progress 5503 / 9694 Time remaining: 3s Progress 5504 / 9694 Time remaining: 3s Progress 5505 / 9694 Time remaining: 3s Progress 5506 / 9694 Time remaining: 3s Progress 5507 / 9694 Time remaining: 3s Progress 5508 / 9694 Time remaining: 3s Progress 5509 / 9694 Time remaining: 3s Progress 5510 / 9694 Time remaining: 3s Progress 5511 / 9694 Time remaining: 3s Progress 5512 / 9694 Time remaining: 3s Progress 5513 / 9694 Time remaining: 3s Progress 5514 / 9694 Time remaining: 3s Progress 5515 / 9694 Time remaining: 3s Progress 5516 / 9694 Time remaining: 3s Progress 5517 / 9694 Time remaining: 3s Progress 5518 / 9694 Time remaining: 3s Progress 5519 / 9694 Time remaining: 3s Progress 5520 / 9694 Time remaining: 3s Progress 5521 / 9694 Time remaining: 3s Progress 5522 / 9694 Time remaining: 3s Progress 5523 / 9694 Time remaining: 3s Progress 5524 / 9694 Time remaining: 3s Progress 5525 / 9694 Time remaining: 3s Progress 5526 / 9694 Time remaining: 3s Progress 5527 / 9694 Time remaining: 3s Progress 5528 / 9694 Time remaining: 3s Progress 5529 / 9694 Time remaining: 3s Progress 5530 / 9694 Time remaining: 3s Progress 5531 / 9694 Time remaining: 3s Progress 5532 / 9694 Time remaining: 3s Progress 5533 / 9694 Time remaining: 3s Progress 5534 / 9694 Time remaining: 3s Progress 5535 / 9694 Time remaining: 3s Progress 5536 / 9694 Time remaining: 3s Progress 5537 / 9694 Time remaining: 3s Progress 5538 / 9694 Time remaining: 3s Progress 5539 / 9694 Time remaining: 3s Progress 5540 / 9694 Time remaining: 3s Progress 5541 / 9694 Time remaining: 3s Progress 5542 / 9694 Time remaining: 3s Progress 5543 / 9694 Time remaining: 3s Progress 5544 / 9694 Time remaining: 3s Progress 5545 / 9694 Time remaining: 3s Progress 5546 / 9694 Time remaining: 3s Progress 5547 / 9694 Time remaining: 3s Progress 5548 / 9694 Time remaining: 3s Progress 5549 / 9694 Time remaining: 3s Progress 5550 / 9694 Time remaining: 3s Progress 5551 / 9694 Time remaining: 3s Progress 5552 / 9694 Time remaining: 3s Progress 5553 / 9694 Time remaining: 3s Progress 5554 / 9694 Time remaining: 3s Progress 5555 / 9694 Time remaining: 3s Progress 5556 / 9694 Time remaining: 3s Progress 5557 / 9694 Time remaining: 3s Progress 5558 / 9694 Time remaining: 3s Progress 5559 / 9694 Time remaining: 3s Progress 5560 / 9694 Time remaining: 3s Progress 5561 / 9694 Time remaining: 3s Progress 5562 / 9694 Time remaining: 3s Progress 5563 / 9694 Time remaining: 3s Progress 5564 / 9694 Time remaining: 3s Progress 5565 / 9694 Time remaining: 3s Progress 5566 / 9694 Time remaining: 3s Progress 5567 / 9694 Time remaining: 3s Progress 5568 / 9694 Time remaining: 3s Progress 5569 / 9694 Time remaining: 3s Progress 5570 / 9694 Time remaining: 3s Progress 5571 / 9694 Time remaining: 3s Progress 5572 / 9694 Time remaining: 3s Progress 5573 / 9694 Time remaining: 3s Progress 5574 / 9694 Time remaining: 3s Progress 5575 / 9694 Time remaining: 3s Progress 5576 / 9694 Time remaining: 3s Progress 5577 / 9694 Time remaining: 3s Progress 5578 / 9694 Time remaining: 3s Progress 5579 / 9694 Time remaining: 3s Progress 5580 / 9694 Time remaining: 3s Progress 5581 / 9694 Time remaining: 3s Progress 5582 / 9694 Time remaining: 3s Progress 5583 / 9694 Time remaining: 3s Progress 5584 / 9694 Time remaining: 3s Progress 5585 / 9694 Time remaining: 3s Progress 5586 / 9694 Time remaining: 3s Progress 5587 / 9694 Time remaining: 3s Progress 5588 / 9694 Time remaining: 3s Progress 5589 / 9694 Time remaining: 3s Progress 5590 / 9694 Time remaining: 3s Progress 5591 / 9694 Time remaining: 3s Progress 5592 / 9694 Time remaining: 3s Progress 5593 / 9694 Time remaining: 3s Progress 5594 / 9694 Time remaining: 3s Progress 5595 / 9694 Time remaining: 3s Progress 5596 / 9694 Time remaining: 3s Progress 5597 / 9694 Time remaining: 3s Progress 5598 / 9694 Time remaining: 3s Progress 5599 / 9694 Time remaining: 3s Progress 5600 / 9694 Time remaining: 3s Progress 5601 / 9694 Time remaining: 3s Progress 5602 / 9694 Time remaining: 3s Progress 5603 / 9694 Time remaining: 3s Progress 5604 / 9694 Time remaining: 3s Progress 5605 / 9694 Time remaining: 3s Progress 5606 / 9694 Time remaining: 3s Progress 5607 / 9694 Time remaining: 3s Progress 5608 / 9694 Time remaining: 3s Progress 5609 / 9694 Time remaining: 3s Progress 5610 / 9694 Time remaining: 2s Progress 5611 / 9694 Time remaining: 2s Progress 5612 / 9694 Time remaining: 2s Progress 5613 / 9694 Time remaining: 2s Progress 5614 / 9694 Time remaining: 2s Progress 5615 / 9694 Time remaining: 2s Progress 5616 / 9694 Time remaining: 2s Progress 5617 / 9694 Time remaining: 2s Progress 5618 / 9694 Time remaining: 2s Progress 5619 / 9694 Time remaining: 2s Progress 5620 / 9694 Time remaining: 2s Progress 5621 / 9694 Time remaining: 2s Progress 5622 / 9694 Time remaining: 2s Progress 5623 / 9694 Time remaining: 2s Progress 5624 / 9694 Time remaining: 2s Progress 5625 / 9694 Time remaining: 2s Progress 5626 / 9694 Time remaining: 2s Progress 5627 / 9694 Time remaining: 2s Progress 5628 / 9694 Time remaining: 2s Progress 5629 / 9694 Time remaining: 2s Progress 5630 / 9694 Time remaining: 2s Progress 5631 / 9694 Time remaining: 2s Progress 5632 / 9694 Time remaining: 2s Progress 5633 / 9694 Time remaining: 2s Progress 5634 / 9694 Time remaining: 2s Progress 5635 / 9694 Time remaining: 2s Progress 5636 / 9694 Time remaining: 2s Progress 5637 / 9694 Time remaining: 2s Progress 5638 / 9694 Time remaining: 2s Progress 5639 / 9694 Time remaining: 2s Progress 5640 / 9694 Time remaining: 2s Progress 5641 / 9694 Time remaining: 2s Progress 5642 / 9694 Time remaining: 2s Progress 5643 / 9694 Time remaining: 2s Progress 5644 / 9694 Time remaining: 2s Progress 5645 / 9694 Time remaining: 2s Progress 5646 / 9694 Time remaining: 2s Progress 5647 / 9694 Time remaining: 2s Progress 5648 / 9694 Time remaining: 2s Progress 5649 / 9694 Time remaining: 2s Progress 5650 / 9694 Time remaining: 2s Progress 5651 / 9694 Time remaining: 2s Progress 5652 / 9694 Time remaining: 2s Progress 5653 / 9694 Time remaining: 2s Progress 5654 / 9694 Time remaining: 2s Progress 5655 / 9694 Time remaining: 2s Progress 5656 / 9694 Time remaining: 2s Progress 5657 / 9694 Time remaining: 2s Progress 5658 / 9694 Time remaining: 2s Progress 5659 / 9694 Time remaining: 2s Progress 5660 / 9694 Time remaining: 2s Progress 5661 / 9694 Time remaining: 2s Progress 5662 / 9694 Time remaining: 2s Progress 5663 / 9694 Time remaining: 2s Progress 5664 / 9694 Time remaining: 2s Progress 5665 / 9694 Time remaining: 2s Progress 5666 / 9694 Time remaining: 2s Progress 5667 / 9694 Time remaining: 2s Progress 5668 / 9694 Time remaining: 2s Progress 5669 / 9694 Time remaining: 2s Progress 5670 / 9694 Time remaining: 2s Progress 5671 / 9694 Time remaining: 2s Progress 5672 / 9694 Time remaining: 2s Progress 5673 / 9694 Time remaining: 2s Progress 5674 / 9694 Time remaining: 2s Progress 5675 / 9694 Time remaining: 2s Progress 5676 / 9694 Time remaining: 2s Progress 5677 / 9694 Time remaining: 2s Progress 5678 / 9694 Time remaining: 2s Progress 5679 / 9694 Time remaining: 2s Progress 5680 / 9694 Time remaining: 2s Progress 5681 / 9694 Time remaining: 2s Progress 5682 / 9694 Time remaining: 2s Progress 5683 / 9694 Time remaining: 2s Progress 5684 / 9694 Time remaining: 2s Progress 5685 / 9694 Time remaining: 2s Progress 5686 / 9694 Time remaining: 2s Progress 5687 / 9694 Time remaining: 2s Progress 5688 / 9694 Time remaining: 2s Progress 5689 / 9694 Time remaining: 2s Progress 5690 / 9694 Time remaining: 2s Progress 5691 / 9694 Time remaining: 2s Progress 5692 / 9694 Time remaining: 2s Progress 5693 / 9694 Time remaining: 2s Progress 5694 / 9694 Time remaining: 2s Progress 5695 / 9694 Time remaining: 2s Progress 5696 / 9694 Time remaining: 2s Progress 5697 / 9694 Time remaining: 2s Progress 5698 / 9694 Time remaining: 2s Progress 5699 / 9694 Time remaining: 2s Progress 5700 / 9694 Time remaining: 2s Progress 5701 / 9694 Time remaining: 2s Progress 5702 / 9694 Time remaining: 2s Progress 5703 / 9694 Time remaining: 2s Progress 5704 / 9694 Time remaining: 2s Progress 5705 / 9694 Time remaining: 2s Progress 5706 / 9694 Time remaining: 2s Progress 5707 / 9694 Time remaining: 2s Progress 5708 / 9694 Time remaining: 2s Progress 5709 / 9694 Time remaining: 2s Progress 5710 / 9694 Time remaining: 2s Progress 5711 / 9694 Time remaining: 2s Progress 5712 / 9694 Time remaining: 2s Progress 5713 / 9694 Time remaining: 2s Progress 5714 / 9694 Time remaining: 2s Progress 5715 / 9694 Time remaining: 2s Progress 5716 / 9694 Time remaining: 2s Progress 5717 / 9694 Time remaining: 2s Progress 5718 / 9694 Time remaining: 2s Progress 5719 / 9694 Time remaining: 2s Progress 5720 / 9694 Time remaining: 2s Progress 5721 / 9694 Time remaining: 2s Progress 5722 / 9694 Time remaining: 2s Progress 5723 / 9694 Time remaining: 2s Progress 5724 / 9694 Time remaining: 2s Progress 5725 / 9694 Time remaining: 2s Progress 5726 / 9694 Time remaining: 2s Progress 5727 / 9694 Time remaining: 2s Progress 5728 / 9694 Time remaining: 2s Progress 5729 / 9694 Time remaining: 2s Progress 5730 / 9694 Time remaining: 2s Progress 5731 / 9694 Time remaining: 2s Progress 5732 / 9694 Time remaining: 2s Progress 5733 / 9694 Time remaining: 2s Progress 5734 / 9694 Time remaining: 2s Progress 5735 / 9694 Time remaining: 2s Progress 5736 / 9694 Time remaining: 2s Progress 5737 / 9694 Time remaining: 2s Progress 5738 / 9694 Time remaining: 2s Progress 5739 / 9694 Time remaining: 2s Progress 5740 / 9694 Time remaining: 2s Progress 5741 / 9694 Time remaining: 2s Progress 5742 / 9694 Time remaining: 2s Progress 5743 / 9694 Time remaining: 2s Progress 5744 / 9694 Time remaining: 2s Progress 5745 / 9694 Time remaining: 2s Progress 5746 / 9694 Time remaining: 2s Progress 5747 / 9694 Time remaining: 2s Progress 5748 / 9694 Time remaining: 2s Progress 5749 / 9694 Time remaining: 2s Progress 5750 / 9694 Time remaining: 2s Progress 5751 / 9694 Time remaining: 2s Progress 5752 / 9694 Time remaining: 2s Progress 5753 / 9694 Time remaining: 2s Progress 5754 / 9694 Time remaining: 2s Progress 5755 / 9694 Time remaining: 2s Progress 5756 / 9694 Time remaining: 2s Progress 5757 / 9694 Time remaining: 2s Progress 5758 / 9694 Time remaining: 2s Progress 5759 / 9694 Time remaining: 2s Progress 5760 / 9694 Time remaining: 2s Progress 5761 / 9694 Time remaining: 2s Progress 5762 / 9694 Time remaining: 2s Progress 5763 / 9694 Time remaining: 2s Progress 5764 / 9694 Time remaining: 2s Progress 5765 / 9694 Time remaining: 2s Progress 5766 / 9694 Time remaining: 2s Progress 5767 / 9694 Time remaining: 2s Progress 5768 / 9694 Time remaining: 2s Progress 5769 / 9694 Time remaining: 2s Progress 5770 / 9694 Time remaining: 2s Progress 5771 / 9694 Time remaining: 2s Progress 5772 / 9694 Time remaining: 2s Progress 5773 / 9694 Time remaining: 2s Progress 5774 / 9694 Time remaining: 2s Progress 5775 / 9694 Time remaining: 2s Progress 5776 / 9694 Time remaining: 2s Progress 5777 / 9694 Time remaining: 2s Progress 5778 / 9694 Time remaining: 2s Progress 5779 / 9694 Time remaining: 2s Progress 5780 / 9694 Time remaining: 2s Progress 5781 / 9694 Time remaining: 2s Progress 5782 / 9694 Time remaining: 2s Progress 5783 / 9694 Time remaining: 2s Progress 5784 / 9694 Time remaining: 2s Progress 5785 / 9694 Time remaining: 2s Progress 5786 / 9694 Time remaining: 2s Progress 5787 / 9694 Time remaining: 2s Progress 5788 / 9694 Time remaining: 2s Progress 5789 / 9694 Time remaining: 2s Progress 5790 / 9694 Time remaining: 2s Progress 5791 / 9694 Time remaining: 2s Progress 5792 / 9694 Time remaining: 2s Progress 5793 / 9694 Time remaining: 2s Progress 5794 / 9694 Time remaining: 2s Progress 5795 / 9694 Time remaining: 2s Progress 5796 / 9694 Time remaining: 2s Progress 5797 / 9694 Time remaining: 2s Progress 5798 / 9694 Time remaining: 2s Progress 5799 / 9694 Time remaining: 2s Progress 5800 / 9694 Time remaining: 2s Progress 5801 / 9694 Time remaining: 2s Progress 5802 / 9694 Time remaining: 2s Progress 5803 / 9694 Time remaining: 2s Progress 5804 / 9694 Time remaining: 2s Progress 5805 / 9694 Time remaining: 2s Progress 5806 / 9694 Time remaining: 2s Progress 5807 / 9694 Time remaining: 2s Progress 5808 / 9694 Time remaining: 2s Progress 5809 / 9694 Time remaining: 2s Progress 5810 / 9694 Time remaining: 2s Progress 5811 / 9694 Time remaining: 2s Progress 5812 / 9694 Time remaining: 2s Progress 5813 / 9694 Time remaining: 2s Progress 5814 / 9694 Time remaining: 2s Progress 5815 / 9694 Time remaining: 2s Progress 5816 / 9694 Time remaining: 2s Progress 5817 / 9694 Time remaining: 2s Progress 5818 / 9694 Time remaining: 2s Progress 5819 / 9694 Time remaining: 2s Progress 5820 / 9694 Time remaining: 2s Progress 5821 / 9694 Time remaining: 2s Progress 5822 / 9694 Time remaining: 2s Progress 5823 / 9694 Time remaining: 2s Progress 5824 / 9694 Time remaining: 2s Progress 5825 / 9694 Time remaining: 2s Progress 5826 / 9694 Time remaining: 2s Progress 5827 / 9694 Time remaining: 2s Progress 5828 / 9694 Time remaining: 2s Progress 5829 / 9694 Time remaining: 2s Progress 5830 / 9694 Time remaining: 2s Progress 5831 / 9694 Time remaining: 2s Progress 5832 / 9694 Time remaining: 2s Progress 5833 / 9694 Time remaining: 2s Progress 5834 / 9694 Time remaining: 2s Progress 5835 / 9694 Time remaining: 2s Progress 5836 / 9694 Time remaining: 2s Progress 5837 / 9694 Time remaining: 2s Progress 5838 / 9694 Time remaining: 2s Progress 5839 / 9694 Time remaining: 2s Progress 5840 / 9694 Time remaining: 2s Progress 5841 / 9694 Time remaining: 2s Progress 5842 / 9694 Time remaining: 2s Progress 5843 / 9694 Time remaining: 2s Progress 5844 / 9694 Time remaining: 2s Progress 5845 / 9694 Time remaining: 2s Progress 5846 / 9694 Time remaining: 2s Progress 5847 / 9694 Time remaining: 2s Progress 5848 / 9694 Time remaining: 2s Progress 5849 / 9694 Time remaining: 2s Progress 5850 / 9694 Time remaining: 2s Progress 5851 / 9694 Time remaining: 2s Progress 5852 / 9694 Time remaining: 2s Progress 5853 / 9694 Time remaining: 2s Progress 5854 / 9694 Time remaining: 2s Progress 5855 / 9694 Time remaining: 2s Progress 5856 / 9694 Time remaining: 2s Progress 5857 / 9694 Time remaining: 2s Progress 5858 / 9694 Time remaining: 2s Progress 5859 / 9694 Time remaining: 2s Progress 5860 / 9694 Time remaining: 2s Progress 5861 / 9694 Time remaining: 2s Progress 5862 / 9694 Time remaining: 2s Progress 5863 / 9694 Time remaining: 2s Progress 5864 / 9694 Time remaining: 2s Progress 5865 / 9694 Time remaining: 2s Progress 5866 / 9694 Time remaining: 2s Progress 5867 / 9694 Time remaining: 2s Progress 5868 / 9694 Time remaining: 2s Progress 5869 / 9694 Time remaining: 2s Progress 5870 / 9694 Time remaining: 2s Progress 5871 / 9694 Time remaining: 2s Progress 5872 / 9694 Time remaining: 2s Progress 5873 / 9694 Time remaining: 2s Progress 5874 / 9694 Time remaining: 2s Progress 5875 / 9694 Time remaining: 2s Progress 5876 / 9694 Time remaining: 2s Progress 5877 / 9694 Time remaining: 2s Progress 5878 / 9694 Time remaining: 2s Progress 5879 / 9694 Time remaining: 2s Progress 5880 / 9694 Time remaining: 2s Progress 5881 / 9694 Time remaining: 2s Progress 5882 / 9694 Time remaining: 2s Progress 5883 / 9694 Time remaining: 2s Progress 5884 / 9694 Time remaining: 2s Progress 5885 / 9694 Time remaining: 2s Progress 5886 / 9694 Time remaining: 2s Progress 5887 / 9694 Time remaining: 2s Progress 5888 / 9694 Time remaining: 2s Progress 5889 / 9694 Time remaining: 2s Progress 5890 / 9694 Time remaining: 2s Progress 5891 / 9694 Time remaining: 2s Progress 5892 / 9694 Time remaining: 2s Progress 5893 / 9694 Time remaining: 2s Progress 5894 / 9694 Time remaining: 2s Progress 5895 / 9694 Time remaining: 2s Progress 5896 / 9694 Time remaining: 2s Progress 5897 / 9694 Time remaining: 2s Progress 5898 / 9694 Time remaining: 2s Progress 5899 / 9694 Time remaining: 2s Progress 5900 / 9694 Time remaining: 2s Progress 5901 / 9694 Time remaining: 2s Progress 5902 / 9694 Time remaining: 2s Progress 5903 / 9694 Time remaining: 2s Progress 5904 / 9694 Time remaining: 2s Progress 5905 / 9694 Time remaining: 2s Progress 5906 / 9694 Time remaining: 2s Progress 5907 / 9694 Time remaining: 2s Progress 5908 / 9694 Time remaining: 2s Progress 5909 / 9694 Time remaining: 2s Progress 5910 / 9694 Time remaining: 2s Progress 5911 / 9694 Time remaining: 2s Progress 5912 / 9694 Time remaining: 2s Progress 5913 / 9694 Time remaining: 2s Progress 5914 / 9694 Time remaining: 2s Progress 5915 / 9694 Time remaining: 2s Progress 5916 / 9694 Time remaining: 2s Progress 5917 / 9694 Time remaining: 2s Progress 5918 / 9694 Time remaining: 2s Progress 5919 / 9694 Time remaining: 2s Progress 5920 / 9694 Time remaining: 2s Progress 5921 / 9694 Time remaining: 2s Progress 5922 / 9694 Time remaining: 2s Progress 5923 / 9694 Time remaining: 2s Progress 5924 / 9694 Time remaining: 2s Progress 5925 / 9694 Time remaining: 2s Progress 5926 / 9694 Time remaining: 2s Progress 5927 / 9694 Time remaining: 2s Progress 5928 / 9694 Time remaining: 2s Progress 5929 / 9694 Time remaining: 2s Progress 5930 / 9694 Time remaining: 2s Progress 5931 / 9694 Time remaining: 2s Progress 5932 / 9694 Time remaining: 2s Progress 5933 / 9694 Time remaining: 2s Progress 5934 / 9694 Time remaining: 2s Progress 5935 / 9694 Time remaining: 2s Progress 5936 / 9694 Time remaining: 2s Progress 5937 / 9694 Time remaining: 2s Progress 5938 / 9694 Time remaining: 2s Progress 5939 / 9694 Time remaining: 2s Progress 5940 / 9694 Time remaining: 2s Progress 5941 / 9694 Time remaining: 2s Progress 5942 / 9694 Time remaining: 2s Progress 5943 / 9694 Time remaining: 2s Progress 5944 / 9694 Time remaining: 2s Progress 5945 / 9694 Time remaining: 2s Progress 5946 / 9694 Time remaining: 2s Progress 5947 / 9694 Time remaining: 2s Progress 5948 / 9694 Time remaining: 2s Progress 5949 / 9694 Time remaining: 2s Progress 5950 / 9694 Time remaining: 2s Progress 5951 / 9694 Time remaining: 2s Progress 5952 / 9694 Time remaining: 2s Progress 5953 / 9694 Time remaining: 2s Progress 5954 / 9694 Time remaining: 2s Progress 5955 / 9694 Time remaining: 2s Progress 5956 / 9694 Time remaining: 2s Progress 5957 / 9694 Time remaining: 2s Progress 5958 / 9694 Time remaining: 2s Progress 5959 / 9694 Time remaining: 2s Progress 5960 / 9694 Time remaining: 2s Progress 5961 / 9694 Time remaining: 2s Progress 5962 / 9694 Time remaining: 2s Progress 5963 / 9694 Time remaining: 2s Progress 5964 / 9694 Time remaining: 2s Progress 5965 / 9694 Time remaining: 2s Progress 5966 / 9694 Time remaining: 2s Progress 5967 / 9694 Time remaining: 2s Progress 5968 / 9694 Time remaining: 2s Progress 5969 / 9694 Time remaining: 2s Progress 5970 / 9694 Time remaining: 2s Progress 5971 / 9694 Time remaining: 2s Progress 5972 / 9694 Time remaining: 2s Progress 5973 / 9694 Time remaining: 2s Progress 5974 / 9694 Time remaining: 2s Progress 5975 / 9694 Time remaining: 2s Progress 5976 / 9694 Time remaining: 2s Progress 5977 / 9694 Time remaining: 2s Progress 5978 / 9694 Time remaining: 2s Progress 5979 / 9694 Time remaining: 2s Progress 5980 / 9694 Time remaining: 2s Progress 5981 / 9694 Time remaining: 2s Progress 5982 / 9694 Time remaining: 2s Progress 5983 / 9694 Time remaining: 2s Progress 5984 / 9694 Time remaining: 2s Progress 5985 / 9694 Time remaining: 2s Progress 5986 / 9694 Time remaining: 2s Progress 5987 / 9694 Time remaining: 2s Progress 5988 / 9694 Time remaining: 2s Progress 5989 / 9694 Time remaining: 2s Progress 5990 / 9694 Time remaining: 2s Progress 5991 / 9694 Time remaining: 2s Progress 5992 / 9694 Time remaining: 2s Progress 5993 / 9694 Time remaining: 2s Progress 5994 / 9694 Time remaining: 2s Progress 5995 / 9694 Time remaining: 2s Progress 5996 / 9694 Time remaining: 2s Progress 5997 / 9694 Time remaining: 2s Progress 5998 / 9694 Time remaining: 2s Progress 5999 / 9694 Time remaining: 2s Progress 6000 / 9694 Time remaining: 2s Progress 6001 / 9694 Time remaining: 2s Progress 6002 / 9694 Time remaining: 2s Progress 6003 / 9694 Time remaining: 2s Progress 6004 / 9694 Time remaining: 2s Progress 6005 / 9694 Time remaining: 2s Progress 6006 / 9694 Time remaining: 2s Progress 6007 / 9694 Time remaining: 2s Progress 6008 / 9694 Time remaining: 2s Progress 6009 / 9694 Time remaining: 2s Progress 6010 / 9694 Time remaining: 2s Progress 6011 / 9694 Time remaining: 2s Progress 6012 / 9694 Time remaining: 2s Progress 6013 / 9694 Time remaining: 2s Progress 6014 / 9694 Time remaining: 2s Progress 6015 / 9694 Time remaining: 2s Progress 6016 / 9694 Time remaining: 2s Progress 6017 / 9694 Time remaining: 2s Progress 6018 / 9694 Time remaining: 2s Progress 6019 / 9694 Time remaining: 2s Progress 6020 / 9694 Time remaining: 2s Progress 6021 / 9694 Time remaining: 2s Progress 6022 / 9694 Time remaining: 2s Progress 6023 / 9694 Time remaining: 2s Progress 6024 / 9694 Time remaining: 2s Progress 6025 / 9694 Time remaining: 2s Progress 6026 / 9694 Time remaining: 2s Progress 6027 / 9694 Time remaining: 2s Progress 6028 / 9694 Time remaining: 2s Progress 6029 / 9694 Time remaining: 2s Progress 6030 / 9694 Time remaining: 2s Progress 6031 / 9694 Time remaining: 2s Progress 6032 / 9694 Time remaining: 2s Progress 6033 / 9694 Time remaining: 2s Progress 6034 / 9694 Time remaining: 2s Progress 6035 / 9694 Time remaining: 2s Progress 6036 / 9694 Time remaining: 2s Progress 6037 / 9694 Time remaining: 2s Progress 6038 / 9694 Time remaining: 2s Progress 6039 / 9694 Time remaining: 2s Progress 6040 / 9694 Time remaining: 2s Progress 6041 / 9694 Time remaining: 2s Progress 6042 / 9694 Time remaining: 2s Progress 6043 / 9694 Time remaining: 2s Progress 6044 / 9694 Time remaining: 2s Progress 6045 / 9694 Time remaining: 2s Progress 6046 / 9694 Time remaining: 2s Progress 6047 / 9694 Time remaining: 2s Progress 6048 / 9694 Time remaining: 2s Progress 6049 / 9694 Time remaining: 2s Progress 6050 / 9694 Time remaining: 2s Progress 6051 / 9694 Time remaining: 2s Progress 6052 / 9694 Time remaining: 2s Progress 6053 / 9694 Time remaining: 2s Progress 6054 / 9694 Time remaining: 2s Progress 6055 / 9694 Time remaining: 2s Progress 6056 / 9694 Time remaining: 2s Progress 6057 / 9694 Time remaining: 2s Progress 6058 / 9694 Time remaining: 2s Progress 6059 / 9694 Time remaining: 2s Progress 6060 / 9694 Time remaining: 2s Progress 6061 / 9694 Time remaining: 2s Progress 6062 / 9694 Time remaining: 2s Progress 6063 / 9694 Time remaining: 2s Progress 6064 / 9694 Time remaining: 2s Progress 6065 / 9694 Time remaining: 2s Progress 6066 / 9694 Time remaining: 2s Progress 6067 / 9694 Time remaining: 2s Progress 6068 / 9694 Time remaining: 2s Progress 6069 / 9694 Time remaining: 2s Progress 6070 / 9694 Time remaining: 2s Progress 6071 / 9694 Time remaining: 2s Progress 6072 / 9694 Time remaining: 2s Progress 6073 / 9694 Time remaining: 2s Progress 6074 / 9694 Time remaining: 2s Progress 6075 / 9694 Time remaining: 2s Progress 6076 / 9694 Time remaining: 2s Progress 6077 / 9694 Time remaining: 2s Progress 6078 / 9694 Time remaining: 2s Progress 6079 / 9694 Time remaining: 2s Progress 6080 / 9694 Time remaining: 2s Progress 6081 / 9694 Time remaining: 2s Progress 6082 / 9694 Time remaining: 2s Progress 6083 / 9694 Time remaining: 2s Progress 6084 / 9694 Time remaining: 2s Progress 6085 / 9694 Time remaining: 2s Progress 6086 / 9694 Time remaining: 2s Progress 6087 / 9694 Time remaining: 2s Progress 6088 / 9694 Time remaining: 2s Progress 6089 / 9694 Time remaining: 2s Progress 6090 / 9694 Time remaining: 2s Progress 6091 / 9694 Time remaining: 2s Progress 6092 / 9694 Time remaining: 2s Progress 6093 / 9694 Time remaining: 2s Progress 6094 / 9694 Time remaining: 2s Progress 6095 / 9694 Time remaining: 2s Progress 6096 / 9694 Time remaining: 2s Progress 6097 / 9694 Time remaining: 2s Progress 6098 / 9694 Time remaining: 2s Progress 6099 / 9694 Time remaining: 2s Progress 6100 / 9694 Time remaining: 2s Progress 6101 / 9694 Time remaining: 2s Progress 6102 / 9694 Time remaining: 2s Progress 6103 / 9694 Time remaining: 2s Progress 6104 / 9694 Time remaining: 2s Progress 6105 / 9694 Time remaining: 2s Progress 6106 / 9694 Time remaining: 2s Progress 6107 / 9694 Time remaining: 2s Progress 6108 / 9694 Time remaining: 2s Progress 6109 / 9694 Time remaining: 2s Progress 6110 / 9694 Time remaining: 2s Progress 6111 / 9694 Time remaining: 2s Progress 6112 / 9694 Time remaining: 2s Progress 6113 / 9694 Time remaining: 2s Progress 6114 / 9694 Time remaining: 2s Progress 6115 / 9694 Time remaining: 2s Progress 6116 / 9694 Time remaining: 2s Progress 6117 / 9694 Time remaining: 2s Progress 6118 / 9694 Time remaining: 2s Progress 6119 / 9694 Time remaining: 2s Progress 6120 / 9694 Time remaining: 2s Progress 6121 / 9694 Time remaining: 2s Progress 6122 / 9694 Time remaining: 2s Progress 6123 / 9694 Time remaining: 2s Progress 6124 / 9694 Time remaining: 2s Progress 6125 / 9694 Time remaining: 2s Progress 6126 / 9694 Time remaining: 2s Progress 6127 / 9694 Time remaining: 2s Progress 6128 / 9694 Time remaining: 2s Progress 6129 / 9694 Time remaining: 2s Progress 6130 / 9694 Time remaining: 2s Progress 6131 / 9694 Time remaining: 2s Progress 6132 / 9694 Time remaining: 2s Progress 6133 / 9694 Time remaining: 2s Progress 6134 / 9694 Time remaining: 2s Progress 6135 / 9694 Time remaining: 2s Progress 6136 / 9694 Time remaining: 2s Progress 6137 / 9694 Time remaining: 2s Progress 6138 / 9694 Time remaining: 2s Progress 6139 / 9694 Time remaining: 2s Progress 6140 / 9694 Time remaining: 2s Progress 6141 / 9694 Time remaining: 2s Progress 6142 / 9694 Time remaining: 2s Progress 6143 / 9694 Time remaining: 2s Progress 6144 / 9694 Time remaining: 2s Progress 6145 / 9694 Time remaining: 2s Progress 6146 / 9694 Time remaining: 2s Progress 6147 / 9694 Time remaining: 2s Progress 6148 / 9694 Time remaining: 2s Progress 6149 / 9694 Time remaining: 2s Progress 6150 / 9694 Time remaining: 2s Progress 6151 / 9694 Time remaining: 2s Progress 6152 / 9694 Time remaining: 2s Progress 6153 / 9694 Time remaining: 2s Progress 6154 / 9694 Time remaining: 2s Progress 6155 / 9694 Time remaining: 2s Progress 6156 / 9694 Time remaining: 2s Progress 6157 / 9694 Time remaining: 2s Progress 6158 / 9694 Time remaining: 2s Progress 6159 / 9694 Time remaining: 2s Progress 6160 / 9694 Time remaining: 2s Progress 6161 / 9694 Time remaining: 2s Progress 6162 / 9694 Time remaining: 2s Progress 6163 / 9694 Time remaining: 2s Progress 6164 / 9694 Time remaining: 2s Progress 6165 / 9694 Time remaining: 2s Progress 6166 / 9694 Time remaining: 2s Progress 6167 / 9694 Time remaining: 2s Progress 6168 / 9694 Time remaining: 2s Progress 6169 / 9694 Time remaining: 2s Progress 6170 / 9694 Time remaining: 2s Progress 6171 / 9694 Time remaining: 2s Progress 6172 / 9694 Time remaining: 2s Progress 6173 / 9694 Time remaining: 2s Progress 6174 / 9694 Time remaining: 2s Progress 6175 / 9694 Time remaining: 2s Progress 6176 / 9694 Time remaining: 2s Progress 6177 / 9694 Time remaining: 2s Progress 6178 / 9694 Time remaining: 2s Progress 6179 / 9694 Time remaining: 2s Progress 6180 / 9694 Time remaining: 2s Progress 6181 / 9694 Time remaining: 2s Progress 6182 / 9694 Time remaining: 2s Progress 6183 / 9694 Time remaining: 2s Progress 6184 / 9694 Time remaining: 2s Progress 6185 / 9694 Time remaining: 2s Progress 6186 / 9694 Time remaining: 2s Progress 6187 / 9694 Time remaining: 2s Progress 6188 / 9694 Time remaining: 2s Progress 6189 / 9694 Time remaining: 2s Progress 6190 / 9694 Time remaining: 2s Progress 6191 / 9694 Time remaining: 2s Progress 6192 / 9694 Time remaining: 2s Progress 6193 / 9694 Time remaining: 2s Progress 6194 / 9694 Time remaining: 2s Progress 6195 / 9694 Time remaining: 2s Progress 6196 / 9694 Time remaining: 2s Progress 6197 / 9694 Time remaining: 2s Progress 6198 / 9694 Time remaining: 2s Progress 6199 / 9694 Time remaining: 2s Progress 6200 / 9694 Time remaining: 2s Progress 6201 / 9694 Time remaining: 2s Progress 6202 / 9694 Time remaining: 2s Progress 6203 / 9694 Time remaining: 2s Progress 6204 / 9694 Time remaining: 2s Progress 6205 / 9694 Time remaining: 2s Progress 6206 / 9694 Time remaining: 2s Progress 6207 / 9694 Time remaining: 2s Progress 6208 / 9694 Time remaining: 2s Progress 6209 / 9694 Time remaining: 2s Progress 6210 / 9694 Time remaining: 2s Progress 6211 / 9694 Time remaining: 2s Progress 6212 / 9694 Time remaining: 2s Progress 6213 / 9694 Time remaining: 2s Progress 6214 / 9694 Time remaining: 2s Progress 6215 / 9694 Time remaining: 2s Progress 6216 / 9694 Time remaining: 2s Progress 6217 / 9694 Time remaining: 2s Progress 6218 / 9694 Time remaining: 2s Progress 6219 / 9694 Time remaining: 2s Progress 6220 / 9694 Time remaining: 2s Progress 6221 / 9694 Time remaining: 2s Progress 6222 / 9694 Time remaining: 2s Progress 6223 / 9694 Time remaining: 2s Progress 6224 / 9694 Time remaining: 2s Progress 6225 / 9694 Time remaining: 2s Progress 6226 / 9694 Time remaining: 2s Progress 6227 / 9694 Time remaining: 2s Progress 6228 / 9694 Time remaining: 2s Progress 6229 / 9694 Time remaining: 2s Progress 6230 / 9694 Time remaining: 2s Progress 6231 / 9694 Time remaining: 2s Progress 6232 / 9694 Time remaining: 2s Progress 6233 / 9694 Time remaining: 2s Progress 6234 / 9694 Time remaining: 2s Progress 6235 / 9694 Time remaining: 2s Progress 6236 / 9694 Time remaining: 2s Progress 6237 / 9694 Time remaining: 2s Progress 6238 / 9694 Time remaining: 2s Progress 6239 / 9694 Time remaining: 2s Progress 6240 / 9694 Time remaining: 2s Progress 6241 / 9694 Time remaining: 2s Progress 6242 / 9694 Time remaining: 2s Progress 6243 / 9694 Time remaining: 2s Progress 6244 / 9694 Time remaining: 2s Progress 6245 / 9694 Time remaining: 2s Progress 6246 / 9694 Time remaining: 2s Progress 6247 / 9694 Time remaining: 2s Progress 6248 / 9694 Time remaining: 2s Progress 6249 / 9694 Time remaining: 2s Progress 6250 / 9694 Time remaining: 2s Progress 6251 / 9694 Time remaining: 2s Progress 6252 / 9694 Time remaining: 2s Progress 6253 / 9694 Time remaining: 2s Progress 6254 / 9694 Time remaining: 2s Progress 6255 / 9694 Time remaining: 2s Progress 6256 / 9694 Time remaining: 2s Progress 6257 / 9694 Time remaining: 2s Progress 6258 / 9694 Time remaining: 2s Progress 6259 / 9694 Time remaining: 2s Progress 6260 / 9694 Time remaining: 2s Progress 6261 / 9694 Time remaining: 2s Progress 6262 / 9694 Time remaining: 2s Progress 6263 / 9694 Time remaining: 2s Progress 6264 / 9694 Time remaining: 2s Progress 6265 / 9694 Time remaining: 2s Progress 6266 / 9694 Time remaining: 2s Progress 6267 / 9694 Time remaining: 2s Progress 6268 / 9694 Time remaining: 2s Progress 6269 / 9694 Time remaining: 2s Progress 6270 / 9694 Time remaining: 2s Progress 6271 / 9694 Time remaining: 2s Progress 6272 / 9694 Time remaining: 2s Progress 6273 / 9694 Time remaining: 2s Progress 6274 / 9694 Time remaining: 2s Progress 6275 / 9694 Time remaining: 2s Progress 6276 / 9694 Time remaining: 2s Progress 6277 / 9694 Time remaining: 2s Progress 6278 / 9694 Time remaining: 2s Progress 6279 / 9694 Time remaining: 2s Progress 6280 / 9694 Time remaining: 2s Progress 6281 / 9694 Time remaining: 2s Progress 6282 / 9694 Time remaining: 2s Progress 6283 / 9694 Time remaining: 2s Progress 6284 / 9694 Time remaining: 2s Progress 6285 / 9694 Time remaining: 2s Progress 6286 / 9694 Time remaining: 2s Progress 6287 / 9694 Time remaining: 2s Progress 6288 / 9694 Time remaining: 2s Progress 6289 / 9694 Time remaining: 2s Progress 6290 / 9694 Time remaining: 2s Progress 6291 / 9694 Time remaining: 2s Progress 6292 / 9694 Time remaining: 2s Progress 6293 / 9694 Time remaining: 2s Progress 6294 / 9694 Time remaining: 2s Progress 6295 / 9694 Time remaining: 2s Progress 6296 / 9694 Time remaining: 2s Progress 6297 / 9694 Time remaining: 2s Progress 6298 / 9694 Time remaining: 2s Progress 6299 / 9694 Time remaining: 2s Progress 6300 / 9694 Time remaining: 2s Progress 6301 / 9694 Time remaining: 2s Progress 6302 / 9694 Time remaining: 2s Progress 6303 / 9694 Time remaining: 2s Progress 6304 / 9694 Time remaining: 2s Progress 6305 / 9694 Time remaining: 2s Progress 6306 / 9694 Time remaining: 2s Progress 6307 / 9694 Time remaining: 2s Progress 6308 / 9694 Time remaining: 2s Progress 6309 / 9694 Time remaining: 2s Progress 6310 / 9694 Time remaining: 2s Progress 6311 / 9694 Time remaining: 2s Progress 6312 / 9694 Time remaining: 2s Progress 6313 / 9694 Time remaining: 2s Progress 6314 / 9694 Time remaining: 2s Progress 6315 / 9694 Time remaining: 2s Progress 6316 / 9694 Time remaining: 2s Progress 6317 / 9694 Time remaining: 2s Progress 6318 / 9694 Time remaining: 2s Progress 6319 / 9694 Time remaining: 2s Progress 6320 / 9694 Time remaining: 2s Progress 6321 / 9694 Time remaining: 2s Progress 6322 / 9694 Time remaining: 2s Progress 6323 / 9694 Time remaining: 2s Progress 6324 / 9694 Time remaining: 2s Progress 6325 / 9694 Time remaining: 2s Progress 6326 / 9694 Time remaining: 2s Progress 6327 / 9694 Time remaining: 2s Progress 6328 / 9694 Time remaining: 2s Progress 6329 / 9694 Time remaining: 2s Progress 6330 / 9694 Time remaining: 2s Progress 6331 / 9694 Time remaining: 2s Progress 6332 / 9694 Time remaining: 2s Progress 6333 / 9694 Time remaining: 2s Progress 6334 / 9694 Time remaining: 2s Progress 6335 / 9694 Time remaining: 2s Progress 6336 / 9694 Time remaining: 2s Progress 6337 / 9694 Time remaining: 2s Progress 6338 / 9694 Time remaining: 2s Progress 6339 / 9694 Time remaining: 2s Progress 6340 / 9694 Time remaining: 2s Progress 6341 / 9694 Time remaining: 2s Progress 6342 / 9694 Time remaining: 2s Progress 6343 / 9694 Time remaining: 2s Progress 6344 / 9694 Time remaining: 2s Progress 6345 / 9694 Time remaining: 2s Progress 6346 / 9694 Time remaining: 2s Progress 6347 / 9694 Time remaining: 2s Progress 6348 / 9694 Time remaining: 2s Progress 6349 / 9694 Time remaining: 2s Progress 6350 / 9694 Time remaining: 2s Progress 6351 / 9694 Time remaining: 2s Progress 6352 / 9694 Time remaining: 2s Progress 6353 / 9694 Time remaining: 2s Progress 6354 / 9694 Time remaining: 2s Progress 6355 / 9694 Time remaining: 2s Progress 6356 / 9694 Time remaining: 2s Progress 6357 / 9694 Time remaining: 2s Progress 6358 / 9694 Time remaining: 2s Progress 6359 / 9694 Time remaining: 2s Progress 6360 / 9694 Time remaining: 2s Progress 6361 / 9694 Time remaining: 2s Progress 6362 / 9694 Time remaining: 2s Progress 6363 / 9694 Time remaining: 2s Progress 6364 / 9694 Time remaining: 2s Progress 6365 / 9694 Time remaining: 2s Progress 6366 / 9694 Time remaining: 2s Progress 6367 / 9694 Time remaining: 2s Progress 6368 / 9694 Time remaining: 2s Progress 6369 / 9694 Time remaining: 2s Progress 6370 / 9694 Time remaining: 2s Progress 6371 / 9694 Time remaining: 2s Progress 6372 / 9694 Time remaining: 2s Progress 6373 / 9694 Time remaining: 2s Progress 6374 / 9694 Time remaining: 2s Progress 6375 / 9694 Time remaining: 2s Progress 6376 / 9694 Time remaining: 2s Progress 6377 / 9694 Time remaining: 2s Progress 6378 / 9694 Time remaining: 2s Progress 6379 / 9694 Time remaining: 2s Progress 6380 / 9694 Time remaining: 2s Progress 6381 / 9694 Time remaining: 2s Progress 6382 / 9694 Time remaining: 2s Progress 6383 / 9694 Time remaining: 2s Progress 6384 / 9694 Time remaining: 2s Progress 6385 / 9694 Time remaining: 2s Progress 6386 / 9694 Time remaining: 2s Progress 6387 / 9694 Time remaining: 2s Progress 6388 / 9694 Time remaining: 2s Progress 6389 / 9694 Time remaining: 2s Progress 6390 / 9694 Time remaining: 2s Progress 6391 / 9694 Time remaining: 2s Progress 6392 / 9694 Time remaining: 2s Progress 6393 / 9694 Time remaining: 2s Progress 6394 / 9694 Time remaining: 2s Progress 6395 / 9694 Time remaining: 2s Progress 6396 / 9694 Time remaining: 2s Progress 6397 / 9694 Time remaining: 2s Progress 6398 / 9694 Time remaining: 2s Progress 6399 / 9694 Time remaining: 2s Progress 6400 / 9694 Time remaining: 2s Progress 6401 / 9694 Time remaining: 2s Progress 6402 / 9694 Time remaining: 2s Progress 6403 / 9694 Time remaining: 2s Progress 6404 / 9694 Time remaining: 2s Progress 6405 / 9694 Time remaining: 2s Progress 6406 / 9694 Time remaining: 2s Progress 6407 / 9694 Time remaining: 2s Progress 6408 / 9694 Time remaining: 2s Progress 6409 / 9694 Time remaining: 2s Progress 6410 / 9694 Time remaining: 2s Progress 6411 / 9694 Time remaining: 2s Progress 6412 / 9694 Time remaining: 2s Progress 6413 / 9694 Time remaining: 2s Progress 6414 / 9694 Time remaining: 2s Progress 6415 / 9694 Time remaining: 2s Progress 6416 / 9694 Time remaining: 2s Progress 6417 / 9694 Time remaining: 2s Progress 6418 / 9694 Time remaining: 2s Progress 6419 / 9694 Time remaining: 2s Progress 6420 / 9694 Time remaining: 2s Progress 6421 / 9694 Time remaining: 2s Progress 6422 / 9694 Time remaining: 2s Progress 6423 / 9694 Time remaining: 2s Progress 6424 / 9694 Time remaining: 2s Progress 6425 / 9694 Time remaining: 2s Progress 6426 / 9694 Time remaining: 2s Progress 6427 / 9694 Time remaining: 2s Progress 6428 / 9694 Time remaining: 2s Progress 6429 / 9694 Time remaining: 2s Progress 6430 / 9694 Time remaining: 2s Progress 6431 / 9694 Time remaining: 2s Progress 6432 / 9694 Time remaining: 2s Progress 6433 / 9694 Time remaining: 2s Progress 6434 / 9694 Time remaining: 2s Progress 6435 / 9694 Time remaining: 2s Progress 6436 / 9694 Time remaining: 2s Progress 6437 / 9694 Time remaining: 2s Progress 6438 / 9694 Time remaining: 2s Progress 6439 / 9694 Time remaining: 2s Progress 6440 / 9694 Time remaining: 2s Progress 6441 / 9694 Time remaining: 2s Progress 6442 / 9694 Time remaining: 2s Progress 6443 / 9694 Time remaining: 2s Progress 6444 / 9694 Time remaining: 2s Progress 6445 / 9694 Time remaining: 2s Progress 6446 / 9694 Time remaining: 2s Progress 6447 / 9694 Time remaining: 2s Progress 6448 / 9694 Time remaining: 2s Progress 6449 / 9694 Time remaining: 2s Progress 6450 / 9694 Time remaining: 2s Progress 6451 / 9694 Time remaining: 2s Progress 6452 / 9694 Time remaining: 2s Progress 6453 / 9694 Time remaining: 2s Progress 6454 / 9694 Time remaining: 2s Progress 6455 / 9694 Time remaining: 2s Progress 6456 / 9694 Time remaining: 2s Progress 6457 / 9694 Time remaining: 2s Progress 6458 / 9694 Time remaining: 2s Progress 6459 / 9694 Time remaining: 2s Progress 6460 / 9694 Time remaining: 2s Progress 6461 / 9694 Time remaining: 2s Progress 6462 / 9694 Time remaining: 2s Progress 6463 / 9694 Time remaining: 2s Progress 6464 / 9694 Time remaining: 2s Progress 6465 / 9694 Time remaining: 2s Progress 6466 / 9694 Time remaining: 2s Progress 6467 / 9694 Time remaining: 2s Progress 6468 / 9694 Time remaining: 2s Progress 6469 / 9694 Time remaining: 2s Progress 6470 / 9694 Time remaining: 2s Progress 6471 / 9694 Time remaining: 2s Progress 6472 / 9694 Time remaining: 2s Progress 6473 / 9694 Time remaining: 2s Progress 6474 / 9694 Time remaining: 2s Progress 6475 / 9694 Time remaining: 2s Progress 6476 / 9694 Time remaining: 2s Progress 6477 / 9694 Time remaining: 2s Progress 6478 / 9694 Time remaining: 2s Progress 6479 / 9694 Time remaining: 2s Progress 6480 / 9694 Time remaining: 2s Progress 6481 / 9694 Time remaining: 2s Progress 6482 / 9694 Time remaining: 2s Progress 6483 / 9694 Time remaining: 2s Progress 6484 / 9694 Time remaining: 2s Progress 6485 / 9694 Time remaining: 2s Progress 6486 / 9694 Time remaining: 2s Progress 6487 / 9694 Time remaining: 2s Progress 6488 / 9694 Time remaining: 2s Progress 6489 / 9694 Time remaining: 2s Progress 6490 / 9694 Time remaining: 2s Progress 6491 / 9694 Time remaining: 2s Progress 6492 / 9694 Time remaining: 2s Progress 6493 / 9694 Time remaining: 2s Progress 6494 / 9694 Time remaining: 2s Progress 6495 / 9694 Time remaining: 2s Progress 6496 / 9694 Time remaining: 2s Progress 6497 / 9694 Time remaining: 2s Progress 6498 / 9694 Time remaining: 2s Progress 6499 / 9694 Time remaining: 2s Progress 6500 / 9694 Time remaining: 2s Progress 6501 / 9694 Time remaining: 2s Progress 6502 / 9694 Time remaining: 2s Progress 6503 / 9694 Time remaining: 2s Progress 6504 / 9694 Time remaining: 2s Progress 6505 / 9694 Time remaining: 2s Progress 6506 / 9694 Time remaining: 2s Progress 6507 / 9694 Time remaining: 2s Progress 6508 / 9694 Time remaining: 2s Progress 6509 / 9694 Time remaining: 2s Progress 6510 / 9694 Time remaining: 2s Progress 6511 / 9694 Time remaining: 2s Progress 6512 / 9694 Time remaining: 2s Progress 6513 / 9694 Time remaining: 2s Progress 6514 / 9694 Time remaining: 2s Progress 6515 / 9694 Time remaining: 2s Progress 6516 / 9694 Time remaining: 2s Progress 6517 / 9694 Time remaining: 2s Progress 6518 / 9694 Time remaining: 2s Progress 6519 / 9694 Time remaining: 2s Progress 6520 / 9694 Time remaining: 2s Progress 6521 / 9694 Time remaining: 2s Progress 6522 / 9694 Time remaining: 2s Progress 6523 / 9694 Time remaining: 2s Progress 6524 / 9694 Time remaining: 2s Progress 6525 / 9694 Time remaining: 2s Progress 6526 / 9694 Time remaining: 2s Progress 6527 / 9694 Time remaining: 2s Progress 6528 / 9694 Time remaining: 2s Progress 6529 / 9694 Time remaining: 2s Progress 6530 / 9694 Time remaining: 2s Progress 6531 / 9694 Time remaining: 2s Progress 6532 / 9694 Time remaining: 2s Progress 6533 / 9694 Time remaining: 2s Progress 6534 / 9694 Time remaining: 2s Progress 6535 / 9694 Time remaining: 2s Progress 6536 / 9694 Time remaining: 2s Progress 6537 / 9694 Time remaining: 2s Progress 6538 / 9694 Time remaining: 2s Progress 6539 / 9694 Time remaining: 2s Progress 6540 / 9694 Time remaining: 2s Progress 6541 / 9694 Time remaining: 2s Progress 6542 / 9694 Time remaining: 2s Progress 6543 / 9694 Time remaining: 2s Progress 6544 / 9694 Time remaining: 2s Progress 6545 / 9694 Time remaining: 2s Progress 6546 / 9694 Time remaining: 2s Progress 6547 / 9694 Time remaining: 2s Progress 6548 / 9694 Time remaining: 2s Progress 6549 / 9694 Time remaining: 2s Progress 6550 / 9694 Time remaining: 2s Progress 6551 / 9694 Time remaining: 2s Progress 6552 / 9694 Time remaining: 2s Progress 6553 / 9694 Time remaining: 2s Progress 6554 / 9694 Time remaining: 2s Progress 6555 / 9694 Time remaining: 2s Progress 6556 / 9694 Time remaining: 2s Progress 6557 / 9694 Time remaining: 2s Progress 6558 / 9694 Time remaining: 2s Progress 6559 / 9694 Time remaining: 2s Progress 6560 / 9694 Time remaining: 2s Progress 6561 / 9694 Time remaining: 2s Progress 6562 / 9694 Time remaining: 2s Progress 6563 / 9694 Time remaining: 2s Progress 6564 / 9694 Time remaining: 2s Progress 6565 / 9694 Time remaining: 2s Progress 6566 / 9694 Time remaining: 2s Progress 6567 / 9694 Time remaining: 2s Progress 6568 / 9694 Time remaining: 2s Progress 6569 / 9694 Time remaining: 2s Progress 6570 / 9694 Time remaining: 2s Progress 6571 / 9694 Time remaining: 2s Progress 6572 / 9694 Time remaining: 2s Progress 6573 / 9694 Time remaining: 2s Progress 6574 / 9694 Time remaining: 2s Progress 6575 / 9694 Time remaining: 2s Progress 6576 / 9694 Time remaining: 2s Progress 6577 / 9694 Time remaining: 2s Progress 6578 / 9694 Time remaining: 2s Progress 6579 / 9694 Time remaining: 2s Progress 6580 / 9694 Time remaining: 2s Progress 6581 / 9694 Time remaining: 2s Progress 6582 / 9694 Time remaining: 2s Progress 6583 / 9694 Time remaining: 2s Progress 6584 / 9694 Time remaining: 2s Progress 6585 / 9694 Time remaining: 2s Progress 6586 / 9694 Time remaining: 2s Progress 6587 / 9694 Time remaining: 2s Progress 6588 / 9694 Time remaining: 2s Progress 6589 / 9694 Time remaining: 2s Progress 6590 / 9694 Time remaining: 2s Progress 6591 / 9694 Time remaining: 2s Progress 6592 / 9694 Time remaining: 2s Progress 6593 / 9694 Time remaining: 2s Progress 6594 / 9694 Time remaining: 2s Progress 6595 / 9694 Time remaining: 2s Progress 6596 / 9694 Time remaining: 2s Progress 6597 / 9694 Time remaining: 2s Progress 6598 / 9694 Time remaining: 2s Progress 6599 / 9694 Time remaining: 2s Progress 6600 / 9694 Time remaining: 2s Progress 6601 / 9694 Time remaining: 2s Progress 6602 / 9694 Time remaining: 2s Progress 6603 / 9694 Time remaining: 2s Progress 6604 / 9694 Time remaining: 2s Progress 6605 / 9694 Time remaining: 2s Progress 6606 / 9694 Time remaining: 2s Progress 6607 / 9694 Time remaining: 2s Progress 6608 / 9694 Time remaining: 2s Progress 6609 / 9694 Time remaining: 2s Progress 6610 / 9694 Time remaining: 2s Progress 6611 / 9694 Time remaining: 2s Progress 6612 / 9694 Time remaining: 2s Progress 6613 / 9694 Time remaining: 2s Progress 6614 / 9694 Time remaining: 2s Progress 6615 / 9694 Time remaining: 2s Progress 6616 / 9694 Time remaining: 2s Progress 6617 / 9694 Time remaining: 2s Progress 6618 / 9694 Time remaining: 2s Progress 6619 / 9694 Time remaining: 2s Progress 6620 / 9694 Time remaining: 2s Progress 6621 / 9694 Time remaining: 2s Progress 6622 / 9694 Time remaining: 2s Progress 6623 / 9694 Time remaining: 2s Progress 6624 / 9694 Time remaining: 2s Progress 6625 / 9694 Time remaining: 2s Progress 6626 / 9694 Time remaining: 2s Progress 6627 / 9694 Time remaining: 2s Progress 6628 / 9694 Time remaining: 2s Progress 6629 / 9694 Time remaining: 2s Progress 6630 / 9694 Time remaining: 2s Progress 6631 / 9694 Time remaining: 2s Progress 6632 / 9694 Time remaining: 2s Progress 6633 / 9694 Time remaining: 2s Progress 6634 / 9694 Time remaining: 2s Progress 6635 / 9694 Time remaining: 2s Progress 6636 / 9694 Time remaining: 2s Progress 6637 / 9694 Time remaining: 2s Progress 6638 / 9694 Time remaining: 2s Progress 6639 / 9694 Time remaining: 2s Progress 6640 / 9694 Time remaining: 2s Progress 6641 / 9694 Time remaining: 2s Progress 6642 / 9694 Time remaining: 2s Progress 6643 / 9694 Time remaining: 2s Progress 6644 / 9694 Time remaining: 2s Progress 6645 / 9694 Time remaining: 2s Progress 6646 / 9694 Time remaining: 2s Progress 6647 / 9694 Time remaining: 2s Progress 6648 / 9694 Time remaining: 2s Progress 6649 / 9694 Time remaining: 2s Progress 6650 / 9694 Time remaining: 2s Progress 6651 / 9694 Time remaining: 2s Progress 6652 / 9694 Time remaining: 2s Progress 6653 / 9694 Time remaining: 2s Progress 6654 / 9694 Time remaining: 2s Progress 6655 / 9694 Time remaining: 2s Progress 6656 / 9694 Time remaining: 2s Progress 6657 / 9694 Time remaining: 2s Progress 6658 / 9694 Time remaining: 2s Progress 6659 / 9694 Time remaining: 2s Progress 6660 / 9694 Time remaining: 2s Progress 6661 / 9694 Time remaining: 2s Progress 6662 / 9694 Time remaining: 2s Progress 6663 / 9694 Time remaining: 2s Progress 6664 / 9694 Time remaining: 2s Progress 6665 / 9694 Time remaining: 2s Progress 6666 / 9694 Time remaining: 2s Progress 6667 / 9694 Time remaining: 2s Progress 6668 / 9694 Time remaining: 2s Progress 6669 / 9694 Time remaining: 2s Progress 6670 / 9694 Time remaining: 2s Progress 6671 / 9694 Time remaining: 2s Progress 6672 / 9694 Time remaining: 2s Progress 6673 / 9694 Time remaining: 2s Progress 6674 / 9694 Time remaining: 2s Progress 6675 / 9694 Time remaining: 2s Progress 6676 / 9694 Time remaining: 2s Progress 6677 / 9694 Time remaining: 2s Progress 6678 / 9694 Time remaining: 2s Progress 6679 / 9694 Time remaining: 2s Progress 6680 / 9694 Time remaining: 2s Progress 6681 / 9694 Time remaining: 2s Progress 6682 / 9694 Time remaining: 2s Progress 6683 / 9694 Time remaining: 2s Progress 6684 / 9694 Time remaining: 2s Progress 6685 / 9694 Time remaining: 2s Progress 6686 / 9694 Time remaining: 2s Progress 6687 / 9694 Time remaining: 2s Progress 6688 / 9694 Time remaining: 2s Progress 6689 / 9694 Time remaining: 2s Progress 6690 / 9694 Time remaining: 2s Progress 6691 / 9694 Time remaining: 2s Progress 6692 / 9694 Time remaining: 2s Progress 6693 / 9694 Time remaining: 2s Progress 6694 / 9694 Time remaining: 2s Progress 6695 / 9694 Time remaining: 2s Progress 6696 / 9694 Time remaining: 2s Progress 6697 / 9694 Time remaining: 2s Progress 6698 / 9694 Time remaining: 2s Progress 6699 / 9694 Time remaining: 2s Progress 6700 / 9694 Time remaining: 2s Progress 6701 / 9694 Time remaining: 2s Progress 6702 / 9694 Time remaining: 2s Progress 6703 / 9694 Time remaining: 2s Progress 6704 / 9694 Time remaining: 2s Progress 6705 / 9694 Time remaining: 2s Progress 6706 / 9694 Time remaining: 2s Progress 6707 / 9694 Time remaining: 2s Progress 6708 / 9694 Time remaining: 2s Progress 6709 / 9694 Time remaining: 2s Progress 6710 / 9694 Time remaining: 2s Progress 6711 / 9694 Time remaining: 2s Progress 6712 / 9694 Time remaining: 2s Progress 6713 / 9694 Time remaining: 2s Progress 6714 / 9694 Time remaining: 2s Progress 6715 / 9694 Time remaining: 2s Progress 6716 / 9694 Time remaining: 2s Progress 6717 / 9694 Time remaining: 2s Progress 6718 / 9694 Time remaining: 2s Progress 6719 / 9694 Time remaining: 2s Progress 6720 / 9694 Time remaining: 2s Progress 6721 / 9694 Time remaining: 2s Progress 6722 / 9694 Time remaining: 2s Progress 6723 / 9694 Time remaining: 2s Progress 6724 / 9694 Time remaining: 2s Progress 6725 / 9694 Time remaining: 2s Progress 6726 / 9694 Time remaining: 2s Progress 6727 / 9694 Time remaining: 2s Progress 6728 / 9694 Time remaining: 2s Progress 6729 / 9694 Time remaining: 2s Progress 6730 / 9694 Time remaining: 2s Progress 6731 / 9694 Time remaining: 2s Progress 6732 / 9694 Time remaining: 2s Progress 6733 / 9694 Time remaining: 2s Progress 6734 / 9694 Time remaining: 2s Progress 6735 / 9694 Time remaining: 2s Progress 6736 / 9694 Time remaining: 2s Progress 6737 / 9694 Time remaining: 2s Progress 6738 / 9694 Time remaining: 2s Progress 6739 / 9694 Time remaining: 2s Progress 6740 / 9694 Time remaining: 2s Progress 6741 / 9694 Time remaining: 2s Progress 6742 / 9694 Time remaining: 2s Progress 6743 / 9694 Time remaining: 2s Progress 6744 / 9694 Time remaining: 2s Progress 6745 / 9694 Time remaining: 2s Progress 6746 / 9694 Time remaining: 2s Progress 6747 / 9694 Time remaining: 2s Progress 6748 / 9694 Time remaining: 2s Progress 6749 / 9694 Time remaining: 2s Progress 6750 / 9694 Time remaining: 2s Progress 6751 / 9694 Time remaining: 2s Progress 6752 / 9694 Time remaining: 2s Progress 6753 / 9694 Time remaining: 2s Progress 6754 / 9694 Time remaining: 2s Progress 6755 / 9694 Time remaining: 2s Progress 6756 / 9694 Time remaining: 2s Progress 6757 / 9694 Time remaining: 2s Progress 6758 / 9694 Time remaining: 2s Progress 6759 / 9694 Time remaining: 2s Progress 6760 / 9694 Time remaining: 2s Progress 6761 / 9694 Time remaining: 2s Progress 6762 / 9694 Time remaining: 2s Progress 6763 / 9694 Time remaining: 2s Progress 6764 / 9694 Time remaining: 2s Progress 6765 / 9694 Time remaining: 2s Progress 6766 / 9694 Time remaining: 2s Progress 6767 / 9694 Time remaining: 2s Progress 6768 / 9694 Time remaining: 2s Progress 6769 / 9694 Time remaining: 2s Progress 6770 / 9694 Time remaining: 2s Progress 6771 / 9694 Time remaining: 2s Progress 6772 / 9694 Time remaining: 2s Progress 6773 / 9694 Time remaining: 2s Progress 6774 / 9694 Time remaining: 2s Progress 6775 / 9694 Time remaining: 2s Progress 6776 / 9694 Time remaining: 2s Progress 6777 / 9694 Time remaining: 2s Progress 6778 / 9694 Time remaining: 2s Progress 6779 / 9694 Time remaining: 2s Progress 6780 / 9694 Time remaining: 2s Progress 6781 / 9694 Time remaining: 2s Progress 6782 / 9694 Time remaining: 2s Progress 6783 / 9694 Time remaining: 2s Progress 6784 / 9694 Time remaining: 2s Progress 6785 / 9694 Time remaining: 2s Progress 6786 / 9694 Time remaining: 2s Progress 6787 / 9694 Time remaining: 2s Progress 6788 / 9694 Time remaining: 2s Progress 6789 / 9694 Time remaining: 2s Progress 6790 / 9694 Time remaining: 2s Progress 6791 / 9694 Time remaining: 2s Progress 6792 / 9694 Time remaining: 2s Progress 6793 / 9694 Time remaining: 2s Progress 6794 / 9694 Time remaining: 2s Progress 6795 / 9694 Time remaining: 2s Progress 6796 / 9694 Time remaining: 2s Progress 6797 / 9694 Time remaining: 2s Progress 6798 / 9694 Time remaining: 2s Progress 6799 / 9694 Time remaining: 2s Progress 6800 / 9694 Time remaining: 2s Progress 6801 / 9694 Time remaining: 2s Progress 6802 / 9694 Time remaining: 2s Progress 6803 / 9694 Time remaining: 2s Progress 6804 / 9694 Time remaining: 2s Progress 6805 / 9694 Time remaining: 2s Progress 6806 / 9694 Time remaining: 2s Progress 6807 / 9694 Time remaining: 2s Progress 6808 / 9694 Time remaining: 2s Progress 6809 / 9694 Time remaining: 2s Progress 6810 / 9694 Time remaining: 2s Progress 6811 / 9694 Time remaining: 2s Progress 6812 / 9694 Time remaining: 2s Progress 6813 / 9694 Time remaining: 2s Progress 6814 / 9694 Time remaining: 2s Progress 6815 / 9694 Time remaining: 2s Progress 6816 / 9694 Time remaining: 2s Progress 6817 / 9694 Time remaining: 2s Progress 6818 / 9694 Time remaining: 2s Progress 6819 / 9694 Time remaining: 2s Progress 6820 / 9694 Time remaining: 2s Progress 6821 / 9694 Time remaining: 2s Progress 6822 / 9694 Time remaining: 2s Progress 6823 / 9694 Time remaining: 2s Progress 6824 / 9694 Time remaining: 2s Progress 6825 / 9694 Time remaining: 2s Progress 6826 / 9694 Time remaining: 2s Progress 6827 / 9694 Time remaining: 2s Progress 6828 / 9694 Time remaining: 2s Progress 6829 / 9694 Time remaining: 2s Progress 6830 / 9694 Time remaining: 2s Progress 6831 / 9694 Time remaining: 2s Progress 6832 / 9694 Time remaining: 2s Progress 6833 / 9694 Time remaining: 2s Progress 6834 / 9694 Time remaining: 2s Progress 6835 / 9694 Time remaining: 2s Progress 6836 / 9694 Time remaining: 2s Progress 6837 / 9694 Time remaining: 2s Progress 6838 / 9694 Time remaining: 2s Progress 6839 / 9694 Time remaining: 2s Progress 6840 / 9694 Time remaining: 2s Progress 6841 / 9694 Time remaining: 2s Progress 6842 / 9694 Time remaining: 2s Progress 6843 / 9694 Time remaining: 2s Progress 6844 / 9694 Time remaining: 2s Progress 6845 / 9694 Time remaining: 2s Progress 6846 / 9694 Time remaining: 2s Progress 6847 / 9694 Time remaining: 2s Progress 6848 / 9694 Time remaining: 2s Progress 6849 / 9694 Time remaining: 2s Progress 6850 / 9694 Time remaining: 2s Progress 6851 / 9694 Time remaining: 2s Progress 6852 / 9694 Time remaining: 2s Progress 6853 / 9694 Time remaining: 2s Progress 6854 / 9694 Time remaining: 2s Progress 6855 / 9694 Time remaining: 2s Progress 6856 / 9694 Time remaining: 2s Progress 6857 / 9694 Time remaining: 2s Progress 6858 / 9694 Time remaining: 2s Progress 6859 / 9694 Time remaining: 2s Progress 6860 / 9694 Time remaining: 2s Progress 6861 / 9694 Time remaining: 2s Progress 6862 / 9694 Time remaining: 2s Progress 6863 / 9694 Time remaining: 2s Progress 6864 / 9694 Time remaining: 2s Progress 6865 / 9694 Time remaining: 2s Progress 6866 / 9694 Time remaining: 2s Progress 6867 / 9694 Time remaining: 2s Progress 6868 / 9694 Time remaining: 2s Progress 6869 / 9694 Time remaining: 2s Progress 6870 / 9694 Time remaining: 2s Progress 6871 / 9694 Time remaining: 2s Progress 6872 / 9694 Time remaining: 2s Progress 6873 / 9694 Time remaining: 2s Progress 6874 / 9694 Time remaining: 2s Progress 6875 / 9694 Time remaining: 2s Progress 6876 / 9694 Time remaining: 2s Progress 6877 / 9694 Time remaining: 2s Progress 6878 / 9694 Time remaining: 2s Progress 6879 / 9694 Time remaining: 2s Progress 6880 / 9694 Time remaining: 2s Progress 6881 / 9694 Time remaining: 2s Progress 6882 / 9694 Time remaining: 2s Progress 6883 / 9694 Time remaining: 2s Progress 6884 / 9694 Time remaining: 2s Progress 6885 / 9694 Time remaining: 2s Progress 6886 / 9694 Time remaining: 2s Progress 6887 / 9694 Time remaining: 2s Progress 6888 / 9694 Time remaining: 2s Progress 6889 / 9694 Time remaining: 2s Progress 6890 / 9694 Time remaining: 2s Progress 6891 / 9694 Time remaining: 2s Progress 6892 / 9694 Time remaining: 2s Progress 6893 / 9694 Time remaining: 2s Progress 6894 / 9694 Time remaining: 2s Progress 6895 / 9694 Time remaining: 2s Progress 6896 / 9694 Time remaining: 2s Progress 6897 / 9694 Time remaining: 2s Progress 6898 / 9694 Time remaining: 2s Progress 6899 / 9694 Time remaining: 2s Progress 6900 / 9694 Time remaining: 2s Progress 6901 / 9694 Time remaining: 2s Progress 6902 / 9694 Time remaining: 2s Progress 6903 / 9694 Time remaining: 2s Progress 6904 / 9694 Time remaining: 2s Progress 6905 / 9694 Time remaining: 2s Progress 6906 / 9694 Time remaining: 2s Progress 6907 / 9694 Time remaining: 2s Progress 6908 / 9694 Time remaining: 2s Progress 6909 / 9694 Time remaining: 2s Progress 6910 / 9694 Time remaining: 2s Progress 6911 / 9694 Time remaining: 2s Progress 6912 / 9694 Time remaining: 2s Progress 6913 / 9694 Time remaining: 2s Progress 6914 / 9694 Time remaining: 2s Progress 6915 / 9694 Time remaining: 2s Progress 6916 / 9694 Time remaining: 2s Progress 6917 / 9694 Time remaining: 2s Progress 6918 / 9694 Time remaining: 2s Progress 6919 / 9694 Time remaining: 2s Progress 6920 / 9694 Time remaining: 2s Progress 6921 / 9694 Time remaining: 2s Progress 6922 / 9694 Time remaining: 2s Progress 6923 / 9694 Time remaining: 2s Progress 6924 / 9694 Time remaining: 2s Progress 6925 / 9694 Time remaining: 2s Progress 6926 / 9694 Time remaining: 2s Progress 6927 / 9694 Time remaining: 2s Progress 6928 / 9694 Time remaining: 2s Progress 6929 / 9694 Time remaining: 2s Progress 6930 / 9694 Time remaining: 2s Progress 6931 / 9694 Time remaining: 2s Progress 6932 / 9694 Time remaining: 2s Progress 6933 / 9694 Time remaining: 2s Progress 6934 / 9694 Time remaining: 2s Progress 6935 / 9694 Time remaining: 2s Progress 6936 / 9694 Time remaining: 2s Progress 6937 / 9694 Time remaining: 2s Progress 6938 / 9694 Time remaining: 2s Progress 6939 / 9694 Time remaining: 2s Progress 6940 / 9694 Time remaining: 2s Progress 6941 / 9694 Time remaining: 2s Progress 6942 / 9694 Time remaining: 2s Progress 6943 / 9694 Time remaining: 2s Progress 6944 / 9694 Time remaining: 2s Progress 6945 / 9694 Time remaining: 2s Progress 6946 / 9694 Time remaining: 2s Progress 6947 / 9694 Time remaining: 2s Progress 6948 / 9694 Time remaining: 2s Progress 6949 / 9694 Time remaining: 2s Progress 6950 / 9694 Time remaining: 2s Progress 6951 / 9694 Time remaining: 2s Progress 6952 / 9694 Time remaining: 2s Progress 6953 / 9694 Time remaining: 2s Progress 6954 / 9694 Time remaining: 2s Progress 6955 / 9694 Time remaining: 2s Progress 6956 / 9694 Time remaining: 2s Progress 6957 / 9694 Time remaining: 2s Progress 6958 / 9694 Time remaining: 2s Progress 6959 / 9694 Time remaining: 2s Progress 6960 / 9694 Time remaining: 2s Progress 6961 / 9694 Time remaining: 2s Progress 6962 / 9694 Time remaining: 2s Progress 6963 / 9694 Time remaining: 2s Progress 6964 / 9694 Time remaining: 2s Progress 6965 / 9694 Time remaining: 2s Progress 6966 / 9694 Time remaining: 2s Progress 6967 / 9694 Time remaining: 2s Progress 6968 / 9694 Time remaining: 2s Progress 6969 / 9694 Time remaining: 2s Progress 6970 / 9694 Time remaining: 2s Progress 6971 / 9694 Time remaining: 2s Progress 6972 / 9694 Time remaining: 2s Progress 6973 / 9694 Time remaining: 2s Progress 6974 / 9694 Time remaining: 2s Progress 6975 / 9694 Time remaining: 2s Progress 6976 / 9694 Time remaining: 1s Progress 6977 / 9694 Time remaining: 1s Progress 6978 / 9694 Time remaining: 1s Progress 6979 / 9694 Time remaining: 1s Progress 6980 / 9694 Time remaining: 1s Progress 6981 / 9694 Time remaining: 1s Progress 6982 / 9694 Time remaining: 1s Progress 6983 / 9694 Time remaining: 1s Progress 6984 / 9694 Time remaining: 1s Progress 6985 / 9694 Time remaining: 1s Progress 6986 / 9694 Time remaining: 1s Progress 6987 / 9694 Time remaining: 1s Progress 6988 / 9694 Time remaining: 1s Progress 6989 / 9694 Time remaining: 1s Progress 6990 / 9694 Time remaining: 1s Progress 6991 / 9694 Time remaining: 1s Progress 6992 / 9694 Time remaining: 1s Progress 6993 / 9694 Time remaining: 1s Progress 6994 / 9694 Time remaining: 1s Progress 6995 / 9694 Time remaining: 1s Progress 6996 / 9694 Time remaining: 1s Progress 6997 / 9694 Time remaining: 1s Progress 6998 / 9694 Time remaining: 1s Progress 6999 / 9694 Time remaining: 1s Progress 7000 / 9694 Time remaining: 1s Progress 7001 / 9694 Time remaining: 1s Progress 7002 / 9694 Time remaining: 1s Progress 7003 / 9694 Time remaining: 1s Progress 7004 / 9694 Time remaining: 1s Progress 7005 / 9694 Time remaining: 1s Progress 7006 / 9694 Time remaining: 1s Progress 7007 / 9694 Time remaining: 1s Progress 7008 / 9694 Time remaining: 1s Progress 7009 / 9694 Time remaining: 1s Progress 7010 / 9694 Time remaining: 1s Progress 7011 / 9694 Time remaining: 1s Progress 7012 / 9694 Time remaining: 1s Progress 7013 / 9694 Time remaining: 1s Progress 7014 / 9694 Time remaining: 1s Progress 7015 / 9694 Time remaining: 1s Progress 7016 / 9694 Time remaining: 1s Progress 7017 / 9694 Time remaining: 1s Progress 7018 / 9694 Time remaining: 1s Progress 7019 / 9694 Time remaining: 1s Progress 7020 / 9694 Time remaining: 1s Progress 7021 / 9694 Time remaining: 1s Progress 7022 / 9694 Time remaining: 1s Progress 7023 / 9694 Time remaining: 1s Progress 7024 / 9694 Time remaining: 1s Progress 7025 / 9694 Time remaining: 1s Progress 7026 / 9694 Time remaining: 1s Progress 7027 / 9694 Time remaining: 1s Progress 7028 / 9694 Time remaining: 1s Progress 7029 / 9694 Time remaining: 1s Progress 7030 / 9694 Time remaining: 1s Progress 7031 / 9694 Time remaining: 1s Progress 7032 / 9694 Time remaining: 1s Progress 7033 / 9694 Time remaining: 1s Progress 7034 / 9694 Time remaining: 1s Progress 7035 / 9694 Time remaining: 1s Progress 7036 / 9694 Time remaining: 1s Progress 7037 / 9694 Time remaining: 1s Progress 7038 / 9694 Time remaining: 1s Progress 7039 / 9694 Time remaining: 1s Progress 7040 / 9694 Time remaining: 1s Progress 7041 / 9694 Time remaining: 1s Progress 7042 / 9694 Time remaining: 1s Progress 7043 / 9694 Time remaining: 1s Progress 7044 / 9694 Time remaining: 1s Progress 7045 / 9694 Time remaining: 1s Progress 7046 / 9694 Time remaining: 1s Progress 7047 / 9694 Time remaining: 1s Progress 7048 / 9694 Time remaining: 1s Progress 7049 / 9694 Time remaining: 1s Progress 7050 / 9694 Time remaining: 1s Progress 7051 / 9694 Time remaining: 1s Progress 7052 / 9694 Time remaining: 1s Progress 7053 / 9694 Time remaining: 1s Progress 7054 / 9694 Time remaining: 1s Progress 7055 / 9694 Time remaining: 1s Progress 7056 / 9694 Time remaining: 1s Progress 7057 / 9694 Time remaining: 1s Progress 7058 / 9694 Time remaining: 1s Progress 7059 / 9694 Time remaining: 1s Progress 7060 / 9694 Time remaining: 1s Progress 7061 / 9694 Time remaining: 1s Progress 7062 / 9694 Time remaining: 1s Progress 7063 / 9694 Time remaining: 1s Progress 7064 / 9694 Time remaining: 1s Progress 7065 / 9694 Time remaining: 1s Progress 7066 / 9694 Time remaining: 1s Progress 7067 / 9694 Time remaining: 1s Progress 7068 / 9694 Time remaining: 1s Progress 7069 / 9694 Time remaining: 1s Progress 7070 / 9694 Time remaining: 1s Progress 7071 / 9694 Time remaining: 1s Progress 7072 / 9694 Time remaining: 1s Progress 7073 / 9694 Time remaining: 1s Progress 7074 / 9694 Time remaining: 1s Progress 7075 / 9694 Time remaining: 1s Progress 7076 / 9694 Time remaining: 1s Progress 7077 / 9694 Time remaining: 1s Progress 7078 / 9694 Time remaining: 1s Progress 7079 / 9694 Time remaining: 1s Progress 7080 / 9694 Time remaining: 1s Progress 7081 / 9694 Time remaining: 1s Progress 7082 / 9694 Time remaining: 1s Progress 7083 / 9694 Time remaining: 1s Progress 7084 / 9694 Time remaining: 1s Progress 7085 / 9694 Time remaining: 1s Progress 7086 / 9694 Time remaining: 1s Progress 7087 / 9694 Time remaining: 1s Progress 7088 / 9694 Time remaining: 1s Progress 7089 / 9694 Time remaining: 1s Progress 7090 / 9694 Time remaining: 1s Progress 7091 / 9694 Time remaining: 1s Progress 7092 / 9694 Time remaining: 1s Progress 7093 / 9694 Time remaining: 1s Progress 7094 / 9694 Time remaining: 1s Progress 7095 / 9694 Time remaining: 1s Progress 7096 / 9694 Time remaining: 1s Progress 7097 / 9694 Time remaining: 1s Progress 7098 / 9694 Time remaining: 1s Progress 7099 / 9694 Time remaining: 1s Progress 7100 / 9694 Time remaining: 1s Progress 7101 / 9694 Time remaining: 1s Progress 7102 / 9694 Time remaining: 1s Progress 7103 / 9694 Time remaining: 1s Progress 7104 / 9694 Time remaining: 1s Progress 7105 / 9694 Time remaining: 1s Progress 7106 / 9694 Time remaining: 1s Progress 7107 / 9694 Time remaining: 1s Progress 7108 / 9694 Time remaining: 1s Progress 7109 / 9694 Time remaining: 1s Progress 7110 / 9694 Time remaining: 1s Progress 7111 / 9694 Time remaining: 1s Progress 7112 / 9694 Time remaining: 1s Progress 7113 / 9694 Time remaining: 1s Progress 7114 / 9694 Time remaining: 1s Progress 7115 / 9694 Time remaining: 1s Progress 7116 / 9694 Time remaining: 1s Progress 7117 / 9694 Time remaining: 1s Progress 7118 / 9694 Time remaining: 1s Progress 7119 / 9694 Time remaining: 1s Progress 7120 / 9694 Time remaining: 1s Progress 7121 / 9694 Time remaining: 1s Progress 7122 / 9694 Time remaining: 1s Progress 7123 / 9694 Time remaining: 1s Progress 7124 / 9694 Time remaining: 1s Progress 7125 / 9694 Time remaining: 1s Progress 7126 / 9694 Time remaining: 1s Progress 7127 / 9694 Time remaining: 1s Progress 7128 / 9694 Time remaining: 1s Progress 7129 / 9694 Time remaining: 1s Progress 7130 / 9694 Time remaining: 1s Progress 7131 / 9694 Time remaining: 1s Progress 7132 / 9694 Time remaining: 1s Progress 7133 / 9694 Time remaining: 1s Progress 7134 / 9694 Time remaining: 1s Progress 7135 / 9694 Time remaining: 1s Progress 7136 / 9694 Time remaining: 1s Progress 7137 / 9694 Time remaining: 1s Progress 7138 / 9694 Time remaining: 1s Progress 7139 / 9694 Time remaining: 1s Progress 7140 / 9694 Time remaining: 1s Progress 7141 / 9694 Time remaining: 1s Progress 7142 / 9694 Time remaining: 1s Progress 7143 / 9694 Time remaining: 1s Progress 7144 / 9694 Time remaining: 1s Progress 7145 / 9694 Time remaining: 1s Progress 7146 / 9694 Time remaining: 1s Progress 7147 / 9694 Time remaining: 1s Progress 7148 / 9694 Time remaining: 1s Progress 7149 / 9694 Time remaining: 1s Progress 7150 / 9694 Time remaining: 1s Progress 7151 / 9694 Time remaining: 1s Progress 7152 / 9694 Time remaining: 1s Progress 7153 / 9694 Time remaining: 1s Progress 7154 / 9694 Time remaining: 1s Progress 7155 / 9694 Time remaining: 1s Progress 7156 / 9694 Time remaining: 1s Progress 7157 / 9694 Time remaining: 1s Progress 7158 / 9694 Time remaining: 1s Progress 7159 / 9694 Time remaining: 1s Progress 7160 / 9694 Time remaining: 1s Progress 7161 / 9694 Time remaining: 1s Progress 7162 / 9694 Time remaining: 1s Progress 7163 / 9694 Time remaining: 1s Progress 7164 / 9694 Time remaining: 1s Progress 7165 / 9694 Time remaining: 1s Progress 7166 / 9694 Time remaining: 1s Progress 7167 / 9694 Time remaining: 1s Progress 7168 / 9694 Time remaining: 1s Progress 7169 / 9694 Time remaining: 1s Progress 7170 / 9694 Time remaining: 1s Progress 7171 / 9694 Time remaining: 1s Progress 7172 / 9694 Time remaining: 1s Progress 7173 / 9694 Time remaining: 1s Progress 7174 / 9694 Time remaining: 1s Progress 7175 / 9694 Time remaining: 1s Progress 7176 / 9694 Time remaining: 1s Progress 7177 / 9694 Time remaining: 1s Progress 7178 / 9694 Time remaining: 1s Progress 7179 / 9694 Time remaining: 1s Progress 7180 / 9694 Time remaining: 1s Progress 7181 / 9694 Time remaining: 1s Progress 7182 / 9694 Time remaining: 1s Progress 7183 / 9694 Time remaining: 1s Progress 7184 / 9694 Time remaining: 1s Progress 7185 / 9694 Time remaining: 1s Progress 7186 / 9694 Time remaining: 1s Progress 7187 / 9694 Time remaining: 1s Progress 7188 / 9694 Time remaining: 1s Progress 7189 / 9694 Time remaining: 1s Progress 7190 / 9694 Time remaining: 1s Progress 7191 / 9694 Time remaining: 1s Progress 7192 / 9694 Time remaining: 1s Progress 7193 / 9694 Time remaining: 1s Progress 7194 / 9694 Time remaining: 1s Progress 7195 / 9694 Time remaining: 1s Progress 7196 / 9694 Time remaining: 1s Progress 7197 / 9694 Time remaining: 1s Progress 7198 / 9694 Time remaining: 1s Progress 7199 / 9694 Time remaining: 1s Progress 7200 / 9694 Time remaining: 1s Progress 7201 / 9694 Time remaining: 1s Progress 7202 / 9694 Time remaining: 1s Progress 7203 / 9694 Time remaining: 1s Progress 7204 / 9694 Time remaining: 1s Progress 7205 / 9694 Time remaining: 1s Progress 7206 / 9694 Time remaining: 1s Progress 7207 / 9694 Time remaining: 1s Progress 7208 / 9694 Time remaining: 1s Progress 7209 / 9694 Time remaining: 1s Progress 7210 / 9694 Time remaining: 1s Progress 7211 / 9694 Time remaining: 1s Progress 7212 / 9694 Time remaining: 1s Progress 7213 / 9694 Time remaining: 1s Progress 7214 / 9694 Time remaining: 1s Progress 7215 / 9694 Time remaining: 1s Progress 7216 / 9694 Time remaining: 1s Progress 7217 / 9694 Time remaining: 1s Progress 7218 / 9694 Time remaining: 1s Progress 7219 / 9694 Time remaining: 1s Progress 7220 / 9694 Time remaining: 1s Progress 7221 / 9694 Time remaining: 1s Progress 7222 / 9694 Time remaining: 1s Progress 7223 / 9694 Time remaining: 1s Progress 7224 / 9694 Time remaining: 1s Progress 7225 / 9694 Time remaining: 1s Progress 7226 / 9694 Time remaining: 1s Progress 7227 / 9694 Time remaining: 1s Progress 7228 / 9694 Time remaining: 1s Progress 7229 / 9694 Time remaining: 1s Progress 7230 / 9694 Time remaining: 1s Progress 7231 / 9694 Time remaining: 1s Progress 7232 / 9694 Time remaining: 1s Progress 7233 / 9694 Time remaining: 1s Progress 7234 / 9694 Time remaining: 1s Progress 7235 / 9694 Time remaining: 1s Progress 7236 / 9694 Time remaining: 1s Progress 7237 / 9694 Time remaining: 1s Progress 7238 / 9694 Time remaining: 1s Progress 7239 / 9694 Time remaining: 1s Progress 7240 / 9694 Time remaining: 1s Progress 7241 / 9694 Time remaining: 1s Progress 7242 / 9694 Time remaining: 1s Progress 7243 / 9694 Time remaining: 1s Progress 7244 / 9694 Time remaining: 1s Progress 7245 / 9694 Time remaining: 1s Progress 7246 / 9694 Time remaining: 1s Progress 7247 / 9694 Time remaining: 1s Progress 7248 / 9694 Time remaining: 1s Progress 7249 / 9694 Time remaining: 1s Progress 7250 / 9694 Time remaining: 1s Progress 7251 / 9694 Time remaining: 1s Progress 7252 / 9694 Time remaining: 1s Progress 7253 / 9694 Time remaining: 1s Progress 7254 / 9694 Time remaining: 1s Progress 7255 / 9694 Time remaining: 1s Progress 7256 / 9694 Time remaining: 1s Progress 7257 / 9694 Time remaining: 1s Progress 7258 / 9694 Time remaining: 1s Progress 7259 / 9694 Time remaining: 1s Progress 7260 / 9694 Time remaining: 1s Progress 7261 / 9694 Time remaining: 1s Progress 7262 / 9694 Time remaining: 1s Progress 7263 / 9694 Time remaining: 1s Progress 7264 / 9694 Time remaining: 1s Progress 7265 / 9694 Time remaining: 1s Progress 7266 / 9694 Time remaining: 1s Progress 7267 / 9694 Time remaining: 1s Progress 7268 / 9694 Time remaining: 1s Progress 7269 / 9694 Time remaining: 1s Progress 7270 / 9694 Time remaining: 1s Progress 7271 / 9694 Time remaining: 1s Progress 7272 / 9694 Time remaining: 1s Progress 7273 / 9694 Time remaining: 1s Progress 7274 / 9694 Time remaining: 1s Progress 7275 / 9694 Time remaining: 1s Progress 7276 / 9694 Time remaining: 1s Progress 7277 / 9694 Time remaining: 1s Progress 7278 / 9694 Time remaining: 1s Progress 7279 / 9694 Time remaining: 1s Progress 7280 / 9694 Time remaining: 1s Progress 7281 / 9694 Time remaining: 1s Progress 7282 / 9694 Time remaining: 1s Progress 7283 / 9694 Time remaining: 1s Progress 7284 / 9694 Time remaining: 1s Progress 7285 / 9694 Time remaining: 1s Progress 7286 / 9694 Time remaining: 1s Progress 7287 / 9694 Time remaining: 1s Progress 7288 / 9694 Time remaining: 1s Progress 7289 / 9694 Time remaining: 1s Progress 7290 / 9694 Time remaining: 1s Progress 7291 / 9694 Time remaining: 1s Progress 7292 / 9694 Time remaining: 1s Progress 7293 / 9694 Time remaining: 1s Progress 7294 / 9694 Time remaining: 1s Progress 7295 / 9694 Time remaining: 1s Progress 7296 / 9694 Time remaining: 1s Progress 7297 / 9694 Time remaining: 1s Progress 7298 / 9694 Time remaining: 1s Progress 7299 / 9694 Time remaining: 1s Progress 7300 / 9694 Time remaining: 1s Progress 7301 / 9694 Time remaining: 1s Progress 7302 / 9694 Time remaining: 1s Progress 7303 / 9694 Time remaining: 1s Progress 7304 / 9694 Time remaining: 1s Progress 7305 / 9694 Time remaining: 1s Progress 7306 / 9694 Time remaining: 1s Progress 7307 / 9694 Time remaining: 1s Progress 7308 / 9694 Time remaining: 1s Progress 7309 / 9694 Time remaining: 1s Progress 7310 / 9694 Time remaining: 1s Progress 7311 / 9694 Time remaining: 1s Progress 7312 / 9694 Time remaining: 1s Progress 7313 / 9694 Time remaining: 1s Progress 7314 / 9694 Time remaining: 1s Progress 7315 / 9694 Time remaining: 1s Progress 7316 / 9694 Time remaining: 1s Progress 7317 / 9694 Time remaining: 1s Progress 7318 / 9694 Time remaining: 1s Progress 7319 / 9694 Time remaining: 1s Progress 7320 / 9694 Time remaining: 1s Progress 7321 / 9694 Time remaining: 1s Progress 7322 / 9694 Time remaining: 1s Progress 7323 / 9694 Time remaining: 1s Progress 7324 / 9694 Time remaining: 1s Progress 7325 / 9694 Time remaining: 1s Progress 7326 / 9694 Time remaining: 1s Progress 7327 / 9694 Time remaining: 1s Progress 7328 / 9694 Time remaining: 1s Progress 7329 / 9694 Time remaining: 1s Progress 7330 / 9694 Time remaining: 1s Progress 7331 / 9694 Time remaining: 1s Progress 7332 / 9694 Time remaining: 1s Progress 7333 / 9694 Time remaining: 1s Progress 7334 / 9694 Time remaining: 1s Progress 7335 / 9694 Time remaining: 1s Progress 7336 / 9694 Time remaining: 1s Progress 7337 / 9694 Time remaining: 1s Progress 7338 / 9694 Time remaining: 1s Progress 7339 / 9694 Time remaining: 1s Progress 7340 / 9694 Time remaining: 1s Progress 7341 / 9694 Time remaining: 1s Progress 7342 / 9694 Time remaining: 1s Progress 7343 / 9694 Time remaining: 1s Progress 7344 / 9694 Time remaining: 1s Progress 7345 / 9694 Time remaining: 1s Progress 7346 / 9694 Time remaining: 1s Progress 7347 / 9694 Time remaining: 1s Progress 7348 / 9694 Time remaining: 1s Progress 7349 / 9694 Time remaining: 1s Progress 7350 / 9694 Time remaining: 1s Progress 7351 / 9694 Time remaining: 1s Progress 7352 / 9694 Time remaining: 1s Progress 7353 / 9694 Time remaining: 1s Progress 7354 / 9694 Time remaining: 1s Progress 7355 / 9694 Time remaining: 1s Progress 7356 / 9694 Time remaining: 1s Progress 7357 / 9694 Time remaining: 1s Progress 7358 / 9694 Time remaining: 1s Progress 7359 / 9694 Time remaining: 1s Progress 7360 / 9694 Time remaining: 1s Progress 7361 / 9694 Time remaining: 1s Progress 7362 / 9694 Time remaining: 1s Progress 7363 / 9694 Time remaining: 1s Progress 7364 / 9694 Time remaining: 1s Progress 7365 / 9694 Time remaining: 1s Progress 7366 / 9694 Time remaining: 1s Progress 7367 / 9694 Time remaining: 1s Progress 7368 / 9694 Time remaining: 1s Progress 7369 / 9694 Time remaining: 1s Progress 7370 / 9694 Time remaining: 1s Progress 7371 / 9694 Time remaining: 1s Progress 7372 / 9694 Time remaining: 1s Progress 7373 / 9694 Time remaining: 1s Progress 7374 / 9694 Time remaining: 1s Progress 7375 / 9694 Time remaining: 1s Progress 7376 / 9694 Time remaining: 1s Progress 7377 / 9694 Time remaining: 1s Progress 7378 / 9694 Time remaining: 1s Progress 7379 / 9694 Time remaining: 1s Progress 7380 / 9694 Time remaining: 1s Progress 7381 / 9694 Time remaining: 1s Progress 7382 / 9694 Time remaining: 1s Progress 7383 / 9694 Time remaining: 1s Progress 7384 / 9694 Time remaining: 1s Progress 7385 / 9694 Time remaining: 1s Progress 7386 / 9694 Time remaining: 1s Progress 7387 / 9694 Time remaining: 1s Progress 7388 / 9694 Time remaining: 1s Progress 7389 / 9694 Time remaining: 1s Progress 7390 / 9694 Time remaining: 1s Progress 7391 / 9694 Time remaining: 1s Progress 7392 / 9694 Time remaining: 1s Progress 7393 / 9694 Time remaining: 1s Progress 7394 / 9694 Time remaining: 1s Progress 7395 / 9694 Time remaining: 1s Progress 7396 / 9694 Time remaining: 1s Progress 7397 / 9694 Time remaining: 1s Progress 7398 / 9694 Time remaining: 1s Progress 7399 / 9694 Time remaining: 1s Progress 7400 / 9694 Time remaining: 1s Progress 7401 / 9694 Time remaining: 1s Progress 7402 / 9694 Time remaining: 1s Progress 7403 / 9694 Time remaining: 1s Progress 7404 / 9694 Time remaining: 1s Progress 7405 / 9694 Time remaining: 1s Progress 7406 / 9694 Time remaining: 1s Progress 7407 / 9694 Time remaining: 1s Progress 7408 / 9694 Time remaining: 1s Progress 7409 / 9694 Time remaining: 1s Progress 7410 / 9694 Time remaining: 1s Progress 7411 / 9694 Time remaining: 1s Progress 7412 / 9694 Time remaining: 1s Progress 7413 / 9694 Time remaining: 1s Progress 7414 / 9694 Time remaining: 1s Progress 7415 / 9694 Time remaining: 1s Progress 7416 / 9694 Time remaining: 1s Progress 7417 / 9694 Time remaining: 1s Progress 7418 / 9694 Time remaining: 1s Progress 7419 / 9694 Time remaining: 1s Progress 7420 / 9694 Time remaining: 1s Progress 7421 / 9694 Time remaining: 1s Progress 7422 / 9694 Time remaining: 1s Progress 7423 / 9694 Time remaining: 1s Progress 7424 / 9694 Time remaining: 1s Progress 7425 / 9694 Time remaining: 1s Progress 7426 / 9694 Time remaining: 1s Progress 7427 / 9694 Time remaining: 1s Progress 7428 / 9694 Time remaining: 1s Progress 7429 / 9694 Time remaining: 1s Progress 7430 / 9694 Time remaining: 1s Progress 7431 / 9694 Time remaining: 1s Progress 7432 / 9694 Time remaining: 1s Progress 7433 / 9694 Time remaining: 1s Progress 7434 / 9694 Time remaining: 1s Progress 7435 / 9694 Time remaining: 1s Progress 7436 / 9694 Time remaining: 1s Progress 7437 / 9694 Time remaining: 1s Progress 7438 / 9694 Time remaining: 1s Progress 7439 / 9694 Time remaining: 1s Progress 7440 / 9694 Time remaining: 1s Progress 7441 / 9694 Time remaining: 1s Progress 7442 / 9694 Time remaining: 1s Progress 7443 / 9694 Time remaining: 1s Progress 7444 / 9694 Time remaining: 1s Progress 7445 / 9694 Time remaining: 1s Progress 7446 / 9694 Time remaining: 1s Progress 7447 / 9694 Time remaining: 1s Progress 7448 / 9694 Time remaining: 1s Progress 7449 / 9694 Time remaining: 1s Progress 7450 / 9694 Time remaining: 1s Progress 7451 / 9694 Time remaining: 1s Progress 7452 / 9694 Time remaining: 1s Progress 7453 / 9694 Time remaining: 1s Progress 7454 / 9694 Time remaining: 1s Progress 7455 / 9694 Time remaining: 1s Progress 7456 / 9694 Time remaining: 1s Progress 7457 / 9694 Time remaining: 1s Progress 7458 / 9694 Time remaining: 1s Progress 7459 / 9694 Time remaining: 1s Progress 7460 / 9694 Time remaining: 1s Progress 7461 / 9694 Time remaining: 1s Progress 7462 / 9694 Time remaining: 1s Progress 7463 / 9694 Time remaining: 1s Progress 7464 / 9694 Time remaining: 1s Progress 7465 / 9694 Time remaining: 1s Progress 7466 / 9694 Time remaining: 1s Progress 7467 / 9694 Time remaining: 1s Progress 7468 / 9694 Time remaining: 1s Progress 7469 / 9694 Time remaining: 1s Progress 7470 / 9694 Time remaining: 1s Progress 7471 / 9694 Time remaining: 1s Progress 7472 / 9694 Time remaining: 1s Progress 7473 / 9694 Time remaining: 1s Progress 7474 / 9694 Time remaining: 1s Progress 7475 / 9694 Time remaining: 1s Progress 7476 / 9694 Time remaining: 1s Progress 7477 / 9694 Time remaining: 1s Progress 7478 / 9694 Time remaining: 1s Progress 7479 / 9694 Time remaining: 1s Progress 7480 / 9694 Time remaining: 1s Progress 7481 / 9694 Time remaining: 1s Progress 7482 / 9694 Time remaining: 1s Progress 7483 / 9694 Time remaining: 1s Progress 7484 / 9694 Time remaining: 1s Progress 7485 / 9694 Time remaining: 1s Progress 7486 / 9694 Time remaining: 1s Progress 7487 / 9694 Time remaining: 1s Progress 7488 / 9694 Time remaining: 1s Progress 7489 / 9694 Time remaining: 1s Progress 7490 / 9694 Time remaining: 1s Progress 7491 / 9694 Time remaining: 1s Progress 7492 / 9694 Time remaining: 1s Progress 7493 / 9694 Time remaining: 1s Progress 7494 / 9694 Time remaining: 1s Progress 7495 / 9694 Time remaining: 1s Progress 7496 / 9694 Time remaining: 1s Progress 7497 / 9694 Time remaining: 1s Progress 7498 / 9694 Time remaining: 1s Progress 7499 / 9694 Time remaining: 1s Progress 7500 / 9694 Time remaining: 1s Progress 7501 / 9694 Time remaining: 1s Progress 7502 / 9694 Time remaining: 1s Progress 7503 / 9694 Time remaining: 1s Progress 7504 / 9694 Time remaining: 1s Progress 7505 / 9694 Time remaining: 1s Progress 7506 / 9694 Time remaining: 1s Progress 7507 / 9694 Time remaining: 1s Progress 7508 / 9694 Time remaining: 1s Progress 7509 / 9694 Time remaining: 1s Progress 7510 / 9694 Time remaining: 1s Progress 7511 / 9694 Time remaining: 1s Progress 7512 / 9694 Time remaining: 1s Progress 7513 / 9694 Time remaining: 1s Progress 7514 / 9694 Time remaining: 1s Progress 7515 / 9694 Time remaining: 1s Progress 7516 / 9694 Time remaining: 1s Progress 7517 / 9694 Time remaining: 1s Progress 7518 / 9694 Time remaining: 1s Progress 7519 / 9694 Time remaining: 1s Progress 7520 / 9694 Time remaining: 1s Progress 7521 / 9694 Time remaining: 1s Progress 7522 / 9694 Time remaining: 1s Progress 7523 / 9694 Time remaining: 1s Progress 7524 / 9694 Time remaining: 1s Progress 7525 / 9694 Time remaining: 1s Progress 7526 / 9694 Time remaining: 1s Progress 7527 / 9694 Time remaining: 1s Progress 7528 / 9694 Time remaining: 1s Progress 7529 / 9694 Time remaining: 1s Progress 7530 / 9694 Time remaining: 1s Progress 7531 / 9694 Time remaining: 1s Progress 7532 / 9694 Time remaining: 1s Progress 7533 / 9694 Time remaining: 1s Progress 7534 / 9694 Time remaining: 1s Progress 7535 / 9694 Time remaining: 1s Progress 7536 / 9694 Time remaining: 1s Progress 7537 / 9694 Time remaining: 1s Progress 7538 / 9694 Time remaining: 1s Progress 7539 / 9694 Time remaining: 1s Progress 7540 / 9694 Time remaining: 1s Progress 7541 / 9694 Time remaining: 1s Progress 7542 / 9694 Time remaining: 1s Progress 7543 / 9694 Time remaining: 1s Progress 7544 / 9694 Time remaining: 1s Progress 7545 / 9694 Time remaining: 1s Progress 7546 / 9694 Time remaining: 1s Progress 7547 / 9694 Time remaining: 1s Progress 7548 / 9694 Time remaining: 1s Progress 7549 / 9694 Time remaining: 1s Progress 7550 / 9694 Time remaining: 1s Progress 7551 / 9694 Time remaining: 1s Progress 7552 / 9694 Time remaining: 1s Progress 7553 / 9694 Time remaining: 1s Progress 7554 / 9694 Time remaining: 1s Progress 7555 / 9694 Time remaining: 1s Progress 7556 / 9694 Time remaining: 1s Progress 7557 / 9694 Time remaining: 1s Progress 7558 / 9694 Time remaining: 1s Progress 7559 / 9694 Time remaining: 1s Progress 7560 / 9694 Time remaining: 1s Progress 7561 / 9694 Time remaining: 1s Progress 7562 / 9694 Time remaining: 1s Progress 7563 / 9694 Time remaining: 1s Progress 7564 / 9694 Time remaining: 1s Progress 7565 / 9694 Time remaining: 1s Progress 7566 / 9694 Time remaining: 1s Progress 7567 / 9694 Time remaining: 1s Progress 7568 / 9694 Time remaining: 1s Progress 7569 / 9694 Time remaining: 1s Progress 7570 / 9694 Time remaining: 1s Progress 7571 / 9694 Time remaining: 1s Progress 7572 / 9694 Time remaining: 1s Progress 7573 / 9694 Time remaining: 1s Progress 7574 / 9694 Time remaining: 1s Progress 7575 / 9694 Time remaining: 1s Progress 7576 / 9694 Time remaining: 1s Progress 7577 / 9694 Time remaining: 1s Progress 7578 / 9694 Time remaining: 1s Progress 7579 / 9694 Time remaining: 1s Progress 7580 / 9694 Time remaining: 1s Progress 7581 / 9694 Time remaining: 1s Progress 7582 / 9694 Time remaining: 1s Progress 7583 / 9694 Time remaining: 1s Progress 7584 / 9694 Time remaining: 1s Progress 7585 / 9694 Time remaining: 1s Progress 7586 / 9694 Time remaining: 1s Progress 7587 / 9694 Time remaining: 1s Progress 7588 / 9694 Time remaining: 1s Progress 7589 / 9694 Time remaining: 1s Progress 7590 / 9694 Time remaining: 1s Progress 7591 / 9694 Time remaining: 1s Progress 7592 / 9694 Time remaining: 1s Progress 7593 / 9694 Time remaining: 1s Progress 7594 / 9694 Time remaining: 1s Progress 7595 / 9694 Time remaining: 1s Progress 7596 / 9694 Time remaining: 1s Progress 7597 / 9694 Time remaining: 1s Progress 7598 / 9694 Time remaining: 1s Progress 7599 / 9694 Time remaining: 1s Progress 7600 / 9694 Time remaining: 1s Progress 7601 / 9694 Time remaining: 1s Progress 7602 / 9694 Time remaining: 1s Progress 7603 / 9694 Time remaining: 1s Progress 7604 / 9694 Time remaining: 1s Progress 7605 / 9694 Time remaining: 1s Progress 7606 / 9694 Time remaining: 1s Progress 7607 / 9694 Time remaining: 1s Progress 7608 / 9694 Time remaining: 1s Progress 7609 / 9694 Time remaining: 1s Progress 7610 / 9694 Time remaining: 1s Progress 7611 / 9694 Time remaining: 1s Progress 7612 / 9694 Time remaining: 1s Progress 7613 / 9694 Time remaining: 1s Progress 7614 / 9694 Time remaining: 1s Progress 7615 / 9694 Time remaining: 1s Progress 7616 / 9694 Time remaining: 1s Progress 7617 / 9694 Time remaining: 1s Progress 7618 / 9694 Time remaining: 1s Progress 7619 / 9694 Time remaining: 1s Progress 7620 / 9694 Time remaining: 1s Progress 7621 / 9694 Time remaining: 1s Progress 7622 / 9694 Time remaining: 1s Progress 7623 / 9694 Time remaining: 1s Progress 7624 / 9694 Time remaining: 1s Progress 7625 / 9694 Time remaining: 1s Progress 7626 / 9694 Time remaining: 1s Progress 7627 / 9694 Time remaining: 1s Progress 7628 / 9694 Time remaining: 1s Progress 7629 / 9694 Time remaining: 1s Progress 7630 / 9694 Time remaining: 1s Progress 7631 / 9694 Time remaining: 1s Progress 7632 / 9694 Time remaining: 1s Progress 7633 / 9694 Time remaining: 1s Progress 7634 / 9694 Time remaining: 1s Progress 7635 / 9694 Time remaining: 1s Progress 7636 / 9694 Time remaining: 1s Progress 7637 / 9694 Time remaining: 1s Progress 7638 / 9694 Time remaining: 1s Progress 7639 / 9694 Time remaining: 1s Progress 7640 / 9694 Time remaining: 1s Progress 7641 / 9694 Time remaining: 1s Progress 7642 / 9694 Time remaining: 1s Progress 7643 / 9694 Time remaining: 1s Progress 7644 / 9694 Time remaining: 1s Progress 7645 / 9694 Time remaining: 1s Progress 7646 / 9694 Time remaining: 1s Progress 7647 / 9694 Time remaining: 1s Progress 7648 / 9694 Time remaining: 1s Progress 7649 / 9694 Time remaining: 1s Progress 7650 / 9694 Time remaining: 1s Progress 7651 / 9694 Time remaining: 1s Progress 7652 / 9694 Time remaining: 1s Progress 7653 / 9694 Time remaining: 1s Progress 7654 / 9694 Time remaining: 1s Progress 7655 / 9694 Time remaining: 1s Progress 7656 / 9694 Time remaining: 1s Progress 7657 / 9694 Time remaining: 1s Progress 7658 / 9694 Time remaining: 1s Progress 7659 / 9694 Time remaining: 1s Progress 7660 / 9694 Time remaining: 1s Progress 7661 / 9694 Time remaining: 1s Progress 7662 / 9694 Time remaining: 1s Progress 7663 / 9694 Time remaining: 1s Progress 7664 / 9694 Time remaining: 1s Progress 7665 / 9694 Time remaining: 1s Progress 7666 / 9694 Time remaining: 1s Progress 7667 / 9694 Time remaining: 1s Progress 7668 / 9694 Time remaining: 1s Progress 7669 / 9694 Time remaining: 1s Progress 7670 / 9694 Time remaining: 1s Progress 7671 / 9694 Time remaining: 1s Progress 7672 / 9694 Time remaining: 1s Progress 7673 / 9694 Time remaining: 1s Progress 7674 / 9694 Time remaining: 1s Progress 7675 / 9694 Time remaining: 1s Progress 7676 / 9694 Time remaining: 1s Progress 7677 / 9694 Time remaining: 1s Progress 7678 / 9694 Time remaining: 1s Progress 7679 / 9694 Time remaining: 1s Progress 7680 / 9694 Time remaining: 1s Progress 7681 / 9694 Time remaining: 1s Progress 7682 / 9694 Time remaining: 1s Progress 7683 / 9694 Time remaining: 1s Progress 7684 / 9694 Time remaining: 1s Progress 7685 / 9694 Time remaining: 1s Progress 7686 / 9694 Time remaining: 1s Progress 7687 / 9694 Time remaining: 1s Progress 7688 / 9694 Time remaining: 1s Progress 7689 / 9694 Time remaining: 1s Progress 7690 / 9694 Time remaining: 1s Progress 7691 / 9694 Time remaining: 1s Progress 7692 / 9694 Time remaining: 1s Progress 7693 / 9694 Time remaining: 1s Progress 7694 / 9694 Time remaining: 1s Progress 7695 / 9694 Time remaining: 1s Progress 7696 / 9694 Time remaining: 1s Progress 7697 / 9694 Time remaining: 1s Progress 7698 / 9694 Time remaining: 1s Progress 7699 / 9694 Time remaining: 1s Progress 7700 / 9694 Time remaining: 1s Progress 7701 / 9694 Time remaining: 1s Progress 7702 / 9694 Time remaining: 1s Progress 7703 / 9694 Time remaining: 1s Progress 7704 / 9694 Time remaining: 1s Progress 7705 / 9694 Time remaining: 1s Progress 7706 / 9694 Time remaining: 1s Progress 7707 / 9694 Time remaining: 1s Progress 7708 / 9694 Time remaining: 1s Progress 7709 / 9694 Time remaining: 1s Progress 7710 / 9694 Time remaining: 1s Progress 7711 / 9694 Time remaining: 1s Progress 7712 / 9694 Time remaining: 1s Progress 7713 / 9694 Time remaining: 1s Progress 7714 / 9694 Time remaining: 1s Progress 7715 / 9694 Time remaining: 1s Progress 7716 / 9694 Time remaining: 1s Progress 7717 / 9694 Time remaining: 1s Progress 7718 / 9694 Time remaining: 1s Progress 7719 / 9694 Time remaining: 1s Progress 7720 / 9694 Time remaining: 1s Progress 7721 / 9694 Time remaining: 1s Progress 7722 / 9694 Time remaining: 1s Progress 7723 / 9694 Time remaining: 1s Progress 7724 / 9694 Time remaining: 1s Progress 7725 / 9694 Time remaining: 1s Progress 7726 / 9694 Time remaining: 1s Progress 7727 / 9694 Time remaining: 1s Progress 7728 / 9694 Time remaining: 1s Progress 7729 / 9694 Time remaining: 1s Progress 7730 / 9694 Time remaining: 1s Progress 7731 / 9694 Time remaining: 1s Progress 7732 / 9694 Time remaining: 1s Progress 7733 / 9694 Time remaining: 1s Progress 7734 / 9694 Time remaining: 1s Progress 7735 / 9694 Time remaining: 1s Progress 7736 / 9694 Time remaining: 1s Progress 7737 / 9694 Time remaining: 1s Progress 7738 / 9694 Time remaining: 1s Progress 7739 / 9694 Time remaining: 1s Progress 7740 / 9694 Time remaining: 1s Progress 7741 / 9694 Time remaining: 1s Progress 7742 / 9694 Time remaining: 1s Progress 7743 / 9694 Time remaining: 1s Progress 7744 / 9694 Time remaining: 1s Progress 7745 / 9694 Time remaining: 1s Progress 7746 / 9694 Time remaining: 1s Progress 7747 / 9694 Time remaining: 1s Progress 7748 / 9694 Time remaining: 1s Progress 7749 / 9694 Time remaining: 1s Progress 7750 / 9694 Time remaining: 1s Progress 7751 / 9694 Time remaining: 1s Progress 7752 / 9694 Time remaining: 1s Progress 7753 / 9694 Time remaining: 1s Progress 7754 / 9694 Time remaining: 1s Progress 7755 / 9694 Time remaining: 1s Progress 7756 / 9694 Time remaining: 1s Progress 7757 / 9694 Time remaining: 1s Progress 7758 / 9694 Time remaining: 1s Progress 7759 / 9694 Time remaining: 1s Progress 7760 / 9694 Time remaining: 1s Progress 7761 / 9694 Time remaining: 1s Progress 7762 / 9694 Time remaining: 1s Progress 7763 / 9694 Time remaining: 1s Progress 7764 / 9694 Time remaining: 1s Progress 7765 / 9694 Time remaining: 1s Progress 7766 / 9694 Time remaining: 1s Progress 7767 / 9694 Time remaining: 1s Progress 7768 / 9694 Time remaining: 1s Progress 7769 / 9694 Time remaining: 1s Progress 7770 / 9694 Time remaining: 1s Progress 7771 / 9694 Time remaining: 1s Progress 7772 / 9694 Time remaining: 1s Progress 7773 / 9694 Time remaining: 1s Progress 7774 / 9694 Time remaining: 1s Progress 7775 / 9694 Time remaining: 1s Progress 7776 / 9694 Time remaining: 1s Progress 7777 / 9694 Time remaining: 1s Progress 7778 / 9694 Time remaining: 1s Progress 7779 / 9694 Time remaining: 1s Progress 7780 / 9694 Time remaining: 1s Progress 7781 / 9694 Time remaining: 1s Progress 7782 / 9694 Time remaining: 1s Progress 7783 / 9694 Time remaining: 1s Progress 7784 / 9694 Time remaining: 1s Progress 7785 / 9694 Time remaining: 1s Progress 7786 / 9694 Time remaining: 1s Progress 7787 / 9694 Time remaining: 1s Progress 7788 / 9694 Time remaining: 1s Progress 7789 / 9694 Time remaining: 1s Progress 7790 / 9694 Time remaining: 1s Progress 7791 / 9694 Time remaining: 1s Progress 7792 / 9694 Time remaining: 1s Progress 7793 / 9694 Time remaining: 1s Progress 7794 / 9694 Time remaining: 1s Progress 7795 / 9694 Time remaining: 1s Progress 7796 / 9694 Time remaining: 1s Progress 7797 / 9694 Time remaining: 1s Progress 7798 / 9694 Time remaining: 1s Progress 7799 / 9694 Time remaining: 1s Progress 7800 / 9694 Time remaining: 1s Progress 7801 / 9694 Time remaining: 1s Progress 7802 / 9694 Time remaining: 1s Progress 7803 / 9694 Time remaining: 1s Progress 7804 / 9694 Time remaining: 1s Progress 7805 / 9694 Time remaining: 1s Progress 7806 / 9694 Time remaining: 1s Progress 7807 / 9694 Time remaining: 1s Progress 7808 / 9694 Time remaining: 1s Progress 7809 / 9694 Time remaining: 1s Progress 7810 / 9694 Time remaining: 1s Progress 7811 / 9694 Time remaining: 1s Progress 7812 / 9694 Time remaining: 1s Progress 7813 / 9694 Time remaining: 1s Progress 7814 / 9694 Time remaining: 1s Progress 7815 / 9694 Time remaining: 1s Progress 7816 / 9694 Time remaining: 1s Progress 7817 / 9694 Time remaining: 1s Progress 7818 / 9694 Time remaining: 1s Progress 7819 / 9694 Time remaining: 1s Progress 7820 / 9694 Time remaining: 1s Progress 7821 / 9694 Time remaining: 1s Progress 7822 / 9694 Time remaining: 1s Progress 7823 / 9694 Time remaining: 1s Progress 7824 / 9694 Time remaining: 1s Progress 7825 / 9694 Time remaining: 1s Progress 7826 / 9694 Time remaining: 1s Progress 7827 / 9694 Time remaining: 1s Progress 7828 / 9694 Time remaining: 1s Progress 7829 / 9694 Time remaining: 1s Progress 7830 / 9694 Time remaining: 1s Progress 7831 / 9694 Time remaining: 1s Progress 7832 / 9694 Time remaining: 1s Progress 7833 / 9694 Time remaining: 1s Progress 7834 / 9694 Time remaining: 1s Progress 7835 / 9694 Time remaining: 1s Progress 7836 / 9694 Time remaining: 1s Progress 7837 / 9694 Time remaining: 1s Progress 7838 / 9694 Time remaining: 1s Progress 7839 / 9694 Time remaining: 1s Progress 7840 / 9694 Time remaining: 1s Progress 7841 / 9694 Time remaining: 1s Progress 7842 / 9694 Time remaining: 1s Progress 7843 / 9694 Time remaining: 1s Progress 7844 / 9694 Time remaining: 1s Progress 7845 / 9694 Time remaining: 1s Progress 7846 / 9694 Time remaining: 1s Progress 7847 / 9694 Time remaining: 1s Progress 7848 / 9694 Time remaining: 1s Progress 7849 / 9694 Time remaining: 1s Progress 7850 / 9694 Time remaining: 1s Progress 7851 / 9694 Time remaining: 1s Progress 7852 / 9694 Time remaining: 1s Progress 7853 / 9694 Time remaining: 1s Progress 7854 / 9694 Time remaining: 1s Progress 7855 / 9694 Time remaining: 1s Progress 7856 / 9694 Time remaining: 1s Progress 7857 / 9694 Time remaining: 1s Progress 7858 / 9694 Time remaining: 1s Progress 7859 / 9694 Time remaining: 1s Progress 7860 / 9694 Time remaining: 1s Progress 7861 / 9694 Time remaining: 1s Progress 7862 / 9694 Time remaining: 1s Progress 7863 / 9694 Time remaining: 1s Progress 7864 / 9694 Time remaining: 1s Progress 7865 / 9694 Time remaining: 1s Progress 7866 / 9694 Time remaining: 1s Progress 7867 / 9694 Time remaining: 1s Progress 7868 / 9694 Time remaining: 1s Progress 7869 / 9694 Time remaining: 1s Progress 7870 / 9694 Time remaining: 1s Progress 7871 / 9694 Time remaining: 1s Progress 7872 / 9694 Time remaining: 1s Progress 7873 / 9694 Time remaining: 1s Progress 7874 / 9694 Time remaining: 1s Progress 7875 / 9694 Time remaining: 1s Progress 7876 / 9694 Time remaining: 1s Progress 7877 / 9694 Time remaining: 1s Progress 7878 / 9694 Time remaining: 1s Progress 7879 / 9694 Time remaining: 1s Progress 7880 / 9694 Time remaining: 1s Progress 7881 / 9694 Time remaining: 1s Progress 7882 / 9694 Time remaining: 1s Progress 7883 / 9694 Time remaining: 1s Progress 7884 / 9694 Time remaining: 1s Progress 7885 / 9694 Time remaining: 1s Progress 7886 / 9694 Time remaining: 1s Progress 7887 / 9694 Time remaining: 1s Progress 7888 / 9694 Time remaining: 1s Progress 7889 / 9694 Time remaining: 1s Progress 7890 / 9694 Time remaining: 1s Progress 7891 / 9694 Time remaining: 1s Progress 7892 / 9694 Time remaining: 1s Progress 7893 / 9694 Time remaining: 1s Progress 7894 / 9694 Time remaining: 1s Progress 7895 / 9694 Time remaining: 1s Progress 7896 / 9694 Time remaining: 1s Progress 7897 / 9694 Time remaining: 1s Progress 7898 / 9694 Time remaining: 1s Progress 7899 / 9694 Time remaining: 1s Progress 7900 / 9694 Time remaining: 1s Progress 7901 / 9694 Time remaining: 1s Progress 7902 / 9694 Time remaining: 1s Progress 7903 / 9694 Time remaining: 1s Progress 7904 / 9694 Time remaining: 1s Progress 7905 / 9694 Time remaining: 1s Progress 7906 / 9694 Time remaining: 1s Progress 7907 / 9694 Time remaining: 1s Progress 7908 / 9694 Time remaining: 1s Progress 7909 / 9694 Time remaining: 1s Progress 7910 / 9694 Time remaining: 1s Progress 7911 / 9694 Time remaining: 1s Progress 7912 / 9694 Time remaining: 1s Progress 7913 / 9694 Time remaining: 1s Progress 7914 / 9694 Time remaining: 1s Progress 7915 / 9694 Time remaining: 1s Progress 7916 / 9694 Time remaining: 1s Progress 7917 / 9694 Time remaining: 1s Progress 7918 / 9694 Time remaining: 1s Progress 7919 / 9694 Time remaining: 1s Progress 7920 / 9694 Time remaining: 1s Progress 7921 / 9694 Time remaining: 1s Progress 7922 / 9694 Time remaining: 1s Progress 7923 / 9694 Time remaining: 1s Progress 7924 / 9694 Time remaining: 1s Progress 7925 / 9694 Time remaining: 1s Progress 7926 / 9694 Time remaining: 1s Progress 7927 / 9694 Time remaining: 1s Progress 7928 / 9694 Time remaining: 1s Progress 7929 / 9694 Time remaining: 1s Progress 7930 / 9694 Time remaining: 1s Progress 7931 / 9694 Time remaining: 1s Progress 7932 / 9694 Time remaining: 1s Progress 7933 / 9694 Time remaining: 1s Progress 7934 / 9694 Time remaining: 1s Progress 7935 / 9694 Time remaining: 1s Progress 7936 / 9694 Time remaining: 1s Progress 7937 / 9694 Time remaining: 1s Progress 7938 / 9694 Time remaining: 1s Progress 7939 / 9694 Time remaining: 1s Progress 7940 / 9694 Time remaining: 1s Progress 7941 / 9694 Time remaining: 1s Progress 7942 / 9694 Time remaining: 1s Progress 7943 / 9694 Time remaining: 1s Progress 7944 / 9694 Time remaining: 1s Progress 7945 / 9694 Time remaining: 1s Progress 7946 / 9694 Time remaining: 1s Progress 7947 / 9694 Time remaining: 1s Progress 7948 / 9694 Time remaining: 1s Progress 7949 / 9694 Time remaining: 1s Progress 7950 / 9694 Time remaining: 1s Progress 7951 / 9694 Time remaining: 1s Progress 7952 / 9694 Time remaining: 1s Progress 7953 / 9694 Time remaining: 1s Progress 7954 / 9694 Time remaining: 1s Progress 7955 / 9694 Time remaining: 1s Progress 7956 / 9694 Time remaining: 1s Progress 7957 / 9694 Time remaining: 1s Progress 7958 / 9694 Time remaining: 1s Progress 7959 / 9694 Time remaining: 1s Progress 7960 / 9694 Time remaining: 1s Progress 7961 / 9694 Time remaining: 1s Progress 7962 / 9694 Time remaining: 1s Progress 7963 / 9694 Time remaining: 1s Progress 7964 / 9694 Time remaining: 1s Progress 7965 / 9694 Time remaining: 1s Progress 7966 / 9694 Time remaining: 1s Progress 7967 / 9694 Time remaining: 1s Progress 7968 / 9694 Time remaining: 1s Progress 7969 / 9694 Time remaining: 1s Progress 7970 / 9694 Time remaining: 1s Progress 7971 / 9694 Time remaining: 1s Progress 7972 / 9694 Time remaining: 1s Progress 7973 / 9694 Time remaining: 1s Progress 7974 / 9694 Time remaining: 1s Progress 7975 / 9694 Time remaining: 1s Progress 7976 / 9694 Time remaining: 1s Progress 7977 / 9694 Time remaining: 1s Progress 7978 / 9694 Time remaining: 1s Progress 7979 / 9694 Time remaining: 1s Progress 7980 / 9694 Time remaining: 1s Progress 7981 / 9694 Time remaining: 1s Progress 7982 / 9694 Time remaining: 1s Progress 7983 / 9694 Time remaining: 1s Progress 7984 / 9694 Time remaining: 1s Progress 7985 / 9694 Time remaining: 1s Progress 7986 / 9694 Time remaining: 1s Progress 7987 / 9694 Time remaining: 1s Progress 7988 / 9694 Time remaining: 1s Progress 7989 / 9694 Time remaining: 1s Progress 7990 / 9694 Time remaining: 1s Progress 7991 / 9694 Time remaining: 1s Progress 7992 / 9694 Time remaining: 1s Progress 7993 / 9694 Time remaining: 1s Progress 7994 / 9694 Time remaining: 1s Progress 7995 / 9694 Time remaining: 1s Progress 7996 / 9694 Time remaining: 1s Progress 7997 / 9694 Time remaining: 1s Progress 7998 / 9694 Time remaining: 1s Progress 7999 / 9694 Time remaining: 1s Progress 8000 / 9694 Time remaining: 1s Progress 8001 / 9694 Time remaining: 1s Progress 8002 / 9694 Time remaining: 1s Progress 8003 / 9694 Time remaining: 1s Progress 8004 / 9694 Time remaining: 1s Progress 8005 / 9694 Time remaining: 1s Progress 8006 / 9694 Time remaining: 1s Progress 8007 / 9694 Time remaining: 1s Progress 8008 / 9694 Time remaining: 1s Progress 8009 / 9694 Time remaining: 1s Progress 8010 / 9694 Time remaining: 1s Progress 8011 / 9694 Time remaining: 1s Progress 8012 / 9694 Time remaining: 1s Progress 8013 / 9694 Time remaining: 1s Progress 8014 / 9694 Time remaining: 1s Progress 8015 / 9694 Time remaining: 1s Progress 8016 / 9694 Time remaining: 1s Progress 8017 / 9694 Time remaining: 1s Progress 8018 / 9694 Time remaining: 1s Progress 8019 / 9694 Time remaining: 1s Progress 8020 / 9694 Time remaining: 1s Progress 8021 / 9694 Time remaining: 1s Progress 8022 / 9694 Time remaining: 1s Progress 8023 / 9694 Time remaining: 1s Progress 8024 / 9694 Time remaining: 1s Progress 8025 / 9694 Time remaining: 1s Progress 8026 / 9694 Time remaining: 1s Progress 8027 / 9694 Time remaining: 1s Progress 8028 / 9694 Time remaining: 1s Progress 8029 / 9694 Time remaining: 1s Progress 8030 / 9694 Time remaining: 1s Progress 8031 / 9694 Time remaining: 1s Progress 8032 / 9694 Time remaining: 1s Progress 8033 / 9694 Time remaining: 1s Progress 8034 / 9694 Time remaining: 1s Progress 8035 / 9694 Time remaining: 1s Progress 8036 / 9694 Time remaining: 1s Progress 8037 / 9694 Time remaining: 1s Progress 8038 / 9694 Time remaining: 1s Progress 8039 / 9694 Time remaining: 1s Progress 8040 / 9694 Time remaining: 1s Progress 8041 / 9694 Time remaining: 1s Progress 8042 / 9694 Time remaining: 1s Progress 8043 / 9694 Time remaining: 1s Progress 8044 / 9694 Time remaining: 1s Progress 8045 / 9694 Time remaining: 1s Progress 8046 / 9694 Time remaining: 1s Progress 8047 / 9694 Time remaining: 1s Progress 8048 / 9694 Time remaining: 1s Progress 8049 / 9694 Time remaining: 1s Progress 8050 / 9694 Time remaining: 1s Progress 8051 / 9694 Time remaining: 1s Progress 8052 / 9694 Time remaining: 1s Progress 8053 / 9694 Time remaining: 1s Progress 8054 / 9694 Time remaining: 1s Progress 8055 / 9694 Time remaining: 1s Progress 8056 / 9694 Time remaining: 1s Progress 8057 / 9694 Time remaining: 1s Progress 8058 / 9694 Time remaining: 1s Progress 8059 / 9694 Time remaining: 1s Progress 8060 / 9694 Time remaining: 1s Progress 8061 / 9694 Time remaining: 1s Progress 8062 / 9694 Time remaining: 1s Progress 8063 / 9694 Time remaining: 1s Progress 8064 / 9694 Time remaining: 1s Progress 8065 / 9694 Time remaining: 1s Progress 8066 / 9694 Time remaining: 1s Progress 8067 / 9694 Time remaining: 1s Progress 8068 / 9694 Time remaining: 1s Progress 8069 / 9694 Time remaining: 1s Progress 8070 / 9694 Time remaining: 1s Progress 8071 / 9694 Time remaining: 1s Progress 8072 / 9694 Time remaining: 1s Progress 8073 / 9694 Time remaining: 1s Progress 8074 / 9694 Time remaining: 1s Progress 8075 / 9694 Time remaining: 1s Progress 8076 / 9694 Time remaining: 1s Progress 8077 / 9694 Time remaining: 1s Progress 8078 / 9694 Time remaining: 1s Progress 8079 / 9694 Time remaining: 1s Progress 8080 / 9694 Time remaining: 1s Progress 8081 / 9694 Time remaining: 1s Progress 8082 / 9694 Time remaining: 1s Progress 8083 / 9694 Time remaining: 1s Progress 8084 / 9694 Time remaining: 1s Progress 8085 / 9694 Time remaining: 1s Progress 8086 / 9694 Time remaining: 1s Progress 8087 / 9694 Time remaining: 1s Progress 8088 / 9694 Time remaining: 1s Progress 8089 / 9694 Time remaining: 1s Progress 8090 / 9694 Time remaining: 1s Progress 8091 / 9694 Time remaining: 1s Progress 8092 / 9694 Time remaining: 1s Progress 8093 / 9694 Time remaining: 1s Progress 8094 / 9694 Time remaining: 1s Progress 8095 / 9694 Time remaining: 1s Progress 8096 / 9694 Time remaining: 1s Progress 8097 / 9694 Time remaining: 1s Progress 8098 / 9694 Time remaining: 1s Progress 8099 / 9694 Time remaining: 1s Progress 8100 / 9694 Time remaining: 1s Progress 8101 / 9694 Time remaining: 1s Progress 8102 / 9694 Time remaining: 1s Progress 8103 / 9694 Time remaining: 1s Progress 8104 / 9694 Time remaining: 1s Progress 8105 / 9694 Time remaining: 1s Progress 8106 / 9694 Time remaining: 1s Progress 8107 / 9694 Time remaining: 1s Progress 8108 / 9694 Time remaining: 1s Progress 8109 / 9694 Time remaining: 1s Progress 8110 / 9694 Time remaining: 1s Progress 8111 / 9694 Time remaining: 1s Progress 8112 / 9694 Time remaining: 1s Progress 8113 / 9694 Time remaining: 1s Progress 8114 / 9694 Time remaining: 1s Progress 8115 / 9694 Time remaining: 1s Progress 8116 / 9694 Time remaining: 1s Progress 8117 / 9694 Time remaining: 1s Progress 8118 / 9694 Time remaining: 1s Progress 8119 / 9694 Time remaining: 1s Progress 8120 / 9694 Time remaining: 1s Progress 8121 / 9694 Time remaining: 1s Progress 8122 / 9694 Time remaining: 1s Progress 8123 / 9694 Time remaining: 1s Progress 8124 / 9694 Time remaining: 1s Progress 8125 / 9694 Time remaining: 1s Progress 8126 / 9694 Time remaining: 1s Progress 8127 / 9694 Time remaining: 1s Progress 8128 / 9694 Time remaining: 1s Progress 8129 / 9694 Time remaining: 1s Progress 8130 / 9694 Time remaining: 1s Progress 8131 / 9694 Time remaining: 1s Progress 8132 / 9694 Time remaining: 1s Progress 8133 / 9694 Time remaining: 1s Progress 8134 / 9694 Time remaining: 1s Progress 8135 / 9694 Time remaining: 1s Progress 8136 / 9694 Time remaining: 1s Progress 8137 / 9694 Time remaining: 1s Progress 8138 / 9694 Time remaining: 1s Progress 8139 / 9694 Time remaining: 1s Progress 8140 / 9694 Time remaining: 1s Progress 8141 / 9694 Time remaining: 1s Progress 8142 / 9694 Time remaining: 1s Progress 8143 / 9694 Time remaining: 1s Progress 8144 / 9694 Time remaining: 1s Progress 8145 / 9694 Time remaining: 1s Progress 8146 / 9694 Time remaining: 1s Progress 8147 / 9694 Time remaining: 1s Progress 8148 / 9694 Time remaining: 1s Progress 8149 / 9694 Time remaining: 1s Progress 8150 / 9694 Time remaining: 1s Progress 8151 / 9694 Time remaining: 1s Progress 8152 / 9694 Time remaining: 1s Progress 8153 / 9694 Time remaining: 1s Progress 8154 / 9694 Time remaining: 1s Progress 8155 / 9694 Time remaining: 1s Progress 8156 / 9694 Time remaining: 1s Progress 8157 / 9694 Time remaining: 1s Progress 8158 / 9694 Time remaining: 1s Progress 8159 / 9694 Time remaining: 1s Progress 8160 / 9694 Time remaining: 1s Progress 8161 / 9694 Time remaining: 1s Progress 8162 / 9694 Time remaining: 1s Progress 8163 / 9694 Time remaining: 1s Progress 8164 / 9694 Time remaining: 1s Progress 8165 / 9694 Time remaining: 1s Progress 8166 / 9694 Time remaining: 1s Progress 8167 / 9694 Time remaining: 1s Progress 8168 / 9694 Time remaining: 1s Progress 8169 / 9694 Time remaining: 1s Progress 8170 / 9694 Time remaining: 1s Progress 8171 / 9694 Time remaining: 1s Progress 8172 / 9694 Time remaining: 1s Progress 8173 / 9694 Time remaining: 1s Progress 8174 / 9694 Time remaining: 1s Progress 8175 / 9694 Time remaining: 1s Progress 8176 / 9694 Time remaining: 1s Progress 8177 / 9694 Time remaining: 1s Progress 8178 / 9694 Time remaining: 1s Progress 8179 / 9694 Time remaining: 1s Progress 8180 / 9694 Time remaining: 1s Progress 8181 / 9694 Time remaining: 1s Progress 8182 / 9694 Time remaining: 1s Progress 8183 / 9694 Time remaining: 1s Progress 8184 / 9694 Time remaining: 1s Progress 8185 / 9694 Time remaining: 1s Progress 8186 / 9694 Time remaining: 1s Progress 8187 / 9694 Time remaining: 1s Progress 8188 / 9694 Time remaining: 1s Progress 8189 / 9694 Time remaining: 1s Progress 8190 / 9694 Time remaining: 1s Progress 8191 / 9694 Time remaining: 1s Progress 8192 / 9694 Time remaining: 1s Progress 8193 / 9694 Time remaining: 1s Progress 8194 / 9694 Time remaining: 1s Progress 8195 / 9694 Time remaining: 1s Progress 8196 / 9694 Time remaining: 1s Progress 8197 / 9694 Time remaining: 1s Progress 8198 / 9694 Time remaining: 1s Progress 8199 / 9694 Time remaining: 1s Progress 8200 / 9694 Time remaining: 1s Progress 8201 / 9694 Time remaining: 1s Progress 8202 / 9694 Time remaining: 1s Progress 8203 / 9694 Time remaining: 1s Progress 8204 / 9694 Time remaining: 1s Progress 8205 / 9694 Time remaining: 1s Progress 8206 / 9694 Time remaining: 1s Progress 8207 / 9694 Time remaining: 1s Progress 8208 / 9694 Time remaining: 1s Progress 8209 / 9694 Time remaining: 1s Progress 8210 / 9694 Time remaining: 1s Progress 8211 / 9694 Time remaining: 1s Progress 8212 / 9694 Time remaining: 1s Progress 8213 / 9694 Time remaining: 1s Progress 8214 / 9694 Time remaining: 1s Progress 8215 / 9694 Time remaining: 1s Progress 8216 / 9694 Time remaining: 1s Progress 8217 / 9694 Time remaining: 1s Progress 8218 / 9694 Time remaining: 1s Progress 8219 / 9694 Time remaining: 1s Progress 8220 / 9694 Time remaining: 1s Progress 8221 / 9694 Time remaining: 1s Progress 8222 / 9694 Time remaining: 1s Progress 8223 / 9694 Time remaining: 1s Progress 8224 / 9694 Time remaining: 1s Progress 8225 / 9694 Time remaining: 1s Progress 8226 / 9694 Time remaining: 1s Progress 8227 / 9694 Time remaining: 1s Progress 8228 / 9694 Time remaining: 1s Progress 8229 / 9694 Time remaining: 1s Progress 8230 / 9694 Time remaining: 1s Progress 8231 / 9694 Time remaining: 1s Progress 8232 / 9694 Time remaining: 1s Progress 8233 / 9694 Time remaining: 1s Progress 8234 / 9694 Time remaining: 1s Progress 8235 / 9694 Time remaining: 1s Progress 8236 / 9694 Time remaining: 1s Progress 8237 / 9694 Time remaining: 1s Progress 8238 / 9694 Time remaining: 1s Progress 8239 / 9694 Time remaining: 1s Progress 8240 / 9694 Time remaining: 1s Progress 8241 / 9694 Time remaining: 1s Progress 8242 / 9694 Time remaining: 1s Progress 8243 / 9694 Time remaining: 1s Progress 8244 / 9694 Time remaining: 1s Progress 8245 / 9694 Time remaining: 1s Progress 8246 / 9694 Time remaining: 1s Progress 8247 / 9694 Time remaining: 1s Progress 8248 / 9694 Time remaining: 1s Progress 8249 / 9694 Time remaining: 1s Progress 8250 / 9694 Time remaining: 1s Progress 8251 / 9694 Time remaining: 1s Progress 8252 / 9694 Time remaining: 1s Progress 8253 / 9694 Time remaining: 1s Progress 8254 / 9694 Time remaining: 1s Progress 8255 / 9694 Time remaining: 1s Progress 8256 / 9694 Time remaining: 1s Progress 8257 / 9694 Time remaining: 1s Progress 8258 / 9694 Time remaining: 1s Progress 8259 / 9694 Time remaining: 1s Progress 8260 / 9694 Time remaining: 1s Progress 8261 / 9694 Time remaining: 1s Progress 8262 / 9694 Time remaining: 1s Progress 8263 / 9694 Time remaining: 1s Progress 8264 / 9694 Time remaining: 1s Progress 8265 / 9694 Time remaining: 1s Progress 8266 / 9694 Time remaining: 1s Progress 8267 / 9694 Time remaining: 1s Progress 8268 / 9694 Time remaining: 1s Progress 8269 / 9694 Time remaining: 1s Progress 8270 / 9694 Time remaining: 1s Progress 8271 / 9694 Time remaining: 1s Progress 8272 / 9694 Time remaining: 1s Progress 8273 / 9694 Time remaining: 1s Progress 8274 / 9694 Time remaining: 1s Progress 8275 / 9694 Time remaining: 1s Progress 8276 / 9694 Time remaining: 1s Progress 8277 / 9694 Time remaining: 1s Progress 8278 / 9694 Time remaining: 1s Progress 8279 / 9694 Time remaining: 1s Progress 8280 / 9694 Time remaining: 1s Progress 8281 / 9694 Time remaining: 1s Progress 8282 / 9694 Time remaining: 1s Progress 8283 / 9694 Time remaining: 1s Progress 8284 / 9694 Time remaining: 1s Progress 8285 / 9694 Time remaining: 1s Progress 8286 / 9694 Time remaining: 1s Progress 8287 / 9694 Time remaining: 1s Progress 8288 / 9694 Time remaining: 1s Progress 8289 / 9694 Time remaining: 1s Progress 8290 / 9694 Time remaining: 1s Progress 8291 / 9694 Time remaining: 1s Progress 8292 / 9694 Time remaining: 1s Progress 8293 / 9694 Time remaining: 1s Progress 8294 / 9694 Time remaining: 1s Progress 8295 / 9694 Time remaining: 1s Progress 8296 / 9694 Time remaining: 1s Progress 8297 / 9694 Time remaining: 1s Progress 8298 / 9694 Time remaining: 1s Progress 8299 / 9694 Time remaining: 1s Progress 8300 / 9694 Time remaining: 1s Progress 8301 / 9694 Time remaining: 1s Progress 8302 / 9694 Time remaining: 1s Progress 8303 / 9694 Time remaining: 1s Progress 8304 / 9694 Time remaining: 1s Progress 8305 / 9694 Time remaining: 1s Progress 8306 / 9694 Time remaining: 1s Progress 8307 / 9694 Time remaining: 1s Progress 8308 / 9694 Time remaining: 1s Progress 8309 / 9694 Time remaining: 1s Progress 8310 / 9694 Time remaining: 1s Progress 8311 / 9694 Time remaining: 1s Progress 8312 / 9694 Time remaining: 1s Progress 8313 / 9694 Time remaining: 1s Progress 8314 / 9694 Time remaining: 1s Progress 8315 / 9694 Time remaining: 1s Progress 8316 / 9694 Time remaining: 1s Progress 8317 / 9694 Time remaining: 1s Progress 8318 / 9694 Time remaining: 1s Progress 8319 / 9694 Time remaining: 1s Progress 8320 / 9694 Time remaining: 1s Progress 8321 / 9694 Time remaining: 1s Progress 8322 / 9694 Time remaining: 1s Progress 8323 / 9694 Time remaining: 1s Progress 8324 / 9694 Time remaining: 1s Progress 8325 / 9694 Time remaining: 1s Progress 8326 / 9694 Time remaining: 1s Progress 8327 / 9694 Time remaining: 1s Progress 8328 / 9694 Time remaining: 1s Progress 8329 / 9694 Time remaining: 1s Progress 8330 / 9694 Time remaining: 1s Progress 8331 / 9694 Time remaining: 1s Progress 8332 / 9694 Time remaining: 1s Progress 8333 / 9694 Time remaining: 1s Progress 8334 / 9694 Time remaining: 0s Progress 8335 / 9694 Time remaining: 0s Progress 8336 / 9694 Time remaining: 0s Progress 8337 / 9694 Time remaining: 0s Progress 8338 / 9694 Time remaining: 0s Progress 8339 / 9694 Time remaining: 0s Progress 8340 / 9694 Time remaining: 0s Progress 8341 / 9694 Time remaining: 0s Progress 8342 / 9694 Time remaining: 0s Progress 8343 / 9694 Time remaining: 0s Progress 8344 / 9694 Time remaining: 0s Progress 8345 / 9694 Time remaining: 0s Progress 8346 / 9694 Time remaining: 0s Progress 8347 / 9694 Time remaining: 0s Progress 8348 / 9694 Time remaining: 0s Progress 8349 / 9694 Time remaining: 0s Progress 8350 / 9694 Time remaining: 0s Progress 8351 / 9694 Time remaining: 0s Progress 8352 / 9694 Time remaining: 0s Progress 8353 / 9694 Time remaining: 0s Progress 8354 / 9694 Time remaining: 0s Progress 8355 / 9694 Time remaining: 0s Progress 8356 / 9694 Time remaining: 0s Progress 8357 / 9694 Time remaining: 0s Progress 8358 / 9694 Time remaining: 0s Progress 8359 / 9694 Time remaining: 0s Progress 8360 / 9694 Time remaining: 0s Progress 8361 / 9694 Time remaining: 0s Progress 8362 / 9694 Time remaining: 0s Progress 8363 / 9694 Time remaining: 0s Progress 8364 / 9694 Time remaining: 0s Progress 8365 / 9694 Time remaining: 0s Progress 8366 / 9694 Time remaining: 0s Progress 8367 / 9694 Time remaining: 0s Progress 8368 / 9694 Time remaining: 0s Progress 8369 / 9694 Time remaining: 0s Progress 8370 / 9694 Time remaining: 0s Progress 8371 / 9694 Time remaining: 0s Progress 8372 / 9694 Time remaining: 0s Progress 8373 / 9694 Time remaining: 0s Progress 8374 / 9694 Time remaining: 0s Progress 8375 / 9694 Time remaining: 0s Progress 8376 / 9694 Time remaining: 0s Progress 8377 / 9694 Time remaining: 0s Progress 8378 / 9694 Time remaining: 0s Progress 8379 / 9694 Time remaining: 0s Progress 8380 / 9694 Time remaining: 0s Progress 8381 / 9694 Time remaining: 0s Progress 8382 / 9694 Time remaining: 0s Progress 8383 / 9694 Time remaining: 0s Progress 8384 / 9694 Time remaining: 0s Progress 8385 / 9694 Time remaining: 0s Progress 8386 / 9694 Time remaining: 0s Progress 8387 / 9694 Time remaining: 0s Progress 8388 / 9694 Time remaining: 0s Progress 8389 / 9694 Time remaining: 0s Progress 8390 / 9694 Time remaining: 0s Progress 8391 / 9694 Time remaining: 0s Progress 8392 / 9694 Time remaining: 0s Progress 8393 / 9694 Time remaining: 0s Progress 8394 / 9694 Time remaining: 0s Progress 8395 / 9694 Time remaining: 0s Progress 8396 / 9694 Time remaining: 0s Progress 8397 / 9694 Time remaining: 0s Progress 8398 / 9694 Time remaining: 0s Progress 8399 / 9694 Time remaining: 0s Progress 8400 / 9694 Time remaining: 0s Progress 8401 / 9694 Time remaining: 0s Progress 8402 / 9694 Time remaining: 0s Progress 8403 / 9694 Time remaining: 0s Progress 8404 / 9694 Time remaining: 0s Progress 8405 / 9694 Time remaining: 0s Progress 8406 / 9694 Time remaining: 0s Progress 8407 / 9694 Time remaining: 0s Progress 8408 / 9694 Time remaining: 0s Progress 8409 / 9694 Time remaining: 0s Progress 8410 / 9694 Time remaining: 0s Progress 8411 / 9694 Time remaining: 0s Progress 8412 / 9694 Time remaining: 0s Progress 8413 / 9694 Time remaining: 0s Progress 8414 / 9694 Time remaining: 0s Progress 8415 / 9694 Time remaining: 0s Progress 8416 / 9694 Time remaining: 0s Progress 8417 / 9694 Time remaining: 0s Progress 8418 / 9694 Time remaining: 0s Progress 8419 / 9694 Time remaining: 0s Progress 8420 / 9694 Time remaining: 0s Progress 8421 / 9694 Time remaining: 0s Progress 8422 / 9694 Time remaining: 0s Progress 8423 / 9694 Time remaining: 0s Progress 8424 / 9694 Time remaining: 0s Progress 8425 / 9694 Time remaining: 0s Progress 8426 / 9694 Time remaining: 0s Progress 8427 / 9694 Time remaining: 0s Progress 8428 / 9694 Time remaining: 0s Progress 8429 / 9694 Time remaining: 0s Progress 8430 / 9694 Time remaining: 0s Progress 8431 / 9694 Time remaining: 0s Progress 8432 / 9694 Time remaining: 0s Progress 8433 / 9694 Time remaining: 0s Progress 8434 / 9694 Time remaining: 0s Progress 8435 / 9694 Time remaining: 0s Progress 8436 / 9694 Time remaining: 0s Progress 8437 / 9694 Time remaining: 0s Progress 8438 / 9694 Time remaining: 0s Progress 8439 / 9694 Time remaining: 0s Progress 8440 / 9694 Time remaining: 0s Progress 8441 / 9694 Time remaining: 0s Progress 8442 / 9694 Time remaining: 0s Progress 8443 / 9694 Time remaining: 0s Progress 8444 / 9694 Time remaining: 0s Progress 8445 / 9694 Time remaining: 0s Progress 8446 / 9694 Time remaining: 0s Progress 8447 / 9694 Time remaining: 0s Progress 8448 / 9694 Time remaining: 0s Progress 8449 / 9694 Time remaining: 0s Progress 8450 / 9694 Time remaining: 0s Progress 8451 / 9694 Time remaining: 0s Progress 8452 / 9694 Time remaining: 0s Progress 8453 / 9694 Time remaining: 0s Progress 8454 / 9694 Time remaining: 0s Progress 8455 / 9694 Time remaining: 0s Progress 8456 / 9694 Time remaining: 0s Progress 8457 / 9694 Time remaining: 0s Progress 8458 / 9694 Time remaining: 0s Progress 8459 / 9694 Time remaining: 0s Progress 8460 / 9694 Time remaining: 0s Progress 8461 / 9694 Time remaining: 0s Progress 8462 / 9694 Time remaining: 0s Progress 8463 / 9694 Time remaining: 0s Progress 8464 / 9694 Time remaining: 0s Progress 8465 / 9694 Time remaining: 0s Progress 8466 / 9694 Time remaining: 0s Progress 8467 / 9694 Time remaining: 0s Progress 8468 / 9694 Time remaining: 0s Progress 8469 / 9694 Time remaining: 0s Progress 8470 / 9694 Time remaining: 0s Progress 8471 / 9694 Time remaining: 0s Progress 8472 / 9694 Time remaining: 0s Progress 8473 / 9694 Time remaining: 0s Progress 8474 / 9694 Time remaining: 0s Progress 8475 / 9694 Time remaining: 0s Progress 8476 / 9694 Time remaining: 0s Progress 8477 / 9694 Time remaining: 0s Progress 8478 / 9694 Time remaining: 0s Progress 8479 / 9694 Time remaining: 0s Progress 8480 / 9694 Time remaining: 0s Progress 8481 / 9694 Time remaining: 0s Progress 8482 / 9694 Time remaining: 0s Progress 8483 / 9694 Time remaining: 0s Progress 8484 / 9694 Time remaining: 0s Progress 8485 / 9694 Time remaining: 0s Progress 8486 / 9694 Time remaining: 0s Progress 8487 / 9694 Time remaining: 0s Progress 8488 / 9694 Time remaining: 0s Progress 8489 / 9694 Time remaining: 0s Progress 8490 / 9694 Time remaining: 0s Progress 8491 / 9694 Time remaining: 0s Progress 8492 / 9694 Time remaining: 0s Progress 8493 / 9694 Time remaining: 0s Progress 8494 / 9694 Time remaining: 0s Progress 8495 / 9694 Time remaining: 0s Progress 8496 / 9694 Time remaining: 0s Progress 8497 / 9694 Time remaining: 0s Progress 8498 / 9694 Time remaining: 0s Progress 8499 / 9694 Time remaining: 0s Progress 8500 / 9694 Time remaining: 0s Progress 8501 / 9694 Time remaining: 0s Progress 8502 / 9694 Time remaining: 0s Progress 8503 / 9694 Time remaining: 0s Progress 8504 / 9694 Time remaining: 0s Progress 8505 / 9694 Time remaining: 0s Progress 8506 / 9694 Time remaining: 0s Progress 8507 / 9694 Time remaining: 0s Progress 8508 / 9694 Time remaining: 0s Progress 8509 / 9694 Time remaining: 0s Progress 8510 / 9694 Time remaining: 0s Progress 8511 / 9694 Time remaining: 0s Progress 8512 / 9694 Time remaining: 0s Progress 8513 / 9694 Time remaining: 0s Progress 8514 / 9694 Time remaining: 0s Progress 8515 / 9694 Time remaining: 0s Progress 8516 / 9694 Time remaining: 0s Progress 8517 / 9694 Time remaining: 0s Progress 8518 / 9694 Time remaining: 0s Progress 8519 / 9694 Time remaining: 0s Progress 8520 / 9694 Time remaining: 0s Progress 8521 / 9694 Time remaining: 0s Progress 8522 / 9694 Time remaining: 0s Progress 8523 / 9694 Time remaining: 0s Progress 8524 / 9694 Time remaining: 0s Progress 8525 / 9694 Time remaining: 0s Progress 8526 / 9694 Time remaining: 0s Progress 8527 / 9694 Time remaining: 0s Progress 8528 / 9694 Time remaining: 0s Progress 8529 / 9694 Time remaining: 0s Progress 8530 / 9694 Time remaining: 0s Progress 8531 / 9694 Time remaining: 0s Progress 8532 / 9694 Time remaining: 0s Progress 8533 / 9694 Time remaining: 0s Progress 8534 / 9694 Time remaining: 0s Progress 8535 / 9694 Time remaining: 0s Progress 8536 / 9694 Time remaining: 0s Progress 8537 / 9694 Time remaining: 0s Progress 8538 / 9694 Time remaining: 0s Progress 8539 / 9694 Time remaining: 0s Progress 8540 / 9694 Time remaining: 0s Progress 8541 / 9694 Time remaining: 0s Progress 8542 / 9694 Time remaining: 0s Progress 8543 / 9694 Time remaining: 0s Progress 8544 / 9694 Time remaining: 0s Progress 8545 / 9694 Time remaining: 0s Progress 8546 / 9694 Time remaining: 0s Progress 8547 / 9694 Time remaining: 0s Progress 8548 / 9694 Time remaining: 0s Progress 8549 / 9694 Time remaining: 0s Progress 8550 / 9694 Time remaining: 0s Progress 8551 / 9694 Time remaining: 0s Progress 8552 / 9694 Time remaining: 0s Progress 8553 / 9694 Time remaining: 0s Progress 8554 / 9694 Time remaining: 0s Progress 8555 / 9694 Time remaining: 0s Progress 8556 / 9694 Time remaining: 0s Progress 8557 / 9694 Time remaining: 0s Progress 8558 / 9694 Time remaining: 0s Progress 8559 / 9694 Time remaining: 0s Progress 8560 / 9694 Time remaining: 0s Progress 8561 / 9694 Time remaining: 0s Progress 8562 / 9694 Time remaining: 0s Progress 8563 / 9694 Time remaining: 0s Progress 8564 / 9694 Time remaining: 0s Progress 8565 / 9694 Time remaining: 0s Progress 8566 / 9694 Time remaining: 0s Progress 8567 / 9694 Time remaining: 0s Progress 8568 / 9694 Time remaining: 0s Progress 8569 / 9694 Time remaining: 0s Progress 8570 / 9694 Time remaining: 0s Progress 8571 / 9694 Time remaining: 0s Progress 8572 / 9694 Time remaining: 0s Progress 8573 / 9694 Time remaining: 0s Progress 8574 / 9694 Time remaining: 0s Progress 8575 / 9694 Time remaining: 0s Progress 8576 / 9694 Time remaining: 0s Progress 8577 / 9694 Time remaining: 0s Progress 8578 / 9694 Time remaining: 0s Progress 8579 / 9694 Time remaining: 0s Progress 8580 / 9694 Time remaining: 0s Progress 8581 / 9694 Time remaining: 0s Progress 8582 / 9694 Time remaining: 0s Progress 8583 / 9694 Time remaining: 0s Progress 8584 / 9694 Time remaining: 0s Progress 8585 / 9694 Time remaining: 0s Progress 8586 / 9694 Time remaining: 0s Progress 8587 / 9694 Time remaining: 0s Progress 8588 / 9694 Time remaining: 0s Progress 8589 / 9694 Time remaining: 0s Progress 8590 / 9694 Time remaining: 0s Progress 8591 / 9694 Time remaining: 0s Progress 8592 / 9694 Time remaining: 0s Progress 8593 / 9694 Time remaining: 0s Progress 8594 / 9694 Time remaining: 0s Progress 8595 / 9694 Time remaining: 0s Progress 8596 / 9694 Time remaining: 0s Progress 8597 / 9694 Time remaining: 0s Progress 8598 / 9694 Time remaining: 0s Progress 8599 / 9694 Time remaining: 0s Progress 8600 / 9694 Time remaining: 0s Progress 8601 / 9694 Time remaining: 0s Progress 8602 / 9694 Time remaining: 0s Progress 8603 / 9694 Time remaining: 0s Progress 8604 / 9694 Time remaining: 0s Progress 8605 / 9694 Time remaining: 0s Progress 8606 / 9694 Time remaining: 0s Progress 8607 / 9694 Time remaining: 0s Progress 8608 / 9694 Time remaining: 0s Progress 8609 / 9694 Time remaining: 0s Progress 8610 / 9694 Time remaining: 0s Progress 8611 / 9694 Time remaining: 0s Progress 8612 / 9694 Time remaining: 0s Progress 8613 / 9694 Time remaining: 0s Progress 8614 / 9694 Time remaining: 0s Progress 8615 / 9694 Time remaining: 0s Progress 8616 / 9694 Time remaining: 0s Progress 8617 / 9694 Time remaining: 0s Progress 8618 / 9694 Time remaining: 0s Progress 8619 / 9694 Time remaining: 0s Progress 8620 / 9694 Time remaining: 0s Progress 8621 / 9694 Time remaining: 0s Progress 8622 / 9694 Time remaining: 0s Progress 8623 / 9694 Time remaining: 0s Progress 8624 / 9694 Time remaining: 0s Progress 8625 / 9694 Time remaining: 0s Progress 8626 / 9694 Time remaining: 0s Progress 8627 / 9694 Time remaining: 0s Progress 8628 / 9694 Time remaining: 0s Progress 8629 / 9694 Time remaining: 0s Progress 8630 / 9694 Time remaining: 0s Progress 8631 / 9694 Time remaining: 0s Progress 8632 / 9694 Time remaining: 0s Progress 8633 / 9694 Time remaining: 0s Progress 8634 / 9694 Time remaining: 0s Progress 8635 / 9694 Time remaining: 0s Progress 8636 / 9694 Time remaining: 0s Progress 8637 / 9694 Time remaining: 0s Progress 8638 / 9694 Time remaining: 0s Progress 8639 / 9694 Time remaining: 0s Progress 8640 / 9694 Time remaining: 0s Progress 8641 / 9694 Time remaining: 0s Progress 8642 / 9694 Time remaining: 0s Progress 8643 / 9694 Time remaining: 0s Progress 8644 / 9694 Time remaining: 0s Progress 8645 / 9694 Time remaining: 0s Progress 8646 / 9694 Time remaining: 0s Progress 8647 / 9694 Time remaining: 0s Progress 8648 / 9694 Time remaining: 0s Progress 8649 / 9694 Time remaining: 0s Progress 8650 / 9694 Time remaining: 0s Progress 8651 / 9694 Time remaining: 0s Progress 8652 / 9694 Time remaining: 0s Progress 8653 / 9694 Time remaining: 0s Progress 8654 / 9694 Time remaining: 0s Progress 8655 / 9694 Time remaining: 0s Progress 8656 / 9694 Time remaining: 0s Progress 8657 / 9694 Time remaining: 0s Progress 8658 / 9694 Time remaining: 0s Progress 8659 / 9694 Time remaining: 0s Progress 8660 / 9694 Time remaining: 0s Progress 8661 / 9694 Time remaining: 0s Progress 8662 / 9694 Time remaining: 0s Progress 8663 / 9694 Time remaining: 0s Progress 8664 / 9694 Time remaining: 0s Progress 8665 / 9694 Time remaining: 0s Progress 8666 / 9694 Time remaining: 0s Progress 8667 / 9694 Time remaining: 0s Progress 8668 / 9694 Time remaining: 0s Progress 8669 / 9694 Time remaining: 0s Progress 8670 / 9694 Time remaining: 0s Progress 8671 / 9694 Time remaining: 0s Progress 8672 / 9694 Time remaining: 0s Progress 8673 / 9694 Time remaining: 0s Progress 8674 / 9694 Time remaining: 0s Progress 8675 / 9694 Time remaining: 0s Progress 8676 / 9694 Time remaining: 0s Progress 8677 / 9694 Time remaining: 0s Progress 8678 / 9694 Time remaining: 0s Progress 8679 / 9694 Time remaining: 0s Progress 8680 / 9694 Time remaining: 0s Progress 8681 / 9694 Time remaining: 0s Progress 8682 / 9694 Time remaining: 0s Progress 8683 / 9694 Time remaining: 0s Progress 8684 / 9694 Time remaining: 0s Progress 8685 / 9694 Time remaining: 0s Progress 8686 / 9694 Time remaining: 0s Progress 8687 / 9694 Time remaining: 0s Progress 8688 / 9694 Time remaining: 0s Progress 8689 / 9694 Time remaining: 0s Progress 8690 / 9694 Time remaining: 0s Progress 8691 / 9694 Time remaining: 0s Progress 8692 / 9694 Time remaining: 0s Progress 8693 / 9694 Time remaining: 0s Progress 8694 / 9694 Time remaining: 0s Progress 8695 / 9694 Time remaining: 0s Progress 8696 / 9694 Time remaining: 0s Progress 8697 / 9694 Time remaining: 0s Progress 8698 / 9694 Time remaining: 0s Progress 8699 / 9694 Time remaining: 0s Progress 8700 / 9694 Time remaining: 0s Progress 8701 / 9694 Time remaining: 0s Progress 8702 / 9694 Time remaining: 0s Progress 8703 / 9694 Time remaining: 0s Progress 8704 / 9694 Time remaining: 0s Progress 8705 / 9694 Time remaining: 0s Progress 8706 / 9694 Time remaining: 0s Progress 8707 / 9694 Time remaining: 0s Progress 8708 / 9694 Time remaining: 0s Progress 8709 / 9694 Time remaining: 0s Progress 8710 / 9694 Time remaining: 0s Progress 8711 / 9694 Time remaining: 0s Progress 8712 / 9694 Time remaining: 0s Progress 8713 / 9694 Time remaining: 0s Progress 8714 / 9694 Time remaining: 0s Progress 8715 / 9694 Time remaining: 0s Progress 8716 / 9694 Time remaining: 0s Progress 8717 / 9694 Time remaining: 0s Progress 8718 / 9694 Time remaining: 0s Progress 8719 / 9694 Time remaining: 0s Progress 8720 / 9694 Time remaining: 0s Progress 8721 / 9694 Time remaining: 0s Progress 8722 / 9694 Time remaining: 0s Progress 8723 / 9694 Time remaining: 0s Progress 8724 / 9694 Time remaining: 0s Progress 8725 / 9694 Time remaining: 0s Progress 8726 / 9694 Time remaining: 0s Progress 8727 / 9694 Time remaining: 0s Progress 8728 / 9694 Time remaining: 0s Progress 8729 / 9694 Time remaining: 0s Progress 8730 / 9694 Time remaining: 0s Progress 8731 / 9694 Time remaining: 0s Progress 8732 / 9694 Time remaining: 0s Progress 8733 / 9694 Time remaining: 0s Progress 8734 / 9694 Time remaining: 0s Progress 8735 / 9694 Time remaining: 0s Progress 8736 / 9694 Time remaining: 0s Progress 8737 / 9694 Time remaining: 0s Progress 8738 / 9694 Time remaining: 0s Progress 8739 / 9694 Time remaining: 0s Progress 8740 / 9694 Time remaining: 0s Progress 8741 / 9694 Time remaining: 0s Progress 8742 / 9694 Time remaining: 0s Progress 8743 / 9694 Time remaining: 0s Progress 8744 / 9694 Time remaining: 0s Progress 8745 / 9694 Time remaining: 0s Progress 8746 / 9694 Time remaining: 0s Progress 8747 / 9694 Time remaining: 0s Progress 8748 / 9694 Time remaining: 0s Progress 8749 / 9694 Time remaining: 0s Progress 8750 / 9694 Time remaining: 0s Progress 8751 / 9694 Time remaining: 0s Progress 8752 / 9694 Time remaining: 0s Progress 8753 / 9694 Time remaining: 0s Progress 8754 / 9694 Time remaining: 0s Progress 8755 / 9694 Time remaining: 0s Progress 8756 / 9694 Time remaining: 0s Progress 8757 / 9694 Time remaining: 0s Progress 8758 / 9694 Time remaining: 0s Progress 8759 / 9694 Time remaining: 0s Progress 8760 / 9694 Time remaining: 0s Progress 8761 / 9694 Time remaining: 0s Progress 8762 / 9694 Time remaining: 0s Progress 8763 / 9694 Time remaining: 0s Progress 8764 / 9694 Time remaining: 0s Progress 8765 / 9694 Time remaining: 0s Progress 8766 / 9694 Time remaining: 0s Progress 8767 / 9694 Time remaining: 0s Progress 8768 / 9694 Time remaining: 0s Progress 8769 / 9694 Time remaining: 0s Progress 8770 / 9694 Time remaining: 0s Progress 8771 / 9694 Time remaining: 0s Progress 8772 / 9694 Time remaining: 0s Progress 8773 / 9694 Time remaining: 0s Progress 8774 / 9694 Time remaining: 0s Progress 8775 / 9694 Time remaining: 0s Progress 8776 / 9694 Time remaining: 0s Progress 8777 / 9694 Time remaining: 0s Progress 8778 / 9694 Time remaining: 0s Progress 8779 / 9694 Time remaining: 0s Progress 8780 / 9694 Time remaining: 0s Progress 8781 / 9694 Time remaining: 0s Progress 8782 / 9694 Time remaining: 0s Progress 8783 / 9694 Time remaining: 0s Progress 8784 / 9694 Time remaining: 0s Progress 8785 / 9694 Time remaining: 0s Progress 8786 / 9694 Time remaining: 0s Progress 8787 / 9694 Time remaining: 0s Progress 8788 / 9694 Time remaining: 0s Progress 8789 / 9694 Time remaining: 0s Progress 8790 / 9694 Time remaining: 0s Progress 8791 / 9694 Time remaining: 0s Progress 8792 / 9694 Time remaining: 0s Progress 8793 / 9694 Time remaining: 0s Progress 8794 / 9694 Time remaining: 0s Progress 8795 / 9694 Time remaining: 0s Progress 8796 / 9694 Time remaining: 0s Progress 8797 / 9694 Time remaining: 0s Progress 8798 / 9694 Time remaining: 0s Progress 8799 / 9694 Time remaining: 0s Progress 8800 / 9694 Time remaining: 0s Progress 8801 / 9694 Time remaining: 0s Progress 8802 / 9694 Time remaining: 0s Progress 8803 / 9694 Time remaining: 0s Progress 8804 / 9694 Time remaining: 0s Progress 8805 / 9694 Time remaining: 0s Progress 8806 / 9694 Time remaining: 0s Progress 8807 / 9694 Time remaining: 0s Progress 8808 / 9694 Time remaining: 0s Progress 8809 / 9694 Time remaining: 0s Progress 8810 / 9694 Time remaining: 0s Progress 8811 / 9694 Time remaining: 0s Progress 8812 / 9694 Time remaining: 0s Progress 8813 / 9694 Time remaining: 0s Progress 8814 / 9694 Time remaining: 0s Progress 8815 / 9694 Time remaining: 0s Progress 8816 / 9694 Time remaining: 0s Progress 8817 / 9694 Time remaining: 0s Progress 8818 / 9694 Time remaining: 0s Progress 8819 / 9694 Time remaining: 0s Progress 8820 / 9694 Time remaining: 0s Progress 8821 / 9694 Time remaining: 0s Progress 8822 / 9694 Time remaining: 0s Progress 8823 / 9694 Time remaining: 0s Progress 8824 / 9694 Time remaining: 0s Progress 8825 / 9694 Time remaining: 0s Progress 8826 / 9694 Time remaining: 0s Progress 8827 / 9694 Time remaining: 0s Progress 8828 / 9694 Time remaining: 0s Progress 8829 / 9694 Time remaining: 0s Progress 8830 / 9694 Time remaining: 0s Progress 8831 / 9694 Time remaining: 0s Progress 8832 / 9694 Time remaining: 0s Progress 8833 / 9694 Time remaining: 0s Progress 8834 / 9694 Time remaining: 0s Progress 8835 / 9694 Time remaining: 0s Progress 8836 / 9694 Time remaining: 0s Progress 8837 / 9694 Time remaining: 0s Progress 8838 / 9694 Time remaining: 0s Progress 8839 / 9694 Time remaining: 0s Progress 8840 / 9694 Time remaining: 0s Progress 8841 / 9694 Time remaining: 0s Progress 8842 / 9694 Time remaining: 0s Progress 8843 / 9694 Time remaining: 0s Progress 8844 / 9694 Time remaining: 0s Progress 8845 / 9694 Time remaining: 0s Progress 8846 / 9694 Time remaining: 0s Progress 8847 / 9694 Time remaining: 0s Progress 8848 / 9694 Time remaining: 0s Progress 8849 / 9694 Time remaining: 0s Progress 8850 / 9694 Time remaining: 0s Progress 8851 / 9694 Time remaining: 0s Progress 8852 / 9694 Time remaining: 0s Progress 8853 / 9694 Time remaining: 0s Progress 8854 / 9694 Time remaining: 0s Progress 8855 / 9694 Time remaining: 0s Progress 8856 / 9694 Time remaining: 0s Progress 8857 / 9694 Time remaining: 0s Progress 8858 / 9694 Time remaining: 0s Progress 8859 / 9694 Time remaining: 0s Progress 8860 / 9694 Time remaining: 0s Progress 8861 / 9694 Time remaining: 0s Progress 8862 / 9694 Time remaining: 0s Progress 8863 / 9694 Time remaining: 0s Progress 8864 / 9694 Time remaining: 0s Progress 8865 / 9694 Time remaining: 0s Progress 8866 / 9694 Time remaining: 0s Progress 8867 / 9694 Time remaining: 0s Progress 8868 / 9694 Time remaining: 0s Progress 8869 / 9694 Time remaining: 0s Progress 8870 / 9694 Time remaining: 0s Progress 8871 / 9694 Time remaining: 0s Progress 8872 / 9694 Time remaining: 0s Progress 8873 / 9694 Time remaining: 0s Progress 8874 / 9694 Time remaining: 0s Progress 8875 / 9694 Time remaining: 0s Progress 8876 / 9694 Time remaining: 0s Progress 8877 / 9694 Time remaining: 0s Progress 8878 / 9694 Time remaining: 0s Progress 8879 / 9694 Time remaining: 0s Progress 8880 / 9694 Time remaining: 0s Progress 8881 / 9694 Time remaining: 0s Progress 8882 / 9694 Time remaining: 0s Progress 8883 / 9694 Time remaining: 0s Progress 8884 / 9694 Time remaining: 0s Progress 8885 / 9694 Time remaining: 0s Progress 8886 / 9694 Time remaining: 0s Progress 8887 / 9694 Time remaining: 0s Progress 8888 / 9694 Time remaining: 0s Progress 8889 / 9694 Time remaining: 0s Progress 8890 / 9694 Time remaining: 0s Progress 8891 / 9694 Time remaining: 0s Progress 8892 / 9694 Time remaining: 0s Progress 8893 / 9694 Time remaining: 0s Progress 8894 / 9694 Time remaining: 0s Progress 8895 / 9694 Time remaining: 0s Progress 8896 / 9694 Time remaining: 0s Progress 8897 / 9694 Time remaining: 0s Progress 8898 / 9694 Time remaining: 0s Progress 8899 / 9694 Time remaining: 0s Progress 8900 / 9694 Time remaining: 0s Progress 8901 / 9694 Time remaining: 0s Progress 8902 / 9694 Time remaining: 0s Progress 8903 / 9694 Time remaining: 0s Progress 8904 / 9694 Time remaining: 0s Progress 8905 / 9694 Time remaining: 0s Progress 8906 / 9694 Time remaining: 0s Progress 8907 / 9694 Time remaining: 0s Progress 8908 / 9694 Time remaining: 0s Progress 8909 / 9694 Time remaining: 0s Progress 8910 / 9694 Time remaining: 0s Progress 8911 / 9694 Time remaining: 0s Progress 8912 / 9694 Time remaining: 0s Progress 8913 / 9694 Time remaining: 0s Progress 8914 / 9694 Time remaining: 0s Progress 8915 / 9694 Time remaining: 0s Progress 8916 / 9694 Time remaining: 0s Progress 8917 / 9694 Time remaining: 0s Progress 8918 / 9694 Time remaining: 0s Progress 8919 / 9694 Time remaining: 0s Progress 8920 / 9694 Time remaining: 0s Progress 8921 / 9694 Time remaining: 0s Progress 8922 / 9694 Time remaining: 0s Progress 8923 / 9694 Time remaining: 0s Progress 8924 / 9694 Time remaining: 0s Progress 8925 / 9694 Time remaining: 0s Progress 8926 / 9694 Time remaining: 0s Progress 8927 / 9694 Time remaining: 0s Progress 8928 / 9694 Time remaining: 0s Progress 8929 / 9694 Time remaining: 0s Progress 8930 / 9694 Time remaining: 0s Progress 8931 / 9694 Time remaining: 0s Progress 8932 / 9694 Time remaining: 0s Progress 8933 / 9694 Time remaining: 0s Progress 8934 / 9694 Time remaining: 0s Progress 8935 / 9694 Time remaining: 0s Progress 8936 / 9694 Time remaining: 0s Progress 8937 / 9694 Time remaining: 0s Progress 8938 / 9694 Time remaining: 0s Progress 8939 / 9694 Time remaining: 0s Progress 8940 / 9694 Time remaining: 0s Progress 8941 / 9694 Time remaining: 0s Progress 8942 / 9694 Time remaining: 0s Progress 8943 / 9694 Time remaining: 0s Progress 8944 / 9694 Time remaining: 0s Progress 8945 / 9694 Time remaining: 0s Progress 8946 / 9694 Time remaining: 0s Progress 8947 / 9694 Time remaining: 0s Progress 8948 / 9694 Time remaining: 0s Progress 8949 / 9694 Time remaining: 0s Progress 8950 / 9694 Time remaining: 0s Progress 8951 / 9694 Time remaining: 0s Progress 8952 / 9694 Time remaining: 0s Progress 8953 / 9694 Time remaining: 0s Progress 8954 / 9694 Time remaining: 0s Progress 8955 / 9694 Time remaining: 0s Progress 8956 / 9694 Time remaining: 0s Progress 8957 / 9694 Time remaining: 0s Progress 8958 / 9694 Time remaining: 0s Progress 8959 / 9694 Time remaining: 0s Progress 8960 / 9694 Time remaining: 0s Progress 8961 / 9694 Time remaining: 0s Progress 8962 / 9694 Time remaining: 0s Progress 8963 / 9694 Time remaining: 0s Progress 8964 / 9694 Time remaining: 0s Progress 8965 / 9694 Time remaining: 0s Progress 8966 / 9694 Time remaining: 0s Progress 8967 / 9694 Time remaining: 0s Progress 8968 / 9694 Time remaining: 0s Progress 8969 / 9694 Time remaining: 0s Progress 8970 / 9694 Time remaining: 0s Progress 8971 / 9694 Time remaining: 0s Progress 8972 / 9694 Time remaining: 0s Progress 8973 / 9694 Time remaining: 0s Progress 8974 / 9694 Time remaining: 0s Progress 8975 / 9694 Time remaining: 0s Progress 8976 / 9694 Time remaining: 0s Progress 8977 / 9694 Time remaining: 0s Progress 8978 / 9694 Time remaining: 0s Progress 8979 / 9694 Time remaining: 0s Progress 8980 / 9694 Time remaining: 0s Progress 8981 / 9694 Time remaining: 0s Progress 8982 / 9694 Time remaining: 0s Progress 8983 / 9694 Time remaining: 0s Progress 8984 / 9694 Time remaining: 0s Progress 8985 / 9694 Time remaining: 0s Progress 8986 / 9694 Time remaining: 0s Progress 8987 / 9694 Time remaining: 0s Progress 8988 / 9694 Time remaining: 0s Progress 8989 / 9694 Time remaining: 0s Progress 8990 / 9694 Time remaining: 0s Progress 8991 / 9694 Time remaining: 0s Progress 8992 / 9694 Time remaining: 0s Progress 8993 / 9694 Time remaining: 0s Progress 8994 / 9694 Time remaining: 0s Progress 8995 / 9694 Time remaining: 0s Progress 8996 / 9694 Time remaining: 0s Progress 8997 / 9694 Time remaining: 0s Progress 8998 / 9694 Time remaining: 0s Progress 8999 / 9694 Time remaining: 0s Progress 9000 / 9694 Time remaining: 0s Progress 9001 / 9694 Time remaining: 0s Progress 9002 / 9694 Time remaining: 0s Progress 9003 / 9694 Time remaining: 0s Progress 9004 / 9694 Time remaining: 0s Progress 9005 / 9694 Time remaining: 0s Progress 9006 / 9694 Time remaining: 0s Progress 9007 / 9694 Time remaining: 0s Progress 9008 / 9694 Time remaining: 0s Progress 9009 / 9694 Time remaining: 0s Progress 9010 / 9694 Time remaining: 0s Progress 9011 / 9694 Time remaining: 0s Progress 9012 / 9694 Time remaining: 0s Progress 9013 / 9694 Time remaining: 0s Progress 9014 / 9694 Time remaining: 0s Progress 9015 / 9694 Time remaining: 0s Progress 9016 / 9694 Time remaining: 0s Progress 9017 / 9694 Time remaining: 0s Progress 9018 / 9694 Time remaining: 0s Progress 9019 / 9694 Time remaining: 0s Progress 9020 / 9694 Time remaining: 0s Progress 9021 / 9694 Time remaining: 0s Progress 9022 / 9694 Time remaining: 0s Progress 9023 / 9694 Time remaining: 0s Progress 9024 / 9694 Time remaining: 0s Progress 9025 / 9694 Time remaining: 0s Progress 9026 / 9694 Time remaining: 0s Progress 9027 / 9694 Time remaining: 0s Progress 9028 / 9694 Time remaining: 0s Progress 9029 / 9694 Time remaining: 0s Progress 9030 / 9694 Time remaining: 0s Progress 9031 / 9694 Time remaining: 0s Progress 9032 / 9694 Time remaining: 0s Progress 9033 / 9694 Time remaining: 0s Progress 9034 / 9694 Time remaining: 0s Progress 9035 / 9694 Time remaining: 0s Progress 9036 / 9694 Time remaining: 0s Progress 9037 / 9694 Time remaining: 0s Progress 9038 / 9694 Time remaining: 0s Progress 9039 / 9694 Time remaining: 0s Progress 9040 / 9694 Time remaining: 0s Progress 9041 / 9694 Time remaining: 0s Progress 9042 / 9694 Time remaining: 0s Progress 9043 / 9694 Time remaining: 0s Progress 9044 / 9694 Time remaining: 0s Progress 9045 / 9694 Time remaining: 0s Progress 9046 / 9694 Time remaining: 0s Progress 9047 / 9694 Time remaining: 0s Progress 9048 / 9694 Time remaining: 0s Progress 9049 / 9694 Time remaining: 0s Progress 9050 / 9694 Time remaining: 0s Progress 9051 / 9694 Time remaining: 0s Progress 9052 / 9694 Time remaining: 0s Progress 9053 / 9694 Time remaining: 0s Progress 9054 / 9694 Time remaining: 0s Progress 9055 / 9694 Time remaining: 0s Progress 9056 / 9694 Time remaining: 0s Progress 9057 / 9694 Time remaining: 0s Progress 9058 / 9694 Time remaining: 0s Progress 9059 / 9694 Time remaining: 0s Progress 9060 / 9694 Time remaining: 0s Progress 9061 / 9694 Time remaining: 0s Progress 9062 / 9694 Time remaining: 0s Progress 9063 / 9694 Time remaining: 0s Progress 9064 / 9694 Time remaining: 0s Progress 9065 / 9694 Time remaining: 0s Progress 9066 / 9694 Time remaining: 0s Progress 9067 / 9694 Time remaining: 0s Progress 9068 / 9694 Time remaining: 0s Progress 9069 / 9694 Time remaining: 0s Progress 9070 / 9694 Time remaining: 0s Progress 9071 / 9694 Time remaining: 0s Progress 9072 / 9694 Time remaining: 0s Progress 9073 / 9694 Time remaining: 0s Progress 9074 / 9694 Time remaining: 0s Progress 9075 / 9694 Time remaining: 0s Progress 9076 / 9694 Time remaining: 0s Progress 9077 / 9694 Time remaining: 0s Progress 9078 / 9694 Time remaining: 0s Progress 9079 / 9694 Time remaining: 0s Progress 9080 / 9694 Time remaining: 0s Progress 9081 / 9694 Time remaining: 0s Progress 9082 / 9694 Time remaining: 0s Progress 9083 / 9694 Time remaining: 0s Progress 9084 / 9694 Time remaining: 0s Progress 9085 / 9694 Time remaining: 0s Progress 9086 / 9694 Time remaining: 0s Progress 9087 / 9694 Time remaining: 0s Progress 9088 / 9694 Time remaining: 0s Progress 9089 / 9694 Time remaining: 0s Progress 9090 / 9694 Time remaining: 0s Progress 9091 / 9694 Time remaining: 0s Progress 9092 / 9694 Time remaining: 0s Progress 9093 / 9694 Time remaining: 0s Progress 9094 / 9694 Time remaining: 0s Progress 9095 / 9694 Time remaining: 0s Progress 9096 / 9694 Time remaining: 0s Progress 9097 / 9694 Time remaining: 0s Progress 9098 / 9694 Time remaining: 0s Progress 9099 / 9694 Time remaining: 0s Progress 9100 / 9694 Time remaining: 0s Progress 9101 / 9694 Time remaining: 0s Progress 9102 / 9694 Time remaining: 0s Progress 9103 / 9694 Time remaining: 0s Progress 9104 / 9694 Time remaining: 0s Progress 9105 / 9694 Time remaining: 0s Progress 9106 / 9694 Time remaining: 0s Progress 9107 / 9694 Time remaining: 0s Progress 9108 / 9694 Time remaining: 0s Progress 9109 / 9694 Time remaining: 0s Progress 9110 / 9694 Time remaining: 0s Progress 9111 / 9694 Time remaining: 0s Progress 9112 / 9694 Time remaining: 0s Progress 9113 / 9694 Time remaining: 0s Progress 9114 / 9694 Time remaining: 0s Progress 9115 / 9694 Time remaining: 0s Progress 9116 / 9694 Time remaining: 0s Progress 9117 / 9694 Time remaining: 0s Progress 9118 / 9694 Time remaining: 0s Progress 9119 / 9694 Time remaining: 0s Progress 9120 / 9694 Time remaining: 0s Progress 9121 / 9694 Time remaining: 0s Progress 9122 / 9694 Time remaining: 0s Progress 9123 / 9694 Time remaining: 0s Progress 9124 / 9694 Time remaining: 0s Progress 9125 / 9694 Time remaining: 0s Progress 9126 / 9694 Time remaining: 0s Progress 9127 / 9694 Time remaining: 0s Progress 9128 / 9694 Time remaining: 0s Progress 9129 / 9694 Time remaining: 0s Progress 9130 / 9694 Time remaining: 0s Progress 9131 / 9694 Time remaining: 0s Progress 9132 / 9694 Time remaining: 0s Progress 9133 / 9694 Time remaining: 0s Progress 9134 / 9694 Time remaining: 0s Progress 9135 / 9694 Time remaining: 0s Progress 9136 / 9694 Time remaining: 0s Progress 9137 / 9694 Time remaining: 0s Progress 9138 / 9694 Time remaining: 0s Progress 9139 / 9694 Time remaining: 0s Progress 9140 / 9694 Time remaining: 0s Progress 9141 / 9694 Time remaining: 0s Progress 9142 / 9694 Time remaining: 0s Progress 9143 / 9694 Time remaining: 0s Progress 9144 / 9694 Time remaining: 0s Progress 9145 / 9694 Time remaining: 0s Progress 9146 / 9694 Time remaining: 0s Progress 9147 / 9694 Time remaining: 0s Progress 9148 / 9694 Time remaining: 0s Progress 9149 / 9694 Time remaining: 0s Progress 9150 / 9694 Time remaining: 0s Progress 9151 / 9694 Time remaining: 0s Progress 9152 / 9694 Time remaining: 0s Progress 9153 / 9694 Time remaining: 0s Progress 9154 / 9694 Time remaining: 0s Progress 9155 / 9694 Time remaining: 0s Progress 9156 / 9694 Time remaining: 0s Progress 9157 / 9694 Time remaining: 0s Progress 9158 / 9694 Time remaining: 0s Progress 9159 / 9694 Time remaining: 0s Progress 9160 / 9694 Time remaining: 0s Progress 9161 / 9694 Time remaining: 0s Progress 9162 / 9694 Time remaining: 0s Progress 9163 / 9694 Time remaining: 0s Progress 9164 / 9694 Time remaining: 0s Progress 9165 / 9694 Time remaining: 0s Progress 9166 / 9694 Time remaining: 0s Progress 9167 / 9694 Time remaining: 0s Progress 9168 / 9694 Time remaining: 0s Progress 9169 / 9694 Time remaining: 0s Progress 9170 / 9694 Time remaining: 0s Progress 9171 / 9694 Time remaining: 0s Progress 9172 / 9694 Time remaining: 0s Progress 9173 / 9694 Time remaining: 0s Progress 9174 / 9694 Time remaining: 0s Progress 9175 / 9694 Time remaining: 0s Progress 9176 / 9694 Time remaining: 0s Progress 9177 / 9694 Time remaining: 0s Progress 9178 / 9694 Time remaining: 0s Progress 9179 / 9694 Time remaining: 0s Progress 9180 / 9694 Time remaining: 0s Progress 9181 / 9694 Time remaining: 0s Progress 9182 / 9694 Time remaining: 0s Progress 9183 / 9694 Time remaining: 0s Progress 9184 / 9694 Time remaining: 0s Progress 9185 / 9694 Time remaining: 0s Progress 9186 / 9694 Time remaining: 0s Progress 9187 / 9694 Time remaining: 0s Progress 9188 / 9694 Time remaining: 0s Progress 9189 / 9694 Time remaining: 0s Progress 9190 / 9694 Time remaining: 0s Progress 9191 / 9694 Time remaining: 0s Progress 9192 / 9694 Time remaining: 0s Progress 9193 / 9694 Time remaining: 0s Progress 9194 / 9694 Time remaining: 0s Progress 9195 / 9694 Time remaining: 0s Progress 9196 / 9694 Time remaining: 0s Progress 9197 / 9694 Time remaining: 0s Progress 9198 / 9694 Time remaining: 0s Progress 9199 / 9694 Time remaining: 0s Progress 9200 / 9694 Time remaining: 0s Progress 9201 / 9694 Time remaining: 0s Progress 9202 / 9694 Time remaining: 0s Progress 9203 / 9694 Time remaining: 0s Progress 9204 / 9694 Time remaining: 0s Progress 9205 / 9694 Time remaining: 0s Progress 9206 / 9694 Time remaining: 0s Progress 9207 / 9694 Time remaining: 0s Progress 9208 / 9694 Time remaining: 0s Progress 9209 / 9694 Time remaining: 0s Progress 9210 / 9694 Time remaining: 0s Progress 9211 / 9694 Time remaining: 0s Progress 9212 / 9694 Time remaining: 0s Progress 9213 / 9694 Time remaining: 0s Progress 9214 / 9694 Time remaining: 0s Progress 9215 / 9694 Time remaining: 0s Progress 9216 / 9694 Time remaining: 0s Progress 9217 / 9694 Time remaining: 0s Progress 9218 / 9694 Time remaining: 0s Progress 9219 / 9694 Time remaining: 0s Progress 9220 / 9694 Time remaining: 0s Progress 9221 / 9694 Time remaining: 0s Progress 9222 / 9694 Time remaining: 0s Progress 9223 / 9694 Time remaining: 0s Progress 9224 / 9694 Time remaining: 0s Progress 9225 / 9694 Time remaining: 0s Progress 9226 / 9694 Time remaining: 0s Progress 9227 / 9694 Time remaining: 0s Progress 9228 / 9694 Time remaining: 0s Progress 9229 / 9694 Time remaining: 0s Progress 9230 / 9694 Time remaining: 0s Progress 9231 / 9694 Time remaining: 0s Progress 9232 / 9694 Time remaining: 0s Progress 9233 / 9694 Time remaining: 0s Progress 9234 / 9694 Time remaining: 0s Progress 9235 / 9694 Time remaining: 0s Progress 9236 / 9694 Time remaining: 0s Progress 9237 / 9694 Time remaining: 0s Progress 9238 / 9694 Time remaining: 0s Progress 9239 / 9694 Time remaining: 0s Progress 9240 / 9694 Time remaining: 0s Progress 9241 / 9694 Time remaining: 0s Progress 9242 / 9694 Time remaining: 0s Progress 9243 / 9694 Time remaining: 0s Progress 9244 / 9694 Time remaining: 0s Progress 9245 / 9694 Time remaining: 0s Progress 9246 / 9694 Time remaining: 0s Progress 9247 / 9694 Time remaining: 0s Progress 9248 / 9694 Time remaining: 0s Progress 9249 / 9694 Time remaining: 0s Progress 9250 / 9694 Time remaining: 0s Progress 9251 / 9694 Time remaining: 0s Progress 9252 / 9694 Time remaining: 0s Progress 9253 / 9694 Time remaining: 0s Progress 9254 / 9694 Time remaining: 0s Progress 9255 / 9694 Time remaining: 0s Progress 9256 / 9694 Time remaining: 0s Progress 9257 / 9694 Time remaining: 0s Progress 9258 / 9694 Time remaining: 0s Progress 9259 / 9694 Time remaining: 0s Progress 9260 / 9694 Time remaining: 0s Progress 9261 / 9694 Time remaining: 0s Progress 9262 / 9694 Time remaining: 0s Progress 9263 / 9694 Time remaining: 0s Progress 9264 / 9694 Time remaining: 0s Progress 9265 / 9694 Time remaining: 0s Progress 9266 / 9694 Time remaining: 0s Progress 9267 / 9694 Time remaining: 0s Progress 9268 / 9694 Time remaining: 0s Progress 9269 / 9694 Time remaining: 0s Progress 9270 / 9694 Time remaining: 0s Progress 9271 / 9694 Time remaining: 0s Progress 9272 / 9694 Time remaining: 0s Progress 9273 / 9694 Time remaining: 0s Progress 9274 / 9694 Time remaining: 0s Progress 9275 / 9694 Time remaining: 0s Progress 9276 / 9694 Time remaining: 0s Progress 9277 / 9694 Time remaining: 0s Progress 9278 / 9694 Time remaining: 0s Progress 9279 / 9694 Time remaining: 0s Progress 9280 / 9694 Time remaining: 0s Progress 9281 / 9694 Time remaining: 0s Progress 9282 / 9694 Time remaining: 0s Progress 9283 / 9694 Time remaining: 0s Progress 9284 / 9694 Time remaining: 0s Progress 9285 / 9694 Time remaining: 0s Progress 9286 / 9694 Time remaining: 0s Progress 9287 / 9694 Time remaining: 0s Progress 9288 / 9694 Time remaining: 0s Progress 9289 / 9694 Time remaining: 0s Progress 9290 / 9694 Time remaining: 0s Progress 9291 / 9694 Time remaining: 0s Progress 9292 / 9694 Time remaining: 0s Progress 9293 / 9694 Time remaining: 0s Progress 9294 / 9694 Time remaining: 0s Progress 9295 / 9694 Time remaining: 0s Progress 9296 / 9694 Time remaining: 0s Progress 9297 / 9694 Time remaining: 0s Progress 9298 / 9694 Time remaining: 0s Progress 9299 / 9694 Time remaining: 0s Progress 9300 / 9694 Time remaining: 0s Progress 9301 / 9694 Time remaining: 0s Progress 9302 / 9694 Time remaining: 0s Progress 9303 / 9694 Time remaining: 0s Progress 9304 / 9694 Time remaining: 0s Progress 9305 / 9694 Time remaining: 0s Progress 9306 / 9694 Time remaining: 0s Progress 9307 / 9694 Time remaining: 0s Progress 9308 / 9694 Time remaining: 0s Progress 9309 / 9694 Time remaining: 0s Progress 9310 / 9694 Time remaining: 0s Progress 9311 / 9694 Time remaining: 0s Progress 9312 / 9694 Time remaining: 0s Progress 9313 / 9694 Time remaining: 0s Progress 9314 / 9694 Time remaining: 0s Progress 9315 / 9694 Time remaining: 0s Progress 9316 / 9694 Time remaining: 0s Progress 9317 / 9694 Time remaining: 0s Progress 9318 / 9694 Time remaining: 0s Progress 9319 / 9694 Time remaining: 0s Progress 9320 / 9694 Time remaining: 0s Progress 9321 / 9694 Time remaining: 0s Progress 9322 / 9694 Time remaining: 0s Progress 9323 / 9694 Time remaining: 0s Progress 9324 / 9694 Time remaining: 0s Progress 9325 / 9694 Time remaining: 0s Progress 9326 / 9694 Time remaining: 0s Progress 9327 / 9694 Time remaining: 0s Progress 9328 / 9694 Time remaining: 0s Progress 9329 / 9694 Time remaining: 0s Progress 9330 / 9694 Time remaining: 0s Progress 9331 / 9694 Time remaining: 0s Progress 9332 / 9694 Time remaining: 0s Progress 9333 / 9694 Time remaining: 0s Progress 9334 / 9694 Time remaining: 0s Progress 9335 / 9694 Time remaining: 0s Progress 9336 / 9694 Time remaining: 0s Progress 9337 / 9694 Time remaining: 0s Progress 9338 / 9694 Time remaining: 0s Progress 9339 / 9694 Time remaining: 0s Progress 9340 / 9694 Time remaining: 0s Progress 9341 / 9694 Time remaining: 0s Progress 9342 / 9694 Time remaining: 0s Progress 9343 / 9694 Time remaining: 0s Progress 9344 / 9694 Time remaining: 0s Progress 9345 / 9694 Time remaining: 0s Progress 9346 / 9694 Time remaining: 0s Progress 9347 / 9694 Time remaining: 0s Progress 9348 / 9694 Time remaining: 0s Progress 9349 / 9694 Time remaining: 0s Progress 9350 / 9694 Time remaining: 0s Progress 9351 / 9694 Time remaining: 0s Progress 9352 / 9694 Time remaining: 0s Progress 9353 / 9694 Time remaining: 0s Progress 9354 / 9694 Time remaining: 0s Progress 9355 / 9694 Time remaining: 0s Progress 9356 / 9694 Time remaining: 0s Progress 9357 / 9694 Time remaining: 0s Progress 9358 / 9694 Time remaining: 0s Progress 9359 / 9694 Time remaining: 0s Progress 9360 / 9694 Time remaining: 0s Progress 9361 / 9694 Time remaining: 0s Progress 9362 / 9694 Time remaining: 0s Progress 9363 / 9694 Time remaining: 0s Progress 9364 / 9694 Time remaining: 0s Progress 9365 / 9694 Time remaining: 0s Progress 9366 / 9694 Time remaining: 0s Progress 9367 / 9694 Time remaining: 0s Progress 9368 / 9694 Time remaining: 0s Progress 9369 / 9694 Time remaining: 0s Progress 9370 / 9694 Time remaining: 0s Progress 9371 / 9694 Time remaining: 0s Progress 9372 / 9694 Time remaining: 0s Progress 9373 / 9694 Time remaining: 0s Progress 9374 / 9694 Time remaining: 0s Progress 9375 / 9694 Time remaining: 0s Progress 9376 / 9694 Time remaining: 0s Progress 9377 / 9694 Time remaining: 0s Progress 9378 / 9694 Time remaining: 0s Progress 9379 / 9694 Time remaining: 0s Progress 9380 / 9694 Time remaining: 0s Progress 9381 / 9694 Time remaining: 0s Progress 9382 / 9694 Time remaining: 0s Progress 9383 / 9694 Time remaining: 0s Progress 9384 / 9694 Time remaining: 0s Progress 9385 / 9694 Time remaining: 0s Progress 9386 / 9694 Time remaining: 0s Progress 9387 / 9694 Time remaining: 0s Progress 9388 / 9694 Time remaining: 0s Progress 9389 / 9694 Time remaining: 0s Progress 9390 / 9694 Time remaining: 0s Progress 9391 / 9694 Time remaining: 0s Progress 9392 / 9694 Time remaining: 0s Progress 9393 / 9694 Time remaining: 0s Progress 9394 / 9694 Time remaining: 0s Progress 9395 / 9694 Time remaining: 0s Progress 9396 / 9694 Time remaining: 0s Progress 9397 / 9694 Time remaining: 0s Progress 9398 / 9694 Time remaining: 0s Progress 9399 / 9694 Time remaining: 0s Progress 9400 / 9694 Time remaining: 0s Progress 9401 / 9694 Time remaining: 0s Progress 9402 / 9694 Time remaining: 0s Progress 9403 / 9694 Time remaining: 0s Progress 9404 / 9694 Time remaining: 0s Progress 9405 / 9694 Time remaining: 0s Progress 9406 / 9694 Time remaining: 0s Progress 9407 / 9694 Time remaining: 0s Progress 9408 / 9694 Time remaining: 0s Progress 9409 / 9694 Time remaining: 0s Progress 9410 / 9694 Time remaining: 0s Progress 9411 / 9694 Time remaining: 0s Progress 9412 / 9694 Time remaining: 0s Progress 9413 / 9694 Time remaining: 0s Progress 9414 / 9694 Time remaining: 0s Progress 9415 / 9694 Time remaining: 0s Progress 9416 / 9694 Time remaining: 0s Progress 9417 / 9694 Time remaining: 0s Progress 9418 / 9694 Time remaining: 0s Progress 9419 / 9694 Time remaining: 0s Progress 9420 / 9694 Time remaining: 0s Progress 9421 / 9694 Time remaining: 0s Progress 9422 / 9694 Time remaining: 0s Progress 9423 / 9694 Time remaining: 0s Progress 9424 / 9694 Time remaining: 0s Progress 9425 / 9694 Time remaining: 0s Progress 9426 / 9694 Time remaining: 0s Progress 9427 / 9694 Time remaining: 0s Progress 9428 / 9694 Time remaining: 0s Progress 9429 / 9694 Time remaining: 0s Progress 9430 / 9694 Time remaining: 0s Progress 9431 / 9694 Time remaining: 0s Progress 9432 / 9694 Time remaining: 0s Progress 9433 / 9694 Time remaining: 0s Progress 9434 / 9694 Time remaining: 0s Progress 9435 / 9694 Time remaining: 0s Progress 9436 / 9694 Time remaining: 0s Progress 9437 / 9694 Time remaining: 0s Progress 9438 / 9694 Time remaining: 0s Progress 9439 / 9694 Time remaining: 0s Progress 9440 / 9694 Time remaining: 0s Progress 9441 / 9694 Time remaining: 0s Progress 9442 / 9694 Time remaining: 0s Progress 9443 / 9694 Time remaining: 0s Progress 9444 / 9694 Time remaining: 0s Progress 9445 / 9694 Time remaining: 0s Progress 9446 / 9694 Time remaining: 0s Progress 9447 / 9694 Time remaining: 0s Progress 9448 / 9694 Time remaining: 0s Progress 9449 / 9694 Time remaining: 0s Progress 9450 / 9694 Time remaining: 0s Progress 9451 / 9694 Time remaining: 0s Progress 9452 / 9694 Time remaining: 0s Progress 9453 / 9694 Time remaining: 0s Progress 9454 / 9694 Time remaining: 0s Progress 9455 / 9694 Time remaining: 0s Progress 9456 / 9694 Time remaining: 0s Progress 9457 / 9694 Time remaining: 0s Progress 9458 / 9694 Time remaining: 0s Progress 9459 / 9694 Time remaining: 0s Progress 9460 / 9694 Time remaining: 0s Progress 9461 / 9694 Time remaining: 0s Progress 9462 / 9694 Time remaining: 0s Progress 9463 / 9694 Time remaining: 0s Progress 9464 / 9694 Time remaining: 0s Progress 9465 / 9694 Time remaining: 0s Progress 9466 / 9694 Time remaining: 0s Progress 9467 / 9694 Time remaining: 0s Progress 9468 / 9694 Time remaining: 0s Progress 9469 / 9694 Time remaining: 0s Progress 9470 / 9694 Time remaining: 0s Progress 9471 / 9694 Time remaining: 0s Progress 9472 / 9694 Time remaining: 0s Progress 9473 / 9694 Time remaining: 0s Progress 9474 / 9694 Time remaining: 0s Progress 9475 / 9694 Time remaining: 0s Progress 9476 / 9694 Time remaining: 0s Progress 9477 / 9694 Time remaining: 0s Progress 9478 / 9694 Time remaining: 0s Progress 9479 / 9694 Time remaining: 0s Progress 9480 / 9694 Time remaining: 0s Progress 9481 / 9694 Time remaining: 0s Progress 9482 / 9694 Time remaining: 0s Progress 9483 / 9694 Time remaining: 0s Progress 9484 / 9694 Time remaining: 0s Progress 9485 / 9694 Time remaining: 0s Progress 9486 / 9694 Time remaining: 0s Progress 9487 / 9694 Time remaining: 0s Progress 9488 / 9694 Time remaining: 0s Progress 9489 / 9694 Time remaining: 0s Progress 9490 / 9694 Time remaining: 0s Progress 9491 / 9694 Time remaining: 0s Progress 9492 / 9694 Time remaining: 0s Progress 9493 / 9694 Time remaining: 0s Progress 9494 / 9694 Time remaining: 0s Progress 9495 / 9694 Time remaining: 0s Progress 9496 / 9694 Time remaining: 0s Progress 9497 / 9694 Time remaining: 0s Progress 9498 / 9694 Time remaining: 0s Progress 9499 / 9694 Time remaining: 0s Progress 9500 / 9694 Time remaining: 0s Progress 9501 / 9694 Time remaining: 0s Progress 9502 / 9694 Time remaining: 0s Progress 9503 / 9694 Time remaining: 0s Progress 9504 / 9694 Time remaining: 0s Progress 9505 / 9694 Time remaining: 0s Progress 9506 / 9694 Time remaining: 0s Progress 9507 / 9694 Time remaining: 0s Progress 9508 / 9694 Time remaining: 0s Progress 9509 / 9694 Time remaining: 0s Progress 9510 / 9694 Time remaining: 0s Progress 9511 / 9694 Time remaining: 0s Progress 9512 / 9694 Time remaining: 0s Progress 9513 / 9694 Time remaining: 0s Progress 9514 / 9694 Time remaining: 0s Progress 9515 / 9694 Time remaining: 0s Progress 9516 / 9694 Time remaining: 0s Progress 9517 / 9694 Time remaining: 0s Progress 9518 / 9694 Time remaining: 0s Progress 9519 / 9694 Time remaining: 0s Progress 9520 / 9694 Time remaining: 0s Progress 9521 / 9694 Time remaining: 0s Progress 9522 / 9694 Time remaining: 0s Progress 9523 / 9694 Time remaining: 0s Progress 9524 / 9694 Time remaining: 0s Progress 9525 / 9694 Time remaining: 0s Progress 9526 / 9694 Time remaining: 0s Progress 9527 / 9694 Time remaining: 0s Progress 9528 / 9694 Time remaining: 0s Progress 9529 / 9694 Time remaining: 0s Progress 9530 / 9694 Time remaining: 0s Progress 9531 / 9694 Time remaining: 0s Progress 9532 / 9694 Time remaining: 0s Progress 9533 / 9694 Time remaining: 0s Progress 9534 / 9694 Time remaining: 0s Progress 9535 / 9694 Time remaining: 0s Progress 9536 / 9694 Time remaining: 0s Progress 9537 / 9694 Time remaining: 0s Progress 9538 / 9694 Time remaining: 0s Progress 9539 / 9694 Time remaining: 0s Progress 9540 / 9694 Time remaining: 0s Progress 9541 / 9694 Time remaining: 0s Progress 9542 / 9694 Time remaining: 0s Progress 9543 / 9694 Time remaining: 0s Progress 9544 / 9694 Time remaining: 0s Progress 9545 / 9694 Time remaining: 0s Progress 9546 / 9694 Time remaining: 0s Progress 9547 / 9694 Time remaining: 0s Progress 9548 / 9694 Time remaining: 0s Progress 9549 / 9694 Time remaining: 0s Progress 9550 / 9694 Time remaining: 0s Progress 9551 / 9694 Time remaining: 0s Progress 9552 / 9694 Time remaining: 0s Progress 9553 / 9694 Time remaining: 0s Progress 9554 / 9694 Time remaining: 0s Progress 9555 / 9694 Time remaining: 0s Progress 9556 / 9694 Time remaining: 0s Progress 9557 / 9694 Time remaining: 0s Progress 9558 / 9694 Time remaining: 0s Progress 9559 / 9694 Time remaining: 0s Progress 9560 / 9694 Time remaining: 0s Progress 9561 / 9694 Time remaining: 0s Progress 9562 / 9694 Time remaining: 0s Progress 9563 / 9694 Time remaining: 0s Progress 9564 / 9694 Time remaining: 0s Progress 9565 / 9694 Time remaining: 0s Progress 9566 / 9694 Time remaining: 0s Progress 9567 / 9694 Time remaining: 0s Progress 9568 / 9694 Time remaining: 0s Progress 9569 / 9694 Time remaining: 0s Progress 9570 / 9694 Time remaining: 0s Progress 9571 / 9694 Time remaining: 0s Progress 9572 / 9694 Time remaining: 0s Progress 9573 / 9694 Time remaining: 0s Progress 9574 / 9694 Time remaining: 0s Progress 9575 / 9694 Time remaining: 0s Progress 9576 / 9694 Time remaining: 0s Progress 9577 / 9694 Time remaining: 0s Progress 9578 / 9694 Time remaining: 0s Progress 9579 / 9694 Time remaining: 0s Progress 9580 / 9694 Time remaining: 0s Progress 9581 / 9694 Time remaining: 0s Progress 9582 / 9694 Time remaining: 0s Progress 9583 / 9694 Time remaining: 0s Progress 9584 / 9694 Time remaining: 0s Progress 9585 / 9694 Time remaining: 0s Progress 9586 / 9694 Time remaining: 0s Progress 9587 / 9694 Time remaining: 0s Progress 9588 / 9694 Time remaining: 0s Progress 9589 / 9694 Time remaining: 0s Progress 9590 / 9694 Time remaining: 0s Progress 9591 / 9694 Time remaining: 0s Progress 9592 / 9694 Time remaining: 0s Progress 9593 / 9694 Time remaining: 0s Progress 9594 / 9694 Time remaining: 0s Progress 9595 / 9694 Time remaining: 0s Progress 9596 / 9694 Time remaining: 0s Progress 9597 / 9694 Time remaining: 0s Progress 9598 / 9694 Time remaining: 0s Progress 9599 / 9694 Time remaining: 0s Progress 9600 / 9694 Time remaining: 0s Progress 9601 / 9694 Time remaining: 0s Progress 9602 / 9694 Time remaining: 0s Progress 9603 / 9694 Time remaining: 0s Progress 9604 / 9694 Time remaining: 0s Progress 9605 / 9694 Time remaining: 0s Progress 9606 / 9694 Time remaining: 0s Progress 9607 / 9694 Time remaining: 0s Progress 9608 / 9694 Time remaining: 0s Progress 9609 / 9694 Time remaining: 0s Progress 9610 / 9694 Time remaining: 0s Progress 9611 / 9694 Time remaining: 0s Progress 9612 / 9694 Time remaining: 0s Progress 9613 / 9694 Time remaining: 0s Progress 9614 / 9694 Time remaining: 0s Progress 9615 / 9694 Time remaining: 0s Progress 9616 / 9694 Time remaining: 0s Progress 9617 / 9694 Time remaining: 0s Progress 9618 / 9694 Time remaining: 0s Progress 9619 / 9694 Time remaining: 0s Progress 9620 / 9694 Time remaining: 0s Progress 9621 / 9694 Time remaining: 0s Progress 9622 / 9694 Time remaining: 0s Progress 9623 / 9694 Time remaining: 0s Progress 9624 / 9694 Time remaining: 0s Progress 9625 / 9694 Time remaining: 0s Progress 9626 / 9694 Time remaining: 0s Progress 9627 / 9694 Time remaining: 0s Progress 9628 / 9694 Time remaining: 0s Progress 9629 / 9694 Time remaining: 0s Progress 9630 / 9694 Time remaining: 0s Progress 9631 / 9694 Time remaining: 0s Progress 9632 / 9694 Time remaining: 0s Progress 9633 / 9694 Time remaining: 0s Progress 9634 / 9694 Time remaining: 0s Progress 9635 / 9694 Time remaining: 0s Progress 9636 / 9694 Time remaining: 0s Progress 9637 / 9694 Time remaining: 0s Progress 9638 / 9694 Time remaining: 0s Progress 9639 / 9694 Time remaining: 0s Progress 9640 / 9694 Time remaining: 0s Progress 9641 / 9694 Time remaining: 0s Progress 9642 / 9694 Time remaining: 0s Progress 9643 / 9694 Time remaining: 0s Progress 9644 / 9694 Time remaining: 0s Progress 9645 / 9694 Time remaining: 0s Progress 9646 / 9694 Time remaining: 0s Progress 9647 / 9694 Time remaining: 0s Progress 9648 / 9694 Time remaining: 0s Progress 9649 / 9694 Time remaining: 0s Progress 9650 / 9694 Time remaining: 0s Progress 9651 / 9694 Time remaining: 0s Progress 9652 / 9694 Time remaining: 0s Progress 9653 / 9694 Time remaining: 0s Progress 9654 / 9694 Time remaining: 0s Progress 9655 / 9694 Time remaining: 0s Progress 9656 / 9694 Time remaining: 0s Progress 9657 / 9694 Time remaining: 0s Progress 9658 / 9694 Time remaining: 0s Progress 9659 / 9694 Time remaining: 0s Progress 9660 / 9694 Time remaining: 0s Progress 9661 / 9694 Time remaining: 0s Progress 9662 / 9694 Time remaining: 0s Progress 9663 / 9694 Time remaining: 0s Progress 9664 / 9694 Time remaining: 0s Progress 9665 / 9694 Time remaining: 0s Progress 9666 / 9694 Time remaining: 0s Progress 9667 / 9694 Time remaining: 0s Progress 9668 / 9694 Time remaining: 0s Progress 9669 / 9694 Time remaining: 0s Progress 9670 / 9694 Time remaining: 0s Progress 9671 / 9694 Time remaining: 0s Progress 9672 / 9694 Time remaining: 0s Progress 9673 / 9694 Time remaining: 0s Progress 9674 / 9694 Time remaining: 0s Progress 9675 / 9694 Time remaining: 0s Progress 9676 / 9694 Time remaining: 0s Progress 9677 / 9694 Time remaining: 0s Progress 9678 / 9694 Time remaining: 0s Progress 9679 / 9694 Time remaining: 0s Progress 9680 / 9694 Time remaining: 0s Progress 9681 / 9694 Time remaining: 0s Progress 9682 / 9694 Time remaining: 0s Progress 9683 / 9694 Time remaining: 0s Progress 9684 / 9694 Time remaining: 0s Progress 9685 / 9694 Time remaining: 0s Progress 9686 / 9694 Time remaining: 0s Progress 9687 / 9694 Time remaining: 0s Progress 9688 / 9694 Time remaining: 0s Progress 9689 / 9694 Time remaining: 0s Progress 9690 / 9694 Time remaining: 0s Progress 9691 / 9694 Time remaining: 0s Progress 9692 / 9694 Time remaining: 0s Progress 9693 / 9694 Time remaining: 0s Progress 9694 / 9694 Time remaining: Added 9687 of 9694 accelerometer error terms (skipped 7 out-of-bounds measurements) + +Adding gyroscope error terms (/imu0) + Progress 1 / 9694 Time remaining: 3s Progress 2 / 9694 Time remaining: 3s Progress 3 / 9694 Time remaining: 3s Progress 4 / 9694 Time remaining: 4s Progress 5 / 9694 Time remaining: 4s Progress 6 / 9694 Time remaining: 5s Progress 7 / 9694 Time remaining: 5s Progress 8 / 9694 Time remaining: 5s Progress 9 / 9694 Time remaining: 5s Progress 10 / 9694 Time remaining: 5s Progress 11 / 9694 Time remaining: 5s Progress 12 / 9694 Time remaining: 5s Progress 13 / 9694 Time remaining: 6s Progress 14 / 9694 Time remaining: 6s Progress 15 / 9694 Time remaining: 6s Progress 16 / 9694 Time remaining: 6s Progress 17 / 9694 Time remaining: 6s Progress 18 / 9694 Time remaining: 6s Progress 19 / 9694 Time remaining: 6s Progress 20 / 9694 Time remaining: 6s Progress 21 / 9694 Time remaining: 6s Progress 22 / 9694 Time remaining: 6s Progress 23 / 9694 Time remaining: 6s Progress 24 / 9694 Time remaining: 6s Progress 25 / 9694 Time remaining: 6s Progress 26 / 9694 Time remaining: 6s Progress 27 / 9694 Time remaining: 6s Progress 28 / 9694 Time remaining: 6s Progress 29 / 9694 Time remaining: 6s Progress 30 / 9694 Time remaining: 6s Progress 31 / 9694 Time remaining: 6s Progress 32 / 9694 Time remaining: 6s Progress 33 / 9694 Time remaining: 6s Progress 34 / 9694 Time remaining: 6s Progress 35 / 9694 Time remaining: 6s Progress 36 / 9694 Time remaining: 6s Progress 37 / 9694 Time remaining: 6s Progress 38 / 9694 Time remaining: 6s Progress 39 / 9694 Time remaining: 6s Progress 40 / 9694 Time remaining: 6s Progress 41 / 9694 Time remaining: 6s Progress 42 / 9694 Time remaining: 6s Progress 43 / 9694 Time remaining: 6s Progress 44 / 9694 Time remaining: 6s Progress 45 / 9694 Time remaining: 6s Progress 46 / 9694 Time remaining: 6s Progress 47 / 9694 Time remaining: 6s Progress 48 / 9694 Time remaining: 6s Progress 49 / 9694 Time remaining: 6s Progress 50 / 9694 Time remaining: 6s Progress 51 / 9694 Time remaining: 6s Progress 52 / 9694 Time remaining: 6s Progress 53 / 9694 Time remaining: 6s Progress 54 / 9694 Time remaining: 6s Progress 55 / 9694 Time remaining: 6s Progress 56 / 9694 Time remaining: 6s Progress 57 / 9694 Time remaining: 6s Progress 58 / 9694 Time remaining: 6s Progress 59 / 9694 Time remaining: 6s Progress 60 / 9694 Time remaining: 6s Progress 61 / 9694 Time remaining: 6s Progress 62 / 9694 Time remaining: 6s Progress 63 / 9694 Time remaining: 6s Progress 64 / 9694 Time remaining: 6s Progress 65 / 9694 Time remaining: 6s Progress 66 / 9694 Time remaining: 6s Progress 67 / 9694 Time remaining: 6s Progress 68 / 9694 Time remaining: 6s Progress 69 / 9694 Time remaining: 6s Progress 70 / 9694 Time remaining: 6s Progress 71 / 9694 Time remaining: 6s Progress 72 / 9694 Time remaining: 6s Progress 73 / 9694 Time remaining: 6s Progress 74 / 9694 Time remaining: 6s Progress 75 / 9694 Time remaining: 6s Progress 76 / 9694 Time remaining: 6s Progress 77 / 9694 Time remaining: 6s Progress 78 / 9694 Time remaining: 6s Progress 79 / 9694 Time remaining: 6s Progress 80 / 9694 Time remaining: 6s Progress 81 / 9694 Time remaining: 6s Progress 82 / 9694 Time remaining: 6s Progress 83 / 9694 Time remaining: 6s Progress 84 / 9694 Time remaining: 6s Progress 85 / 9694 Time remaining: 6s Progress 86 / 9694 Time remaining: 6s Progress 87 / 9694 Time remaining: 6s Progress 88 / 9694 Time remaining: 6s Progress 89 / 9694 Time remaining: 6s Progress 90 / 9694 Time remaining: 6s Progress 91 / 9694 Time remaining: 6s Progress 92 / 9694 Time remaining: 6s Progress 93 / 9694 Time remaining: 6s Progress 94 / 9694 Time remaining: 6s Progress 95 / 9694 Time remaining: 6s Progress 96 / 9694 Time remaining: 6s Progress 97 / 9694 Time remaining: 6s Progress 98 / 9694 Time remaining: 6s Progress 99 / 9694 Time remaining: 6s Progress 100 / 9694 Time remaining: 6s Progress 101 / 9694 Time remaining: 6s Progress 102 / 9694 Time remaining: 6s Progress 103 / 9694 Time remaining: 6s Progress 104 / 9694 Time remaining: 6s Progress 105 / 9694 Time remaining: 6s Progress 106 / 9694 Time remaining: 6s Progress 107 / 9694 Time remaining: 6s Progress 108 / 9694 Time remaining: 6s Progress 109 / 9694 Time remaining: 6s Progress 110 / 9694 Time remaining: 6s Progress 111 / 9694 Time remaining: 6s Progress 112 / 9694 Time remaining: 6s Progress 113 / 9694 Time remaining: 6s Progress 114 / 9694 Time remaining: 6s Progress 115 / 9694 Time remaining: 6s Progress 116 / 9694 Time remaining: 6s Progress 117 / 9694 Time remaining: 6s Progress 118 / 9694 Time remaining: 6s Progress 119 / 9694 Time remaining: 6s Progress 120 / 9694 Time remaining: 6s Progress 121 / 9694 Time remaining: 6s Progress 122 / 9694 Time remaining: 6s Progress 123 / 9694 Time remaining: 6s Progress 124 / 9694 Time remaining: 6s Progress 125 / 9694 Time remaining: 6s Progress 126 / 9694 Time remaining: 6s Progress 127 / 9694 Time remaining: 6s Progress 128 / 9694 Time remaining: 6s Progress 129 / 9694 Time remaining: 6s Progress 130 / 9694 Time remaining: 6s Progress 131 / 9694 Time remaining: 6s Progress 132 / 9694 Time remaining: 6s Progress 133 / 9694 Time remaining: 6s Progress 134 / 9694 Time remaining: 6s Progress 135 / 9694 Time remaining: 6s Progress 136 / 9694 Time remaining: 6s Progress 137 / 9694 Time remaining: 6s Progress 138 / 9694 Time remaining: 6s Progress 139 / 9694 Time remaining: 6s Progress 140 / 9694 Time remaining: 6s Progress 141 / 9694 Time remaining: 6s Progress 142 / 9694 Time remaining: 6s Progress 143 / 9694 Time remaining: 6s Progress 144 / 9694 Time remaining: 6s Progress 145 / 9694 Time remaining: 6s Progress 146 / 9694 Time remaining: 6s Progress 147 / 9694 Time remaining: 6s Progress 148 / 9694 Time remaining: 6s Progress 149 / 9694 Time remaining: 6s Progress 150 / 9694 Time remaining: 6s Progress 151 / 9694 Time remaining: 6s Progress 152 / 9694 Time remaining: 6s Progress 153 / 9694 Time remaining: 6s Progress 154 / 9694 Time remaining: 6s Progress 155 / 9694 Time remaining: 6s Progress 156 / 9694 Time remaining: 6s Progress 157 / 9694 Time remaining: 6s Progress 158 / 9694 Time remaining: 6s Progress 159 / 9694 Time remaining: 6s Progress 160 / 9694 Time remaining: 6s Progress 161 / 9694 Time remaining: 6s Progress 162 / 9694 Time remaining: 6s Progress 163 / 9694 Time remaining: 6s Progress 164 / 9694 Time remaining: 6s Progress 165 / 9694 Time remaining: 6s Progress 166 / 9694 Time remaining: 6s Progress 167 / 9694 Time remaining: 6s Progress 168 / 9694 Time remaining: 6s Progress 169 / 9694 Time remaining: 6s Progress 170 / 9694 Time remaining: 6s Progress 171 / 9694 Time remaining: 6s Progress 172 / 9694 Time remaining: 6s Progress 173 / 9694 Time remaining: 6s Progress 174 / 9694 Time remaining: 6s Progress 175 / 9694 Time remaining: 6s Progress 176 / 9694 Time remaining: 6s Progress 177 / 9694 Time remaining: 6s Progress 178 / 9694 Time remaining: 6s Progress 179 / 9694 Time remaining: 6s Progress 180 / 9694 Time remaining: 6s Progress 181 / 9694 Time remaining: 6s Progress 182 / 9694 Time remaining: 6s Progress 183 / 9694 Time remaining: 6s Progress 184 / 9694 Time remaining: 6s Progress 185 / 9694 Time remaining: 6s Progress 186 / 9694 Time remaining: 6s Progress 187 / 9694 Time remaining: 6s Progress 188 / 9694 Time remaining: 6s Progress 189 / 9694 Time remaining: 6s Progress 190 / 9694 Time remaining: 6s Progress 191 / 9694 Time remaining: 6s Progress 192 / 9694 Time remaining: 6s Progress 193 / 9694 Time remaining: 6s Progress 194 / 9694 Time remaining: 6s Progress 195 / 9694 Time remaining: 6s Progress 196 / 9694 Time remaining: 6s Progress 197 / 9694 Time remaining: 6s Progress 198 / 9694 Time remaining: 6s Progress 199 / 9694 Time remaining: 6s Progress 200 / 9694 Time remaining: 6s Progress 201 / 9694 Time remaining: 6s Progress 202 / 9694 Time remaining: 6s Progress 203 / 9694 Time remaining: 6s Progress 204 / 9694 Time remaining: 6s Progress 205 / 9694 Time remaining: 6s Progress 206 / 9694 Time remaining: 6s Progress 207 / 9694 Time remaining: 6s Progress 208 / 9694 Time remaining: 6s Progress 209 / 9694 Time remaining: 6s Progress 210 / 9694 Time remaining: 6s Progress 211 / 9694 Time remaining: 6s Progress 212 / 9694 Time remaining: 6s Progress 213 / 9694 Time remaining: 6s Progress 214 / 9694 Time remaining: 6s Progress 215 / 9694 Time remaining: 6s Progress 216 / 9694 Time remaining: 6s Progress 217 / 9694 Time remaining: 6s Progress 218 / 9694 Time remaining: 6s Progress 219 / 9694 Time remaining: 6s Progress 220 / 9694 Time remaining: 6s Progress 221 / 9694 Time remaining: 6s Progress 222 / 9694 Time remaining: 6s Progress 223 / 9694 Time remaining: 6s Progress 224 / 9694 Time remaining: 6s Progress 225 / 9694 Time remaining: 6s Progress 226 / 9694 Time remaining: 6s Progress 227 / 9694 Time remaining: 6s Progress 228 / 9694 Time remaining: 6s Progress 229 / 9694 Time remaining: 6s Progress 230 / 9694 Time remaining: 6s Progress 231 / 9694 Time remaining: 6s Progress 232 / 9694 Time remaining: 6s Progress 233 / 9694 Time remaining: 6s Progress 234 / 9694 Time remaining: 6s Progress 235 / 9694 Time remaining: 6s Progress 236 / 9694 Time remaining: 6s Progress 237 / 9694 Time remaining: 6s Progress 238 / 9694 Time remaining: 6s Progress 239 / 9694 Time remaining: 6s Progress 240 / 9694 Time remaining: 6s Progress 241 / 9694 Time remaining: 6s Progress 242 / 9694 Time remaining: 6s Progress 243 / 9694 Time remaining: 6s Progress 244 / 9694 Time remaining: 6s Progress 245 / 9694 Time remaining: 6s Progress 246 / 9694 Time remaining: 6s Progress 247 / 9694 Time remaining: 6s Progress 248 / 9694 Time remaining: 6s Progress 249 / 9694 Time remaining: 6s Progress 250 / 9694 Time remaining: 6s Progress 251 / 9694 Time remaining: 6s Progress 252 / 9694 Time remaining: 6s Progress 253 / 9694 Time remaining: 6s Progress 254 / 9694 Time remaining: 6s Progress 255 / 9694 Time remaining: 6s Progress 256 / 9694 Time remaining: 6s Progress 257 / 9694 Time remaining: 6s Progress 258 / 9694 Time remaining: 6s Progress 259 / 9694 Time remaining: 6s Progress 260 / 9694 Time remaining: 6s Progress 261 / 9694 Time remaining: 6s Progress 262 / 9694 Time remaining: 6s Progress 263 / 9694 Time remaining: 6s Progress 264 / 9694 Time remaining: 6s Progress 265 / 9694 Time remaining: 6s Progress 266 / 9694 Time remaining: 6s Progress 267 / 9694 Time remaining: 6s Progress 268 / 9694 Time remaining: 6s Progress 269 / 9694 Time remaining: 6s Progress 270 / 9694 Time remaining: 6s Progress 271 / 9694 Time remaining: 6s Progress 272 / 9694 Time remaining: 6s Progress 273 / 9694 Time remaining: 6s Progress 274 / 9694 Time remaining: 6s Progress 275 / 9694 Time remaining: 6s Progress 276 / 9694 Time remaining: 6s Progress 277 / 9694 Time remaining: 6s Progress 278 / 9694 Time remaining: 6s Progress 279 / 9694 Time remaining: 6s Progress 280 / 9694 Time remaining: 6s Progress 281 / 9694 Time remaining: 6s Progress 282 / 9694 Time remaining: 6s Progress 283 / 9694 Time remaining: 6s Progress 284 / 9694 Time remaining: 6s Progress 285 / 9694 Time remaining: 6s Progress 286 / 9694 Time remaining: 6s Progress 287 / 9694 Time remaining: 6s Progress 288 / 9694 Time remaining: 6s Progress 289 / 9694 Time remaining: 6s Progress 290 / 9694 Time remaining: 6s Progress 291 / 9694 Time remaining: 6s Progress 292 / 9694 Time remaining: 6s Progress 293 / 9694 Time remaining: 6s Progress 294 / 9694 Time remaining: 6s Progress 295 / 9694 Time remaining: 6s Progress 296 / 9694 Time remaining: 6s Progress 297 / 9694 Time remaining: 6s Progress 298 / 9694 Time remaining: 6s Progress 299 / 9694 Time remaining: 6s Progress 300 / 9694 Time remaining: 6s Progress 301 / 9694 Time remaining: 6s Progress 302 / 9694 Time remaining: 6s Progress 303 / 9694 Time remaining: 6s Progress 304 / 9694 Time remaining: 6s Progress 305 / 9694 Time remaining: 6s Progress 306 / 9694 Time remaining: 6s Progress 307 / 9694 Time remaining: 6s Progress 308 / 9694 Time remaining: 6s Progress 309 / 9694 Time remaining: 6s Progress 310 / 9694 Time remaining: 6s Progress 311 / 9694 Time remaining: 6s Progress 312 / 9694 Time remaining: 6s Progress 313 / 9694 Time remaining: 6s Progress 314 / 9694 Time remaining: 6s Progress 315 / 9694 Time remaining: 6s Progress 316 / 9694 Time remaining: 6s Progress 317 / 9694 Time remaining: 6s Progress 318 / 9694 Time remaining: 6s Progress 319 / 9694 Time remaining: 6s Progress 320 / 9694 Time remaining: 6s Progress 321 / 9694 Time remaining: 6s Progress 322 / 9694 Time remaining: 6s Progress 323 / 9694 Time remaining: 6s Progress 324 / 9694 Time remaining: 6s Progress 325 / 9694 Time remaining: 6s Progress 326 / 9694 Time remaining: 6s Progress 327 / 9694 Time remaining: 6s Progress 328 / 9694 Time remaining: 6s Progress 329 / 9694 Time remaining: 6s Progress 330 / 9694 Time remaining: 6s Progress 331 / 9694 Time remaining: 6s Progress 332 / 9694 Time remaining: 6s Progress 333 / 9694 Time remaining: 6s Progress 334 / 9694 Time remaining: 6s Progress 335 / 9694 Time remaining: 6s Progress 336 / 9694 Time remaining: 6s Progress 337 / 9694 Time remaining: 6s Progress 338 / 9694 Time remaining: 6s Progress 339 / 9694 Time remaining: 6s Progress 340 / 9694 Time remaining: 6s Progress 341 / 9694 Time remaining: 6s Progress 342 / 9694 Time remaining: 6s Progress 343 / 9694 Time remaining: 6s Progress 344 / 9694 Time remaining: 6s Progress 345 / 9694 Time remaining: 6s Progress 346 / 9694 Time remaining: 6s Progress 347 / 9694 Time remaining: 6s Progress 348 / 9694 Time remaining: 6s Progress 349 / 9694 Time remaining: 6s Progress 350 / 9694 Time remaining: 6s Progress 351 / 9694 Time remaining: 6s Progress 352 / 9694 Time remaining: 6s Progress 353 / 9694 Time remaining: 6s Progress 354 / 9694 Time remaining: 6s Progress 355 / 9694 Time remaining: 6s Progress 356 / 9694 Time remaining: 6s Progress 357 / 9694 Time remaining: 6s Progress 358 / 9694 Time remaining: 6s Progress 359 / 9694 Time remaining: 6s Progress 360 / 9694 Time remaining: 6s Progress 361 / 9694 Time remaining: 6s Progress 362 / 9694 Time remaining: 6s Progress 363 / 9694 Time remaining: 6s Progress 364 / 9694 Time remaining: 6s Progress 365 / 9694 Time remaining: 6s Progress 366 / 9694 Time remaining: 6s Progress 367 / 9694 Time remaining: 6s Progress 368 / 9694 Time remaining: 6s Progress 369 / 9694 Time remaining: 6s Progress 370 / 9694 Time remaining: 6s Progress 371 / 9694 Time remaining: 6s Progress 372 / 9694 Time remaining: 6s Progress 373 / 9694 Time remaining: 6s Progress 374 / 9694 Time remaining: 6s Progress 375 / 9694 Time remaining: 6s Progress 376 / 9694 Time remaining: 6s Progress 377 / 9694 Time remaining: 6s Progress 378 / 9694 Time remaining: 6s Progress 379 / 9694 Time remaining: 6s Progress 380 / 9694 Time remaining: 6s Progress 381 / 9694 Time remaining: 6s Progress 382 / 9694 Time remaining: 6s Progress 383 / 9694 Time remaining: 6s Progress 384 / 9694 Time remaining: 6s Progress 385 / 9694 Time remaining: 6s Progress 386 / 9694 Time remaining: 6s Progress 387 / 9694 Time remaining: 6s Progress 388 / 9694 Time remaining: 6s Progress 389 / 9694 Time remaining: 6s Progress 390 / 9694 Time remaining: 6s Progress 391 / 9694 Time remaining: 6s Progress 392 / 9694 Time remaining: 6s Progress 393 / 9694 Time remaining: 6s Progress 394 / 9694 Time remaining: 6s Progress 395 / 9694 Time remaining: 6s Progress 396 / 9694 Time remaining: 6s Progress 397 / 9694 Time remaining: 6s Progress 398 / 9694 Time remaining: 6s Progress 399 / 9694 Time remaining: 6s Progress 400 / 9694 Time remaining: 6s Progress 401 / 9694 Time remaining: 6s Progress 402 / 9694 Time remaining: 6s Progress 403 / 9694 Time remaining: 6s Progress 404 / 9694 Time remaining: 6s Progress 405 / 9694 Time remaining: 6s Progress 406 / 9694 Time remaining: 6s Progress 407 / 9694 Time remaining: 6s Progress 408 / 9694 Time remaining: 6s Progress 409 / 9694 Time remaining: 6s Progress 410 / 9694 Time remaining: 6s Progress 411 / 9694 Time remaining: 6s Progress 412 / 9694 Time remaining: 6s Progress 413 / 9694 Time remaining: 6s Progress 414 / 9694 Time remaining: 6s Progress 415 / 9694 Time remaining: 6s Progress 416 / 9694 Time remaining: 6s Progress 417 / 9694 Time remaining: 6s Progress 418 / 9694 Time remaining: 6s Progress 419 / 9694 Time remaining: 6s Progress 420 / 9694 Time remaining: 6s Progress 421 / 9694 Time remaining: 6s Progress 422 / 9694 Time remaining: 6s Progress 423 / 9694 Time remaining: 6s Progress 424 / 9694 Time remaining: 6s Progress 425 / 9694 Time remaining: 6s Progress 426 / 9694 Time remaining: 6s Progress 427 / 9694 Time remaining: 6s Progress 428 / 9694 Time remaining: 6s Progress 429 / 9694 Time remaining: 6s Progress 430 / 9694 Time remaining: 6s Progress 431 / 9694 Time remaining: 6s Progress 432 / 9694 Time remaining: 6s Progress 433 / 9694 Time remaining: 6s Progress 434 / 9694 Time remaining: 6s Progress 435 / 9694 Time remaining: 6s Progress 436 / 9694 Time remaining: 6s Progress 437 / 9694 Time remaining: 6s Progress 438 / 9694 Time remaining: 6s Progress 439 / 9694 Time remaining: 6s Progress 440 / 9694 Time remaining: 6s Progress 441 / 9694 Time remaining: 6s Progress 442 / 9694 Time remaining: 6s Progress 443 / 9694 Time remaining: 6s Progress 444 / 9694 Time remaining: 6s Progress 445 / 9694 Time remaining: 6s Progress 446 / 9694 Time remaining: 6s Progress 447 / 9694 Time remaining: 6s Progress 448 / 9694 Time remaining: 6s Progress 449 / 9694 Time remaining: 6s Progress 450 / 9694 Time remaining: 6s Progress 451 / 9694 Time remaining: 6s Progress 452 / 9694 Time remaining: 6s Progress 453 / 9694 Time remaining: 6s Progress 454 / 9694 Time remaining: 6s Progress 455 / 9694 Time remaining: 6s Progress 456 / 9694 Time remaining: 6s Progress 457 / 9694 Time remaining: 6s Progress 458 / 9694 Time remaining: 6s Progress 459 / 9694 Time remaining: 6s Progress 460 / 9694 Time remaining: 6s Progress 461 / 9694 Time remaining: 6s Progress 462 / 9694 Time remaining: 6s Progress 463 / 9694 Time remaining: 6s Progress 464 / 9694 Time remaining: 6s Progress 465 / 9694 Time remaining: 6s Progress 466 / 9694 Time remaining: 6s Progress 467 / 9694 Time remaining: 6s Progress 468 / 9694 Time remaining: 6s Progress 469 / 9694 Time remaining: 6s Progress 470 / 9694 Time remaining: 6s Progress 471 / 9694 Time remaining: 6s Progress 472 / 9694 Time remaining: 6s Progress 473 / 9694 Time remaining: 6s Progress 474 / 9694 Time remaining: 6s Progress 475 / 9694 Time remaining: 6s Progress 476 / 9694 Time remaining: 6s Progress 477 / 9694 Time remaining: 6s Progress 478 / 9694 Time remaining: 6s Progress 479 / 9694 Time remaining: 6s Progress 480 / 9694 Time remaining: 6s Progress 481 / 9694 Time remaining: 6s Progress 482 / 9694 Time remaining: 6s Progress 483 / 9694 Time remaining: 6s Progress 484 / 9694 Time remaining: 6s Progress 485 / 9694 Time remaining: 6s Progress 486 / 9694 Time remaining: 6s Progress 487 / 9694 Time remaining: 6s Progress 488 / 9694 Time remaining: 6s Progress 489 / 9694 Time remaining: 6s Progress 490 / 9694 Time remaining: 6s Progress 491 / 9694 Time remaining: 6s Progress 492 / 9694 Time remaining: 6s Progress 493 / 9694 Time remaining: 6s Progress 494 / 9694 Time remaining: 6s Progress 495 / 9694 Time remaining: 6s Progress 496 / 9694 Time remaining: 6s Progress 497 / 9694 Time remaining: 6s Progress 498 / 9694 Time remaining: 6s Progress 499 / 9694 Time remaining: 6s Progress 500 / 9694 Time remaining: 6s Progress 501 / 9694 Time remaining: 6s Progress 502 / 9694 Time remaining: 6s Progress 503 / 9694 Time remaining: 6s Progress 504 / 9694 Time remaining: 6s Progress 505 / 9694 Time remaining: 6s Progress 506 / 9694 Time remaining: 6s Progress 507 / 9694 Time remaining: 6s Progress 508 / 9694 Time remaining: 6s Progress 509 / 9694 Time remaining: 6s Progress 510 / 9694 Time remaining: 6s Progress 511 / 9694 Time remaining: 6s Progress 512 / 9694 Time remaining: 6s Progress 513 / 9694 Time remaining: 6s Progress 514 / 9694 Time remaining: 6s Progress 515 / 9694 Time remaining: 6s Progress 516 / 9694 Time remaining: 6s Progress 517 / 9694 Time remaining: 6s Progress 518 / 9694 Time remaining: 6s Progress 519 / 9694 Time remaining: 6s Progress 520 / 9694 Time remaining: 6s Progress 521 / 9694 Time remaining: 6s Progress 522 / 9694 Time remaining: 6s Progress 523 / 9694 Time remaining: 6s Progress 524 / 9694 Time remaining: 6s Progress 525 / 9694 Time remaining: 6s Progress 526 / 9694 Time remaining: 6s Progress 527 / 9694 Time remaining: 6s Progress 528 / 9694 Time remaining: 6s Progress 529 / 9694 Time remaining: 6s Progress 530 / 9694 Time remaining: 6s Progress 531 / 9694 Time remaining: 6s Progress 532 / 9694 Time remaining: 6s Progress 533 / 9694 Time remaining: 6s Progress 534 / 9694 Time remaining: 6s Progress 535 / 9694 Time remaining: 6s Progress 536 / 9694 Time remaining: 6s Progress 537 / 9694 Time remaining: 6s Progress 538 / 9694 Time remaining: 6s Progress 539 / 9694 Time remaining: 6s Progress 540 / 9694 Time remaining: 6s Progress 541 / 9694 Time remaining: 6s Progress 542 / 9694 Time remaining: 6s Progress 543 / 9694 Time remaining: 6s Progress 544 / 9694 Time remaining: 6s Progress 545 / 9694 Time remaining: 6s Progress 546 / 9694 Time remaining: 6s Progress 547 / 9694 Time remaining: 6s Progress 548 / 9694 Time remaining: 6s Progress 549 / 9694 Time remaining: 6s Progress 550 / 9694 Time remaining: 6s Progress 551 / 9694 Time remaining: 6s Progress 552 / 9694 Time remaining: 6s Progress 553 / 9694 Time remaining: 6s Progress 554 / 9694 Time remaining: 6s Progress 555 / 9694 Time remaining: 6s Progress 556 / 9694 Time remaining: 6s Progress 557 / 9694 Time remaining: 6s Progress 558 / 9694 Time remaining: 6s Progress 559 / 9694 Time remaining: 6s Progress 560 / 9694 Time remaining: 6s Progress 561 / 9694 Time remaining: 6s Progress 562 / 9694 Time remaining: 6s Progress 563 / 9694 Time remaining: 6s Progress 564 / 9694 Time remaining: 6s Progress 565 / 9694 Time remaining: 6s Progress 566 / 9694 Time remaining: 6s Progress 567 / 9694 Time remaining: 6s Progress 568 / 9694 Time remaining: 6s Progress 569 / 9694 Time remaining: 6s Progress 570 / 9694 Time remaining: 6s Progress 571 / 9694 Time remaining: 6s Progress 572 / 9694 Time remaining: 6s Progress 573 / 9694 Time remaining: 6s Progress 574 / 9694 Time remaining: 6s Progress 575 / 9694 Time remaining: 6s Progress 576 / 9694 Time remaining: 6s Progress 577 / 9694 Time remaining: 6s Progress 578 / 9694 Time remaining: 6s Progress 579 / 9694 Time remaining: 6s Progress 580 / 9694 Time remaining: 6s Progress 581 / 9694 Time remaining: 6s Progress 582 / 9694 Time remaining: 6s Progress 583 / 9694 Time remaining: 6s Progress 584 / 9694 Time remaining: 6s Progress 585 / 9694 Time remaining: 6s Progress 586 / 9694 Time remaining: 6s Progress 587 / 9694 Time remaining: 6s Progress 588 / 9694 Time remaining: 6s Progress 589 / 9694 Time remaining: 6s Progress 590 / 9694 Time remaining: 6s Progress 591 / 9694 Time remaining: 6s Progress 592 / 9694 Time remaining: 6s Progress 593 / 9694 Time remaining: 6s Progress 594 / 9694 Time remaining: 6s Progress 595 / 9694 Time remaining: 6s Progress 596 / 9694 Time remaining: 6s Progress 597 / 9694 Time remaining: 6s Progress 598 / 9694 Time remaining: 6s Progress 599 / 9694 Time remaining: 6s Progress 600 / 9694 Time remaining: 6s Progress 601 / 9694 Time remaining: 6s Progress 602 / 9694 Time remaining: 6s Progress 603 / 9694 Time remaining: 6s Progress 604 / 9694 Time remaining: 6s Progress 605 / 9694 Time remaining: 6s Progress 606 / 9694 Time remaining: 6s Progress 607 / 9694 Time remaining: 6s Progress 608 / 9694 Time remaining: 6s Progress 609 / 9694 Time remaining: 6s Progress 610 / 9694 Time remaining: 6s Progress 611 / 9694 Time remaining: 6s Progress 612 / 9694 Time remaining: 6s Progress 613 / 9694 Time remaining: 6s Progress 614 / 9694 Time remaining: 6s Progress 615 / 9694 Time remaining: 6s Progress 616 / 9694 Time remaining: 6s Progress 617 / 9694 Time remaining: 6s Progress 618 / 9694 Time remaining: 6s Progress 619 / 9694 Time remaining: 6s Progress 620 / 9694 Time remaining: 6s Progress 621 / 9694 Time remaining: 6s Progress 622 / 9694 Time remaining: 6s Progress 623 / 9694 Time remaining: 6s Progress 624 / 9694 Time remaining: 6s Progress 625 / 9694 Time remaining: 6s Progress 626 / 9694 Time remaining: 6s Progress 627 / 9694 Time remaining: 6s Progress 628 / 9694 Time remaining: 6s Progress 629 / 9694 Time remaining: 6s Progress 630 / 9694 Time remaining: 6s Progress 631 / 9694 Time remaining: 6s Progress 632 / 9694 Time remaining: 6s Progress 633 / 9694 Time remaining: 6s Progress 634 / 9694 Time remaining: 6s Progress 635 / 9694 Time remaining: 6s Progress 636 / 9694 Time remaining: 6s Progress 637 / 9694 Time remaining: 6s Progress 638 / 9694 Time remaining: 6s Progress 639 / 9694 Time remaining: 6s Progress 640 / 9694 Time remaining: 6s Progress 641 / 9694 Time remaining: 6s Progress 642 / 9694 Time remaining: 6s Progress 643 / 9694 Time remaining: 6s Progress 644 / 9694 Time remaining: 6s Progress 645 / 9694 Time remaining: 6s Progress 646 / 9694 Time remaining: 6s Progress 647 / 9694 Time remaining: 6s Progress 648 / 9694 Time remaining: 6s Progress 649 / 9694 Time remaining: 6s Progress 650 / 9694 Time remaining: 6s Progress 651 / 9694 Time remaining: 6s Progress 652 / 9694 Time remaining: 6s Progress 653 / 9694 Time remaining: 6s Progress 654 / 9694 Time remaining: 6s Progress 655 / 9694 Time remaining: 6s Progress 656 / 9694 Time remaining: 6s Progress 657 / 9694 Time remaining: 6s Progress 658 / 9694 Time remaining: 6s Progress 659 / 9694 Time remaining: 6s Progress 660 / 9694 Time remaining: 6s Progress 661 / 9694 Time remaining: 6s Progress 662 / 9694 Time remaining: 6s Progress 663 / 9694 Time remaining: 6s Progress 664 / 9694 Time remaining: 6s Progress 665 / 9694 Time remaining: 6s Progress 666 / 9694 Time remaining: 6s Progress 667 / 9694 Time remaining: 6s Progress 668 / 9694 Time remaining: 6s Progress 669 / 9694 Time remaining: 6s Progress 670 / 9694 Time remaining: 6s Progress 671 / 9694 Time remaining: 6s Progress 672 / 9694 Time remaining: 6s Progress 673 / 9694 Time remaining: 6s Progress 674 / 9694 Time remaining: 6s Progress 675 / 9694 Time remaining: 6s Progress 676 / 9694 Time remaining: 6s Progress 677 / 9694 Time remaining: 6s Progress 678 / 9694 Time remaining: 6s Progress 679 / 9694 Time remaining: 6s Progress 680 / 9694 Time remaining: 6s Progress 681 / 9694 Time remaining: 6s Progress 682 / 9694 Time remaining: 6s Progress 683 / 9694 Time remaining: 6s Progress 684 / 9694 Time remaining: 6s Progress 685 / 9694 Time remaining: 6s Progress 686 / 9694 Time remaining: 6s Progress 687 / 9694 Time remaining: 6s Progress 688 / 9694 Time remaining: 6s Progress 689 / 9694 Time remaining: 6s Progress 690 / 9694 Time remaining: 6s Progress 691 / 9694 Time remaining: 6s Progress 692 / 9694 Time remaining: 6s Progress 693 / 9694 Time remaining: 6s Progress 694 / 9694 Time remaining: 6s Progress 695 / 9694 Time remaining: 6s Progress 696 / 9694 Time remaining: 6s Progress 697 / 9694 Time remaining: 6s Progress 698 / 9694 Time remaining: 6s Progress 699 / 9694 Time remaining: 6s Progress 700 / 9694 Time remaining: 6s Progress 701 / 9694 Time remaining: 6s Progress 702 / 9694 Time remaining: 6s Progress 703 / 9694 Time remaining: 6s Progress 704 / 9694 Time remaining: 6s Progress 705 / 9694 Time remaining: 6s Progress 706 / 9694 Time remaining: 6s Progress 707 / 9694 Time remaining: 6s Progress 708 / 9694 Time remaining: 6s Progress 709 / 9694 Time remaining: 6s Progress 710 / 9694 Time remaining: 6s Progress 711 / 9694 Time remaining: 6s Progress 712 / 9694 Time remaining: 6s Progress 713 / 9694 Time remaining: 6s Progress 714 / 9694 Time remaining: 6s Progress 715 / 9694 Time remaining: 6s Progress 716 / 9694 Time remaining: 6s Progress 717 / 9694 Time remaining: 6s Progress 718 / 9694 Time remaining: 6s Progress 719 / 9694 Time remaining: 6s Progress 720 / 9694 Time remaining: 6s Progress 721 / 9694 Time remaining: 6s Progress 722 / 9694 Time remaining: 6s Progress 723 / 9694 Time remaining: 6s Progress 724 / 9694 Time remaining: 6s Progress 725 / 9694 Time remaining: 6s Progress 726 / 9694 Time remaining: 6s Progress 727 / 9694 Time remaining: 6s Progress 728 / 9694 Time remaining: 6s Progress 729 / 9694 Time remaining: 6s Progress 730 / 9694 Time remaining: 6s Progress 731 / 9694 Time remaining: 6s Progress 732 / 9694 Time remaining: 6s Progress 733 / 9694 Time remaining: 6s Progress 734 / 9694 Time remaining: 6s Progress 735 / 9694 Time remaining: 6s Progress 736 / 9694 Time remaining: 6s Progress 737 / 9694 Time remaining: 6s Progress 738 / 9694 Time remaining: 6s Progress 739 / 9694 Time remaining: 6s Progress 740 / 9694 Time remaining: 6s Progress 741 / 9694 Time remaining: 6s Progress 742 / 9694 Time remaining: 6s Progress 743 / 9694 Time remaining: 6s Progress 744 / 9694 Time remaining: 6s Progress 745 / 9694 Time remaining: 6s Progress 746 / 9694 Time remaining: 6s Progress 747 / 9694 Time remaining: 6s Progress 748 / 9694 Time remaining: 6s Progress 749 / 9694 Time remaining: 6s Progress 750 / 9694 Time remaining: 6s Progress 751 / 9694 Time remaining: 6s Progress 752 / 9694 Time remaining: 6s Progress 753 / 9694 Time remaining: 6s Progress 754 / 9694 Time remaining: 6s Progress 755 / 9694 Time remaining: 6s Progress 756 / 9694 Time remaining: 6s Progress 757 / 9694 Time remaining: 6s Progress 758 / 9694 Time remaining: 6s Progress 759 / 9694 Time remaining: 6s Progress 760 / 9694 Time remaining: 6s Progress 761 / 9694 Time remaining: 6s Progress 762 / 9694 Time remaining: 6s Progress 763 / 9694 Time remaining: 6s Progress 764 / 9694 Time remaining: 6s Progress 765 / 9694 Time remaining: 6s Progress 766 / 9694 Time remaining: 6s Progress 767 / 9694 Time remaining: 6s Progress 768 / 9694 Time remaining: 6s Progress 769 / 9694 Time remaining: 6s Progress 770 / 9694 Time remaining: 6s Progress 771 / 9694 Time remaining: 6s Progress 772 / 9694 Time remaining: 6s Progress 773 / 9694 Time remaining: 6s Progress 774 / 9694 Time remaining: 6s Progress 775 / 9694 Time remaining: 6s Progress 776 / 9694 Time remaining: 6s Progress 777 / 9694 Time remaining: 6s Progress 778 / 9694 Time remaining: 6s Progress 779 / 9694 Time remaining: 6s Progress 780 / 9694 Time remaining: 6s Progress 781 / 9694 Time remaining: 6s Progress 782 / 9694 Time remaining: 6s Progress 783 / 9694 Time remaining: 6s Progress 784 / 9694 Time remaining: 6s Progress 785 / 9694 Time remaining: 6s Progress 786 / 9694 Time remaining: 6s Progress 787 / 9694 Time remaining: 6s Progress 788 / 9694 Time remaining: 6s Progress 789 / 9694 Time remaining: 6s Progress 790 / 9694 Time remaining: 6s Progress 791 / 9694 Time remaining: 6s Progress 792 / 9694 Time remaining: 6s Progress 793 / 9694 Time remaining: 6s Progress 794 / 9694 Time remaining: 6s Progress 795 / 9694 Time remaining: 6s Progress 796 / 9694 Time remaining: 6s Progress 797 / 9694 Time remaining: 6s Progress 798 / 9694 Time remaining: 6s Progress 799 / 9694 Time remaining: 6s Progress 800 / 9694 Time remaining: 6s Progress 801 / 9694 Time remaining: 6s Progress 802 / 9694 Time remaining: 6s Progress 803 / 9694 Time remaining: 6s Progress 804 / 9694 Time remaining: 6s Progress 805 / 9694 Time remaining: 6s Progress 806 / 9694 Time remaining: 6s Progress 807 / 9694 Time remaining: 6s Progress 808 / 9694 Time remaining: 6s Progress 809 / 9694 Time remaining: 6s Progress 810 / 9694 Time remaining: 6s Progress 811 / 9694 Time remaining: 6s Progress 812 / 9694 Time remaining: 6s Progress 813 / 9694 Time remaining: 6s Progress 814 / 9694 Time remaining: 6s Progress 815 / 9694 Time remaining: 6s Progress 816 / 9694 Time remaining: 6s Progress 817 / 9694 Time remaining: 6s Progress 818 / 9694 Time remaining: 6s Progress 819 / 9694 Time remaining: 6s Progress 820 / 9694 Time remaining: 6s Progress 821 / 9694 Time remaining: 6s Progress 822 / 9694 Time remaining: 6s Progress 823 / 9694 Time remaining: 6s Progress 824 / 9694 Time remaining: 6s Progress 825 / 9694 Time remaining: 6s Progress 826 / 9694 Time remaining: 6s Progress 827 / 9694 Time remaining: 6s Progress 828 / 9694 Time remaining: 6s Progress 829 / 9694 Time remaining: 6s Progress 830 / 9694 Time remaining: 6s Progress 831 / 9694 Time remaining: 6s Progress 832 / 9694 Time remaining: 6s Progress 833 / 9694 Time remaining: 6s Progress 834 / 9694 Time remaining: 6s Progress 835 / 9694 Time remaining: 6s Progress 836 / 9694 Time remaining: 6s Progress 837 / 9694 Time remaining: 6s Progress 838 / 9694 Time remaining: 6s Progress 839 / 9694 Time remaining: 6s Progress 840 / 9694 Time remaining: 6s Progress 841 / 9694 Time remaining: 6s Progress 842 / 9694 Time remaining: 6s Progress 843 / 9694 Time remaining: 6s Progress 844 / 9694 Time remaining: 6s Progress 845 / 9694 Time remaining: 6s Progress 846 / 9694 Time remaining: 6s Progress 847 / 9694 Time remaining: 6s Progress 848 / 9694 Time remaining: 6s Progress 849 / 9694 Time remaining: 6s Progress 850 / 9694 Time remaining: 6s Progress 851 / 9694 Time remaining: 6s Progress 852 / 9694 Time remaining: 6s Progress 853 / 9694 Time remaining: 6s Progress 854 / 9694 Time remaining: 6s Progress 855 / 9694 Time remaining: 6s Progress 856 / 9694 Time remaining: 6s Progress 857 / 9694 Time remaining: 6s Progress 858 / 9694 Time remaining: 6s Progress 859 / 9694 Time remaining: 6s Progress 860 / 9694 Time remaining: 6s Progress 861 / 9694 Time remaining: 6s Progress 862 / 9694 Time remaining: 6s Progress 863 / 9694 Time remaining: 6s Progress 864 / 9694 Time remaining: 6s Progress 865 / 9694 Time remaining: 6s Progress 866 / 9694 Time remaining: 6s Progress 867 / 9694 Time remaining: 6s Progress 868 / 9694 Time remaining: 6s Progress 869 / 9694 Time remaining: 6s Progress 870 / 9694 Time remaining: 6s Progress 871 / 9694 Time remaining: 6s Progress 872 / 9694 Time remaining: 6s Progress 873 / 9694 Time remaining: 6s Progress 874 / 9694 Time remaining: 6s Progress 875 / 9694 Time remaining: 6s Progress 876 / 9694 Time remaining: 6s Progress 877 / 9694 Time remaining: 6s Progress 878 / 9694 Time remaining: 6s Progress 879 / 9694 Time remaining: 6s Progress 880 / 9694 Time remaining: 6s Progress 881 / 9694 Time remaining: 6s Progress 882 / 9694 Time remaining: 6s Progress 883 / 9694 Time remaining: 6s Progress 884 / 9694 Time remaining: 6s Progress 885 / 9694 Time remaining: 6s Progress 886 / 9694 Time remaining: 6s Progress 887 / 9694 Time remaining: 6s Progress 888 / 9694 Time remaining: 6s Progress 889 / 9694 Time remaining: 6s Progress 890 / 9694 Time remaining: 6s Progress 891 / 9694 Time remaining: 6s Progress 892 / 9694 Time remaining: 6s Progress 893 / 9694 Time remaining: 6s Progress 894 / 9694 Time remaining: 6s Progress 895 / 9694 Time remaining: 6s Progress 896 / 9694 Time remaining: 6s Progress 897 / 9694 Time remaining: 6s Progress 898 / 9694 Time remaining: 6s Progress 899 / 9694 Time remaining: 6s Progress 900 / 9694 Time remaining: 6s Progress 901 / 9694 Time remaining: 6s Progress 902 / 9694 Time remaining: 6s Progress 903 / 9694 Time remaining: 6s Progress 904 / 9694 Time remaining: 6s Progress 905 / 9694 Time remaining: 6s Progress 906 / 9694 Time remaining: 6s Progress 907 / 9694 Time remaining: 6s Progress 908 / 9694 Time remaining: 6s Progress 909 / 9694 Time remaining: 6s Progress 910 / 9694 Time remaining: 6s Progress 911 / 9694 Time remaining: 6s Progress 912 / 9694 Time remaining: 6s Progress 913 / 9694 Time remaining: 6s Progress 914 / 9694 Time remaining: 6s Progress 915 / 9694 Time remaining: 6s Progress 916 / 9694 Time remaining: 6s Progress 917 / 9694 Time remaining: 6s Progress 918 / 9694 Time remaining: 6s Progress 919 / 9694 Time remaining: 6s Progress 920 / 9694 Time remaining: 6s Progress 921 / 9694 Time remaining: 6s Progress 922 / 9694 Time remaining: 6s Progress 923 / 9694 Time remaining: 6s Progress 924 / 9694 Time remaining: 6s Progress 925 / 9694 Time remaining: 6s Progress 926 / 9694 Time remaining: 6s Progress 927 / 9694 Time remaining: 6s Progress 928 / 9694 Time remaining: 6s Progress 929 / 9694 Time remaining: 6s Progress 930 / 9694 Time remaining: 6s Progress 931 / 9694 Time remaining: 6s Progress 932 / 9694 Time remaining: 6s Progress 933 / 9694 Time remaining: 6s Progress 934 / 9694 Time remaining: 6s Progress 935 / 9694 Time remaining: 6s Progress 936 / 9694 Time remaining: 6s Progress 937 / 9694 Time remaining: 6s Progress 938 / 9694 Time remaining: 6s Progress 939 / 9694 Time remaining: 6s Progress 940 / 9694 Time remaining: 6s Progress 941 / 9694 Time remaining: 6s Progress 942 / 9694 Time remaining: 6s Progress 943 / 9694 Time remaining: 6s Progress 944 / 9694 Time remaining: 6s Progress 945 / 9694 Time remaining: 6s Progress 946 / 9694 Time remaining: 6s Progress 947 / 9694 Time remaining: 6s Progress 948 / 9694 Time remaining: 6s Progress 949 / 9694 Time remaining: 6s Progress 950 / 9694 Time remaining: 6s Progress 951 / 9694 Time remaining: 6s Progress 952 / 9694 Time remaining: 6s Progress 953 / 9694 Time remaining: 6s Progress 954 / 9694 Time remaining: 6s Progress 955 / 9694 Time remaining: 6s Progress 956 / 9694 Time remaining: 6s Progress 957 / 9694 Time remaining: 6s Progress 958 / 9694 Time remaining: 6s Progress 959 / 9694 Time remaining: 6s Progress 960 / 9694 Time remaining: 6s Progress 961 / 9694 Time remaining: 6s Progress 962 / 9694 Time remaining: 6s Progress 963 / 9694 Time remaining: 6s Progress 964 / 9694 Time remaining: 6s Progress 965 / 9694 Time remaining: 6s Progress 966 / 9694 Time remaining: 6s Progress 967 / 9694 Time remaining: 6s Progress 968 / 9694 Time remaining: 6s Progress 969 / 9694 Time remaining: 6s Progress 970 / 9694 Time remaining: 6s Progress 971 / 9694 Time remaining: 6s Progress 972 / 9694 Time remaining: 6s Progress 973 / 9694 Time remaining: 6s Progress 974 / 9694 Time remaining: 6s Progress 975 / 9694 Time remaining: 6s Progress 976 / 9694 Time remaining: 6s Progress 977 / 9694 Time remaining: 6s Progress 978 / 9694 Time remaining: 6s Progress 979 / 9694 Time remaining: 6s Progress 980 / 9694 Time remaining: 6s Progress 981 / 9694 Time remaining: 6s Progress 982 / 9694 Time remaining: 6s Progress 983 / 9694 Time remaining: 6s Progress 984 / 9694 Time remaining: 6s Progress 985 / 9694 Time remaining: 6s Progress 986 / 9694 Time remaining: 6s Progress 987 / 9694 Time remaining: 6s Progress 988 / 9694 Time remaining: 6s Progress 989 / 9694 Time remaining: 6s Progress 990 / 9694 Time remaining: 6s Progress 991 / 9694 Time remaining: 6s Progress 992 / 9694 Time remaining: 6s Progress 993 / 9694 Time remaining: 6s Progress 994 / 9694 Time remaining: 6s Progress 995 / 9694 Time remaining: 6s Progress 996 / 9694 Time remaining: 6s Progress 997 / 9694 Time remaining: 6s Progress 998 / 9694 Time remaining: 6s Progress 999 / 9694 Time remaining: 6s Progress 1000 / 9694 Time remaining: 6s Progress 1001 / 9694 Time remaining: 6s Progress 1002 / 9694 Time remaining: 6s Progress 1003 / 9694 Time remaining: 6s Progress 1004 / 9694 Time remaining: 6s Progress 1005 / 9694 Time remaining: 6s Progress 1006 / 9694 Time remaining: 6s Progress 1007 / 9694 Time remaining: 6s Progress 1008 / 9694 Time remaining: 6s Progress 1009 / 9694 Time remaining: 6s Progress 1010 / 9694 Time remaining: 6s Progress 1011 / 9694 Time remaining: 6s Progress 1012 / 9694 Time remaining: 6s Progress 1013 / 9694 Time remaining: 6s Progress 1014 / 9694 Time remaining: 6s Progress 1015 / 9694 Time remaining: 6s Progress 1016 / 9694 Time remaining: 6s Progress 1017 / 9694 Time remaining: 6s Progress 1018 / 9694 Time remaining: 6s Progress 1019 / 9694 Time remaining: 6s Progress 1020 / 9694 Time remaining: 6s Progress 1021 / 9694 Time remaining: 6s Progress 1022 / 9694 Time remaining: 6s Progress 1023 / 9694 Time remaining: 6s Progress 1024 / 9694 Time remaining: 6s Progress 1025 / 9694 Time remaining: 6s Progress 1026 / 9694 Time remaining: 6s Progress 1027 / 9694 Time remaining: 6s Progress 1028 / 9694 Time remaining: 6s Progress 1029 / 9694 Time remaining: 6s Progress 1030 / 9694 Time remaining: 6s Progress 1031 / 9694 Time remaining: 6s Progress 1032 / 9694 Time remaining: 6s Progress 1033 / 9694 Time remaining: 6s Progress 1034 / 9694 Time remaining: 6s Progress 1035 / 9694 Time remaining: 6s Progress 1036 / 9694 Time remaining: 6s Progress 1037 / 9694 Time remaining: 6s Progress 1038 / 9694 Time remaining: 6s Progress 1039 / 9694 Time remaining: 6s Progress 1040 / 9694 Time remaining: 6s Progress 1041 / 9694 Time remaining: 6s Progress 1042 / 9694 Time remaining: 6s Progress 1043 / 9694 Time remaining: 6s Progress 1044 / 9694 Time remaining: 6s Progress 1045 / 9694 Time remaining: 6s Progress 1046 / 9694 Time remaining: 6s Progress 1047 / 9694 Time remaining: 6s Progress 1048 / 9694 Time remaining: 6s Progress 1049 / 9694 Time remaining: 6s Progress 1050 / 9694 Time remaining: 6s Progress 1051 / 9694 Time remaining: 6s Progress 1052 / 9694 Time remaining: 6s Progress 1053 / 9694 Time remaining: 6s Progress 1054 / 9694 Time remaining: 6s Progress 1055 / 9694 Time remaining: 6s Progress 1056 / 9694 Time remaining: 6s Progress 1057 / 9694 Time remaining: 6s Progress 1058 / 9694 Time remaining: 6s Progress 1059 / 9694 Time remaining: 6s Progress 1060 / 9694 Time remaining: 6s Progress 1061 / 9694 Time remaining: 6s Progress 1062 / 9694 Time remaining: 6s Progress 1063 / 9694 Time remaining: 6s Progress 1064 / 9694 Time remaining: 6s Progress 1065 / 9694 Time remaining: 6s Progress 1066 / 9694 Time remaining: 6s Progress 1067 / 9694 Time remaining: 6s Progress 1068 / 9694 Time remaining: 6s Progress 1069 / 9694 Time remaining: 6s Progress 1070 / 9694 Time remaining: 6s Progress 1071 / 9694 Time remaining: 6s Progress 1072 / 9694 Time remaining: 6s Progress 1073 / 9694 Time remaining: 6s Progress 1074 / 9694 Time remaining: 6s Progress 1075 / 9694 Time remaining: 6s Progress 1076 / 9694 Time remaining: 6s Progress 1077 / 9694 Time remaining: 6s Progress 1078 / 9694 Time remaining: 6s Progress 1079 / 9694 Time remaining: 6s Progress 1080 / 9694 Time remaining: 6s Progress 1081 / 9694 Time remaining: 6s Progress 1082 / 9694 Time remaining: 6s Progress 1083 / 9694 Time remaining: 6s Progress 1084 / 9694 Time remaining: 6s Progress 1085 / 9694 Time remaining: 6s Progress 1086 / 9694 Time remaining: 6s Progress 1087 / 9694 Time remaining: 6s Progress 1088 / 9694 Time remaining: 6s Progress 1089 / 9694 Time remaining: 6s Progress 1090 / 9694 Time remaining: 6s Progress 1091 / 9694 Time remaining: 6s Progress 1092 / 9694 Time remaining: 6s Progress 1093 / 9694 Time remaining: 6s Progress 1094 / 9694 Time remaining: 6s Progress 1095 / 9694 Time remaining: 6s Progress 1096 / 9694 Time remaining: 6s Progress 1097 / 9694 Time remaining: 6s Progress 1098 / 9694 Time remaining: 6s Progress 1099 / 9694 Time remaining: 6s Progress 1100 / 9694 Time remaining: 6s Progress 1101 / 9694 Time remaining: 6s Progress 1102 / 9694 Time remaining: 6s Progress 1103 / 9694 Time remaining: 6s Progress 1104 / 9694 Time remaining: 6s Progress 1105 / 9694 Time remaining: 6s Progress 1106 / 9694 Time remaining: 6s Progress 1107 / 9694 Time remaining: 6s Progress 1108 / 9694 Time remaining: 6s Progress 1109 / 9694 Time remaining: 6s Progress 1110 / 9694 Time remaining: 6s Progress 1111 / 9694 Time remaining: 6s Progress 1112 / 9694 Time remaining: 6s Progress 1113 / 9694 Time remaining: 6s Progress 1114 / 9694 Time remaining: 6s Progress 1115 / 9694 Time remaining: 6s Progress 1116 / 9694 Time remaining: 6s Progress 1117 / 9694 Time remaining: 6s Progress 1118 / 9694 Time remaining: 6s Progress 1119 / 9694 Time remaining: 6s Progress 1120 / 9694 Time remaining: 6s Progress 1121 / 9694 Time remaining: 6s Progress 1122 / 9694 Time remaining: 6s Progress 1123 / 9694 Time remaining: 6s Progress 1124 / 9694 Time remaining: 6s Progress 1125 / 9694 Time remaining: 6s Progress 1126 / 9694 Time remaining: 6s Progress 1127 / 9694 Time remaining: 6s Progress 1128 / 9694 Time remaining: 6s Progress 1129 / 9694 Time remaining: 6s Progress 1130 / 9694 Time remaining: 6s Progress 1131 / 9694 Time remaining: 6s Progress 1132 / 9694 Time remaining: 6s Progress 1133 / 9694 Time remaining: 6s Progress 1134 / 9694 Time remaining: 6s Progress 1135 / 9694 Time remaining: 6s Progress 1136 / 9694 Time remaining: 6s Progress 1137 / 9694 Time remaining: 6s Progress 1138 / 9694 Time remaining: 6s Progress 1139 / 9694 Time remaining: 6s Progress 1140 / 9694 Time remaining: 6s Progress 1141 / 9694 Time remaining: 6s Progress 1142 / 9694 Time remaining: 6s Progress 1143 / 9694 Time remaining: 6s Progress 1144 / 9694 Time remaining: 6s Progress 1145 / 9694 Time remaining: 6s Progress 1146 / 9694 Time remaining: 6s Progress 1147 / 9694 Time remaining: 6s Progress 1148 / 9694 Time remaining: 6s Progress 1149 / 9694 Time remaining: 6s Progress 1150 / 9694 Time remaining: 6s Progress 1151 / 9694 Time remaining: 6s Progress 1152 / 9694 Time remaining: 6s Progress 1153 / 9694 Time remaining: 6s Progress 1154 / 9694 Time remaining: 6s Progress 1155 / 9694 Time remaining: 6s Progress 1156 / 9694 Time remaining: 6s Progress 1157 / 9694 Time remaining: 6s Progress 1158 / 9694 Time remaining: 6s Progress 1159 / 9694 Time remaining: 6s Progress 1160 / 9694 Time remaining: 6s Progress 1161 / 9694 Time remaining: 6s Progress 1162 / 9694 Time remaining: 6s Progress 1163 / 9694 Time remaining: 6s Progress 1164 / 9694 Time remaining: 6s Progress 1165 / 9694 Time remaining: 6s Progress 1166 / 9694 Time remaining: 6s Progress 1167 / 9694 Time remaining: 6s Progress 1168 / 9694 Time remaining: 6s Progress 1169 / 9694 Time remaining: 6s Progress 1170 / 9694 Time remaining: 6s Progress 1171 / 9694 Time remaining: 6s Progress 1172 / 9694 Time remaining: 6s Progress 1173 / 9694 Time remaining: 6s Progress 1174 / 9694 Time remaining: 6s Progress 1175 / 9694 Time remaining: 6s Progress 1176 / 9694 Time remaining: 6s Progress 1177 / 9694 Time remaining: 6s Progress 1178 / 9694 Time remaining: 6s Progress 1179 / 9694 Time remaining: 6s Progress 1180 / 9694 Time remaining: 6s Progress 1181 / 9694 Time remaining: 6s Progress 1182 / 9694 Time remaining: 6s Progress 1183 / 9694 Time remaining: 6s Progress 1184 / 9694 Time remaining: 6s Progress 1185 / 9694 Time remaining: 6s Progress 1186 / 9694 Time remaining: 6s Progress 1187 / 9694 Time remaining: 6s Progress 1188 / 9694 Time remaining: 6s Progress 1189 / 9694 Time remaining: 6s Progress 1190 / 9694 Time remaining: 6s Progress 1191 / 9694 Time remaining: 6s Progress 1192 / 9694 Time remaining: 6s Progress 1193 / 9694 Time remaining: 6s Progress 1194 / 9694 Time remaining: 6s Progress 1195 / 9694 Time remaining: 6s Progress 1196 / 9694 Time remaining: 6s Progress 1197 / 9694 Time remaining: 6s Progress 1198 / 9694 Time remaining: 6s Progress 1199 / 9694 Time remaining: 6s Progress 1200 / 9694 Time remaining: 6s Progress 1201 / 9694 Time remaining: 6s Progress 1202 / 9694 Time remaining: 6s Progress 1203 / 9694 Time remaining: 6s Progress 1204 / 9694 Time remaining: 6s Progress 1205 / 9694 Time remaining: 6s Progress 1206 / 9694 Time remaining: 6s Progress 1207 / 9694 Time remaining: 6s Progress 1208 / 9694 Time remaining: 6s Progress 1209 / 9694 Time remaining: 6s Progress 1210 / 9694 Time remaining: 6s Progress 1211 / 9694 Time remaining: 6s Progress 1212 / 9694 Time remaining: 6s Progress 1213 / 9694 Time remaining: 6s Progress 1214 / 9694 Time remaining: 6s Progress 1215 / 9694 Time remaining: 6s Progress 1216 / 9694 Time remaining: 6s Progress 1217 / 9694 Time remaining: 6s Progress 1218 / 9694 Time remaining: 6s Progress 1219 / 9694 Time remaining: 6s Progress 1220 / 9694 Time remaining: 6s Progress 1221 / 9694 Time remaining: 6s Progress 1222 / 9694 Time remaining: 6s Progress 1223 / 9694 Time remaining: 6s Progress 1224 / 9694 Time remaining: 6s Progress 1225 / 9694 Time remaining: 6s Progress 1226 / 9694 Time remaining: 6s Progress 1227 / 9694 Time remaining: 6s Progress 1228 / 9694 Time remaining: 6s Progress 1229 / 9694 Time remaining: 6s Progress 1230 / 9694 Time remaining: 6s Progress 1231 / 9694 Time remaining: 6s Progress 1232 / 9694 Time remaining: 6s Progress 1233 / 9694 Time remaining: 6s Progress 1234 / 9694 Time remaining: 6s Progress 1235 / 9694 Time remaining: 6s Progress 1236 / 9694 Time remaining: 6s Progress 1237 / 9694 Time remaining: 6s Progress 1238 / 9694 Time remaining: 6s Progress 1239 / 9694 Time remaining: 6s Progress 1240 / 9694 Time remaining: 6s Progress 1241 / 9694 Time remaining: 6s Progress 1242 / 9694 Time remaining: 6s Progress 1243 / 9694 Time remaining: 6s Progress 1244 / 9694 Time remaining: 6s Progress 1245 / 9694 Time remaining: 6s Progress 1246 / 9694 Time remaining: 6s Progress 1247 / 9694 Time remaining: 6s Progress 1248 / 9694 Time remaining: 6s Progress 1249 / 9694 Time remaining: 6s Progress 1250 / 9694 Time remaining: 6s Progress 1251 / 9694 Time remaining: 5s Progress 1252 / 9694 Time remaining: 5s Progress 1253 / 9694 Time remaining: 5s Progress 1254 / 9694 Time remaining: 5s Progress 1255 / 9694 Time remaining: 5s Progress 1256 / 9694 Time remaining: 5s Progress 1257 / 9694 Time remaining: 5s Progress 1258 / 9694 Time remaining: 5s Progress 1259 / 9694 Time remaining: 5s Progress 1260 / 9694 Time remaining: 5s Progress 1261 / 9694 Time remaining: 5s Progress 1262 / 9694 Time remaining: 5s Progress 1263 / 9694 Time remaining: 5s Progress 1264 / 9694 Time remaining: 5s Progress 1265 / 9694 Time remaining: 5s Progress 1266 / 9694 Time remaining: 5s Progress 1267 / 9694 Time remaining: 5s Progress 1268 / 9694 Time remaining: 5s Progress 1269 / 9694 Time remaining: 5s Progress 1270 / 9694 Time remaining: 5s Progress 1271 / 9694 Time remaining: 5s Progress 1272 / 9694 Time remaining: 5s Progress 1273 / 9694 Time remaining: 5s Progress 1274 / 9694 Time remaining: 5s Progress 1275 / 9694 Time remaining: 5s Progress 1276 / 9694 Time remaining: 5s Progress 1277 / 9694 Time remaining: 5s Progress 1278 / 9694 Time remaining: 5s Progress 1279 / 9694 Time remaining: 5s Progress 1280 / 9694 Time remaining: 5s Progress 1281 / 9694 Time remaining: 5s Progress 1282 / 9694 Time remaining: 5s Progress 1283 / 9694 Time remaining: 5s Progress 1284 / 9694 Time remaining: 5s Progress 1285 / 9694 Time remaining: 5s Progress 1286 / 9694 Time remaining: 5s Progress 1287 / 9694 Time remaining: 5s Progress 1288 / 9694 Time remaining: 5s Progress 1289 / 9694 Time remaining: 5s Progress 1290 / 9694 Time remaining: 5s Progress 1291 / 9694 Time remaining: 5s Progress 1292 / 9694 Time remaining: 5s Progress 1293 / 9694 Time remaining: 5s Progress 1294 / 9694 Time remaining: 5s Progress 1295 / 9694 Time remaining: 5s Progress 1296 / 9694 Time remaining: 5s Progress 1297 / 9694 Time remaining: 5s Progress 1298 / 9694 Time remaining: 5s Progress 1299 / 9694 Time remaining: 5s Progress 1300 / 9694 Time remaining: 5s Progress 1301 / 9694 Time remaining: 5s Progress 1302 / 9694 Time remaining: 5s Progress 1303 / 9694 Time remaining: 5s Progress 1304 / 9694 Time remaining: 5s Progress 1305 / 9694 Time remaining: 5s Progress 1306 / 9694 Time remaining: 5s Progress 1307 / 9694 Time remaining: 5s Progress 1308 / 9694 Time remaining: 5s Progress 1309 / 9694 Time remaining: 5s Progress 1310 / 9694 Time remaining: 5s Progress 1311 / 9694 Time remaining: 5s Progress 1312 / 9694 Time remaining: 5s Progress 1313 / 9694 Time remaining: 5s Progress 1314 / 9694 Time remaining: 5s Progress 1315 / 9694 Time remaining: 5s Progress 1316 / 9694 Time remaining: 5s Progress 1317 / 9694 Time remaining: 5s Progress 1318 / 9694 Time remaining: 5s Progress 1319 / 9694 Time remaining: 5s Progress 1320 / 9694 Time remaining: 5s Progress 1321 / 9694 Time remaining: 5s Progress 1322 / 9694 Time remaining: 5s Progress 1323 / 9694 Time remaining: 5s Progress 1324 / 9694 Time remaining: 5s Progress 1325 / 9694 Time remaining: 5s Progress 1326 / 9694 Time remaining: 5s Progress 1327 / 9694 Time remaining: 5s Progress 1328 / 9694 Time remaining: 5s Progress 1329 / 9694 Time remaining: 5s Progress 1330 / 9694 Time remaining: 5s Progress 1331 / 9694 Time remaining: 5s Progress 1332 / 9694 Time remaining: 5s Progress 1333 / 9694 Time remaining: 5s Progress 1334 / 9694 Time remaining: 5s Progress 1335 / 9694 Time remaining: 5s Progress 1336 / 9694 Time remaining: 5s Progress 1337 / 9694 Time remaining: 5s Progress 1338 / 9694 Time remaining: 5s Progress 1339 / 9694 Time remaining: 5s Progress 1340 / 9694 Time remaining: 5s Progress 1341 / 9694 Time remaining: 5s Progress 1342 / 9694 Time remaining: 5s Progress 1343 / 9694 Time remaining: 5s Progress 1344 / 9694 Time remaining: 5s Progress 1345 / 9694 Time remaining: 5s Progress 1346 / 9694 Time remaining: 5s Progress 1347 / 9694 Time remaining: 5s Progress 1348 / 9694 Time remaining: 5s Progress 1349 / 9694 Time remaining: 5s Progress 1350 / 9694 Time remaining: 5s Progress 1351 / 9694 Time remaining: 5s Progress 1352 / 9694 Time remaining: 5s Progress 1353 / 9694 Time remaining: 5s Progress 1354 / 9694 Time remaining: 5s Progress 1355 / 9694 Time remaining: 5s Progress 1356 / 9694 Time remaining: 5s Progress 1357 / 9694 Time remaining: 5s Progress 1358 / 9694 Time remaining: 5s Progress 1359 / 9694 Time remaining: 5s Progress 1360 / 9694 Time remaining: 5s Progress 1361 / 9694 Time remaining: 5s Progress 1362 / 9694 Time remaining: 5s Progress 1363 / 9694 Time remaining: 5s Progress 1364 / 9694 Time remaining: 5s Progress 1365 / 9694 Time remaining: 5s Progress 1366 / 9694 Time remaining: 5s Progress 1367 / 9694 Time remaining: 5s Progress 1368 / 9694 Time remaining: 5s Progress 1369 / 9694 Time remaining: 5s Progress 1370 / 9694 Time remaining: 5s Progress 1371 / 9694 Time remaining: 5s Progress 1372 / 9694 Time remaining: 5s Progress 1373 / 9694 Time remaining: 5s Progress 1374 / 9694 Time remaining: 5s Progress 1375 / 9694 Time remaining: 5s Progress 1376 / 9694 Time remaining: 5s Progress 1377 / 9694 Time remaining: 5s Progress 1378 / 9694 Time remaining: 5s Progress 1379 / 9694 Time remaining: 5s Progress 1380 / 9694 Time remaining: 5s Progress 1381 / 9694 Time remaining: 5s Progress 1382 / 9694 Time remaining: 5s Progress 1383 / 9694 Time remaining: 5s Progress 1384 / 9694 Time remaining: 5s Progress 1385 / 9694 Time remaining: 5s Progress 1386 / 9694 Time remaining: 5s Progress 1387 / 9694 Time remaining: 5s Progress 1388 / 9694 Time remaining: 5s Progress 1389 / 9694 Time remaining: 5s Progress 1390 / 9694 Time remaining: 5s Progress 1391 / 9694 Time remaining: 5s Progress 1392 / 9694 Time remaining: 5s Progress 1393 / 9694 Time remaining: 5s Progress 1394 / 9694 Time remaining: 5s Progress 1395 / 9694 Time remaining: 5s Progress 1396 / 9694 Time remaining: 5s Progress 1397 / 9694 Time remaining: 5s Progress 1398 / 9694 Time remaining: 5s Progress 1399 / 9694 Time remaining: 5s Progress 1400 / 9694 Time remaining: 5s Progress 1401 / 9694 Time remaining: 5s Progress 1402 / 9694 Time remaining: 5s Progress 1403 / 9694 Time remaining: 5s Progress 1404 / 9694 Time remaining: 5s Progress 1405 / 9694 Time remaining: 5s Progress 1406 / 9694 Time remaining: 5s Progress 1407 / 9694 Time remaining: 5s Progress 1408 / 9694 Time remaining: 5s Progress 1409 / 9694 Time remaining: 5s Progress 1410 / 9694 Time remaining: 5s Progress 1411 / 9694 Time remaining: 5s Progress 1412 / 9694 Time remaining: 5s Progress 1413 / 9694 Time remaining: 5s Progress 1414 / 9694 Time remaining: 5s Progress 1415 / 9694 Time remaining: 5s Progress 1416 / 9694 Time remaining: 5s Progress 1417 / 9694 Time remaining: 5s Progress 1418 / 9694 Time remaining: 5s Progress 1419 / 9694 Time remaining: 5s Progress 1420 / 9694 Time remaining: 5s Progress 1421 / 9694 Time remaining: 5s Progress 1422 / 9694 Time remaining: 5s Progress 1423 / 9694 Time remaining: 5s Progress 1424 / 9694 Time remaining: 5s Progress 1425 / 9694 Time remaining: 5s Progress 1426 / 9694 Time remaining: 5s Progress 1427 / 9694 Time remaining: 5s Progress 1428 / 9694 Time remaining: 5s Progress 1429 / 9694 Time remaining: 5s Progress 1430 / 9694 Time remaining: 5s Progress 1431 / 9694 Time remaining: 5s Progress 1432 / 9694 Time remaining: 5s Progress 1433 / 9694 Time remaining: 5s Progress 1434 / 9694 Time remaining: 5s Progress 1435 / 9694 Time remaining: 5s Progress 1436 / 9694 Time remaining: 5s Progress 1437 / 9694 Time remaining: 5s Progress 1438 / 9694 Time remaining: 5s Progress 1439 / 9694 Time remaining: 5s Progress 1440 / 9694 Time remaining: 5s Progress 1441 / 9694 Time remaining: 5s Progress 1442 / 9694 Time remaining: 5s Progress 1443 / 9694 Time remaining: 5s Progress 1444 / 9694 Time remaining: 5s Progress 1445 / 9694 Time remaining: 5s Progress 1446 / 9694 Time remaining: 5s Progress 1447 / 9694 Time remaining: 5s Progress 1448 / 9694 Time remaining: 5s Progress 1449 / 9694 Time remaining: 5s Progress 1450 / 9694 Time remaining: 5s Progress 1451 / 9694 Time remaining: 5s Progress 1452 / 9694 Time remaining: 5s Progress 1453 / 9694 Time remaining: 5s Progress 1454 / 9694 Time remaining: 5s Progress 1455 / 9694 Time remaining: 5s Progress 1456 / 9694 Time remaining: 5s Progress 1457 / 9694 Time remaining: 5s Progress 1458 / 9694 Time remaining: 5s Progress 1459 / 9694 Time remaining: 5s Progress 1460 / 9694 Time remaining: 5s Progress 1461 / 9694 Time remaining: 5s Progress 1462 / 9694 Time remaining: 5s Progress 1463 / 9694 Time remaining: 5s Progress 1464 / 9694 Time remaining: 5s Progress 1465 / 9694 Time remaining: 5s Progress 1466 / 9694 Time remaining: 5s Progress 1467 / 9694 Time remaining: 5s Progress 1468 / 9694 Time remaining: 5s Progress 1469 / 9694 Time remaining: 5s Progress 1470 / 9694 Time remaining: 5s Progress 1471 / 9694 Time remaining: 5s Progress 1472 / 9694 Time remaining: 5s Progress 1473 / 9694 Time remaining: 5s Progress 1474 / 9694 Time remaining: 5s Progress 1475 / 9694 Time remaining: 5s Progress 1476 / 9694 Time remaining: 5s Progress 1477 / 9694 Time remaining: 5s Progress 1478 / 9694 Time remaining: 5s Progress 1479 / 9694 Time remaining: 5s Progress 1480 / 9694 Time remaining: 5s Progress 1481 / 9694 Time remaining: 5s Progress 1482 / 9694 Time remaining: 5s Progress 1483 / 9694 Time remaining: 5s Progress 1484 / 9694 Time remaining: 5s Progress 1485 / 9694 Time remaining: 5s Progress 1486 / 9694 Time remaining: 5s Progress 1487 / 9694 Time remaining: 5s Progress 1488 / 9694 Time remaining: 5s Progress 1489 / 9694 Time remaining: 5s Progress 1490 / 9694 Time remaining: 5s Progress 1491 / 9694 Time remaining: 5s Progress 1492 / 9694 Time remaining: 5s Progress 1493 / 9694 Time remaining: 5s Progress 1494 / 9694 Time remaining: 5s Progress 1495 / 9694 Time remaining: 5s Progress 1496 / 9694 Time remaining: 5s Progress 1497 / 9694 Time remaining: 5s Progress 1498 / 9694 Time remaining: 5s Progress 1499 / 9694 Time remaining: 5s Progress 1500 / 9694 Time remaining: 5s Progress 1501 / 9694 Time remaining: 5s Progress 1502 / 9694 Time remaining: 5s Progress 1503 / 9694 Time remaining: 5s Progress 1504 / 9694 Time remaining: 5s Progress 1505 / 9694 Time remaining: 5s Progress 1506 / 9694 Time remaining: 5s Progress 1507 / 9694 Time remaining: 5s Progress 1508 / 9694 Time remaining: 5s Progress 1509 / 9694 Time remaining: 5s Progress 1510 / 9694 Time remaining: 5s Progress 1511 / 9694 Time remaining: 5s Progress 1512 / 9694 Time remaining: 5s Progress 1513 / 9694 Time remaining: 5s Progress 1514 / 9694 Time remaining: 5s Progress 1515 / 9694 Time remaining: 5s Progress 1516 / 9694 Time remaining: 5s Progress 1517 / 9694 Time remaining: 5s Progress 1518 / 9694 Time remaining: 5s Progress 1519 / 9694 Time remaining: 5s Progress 1520 / 9694 Time remaining: 5s Progress 1521 / 9694 Time remaining: 5s Progress 1522 / 9694 Time remaining: 5s Progress 1523 / 9694 Time remaining: 5s Progress 1524 / 9694 Time remaining: 5s Progress 1525 / 9694 Time remaining: 5s Progress 1526 / 9694 Time remaining: 5s Progress 1527 / 9694 Time remaining: 5s Progress 1528 / 9694 Time remaining: 5s Progress 1529 / 9694 Time remaining: 5s Progress 1530 / 9694 Time remaining: 5s Progress 1531 / 9694 Time remaining: 5s Progress 1532 / 9694 Time remaining: 5s Progress 1533 / 9694 Time remaining: 5s Progress 1534 / 9694 Time remaining: 5s Progress 1535 / 9694 Time remaining: 5s Progress 1536 / 9694 Time remaining: 5s Progress 1537 / 9694 Time remaining: 5s Progress 1538 / 9694 Time remaining: 5s Progress 1539 / 9694 Time remaining: 5s Progress 1540 / 9694 Time remaining: 5s Progress 1541 / 9694 Time remaining: 5s Progress 1542 / 9694 Time remaining: 5s Progress 1543 / 9694 Time remaining: 5s Progress 1544 / 9694 Time remaining: 5s Progress 1545 / 9694 Time remaining: 5s Progress 1546 / 9694 Time remaining: 5s Progress 1547 / 9694 Time remaining: 5s Progress 1548 / 9694 Time remaining: 5s Progress 1549 / 9694 Time remaining: 5s Progress 1550 / 9694 Time remaining: 5s Progress 1551 / 9694 Time remaining: 5s Progress 1552 / 9694 Time remaining: 5s Progress 1553 / 9694 Time remaining: 5s Progress 1554 / 9694 Time remaining: 5s Progress 1555 / 9694 Time remaining: 5s Progress 1556 / 9694 Time remaining: 5s Progress 1557 / 9694 Time remaining: 5s Progress 1558 / 9694 Time remaining: 5s Progress 1559 / 9694 Time remaining: 5s Progress 1560 / 9694 Time remaining: 5s Progress 1561 / 9694 Time remaining: 5s Progress 1562 / 9694 Time remaining: 5s Progress 1563 / 9694 Time remaining: 5s Progress 1564 / 9694 Time remaining: 5s Progress 1565 / 9694 Time remaining: 5s Progress 1566 / 9694 Time remaining: 5s Progress 1567 / 9694 Time remaining: 5s Progress 1568 / 9694 Time remaining: 5s Progress 1569 / 9694 Time remaining: 5s Progress 1570 / 9694 Time remaining: 5s Progress 1571 / 9694 Time remaining: 5s Progress 1572 / 9694 Time remaining: 5s Progress 1573 / 9694 Time remaining: 5s Progress 1574 / 9694 Time remaining: 5s Progress 1575 / 9694 Time remaining: 5s Progress 1576 / 9694 Time remaining: 5s Progress 1577 / 9694 Time remaining: 5s Progress 1578 / 9694 Time remaining: 5s Progress 1579 / 9694 Time remaining: 5s Progress 1580 / 9694 Time remaining: 5s Progress 1581 / 9694 Time remaining: 5s Progress 1582 / 9694 Time remaining: 5s Progress 1583 / 9694 Time remaining: 5s Progress 1584 / 9694 Time remaining: 5s Progress 1585 / 9694 Time remaining: 5s Progress 1586 / 9694 Time remaining: 5s Progress 1587 / 9694 Time remaining: 5s Progress 1588 / 9694 Time remaining: 5s Progress 1589 / 9694 Time remaining: 5s Progress 1590 / 9694 Time remaining: 5s Progress 1591 / 9694 Time remaining: 5s Progress 1592 / 9694 Time remaining: 5s Progress 1593 / 9694 Time remaining: 5s Progress 1594 / 9694 Time remaining: 5s Progress 1595 / 9694 Time remaining: 5s Progress 1596 / 9694 Time remaining: 5s Progress 1597 / 9694 Time remaining: 5s Progress 1598 / 9694 Time remaining: 5s Progress 1599 / 9694 Time remaining: 5s Progress 1600 / 9694 Time remaining: 5s Progress 1601 / 9694 Time remaining: 5s Progress 1602 / 9694 Time remaining: 5s Progress 1603 / 9694 Time remaining: 5s Progress 1604 / 9694 Time remaining: 5s Progress 1605 / 9694 Time remaining: 5s Progress 1606 / 9694 Time remaining: 5s Progress 1607 / 9694 Time remaining: 5s Progress 1608 / 9694 Time remaining: 5s Progress 1609 / 9694 Time remaining: 5s Progress 1610 / 9694 Time remaining: 5s Progress 1611 / 9694 Time remaining: 5s Progress 1612 / 9694 Time remaining: 5s Progress 1613 / 9694 Time remaining: 5s Progress 1614 / 9694 Time remaining: 5s Progress 1615 / 9694 Time remaining: 5s Progress 1616 / 9694 Time remaining: 5s Progress 1617 / 9694 Time remaining: 5s Progress 1618 / 9694 Time remaining: 5s Progress 1619 / 9694 Time remaining: 5s Progress 1620 / 9694 Time remaining: 5s Progress 1621 / 9694 Time remaining: 5s Progress 1622 / 9694 Time remaining: 5s Progress 1623 / 9694 Time remaining: 5s Progress 1624 / 9694 Time remaining: 5s Progress 1625 / 9694 Time remaining: 5s Progress 1626 / 9694 Time remaining: 5s Progress 1627 / 9694 Time remaining: 5s Progress 1628 / 9694 Time remaining: 5s Progress 1629 / 9694 Time remaining: 5s Progress 1630 / 9694 Time remaining: 5s Progress 1631 / 9694 Time remaining: 5s Progress 1632 / 9694 Time remaining: 5s Progress 1633 / 9694 Time remaining: 5s Progress 1634 / 9694 Time remaining: 5s Progress 1635 / 9694 Time remaining: 5s Progress 1636 / 9694 Time remaining: 5s Progress 1637 / 9694 Time remaining: 5s Progress 1638 / 9694 Time remaining: 5s Progress 1639 / 9694 Time remaining: 5s Progress 1640 / 9694 Time remaining: 5s Progress 1641 / 9694 Time remaining: 5s Progress 1642 / 9694 Time remaining: 5s Progress 1643 / 9694 Time remaining: 5s Progress 1644 / 9694 Time remaining: 5s Progress 1645 / 9694 Time remaining: 5s Progress 1646 / 9694 Time remaining: 5s Progress 1647 / 9694 Time remaining: 5s Progress 1648 / 9694 Time remaining: 5s Progress 1649 / 9694 Time remaining: 5s Progress 1650 / 9694 Time remaining: 5s Progress 1651 / 9694 Time remaining: 5s Progress 1652 / 9694 Time remaining: 5s Progress 1653 / 9694 Time remaining: 5s Progress 1654 / 9694 Time remaining: 5s Progress 1655 / 9694 Time remaining: 5s Progress 1656 / 9694 Time remaining: 5s Progress 1657 / 9694 Time remaining: 5s Progress 1658 / 9694 Time remaining: 5s Progress 1659 / 9694 Time remaining: 5s Progress 1660 / 9694 Time remaining: 5s Progress 1661 / 9694 Time remaining: 5s Progress 1662 / 9694 Time remaining: 5s Progress 1663 / 9694 Time remaining: 5s Progress 1664 / 9694 Time remaining: 5s Progress 1665 / 9694 Time remaining: 5s Progress 1666 / 9694 Time remaining: 5s Progress 1667 / 9694 Time remaining: 5s Progress 1668 / 9694 Time remaining: 5s Progress 1669 / 9694 Time remaining: 5s Progress 1670 / 9694 Time remaining: 5s Progress 1671 / 9694 Time remaining: 5s Progress 1672 / 9694 Time remaining: 5s Progress 1673 / 9694 Time remaining: 5s Progress 1674 / 9694 Time remaining: 5s Progress 1675 / 9694 Time remaining: 5s Progress 1676 / 9694 Time remaining: 5s Progress 1677 / 9694 Time remaining: 5s Progress 1678 / 9694 Time remaining: 5s Progress 1679 / 9694 Time remaining: 5s Progress 1680 / 9694 Time remaining: 5s Progress 1681 / 9694 Time remaining: 5s Progress 1682 / 9694 Time remaining: 5s Progress 1683 / 9694 Time remaining: 5s Progress 1684 / 9694 Time remaining: 5s Progress 1685 / 9694 Time remaining: 5s Progress 1686 / 9694 Time remaining: 5s Progress 1687 / 9694 Time remaining: 5s Progress 1688 / 9694 Time remaining: 5s Progress 1689 / 9694 Time remaining: 5s Progress 1690 / 9694 Time remaining: 5s Progress 1691 / 9694 Time remaining: 5s Progress 1692 / 9694 Time remaining: 5s Progress 1693 / 9694 Time remaining: 5s Progress 1694 / 9694 Time remaining: 5s Progress 1695 / 9694 Time remaining: 5s Progress 1696 / 9694 Time remaining: 5s Progress 1697 / 9694 Time remaining: 5s Progress 1698 / 9694 Time remaining: 5s Progress 1699 / 9694 Time remaining: 5s Progress 1700 / 9694 Time remaining: 5s Progress 1701 / 9694 Time remaining: 5s Progress 1702 / 9694 Time remaining: 5s Progress 1703 / 9694 Time remaining: 5s Progress 1704 / 9694 Time remaining: 5s Progress 1705 / 9694 Time remaining: 5s Progress 1706 / 9694 Time remaining: 5s Progress 1707 / 9694 Time remaining: 5s Progress 1708 / 9694 Time remaining: 5s Progress 1709 / 9694 Time remaining: 5s Progress 1710 / 9694 Time remaining: 5s Progress 1711 / 9694 Time remaining: 5s Progress 1712 / 9694 Time remaining: 5s Progress 1713 / 9694 Time remaining: 5s Progress 1714 / 9694 Time remaining: 5s Progress 1715 / 9694 Time remaining: 5s Progress 1716 / 9694 Time remaining: 5s Progress 1717 / 9694 Time remaining: 5s Progress 1718 / 9694 Time remaining: 5s Progress 1719 / 9694 Time remaining: 5s Progress 1720 / 9694 Time remaining: 5s Progress 1721 / 9694 Time remaining: 5s Progress 1722 / 9694 Time remaining: 5s Progress 1723 / 9694 Time remaining: 5s Progress 1724 / 9694 Time remaining: 5s Progress 1725 / 9694 Time remaining: 5s Progress 1726 / 9694 Time remaining: 5s Progress 1727 / 9694 Time remaining: 5s Progress 1728 / 9694 Time remaining: 5s Progress 1729 / 9694 Time remaining: 5s Progress 1730 / 9694 Time remaining: 5s Progress 1731 / 9694 Time remaining: 5s Progress 1732 / 9694 Time remaining: 5s Progress 1733 / 9694 Time remaining: 5s Progress 1734 / 9694 Time remaining: 5s Progress 1735 / 9694 Time remaining: 5s Progress 1736 / 9694 Time remaining: 5s Progress 1737 / 9694 Time remaining: 5s Progress 1738 / 9694 Time remaining: 5s Progress 1739 / 9694 Time remaining: 5s Progress 1740 / 9694 Time remaining: 5s Progress 1741 / 9694 Time remaining: 5s Progress 1742 / 9694 Time remaining: 5s Progress 1743 / 9694 Time remaining: 5s Progress 1744 / 9694 Time remaining: 5s Progress 1745 / 9694 Time remaining: 5s Progress 1746 / 9694 Time remaining: 5s Progress 1747 / 9694 Time remaining: 5s Progress 1748 / 9694 Time remaining: 5s Progress 1749 / 9694 Time remaining: 5s Progress 1750 / 9694 Time remaining: 5s Progress 1751 / 9694 Time remaining: 5s Progress 1752 / 9694 Time remaining: 5s Progress 1753 / 9694 Time remaining: 5s Progress 1754 / 9694 Time remaining: 5s Progress 1755 / 9694 Time remaining: 5s Progress 1756 / 9694 Time remaining: 5s Progress 1757 / 9694 Time remaining: 5s Progress 1758 / 9694 Time remaining: 5s Progress 1759 / 9694 Time remaining: 5s Progress 1760 / 9694 Time remaining: 5s Progress 1761 / 9694 Time remaining: 5s Progress 1762 / 9694 Time remaining: 5s Progress 1763 / 9694 Time remaining: 5s Progress 1764 / 9694 Time remaining: 5s Progress 1765 / 9694 Time remaining: 5s Progress 1766 / 9694 Time remaining: 5s Progress 1767 / 9694 Time remaining: 5s Progress 1768 / 9694 Time remaining: 5s Progress 1769 / 9694 Time remaining: 5s Progress 1770 / 9694 Time remaining: 5s Progress 1771 / 9694 Time remaining: 5s Progress 1772 / 9694 Time remaining: 5s Progress 1773 / 9694 Time remaining: 5s Progress 1774 / 9694 Time remaining: 5s Progress 1775 / 9694 Time remaining: 5s Progress 1776 / 9694 Time remaining: 5s Progress 1777 / 9694 Time remaining: 5s Progress 1778 / 9694 Time remaining: 5s Progress 1779 / 9694 Time remaining: 5s Progress 1780 / 9694 Time remaining: 5s Progress 1781 / 9694 Time remaining: 5s Progress 1782 / 9694 Time remaining: 5s Progress 1783 / 9694 Time remaining: 5s Progress 1784 / 9694 Time remaining: 5s Progress 1785 / 9694 Time remaining: 5s Progress 1786 / 9694 Time remaining: 5s Progress 1787 / 9694 Time remaining: 5s Progress 1788 / 9694 Time remaining: 5s Progress 1789 / 9694 Time remaining: 5s Progress 1790 / 9694 Time remaining: 5s Progress 1791 / 9694 Time remaining: 5s Progress 1792 / 9694 Time remaining: 5s Progress 1793 / 9694 Time remaining: 5s Progress 1794 / 9694 Time remaining: 5s Progress 1795 / 9694 Time remaining: 5s Progress 1796 / 9694 Time remaining: 5s Progress 1797 / 9694 Time remaining: 5s Progress 1798 / 9694 Time remaining: 5s Progress 1799 / 9694 Time remaining: 5s Progress 1800 / 9694 Time remaining: 5s Progress 1801 / 9694 Time remaining: 5s Progress 1802 / 9694 Time remaining: 5s Progress 1803 / 9694 Time remaining: 5s Progress 1804 / 9694 Time remaining: 5s Progress 1805 / 9694 Time remaining: 5s Progress 1806 / 9694 Time remaining: 5s Progress 1807 / 9694 Time remaining: 5s Progress 1808 / 9694 Time remaining: 5s Progress 1809 / 9694 Time remaining: 5s Progress 1810 / 9694 Time remaining: 5s Progress 1811 / 9694 Time remaining: 5s Progress 1812 / 9694 Time remaining: 5s Progress 1813 / 9694 Time remaining: 5s Progress 1814 / 9694 Time remaining: 5s Progress 1815 / 9694 Time remaining: 5s Progress 1816 / 9694 Time remaining: 5s Progress 1817 / 9694 Time remaining: 5s Progress 1818 / 9694 Time remaining: 5s Progress 1819 / 9694 Time remaining: 5s Progress 1820 / 9694 Time remaining: 5s Progress 1821 / 9694 Time remaining: 5s Progress 1822 / 9694 Time remaining: 5s Progress 1823 / 9694 Time remaining: 5s Progress 1824 / 9694 Time remaining: 5s Progress 1825 / 9694 Time remaining: 5s Progress 1826 / 9694 Time remaining: 5s Progress 1827 / 9694 Time remaining: 5s Progress 1828 / 9694 Time remaining: 5s Progress 1829 / 9694 Time remaining: 5s Progress 1830 / 9694 Time remaining: 5s Progress 1831 / 9694 Time remaining: 5s Progress 1832 / 9694 Time remaining: 5s Progress 1833 / 9694 Time remaining: 5s Progress 1834 / 9694 Time remaining: 5s Progress 1835 / 9694 Time remaining: 5s Progress 1836 / 9694 Time remaining: 5s Progress 1837 / 9694 Time remaining: 5s Progress 1838 / 9694 Time remaining: 5s Progress 1839 / 9694 Time remaining: 5s Progress 1840 / 9694 Time remaining: 5s Progress 1841 / 9694 Time remaining: 5s Progress 1842 / 9694 Time remaining: 5s Progress 1843 / 9694 Time remaining: 5s Progress 1844 / 9694 Time remaining: 5s Progress 1845 / 9694 Time remaining: 5s Progress 1846 / 9694 Time remaining: 5s Progress 1847 / 9694 Time remaining: 5s Progress 1848 / 9694 Time remaining: 5s Progress 1849 / 9694 Time remaining: 5s Progress 1850 / 9694 Time remaining: 5s Progress 1851 / 9694 Time remaining: 5s Progress 1852 / 9694 Time remaining: 5s Progress 1853 / 9694 Time remaining: 5s Progress 1854 / 9694 Time remaining: 5s Progress 1855 / 9694 Time remaining: 5s Progress 1856 / 9694 Time remaining: 5s Progress 1857 / 9694 Time remaining: 5s Progress 1858 / 9694 Time remaining: 5s Progress 1859 / 9694 Time remaining: 5s Progress 1860 / 9694 Time remaining: 5s Progress 1861 / 9694 Time remaining: 5s Progress 1862 / 9694 Time remaining: 5s Progress 1863 / 9694 Time remaining: 5s Progress 1864 / 9694 Time remaining: 5s Progress 1865 / 9694 Time remaining: 5s Progress 1866 / 9694 Time remaining: 5s Progress 1867 / 9694 Time remaining: 5s Progress 1868 / 9694 Time remaining: 5s Progress 1869 / 9694 Time remaining: 5s Progress 1870 / 9694 Time remaining: 5s Progress 1871 / 9694 Time remaining: 5s Progress 1872 / 9694 Time remaining: 5s Progress 1873 / 9694 Time remaining: 5s Progress 1874 / 9694 Time remaining: 5s Progress 1875 / 9694 Time remaining: 5s Progress 1876 / 9694 Time remaining: 5s Progress 1877 / 9694 Time remaining: 5s Progress 1878 / 9694 Time remaining: 5s Progress 1879 / 9694 Time remaining: 5s Progress 1880 / 9694 Time remaining: 5s Progress 1881 / 9694 Time remaining: 5s Progress 1882 / 9694 Time remaining: 5s Progress 1883 / 9694 Time remaining: 5s Progress 1884 / 9694 Time remaining: 5s Progress 1885 / 9694 Time remaining: 5s Progress 1886 / 9694 Time remaining: 5s Progress 1887 / 9694 Time remaining: 5s Progress 1888 / 9694 Time remaining: 5s Progress 1889 / 9694 Time remaining: 5s Progress 1890 / 9694 Time remaining: 5s Progress 1891 / 9694 Time remaining: 5s Progress 1892 / 9694 Time remaining: 5s Progress 1893 / 9694 Time remaining: 5s Progress 1894 / 9694 Time remaining: 5s Progress 1895 / 9694 Time remaining: 5s Progress 1896 / 9694 Time remaining: 5s Progress 1897 / 9694 Time remaining: 5s Progress 1898 / 9694 Time remaining: 5s Progress 1899 / 9694 Time remaining: 5s Progress 1900 / 9694 Time remaining: 5s Progress 1901 / 9694 Time remaining: 5s Progress 1902 / 9694 Time remaining: 5s Progress 1903 / 9694 Time remaining: 5s Progress 1904 / 9694 Time remaining: 5s Progress 1905 / 9694 Time remaining: 5s Progress 1906 / 9694 Time remaining: 5s Progress 1907 / 9694 Time remaining: 5s Progress 1908 / 9694 Time remaining: 5s Progress 1909 / 9694 Time remaining: 5s Progress 1910 / 9694 Time remaining: 5s Progress 1911 / 9694 Time remaining: 5s Progress 1912 / 9694 Time remaining: 5s Progress 1913 / 9694 Time remaining: 5s Progress 1914 / 9694 Time remaining: 5s Progress 1915 / 9694 Time remaining: 5s Progress 1916 / 9694 Time remaining: 5s Progress 1917 / 9694 Time remaining: 5s Progress 1918 / 9694 Time remaining: 5s Progress 1919 / 9694 Time remaining: 5s Progress 1920 / 9694 Time remaining: 5s Progress 1921 / 9694 Time remaining: 5s Progress 1922 / 9694 Time remaining: 5s Progress 1923 / 9694 Time remaining: 5s Progress 1924 / 9694 Time remaining: 5s Progress 1925 / 9694 Time remaining: 5s Progress 1926 / 9694 Time remaining: 5s Progress 1927 / 9694 Time remaining: 5s Progress 1928 / 9694 Time remaining: 5s Progress 1929 / 9694 Time remaining: 5s Progress 1930 / 9694 Time remaining: 5s Progress 1931 / 9694 Time remaining: 5s Progress 1932 / 9694 Time remaining: 5s Progress 1933 / 9694 Time remaining: 5s Progress 1934 / 9694 Time remaining: 5s Progress 1935 / 9694 Time remaining: 5s Progress 1936 / 9694 Time remaining: 5s Progress 1937 / 9694 Time remaining: 5s Progress 1938 / 9694 Time remaining: 5s Progress 1939 / 9694 Time remaining: 5s Progress 1940 / 9694 Time remaining: 5s Progress 1941 / 9694 Time remaining: 5s Progress 1942 / 9694 Time remaining: 5s Progress 1943 / 9694 Time remaining: 5s Progress 1944 / 9694 Time remaining: 5s Progress 1945 / 9694 Time remaining: 5s Progress 1946 / 9694 Time remaining: 5s Progress 1947 / 9694 Time remaining: 5s Progress 1948 / 9694 Time remaining: 5s Progress 1949 / 9694 Time remaining: 5s Progress 1950 / 9694 Time remaining: 5s Progress 1951 / 9694 Time remaining: 5s Progress 1952 / 9694 Time remaining: 5s Progress 1953 / 9694 Time remaining: 5s Progress 1954 / 9694 Time remaining: 5s Progress 1955 / 9694 Time remaining: 5s Progress 1956 / 9694 Time remaining: 5s Progress 1957 / 9694 Time remaining: 5s Progress 1958 / 9694 Time remaining: 5s Progress 1959 / 9694 Time remaining: 5s Progress 1960 / 9694 Time remaining: 5s Progress 1961 / 9694 Time remaining: 5s Progress 1962 / 9694 Time remaining: 5s Progress 1963 / 9694 Time remaining: 5s Progress 1964 / 9694 Time remaining: 5s Progress 1965 / 9694 Time remaining: 5s Progress 1966 / 9694 Time remaining: 5s Progress 1967 / 9694 Time remaining: 5s Progress 1968 / 9694 Time remaining: 5s Progress 1969 / 9694 Time remaining: 5s Progress 1970 / 9694 Time remaining: 5s Progress 1971 / 9694 Time remaining: 5s Progress 1972 / 9694 Time remaining: 5s Progress 1973 / 9694 Time remaining: 5s Progress 1974 / 9694 Time remaining: 5s Progress 1975 / 9694 Time remaining: 5s Progress 1976 / 9694 Time remaining: 5s Progress 1977 / 9694 Time remaining: 5s Progress 1978 / 9694 Time remaining: 5s Progress 1979 / 9694 Time remaining: 5s Progress 1980 / 9694 Time remaining: 5s Progress 1981 / 9694 Time remaining: 5s Progress 1982 / 9694 Time remaining: 5s Progress 1983 / 9694 Time remaining: 5s Progress 1984 / 9694 Time remaining: 5s Progress 1985 / 9694 Time remaining: 5s Progress 1986 / 9694 Time remaining: 5s Progress 1987 / 9694 Time remaining: 5s Progress 1988 / 9694 Time remaining: 5s Progress 1989 / 9694 Time remaining: 5s Progress 1990 / 9694 Time remaining: 5s Progress 1991 / 9694 Time remaining: 5s Progress 1992 / 9694 Time remaining: 5s Progress 1993 / 9694 Time remaining: 5s Progress 1994 / 9694 Time remaining: 5s Progress 1995 / 9694 Time remaining: 5s Progress 1996 / 9694 Time remaining: 5s Progress 1997 / 9694 Time remaining: 5s Progress 1998 / 9694 Time remaining: 5s Progress 1999 / 9694 Time remaining: 5s Progress 2000 / 9694 Time remaining: 5s Progress 2001 / 9694 Time remaining: 5s Progress 2002 / 9694 Time remaining: 5s Progress 2003 / 9694 Time remaining: 5s Progress 2004 / 9694 Time remaining: 5s Progress 2005 / 9694 Time remaining: 5s Progress 2006 / 9694 Time remaining: 5s Progress 2007 / 9694 Time remaining: 5s Progress 2008 / 9694 Time remaining: 5s Progress 2009 / 9694 Time remaining: 5s Progress 2010 / 9694 Time remaining: 5s Progress 2011 / 9694 Time remaining: 5s Progress 2012 / 9694 Time remaining: 5s Progress 2013 / 9694 Time remaining: 5s Progress 2014 / 9694 Time remaining: 5s Progress 2015 / 9694 Time remaining: 5s Progress 2016 / 9694 Time remaining: 5s Progress 2017 / 9694 Time remaining: 5s Progress 2018 / 9694 Time remaining: 5s Progress 2019 / 9694 Time remaining: 5s Progress 2020 / 9694 Time remaining: 5s Progress 2021 / 9694 Time remaining: 5s Progress 2022 / 9694 Time remaining: 5s Progress 2023 / 9694 Time remaining: 5s Progress 2024 / 9694 Time remaining: 5s Progress 2025 / 9694 Time remaining: 5s Progress 2026 / 9694 Time remaining: 5s Progress 2027 / 9694 Time remaining: 5s Progress 2028 / 9694 Time remaining: 5s Progress 2029 / 9694 Time remaining: 5s Progress 2030 / 9694 Time remaining: 5s Progress 2031 / 9694 Time remaining: 5s Progress 2032 / 9694 Time remaining: 5s Progress 2033 / 9694 Time remaining: 5s Progress 2034 / 9694 Time remaining: 5s Progress 2035 / 9694 Time remaining: 5s Progress 2036 / 9694 Time remaining: 5s Progress 2037 / 9694 Time remaining: 5s Progress 2038 / 9694 Time remaining: 5s Progress 2039 / 9694 Time remaining: 5s Progress 2040 / 9694 Time remaining: 5s Progress 2041 / 9694 Time remaining: 5s Progress 2042 / 9694 Time remaining: 5s Progress 2043 / 9694 Time remaining: 5s Progress 2044 / 9694 Time remaining: 5s Progress 2045 / 9694 Time remaining: 5s Progress 2046 / 9694 Time remaining: 5s Progress 2047 / 9694 Time remaining: 5s Progress 2048 / 9694 Time remaining: 5s Progress 2049 / 9694 Time remaining: 5s Progress 2050 / 9694 Time remaining: 5s Progress 2051 / 9694 Time remaining: 5s Progress 2052 / 9694 Time remaining: 5s Progress 2053 / 9694 Time remaining: 5s Progress 2054 / 9694 Time remaining: 5s Progress 2055 / 9694 Time remaining: 5s Progress 2056 / 9694 Time remaining: 5s Progress 2057 / 9694 Time remaining: 5s Progress 2058 / 9694 Time remaining: 5s Progress 2059 / 9694 Time remaining: 5s Progress 2060 / 9694 Time remaining: 5s Progress 2061 / 9694 Time remaining: 5s Progress 2062 / 9694 Time remaining: 5s Progress 2063 / 9694 Time remaining: 5s Progress 2064 / 9694 Time remaining: 5s Progress 2065 / 9694 Time remaining: 5s Progress 2066 / 9694 Time remaining: 5s Progress 2067 / 9694 Time remaining: 5s Progress 2068 / 9694 Time remaining: 5s Progress 2069 / 9694 Time remaining: 5s Progress 2070 / 9694 Time remaining: 5s Progress 2071 / 9694 Time remaining: 5s Progress 2072 / 9694 Time remaining: 5s Progress 2073 / 9694 Time remaining: 5s Progress 2074 / 9694 Time remaining: 5s Progress 2075 / 9694 Time remaining: 5s Progress 2076 / 9694 Time remaining: 5s Progress 2077 / 9694 Time remaining: 5s Progress 2078 / 9694 Time remaining: 5s Progress 2079 / 9694 Time remaining: 5s Progress 2080 / 9694 Time remaining: 5s Progress 2081 / 9694 Time remaining: 5s Progress 2082 / 9694 Time remaining: 5s Progress 2083 / 9694 Time remaining: 5s Progress 2084 / 9694 Time remaining: 5s Progress 2085 / 9694 Time remaining: 5s Progress 2086 / 9694 Time remaining: 5s Progress 2087 / 9694 Time remaining: 5s Progress 2088 / 9694 Time remaining: 5s Progress 2089 / 9694 Time remaining: 5s Progress 2090 / 9694 Time remaining: 5s Progress 2091 / 9694 Time remaining: 5s Progress 2092 / 9694 Time remaining: 5s Progress 2093 / 9694 Time remaining: 5s Progress 2094 / 9694 Time remaining: 5s Progress 2095 / 9694 Time remaining: 5s Progress 2096 / 9694 Time remaining: 5s Progress 2097 / 9694 Time remaining: 5s Progress 2098 / 9694 Time remaining: 5s Progress 2099 / 9694 Time remaining: 5s Progress 2100 / 9694 Time remaining: 5s Progress 2101 / 9694 Time remaining: 5s Progress 2102 / 9694 Time remaining: 5s Progress 2103 / 9694 Time remaining: 5s Progress 2104 / 9694 Time remaining: 5s Progress 2105 / 9694 Time remaining: 5s Progress 2106 / 9694 Time remaining: 5s Progress 2107 / 9694 Time remaining: 5s Progress 2108 / 9694 Time remaining: 5s Progress 2109 / 9694 Time remaining: 5s Progress 2110 / 9694 Time remaining: 5s Progress 2111 / 9694 Time remaining: 5s Progress 2112 / 9694 Time remaining: 5s Progress 2113 / 9694 Time remaining: 5s Progress 2114 / 9694 Time remaining: 5s Progress 2115 / 9694 Time remaining: 5s Progress 2116 / 9694 Time remaining: 5s Progress 2117 / 9694 Time remaining: 5s Progress 2118 / 9694 Time remaining: 5s Progress 2119 / 9694 Time remaining: 5s Progress 2120 / 9694 Time remaining: 5s Progress 2121 / 9694 Time remaining: 5s Progress 2122 / 9694 Time remaining: 5s Progress 2123 / 9694 Time remaining: 5s Progress 2124 / 9694 Time remaining: 5s Progress 2125 / 9694 Time remaining: 5s Progress 2126 / 9694 Time remaining: 5s Progress 2127 / 9694 Time remaining: 5s Progress 2128 / 9694 Time remaining: 5s Progress 2129 / 9694 Time remaining: 5s Progress 2130 / 9694 Time remaining: 5s Progress 2131 / 9694 Time remaining: 5s Progress 2132 / 9694 Time remaining: 5s Progress 2133 / 9694 Time remaining: 5s Progress 2134 / 9694 Time remaining: 5s Progress 2135 / 9694 Time remaining: 5s Progress 2136 / 9694 Time remaining: 5s Progress 2137 / 9694 Time remaining: 5s Progress 2138 / 9694 Time remaining: 5s Progress 2139 / 9694 Time remaining: 5s Progress 2140 / 9694 Time remaining: 5s Progress 2141 / 9694 Time remaining: 5s Progress 2142 / 9694 Time remaining: 5s Progress 2143 / 9694 Time remaining: 5s Progress 2144 / 9694 Time remaining: 5s Progress 2145 / 9694 Time remaining: 5s Progress 2146 / 9694 Time remaining: 5s Progress 2147 / 9694 Time remaining: 5s Progress 2148 / 9694 Time remaining: 5s Progress 2149 / 9694 Time remaining: 5s Progress 2150 / 9694 Time remaining: 5s Progress 2151 / 9694 Time remaining: 5s Progress 2152 / 9694 Time remaining: 5s Progress 2153 / 9694 Time remaining: 5s Progress 2154 / 9694 Time remaining: 5s Progress 2155 / 9694 Time remaining: 5s Progress 2156 / 9694 Time remaining: 5s Progress 2157 / 9694 Time remaining: 5s Progress 2158 / 9694 Time remaining: 5s Progress 2159 / 9694 Time remaining: 5s Progress 2160 / 9694 Time remaining: 5s Progress 2161 / 9694 Time remaining: 5s Progress 2162 / 9694 Time remaining: 5s Progress 2163 / 9694 Time remaining: 5s Progress 2164 / 9694 Time remaining: 5s Progress 2165 / 9694 Time remaining: 5s Progress 2166 / 9694 Time remaining: 5s Progress 2167 / 9694 Time remaining: 5s Progress 2168 / 9694 Time remaining: 5s Progress 2169 / 9694 Time remaining: 5s Progress 2170 / 9694 Time remaining: 5s Progress 2171 / 9694 Time remaining: 5s Progress 2172 / 9694 Time remaining: 5s Progress 2173 / 9694 Time remaining: 5s Progress 2174 / 9694 Time remaining: 5s Progress 2175 / 9694 Time remaining: 5s Progress 2176 / 9694 Time remaining: 5s Progress 2177 / 9694 Time remaining: 5s Progress 2178 / 9694 Time remaining: 5s Progress 2179 / 9694 Time remaining: 5s Progress 2180 / 9694 Time remaining: 5s Progress 2181 / 9694 Time remaining: 5s Progress 2182 / 9694 Time remaining: 5s Progress 2183 / 9694 Time remaining: 5s Progress 2184 / 9694 Time remaining: 5s Progress 2185 / 9694 Time remaining: 5s Progress 2186 / 9694 Time remaining: 5s Progress 2187 / 9694 Time remaining: 5s Progress 2188 / 9694 Time remaining: 5s Progress 2189 / 9694 Time remaining: 5s Progress 2190 / 9694 Time remaining: 5s Progress 2191 / 9694 Time remaining: 5s Progress 2192 / 9694 Time remaining: 5s Progress 2193 / 9694 Time remaining: 5s Progress 2194 / 9694 Time remaining: 5s Progress 2195 / 9694 Time remaining: 5s Progress 2196 / 9694 Time remaining: 5s Progress 2197 / 9694 Time remaining: 5s Progress 2198 / 9694 Time remaining: 5s Progress 2199 / 9694 Time remaining: 5s Progress 2200 / 9694 Time remaining: 5s Progress 2201 / 9694 Time remaining: 5s Progress 2202 / 9694 Time remaining: 5s Progress 2203 / 9694 Time remaining: 5s Progress 2204 / 9694 Time remaining: 5s Progress 2205 / 9694 Time remaining: 5s Progress 2206 / 9694 Time remaining: 5s Progress 2207 / 9694 Time remaining: 5s Progress 2208 / 9694 Time remaining: 5s Progress 2209 / 9694 Time remaining: 5s Progress 2210 / 9694 Time remaining: 5s Progress 2211 / 9694 Time remaining: 5s Progress 2212 / 9694 Time remaining: 5s Progress 2213 / 9694 Time remaining: 5s Progress 2214 / 9694 Time remaining: 5s Progress 2215 / 9694 Time remaining: 5s Progress 2216 / 9694 Time remaining: 5s Progress 2217 / 9694 Time remaining: 5s Progress 2218 / 9694 Time remaining: 5s Progress 2219 / 9694 Time remaining: 5s Progress 2220 / 9694 Time remaining: 5s Progress 2221 / 9694 Time remaining: 5s Progress 2222 / 9694 Time remaining: 5s Progress 2223 / 9694 Time remaining: 5s Progress 2224 / 9694 Time remaining: 5s Progress 2225 / 9694 Time remaining: 5s Progress 2226 / 9694 Time remaining: 5s Progress 2227 / 9694 Time remaining: 5s Progress 2228 / 9694 Time remaining: 5s Progress 2229 / 9694 Time remaining: 5s Progress 2230 / 9694 Time remaining: 5s Progress 2231 / 9694 Time remaining: 5s Progress 2232 / 9694 Time remaining: 5s Progress 2233 / 9694 Time remaining: 5s Progress 2234 / 9694 Time remaining: 5s Progress 2235 / 9694 Time remaining: 5s Progress 2236 / 9694 Time remaining: 5s Progress 2237 / 9694 Time remaining: 5s Progress 2238 / 9694 Time remaining: 5s Progress 2239 / 9694 Time remaining: 5s Progress 2240 / 9694 Time remaining: 5s Progress 2241 / 9694 Time remaining: 5s Progress 2242 / 9694 Time remaining: 5s Progress 2243 / 9694 Time remaining: 5s Progress 2244 / 9694 Time remaining: 5s Progress 2245 / 9694 Time remaining: 5s Progress 2246 / 9694 Time remaining: 5s Progress 2247 / 9694 Time remaining: 5s Progress 2248 / 9694 Time remaining: 5s Progress 2249 / 9694 Time remaining: 5s Progress 2250 / 9694 Time remaining: 5s Progress 2251 / 9694 Time remaining: 5s Progress 2252 / 9694 Time remaining: 5s Progress 2253 / 9694 Time remaining: 5s Progress 2254 / 9694 Time remaining: 5s Progress 2255 / 9694 Time remaining: 5s Progress 2256 / 9694 Time remaining: 5s Progress 2257 / 9694 Time remaining: 5s Progress 2258 / 9694 Time remaining: 5s Progress 2259 / 9694 Time remaining: 5s Progress 2260 / 9694 Time remaining: 5s Progress 2261 / 9694 Time remaining: 5s Progress 2262 / 9694 Time remaining: 5s Progress 2263 / 9694 Time remaining: 5s Progress 2264 / 9694 Time remaining: 5s Progress 2265 / 9694 Time remaining: 5s Progress 2266 / 9694 Time remaining: 5s Progress 2267 / 9694 Time remaining: 5s Progress 2268 / 9694 Time remaining: 5s Progress 2269 / 9694 Time remaining: 5s Progress 2270 / 9694 Time remaining: 5s Progress 2271 / 9694 Time remaining: 5s Progress 2272 / 9694 Time remaining: 5s Progress 2273 / 9694 Time remaining: 5s Progress 2274 / 9694 Time remaining: 5s Progress 2275 / 9694 Time remaining: 5s Progress 2276 / 9694 Time remaining: 5s Progress 2277 / 9694 Time remaining: 5s Progress 2278 / 9694 Time remaining: 5s Progress 2279 / 9694 Time remaining: 5s Progress 2280 / 9694 Time remaining: 5s Progress 2281 / 9694 Time remaining: 5s Progress 2282 / 9694 Time remaining: 5s Progress 2283 / 9694 Time remaining: 5s Progress 2284 / 9694 Time remaining: 5s Progress 2285 / 9694 Time remaining: 5s Progress 2286 / 9694 Time remaining: 5s Progress 2287 / 9694 Time remaining: 5s Progress 2288 / 9694 Time remaining: 5s Progress 2289 / 9694 Time remaining: 5s Progress 2290 / 9694 Time remaining: 5s Progress 2291 / 9694 Time remaining: 5s Progress 2292 / 9694 Time remaining: 5s Progress 2293 / 9694 Time remaining: 5s Progress 2294 / 9694 Time remaining: 5s Progress 2295 / 9694 Time remaining: 5s Progress 2296 / 9694 Time remaining: 5s Progress 2297 / 9694 Time remaining: 5s Progress 2298 / 9694 Time remaining: 5s Progress 2299 / 9694 Time remaining: 5s Progress 2300 / 9694 Time remaining: 5s Progress 2301 / 9694 Time remaining: 5s Progress 2302 / 9694 Time remaining: 5s Progress 2303 / 9694 Time remaining: 5s Progress 2304 / 9694 Time remaining: 5s Progress 2305 / 9694 Time remaining: 5s Progress 2306 / 9694 Time remaining: 5s Progress 2307 / 9694 Time remaining: 5s Progress 2308 / 9694 Time remaining: 5s Progress 2309 / 9694 Time remaining: 5s Progress 2310 / 9694 Time remaining: 5s Progress 2311 / 9694 Time remaining: 5s Progress 2312 / 9694 Time remaining: 5s Progress 2313 / 9694 Time remaining: 5s Progress 2314 / 9694 Time remaining: 5s Progress 2315 / 9694 Time remaining: 5s Progress 2316 / 9694 Time remaining: 5s Progress 2317 / 9694 Time remaining: 5s Progress 2318 / 9694 Time remaining: 5s Progress 2319 / 9694 Time remaining: 5s Progress 2320 / 9694 Time remaining: 5s Progress 2321 / 9694 Time remaining: 5s Progress 2322 / 9694 Time remaining: 5s Progress 2323 / 9694 Time remaining: 5s Progress 2324 / 9694 Time remaining: 5s Progress 2325 / 9694 Time remaining: 5s Progress 2326 / 9694 Time remaining: 5s Progress 2327 / 9694 Time remaining: 5s Progress 2328 / 9694 Time remaining: 5s Progress 2329 / 9694 Time remaining: 5s Progress 2330 / 9694 Time remaining: 5s Progress 2331 / 9694 Time remaining: 5s Progress 2332 / 9694 Time remaining: 5s Progress 2333 / 9694 Time remaining: 5s Progress 2334 / 9694 Time remaining: 5s Progress 2335 / 9694 Time remaining: 5s Progress 2336 / 9694 Time remaining: 5s Progress 2337 / 9694 Time remaining: 5s Progress 2338 / 9694 Time remaining: 5s Progress 2339 / 9694 Time remaining: 5s Progress 2340 / 9694 Time remaining: 5s Progress 2341 / 9694 Time remaining: 5s Progress 2342 / 9694 Time remaining: 5s Progress 2343 / 9694 Time remaining: 5s Progress 2344 / 9694 Time remaining: 5s Progress 2345 / 9694 Time remaining: 5s Progress 2346 / 9694 Time remaining: 5s Progress 2347 / 9694 Time remaining: 5s Progress 2348 / 9694 Time remaining: 5s Progress 2349 / 9694 Time remaining: 5s Progress 2350 / 9694 Time remaining: 5s Progress 2351 / 9694 Time remaining: 5s Progress 2352 / 9694 Time remaining: 5s Progress 2353 / 9694 Time remaining: 5s Progress 2354 / 9694 Time remaining: 5s Progress 2355 / 9694 Time remaining: 5s Progress 2356 / 9694 Time remaining: 5s Progress 2357 / 9694 Time remaining: 5s Progress 2358 / 9694 Time remaining: 5s Progress 2359 / 9694 Time remaining: 5s Progress 2360 / 9694 Time remaining: 5s Progress 2361 / 9694 Time remaining: 5s Progress 2362 / 9694 Time remaining: 5s Progress 2363 / 9694 Time remaining: 5s Progress 2364 / 9694 Time remaining: 5s Progress 2365 / 9694 Time remaining: 5s Progress 2366 / 9694 Time remaining: 5s Progress 2367 / 9694 Time remaining: 5s Progress 2368 / 9694 Time remaining: 5s Progress 2369 / 9694 Time remaining: 5s Progress 2370 / 9694 Time remaining: 5s Progress 2371 / 9694 Time remaining: 5s Progress 2372 / 9694 Time remaining: 5s Progress 2373 / 9694 Time remaining: 5s Progress 2374 / 9694 Time remaining: 5s Progress 2375 / 9694 Time remaining: 5s Progress 2376 / 9694 Time remaining: 5s Progress 2377 / 9694 Time remaining: 5s Progress 2378 / 9694 Time remaining: 5s Progress 2379 / 9694 Time remaining: 5s Progress 2380 / 9694 Time remaining: 5s Progress 2381 / 9694 Time remaining: 5s Progress 2382 / 9694 Time remaining: 5s Progress 2383 / 9694 Time remaining: 5s Progress 2384 / 9694 Time remaining: 5s Progress 2385 / 9694 Time remaining: 5s Progress 2386 / 9694 Time remaining: 5s Progress 2387 / 9694 Time remaining: 5s Progress 2388 / 9694 Time remaining: 5s Progress 2389 / 9694 Time remaining: 5s Progress 2390 / 9694 Time remaining: 5s Progress 2391 / 9694 Time remaining: 5s Progress 2392 / 9694 Time remaining: 5s Progress 2393 / 9694 Time remaining: 5s Progress 2394 / 9694 Time remaining: 5s Progress 2395 / 9694 Time remaining: 5s Progress 2396 / 9694 Time remaining: 5s Progress 2397 / 9694 Time remaining: 5s Progress 2398 / 9694 Time remaining: 5s Progress 2399 / 9694 Time remaining: 5s Progress 2400 / 9694 Time remaining: 5s Progress 2401 / 9694 Time remaining: 5s Progress 2402 / 9694 Time remaining: 5s Progress 2403 / 9694 Time remaining: 5s Progress 2404 / 9694 Time remaining: 5s Progress 2405 / 9694 Time remaining: 5s Progress 2406 / 9694 Time remaining: 5s Progress 2407 / 9694 Time remaining: 5s Progress 2408 / 9694 Time remaining: 5s Progress 2409 / 9694 Time remaining: 5s Progress 2410 / 9694 Time remaining: 5s Progress 2411 / 9694 Time remaining: 5s Progress 2412 / 9694 Time remaining: 5s Progress 2413 / 9694 Time remaining: 5s Progress 2414 / 9694 Time remaining: 5s Progress 2415 / 9694 Time remaining: 5s Progress 2416 / 9694 Time remaining: 5s Progress 2417 / 9694 Time remaining: 5s Progress 2418 / 9694 Time remaining: 5s Progress 2419 / 9694 Time remaining: 5s Progress 2420 / 9694 Time remaining: 5s Progress 2421 / 9694 Time remaining: 5s Progress 2422 / 9694 Time remaining: 5s Progress 2423 / 9694 Time remaining: 5s Progress 2424 / 9694 Time remaining: 5s Progress 2425 / 9694 Time remaining: 5s Progress 2426 / 9694 Time remaining: 5s Progress 2427 / 9694 Time remaining: 5s Progress 2428 / 9694 Time remaining: 5s Progress 2429 / 9694 Time remaining: 5s Progress 2430 / 9694 Time remaining: 5s Progress 2431 / 9694 Time remaining: 5s Progress 2432 / 9694 Time remaining: 5s Progress 2433 / 9694 Time remaining: 5s Progress 2434 / 9694 Time remaining: 5s Progress 2435 / 9694 Time remaining: 5s Progress 2436 / 9694 Time remaining: 5s Progress 2437 / 9694 Time remaining: 5s Progress 2438 / 9694 Time remaining: 5s Progress 2439 / 9694 Time remaining: 5s Progress 2440 / 9694 Time remaining: 5s Progress 2441 / 9694 Time remaining: 5s Progress 2442 / 9694 Time remaining: 5s Progress 2443 / 9694 Time remaining: 5s Progress 2444 / 9694 Time remaining: 5s Progress 2445 / 9694 Time remaining: 5s Progress 2446 / 9694 Time remaining: 5s Progress 2447 / 9694 Time remaining: 5s Progress 2448 / 9694 Time remaining: 5s Progress 2449 / 9694 Time remaining: 5s Progress 2450 / 9694 Time remaining: 5s Progress 2451 / 9694 Time remaining: 5s Progress 2452 / 9694 Time remaining: 5s Progress 2453 / 9694 Time remaining: 5s Progress 2454 / 9694 Time remaining: 5s Progress 2455 / 9694 Time remaining: 5s Progress 2456 / 9694 Time remaining: 5s Progress 2457 / 9694 Time remaining: 5s Progress 2458 / 9694 Time remaining: 5s Progress 2459 / 9694 Time remaining: 5s Progress 2460 / 9694 Time remaining: 5s Progress 2461 / 9694 Time remaining: 5s Progress 2462 / 9694 Time remaining: 5s Progress 2463 / 9694 Time remaining: 5s Progress 2464 / 9694 Time remaining: 5s Progress 2465 / 9694 Time remaining: 5s Progress 2466 / 9694 Time remaining: 5s Progress 2467 / 9694 Time remaining: 5s Progress 2468 / 9694 Time remaining: 5s Progress 2469 / 9694 Time remaining: 5s Progress 2470 / 9694 Time remaining: 5s Progress 2471 / 9694 Time remaining: 5s Progress 2472 / 9694 Time remaining: 5s Progress 2473 / 9694 Time remaining: 5s Progress 2474 / 9694 Time remaining: 5s Progress 2475 / 9694 Time remaining: 5s Progress 2476 / 9694 Time remaining: 5s Progress 2477 / 9694 Time remaining: 5s Progress 2478 / 9694 Time remaining: 5s Progress 2479 / 9694 Time remaining: 5s Progress 2480 / 9694 Time remaining: 5s Progress 2481 / 9694 Time remaining: 5s Progress 2482 / 9694 Time remaining: 5s Progress 2483 / 9694 Time remaining: 5s Progress 2484 / 9694 Time remaining: 5s Progress 2485 / 9694 Time remaining: 5s Progress 2486 / 9694 Time remaining: 5s Progress 2487 / 9694 Time remaining: 5s Progress 2488 / 9694 Time remaining: 5s Progress 2489 / 9694 Time remaining: 5s Progress 2490 / 9694 Time remaining: 5s Progress 2491 / 9694 Time remaining: 5s Progress 2492 / 9694 Time remaining: 5s Progress 2493 / 9694 Time remaining: 5s Progress 2494 / 9694 Time remaining: 5s Progress 2495 / 9694 Time remaining: 5s Progress 2496 / 9694 Time remaining: 5s Progress 2497 / 9694 Time remaining: 5s Progress 2498 / 9694 Time remaining: 5s Progress 2499 / 9694 Time remaining: 5s Progress 2500 / 9694 Time remaining: 5s Progress 2501 / 9694 Time remaining: 5s Progress 2502 / 9694 Time remaining: 5s Progress 2503 / 9694 Time remaining: 5s Progress 2504 / 9694 Time remaining: 5s Progress 2505 / 9694 Time remaining: 5s Progress 2506 / 9694 Time remaining: 5s Progress 2507 / 9694 Time remaining: 5s Progress 2508 / 9694 Time remaining: 5s Progress 2509 / 9694 Time remaining: 5s Progress 2510 / 9694 Time remaining: 5s Progress 2511 / 9694 Time remaining: 5s Progress 2512 / 9694 Time remaining: 5s Progress 2513 / 9694 Time remaining: 5s Progress 2514 / 9694 Time remaining: 5s Progress 2515 / 9694 Time remaining: 5s Progress 2516 / 9694 Time remaining: 5s Progress 2517 / 9694 Time remaining: 5s Progress 2518 / 9694 Time remaining: 5s Progress 2519 / 9694 Time remaining: 5s Progress 2520 / 9694 Time remaining: 5s Progress 2521 / 9694 Time remaining: 5s Progress 2522 / 9694 Time remaining: 5s Progress 2523 / 9694 Time remaining: 5s Progress 2524 / 9694 Time remaining: 5s Progress 2525 / 9694 Time remaining: 5s Progress 2526 / 9694 Time remaining: 5s Progress 2527 / 9694 Time remaining: 5s Progress 2528 / 9694 Time remaining: 5s Progress 2529 / 9694 Time remaining: 5s Progress 2530 / 9694 Time remaining: 5s Progress 2531 / 9694 Time remaining: 5s Progress 2532 / 9694 Time remaining: 5s Progress 2533 / 9694 Time remaining: 5s Progress 2534 / 9694 Time remaining: 5s Progress 2535 / 9694 Time remaining: 5s Progress 2536 / 9694 Time remaining: 5s Progress 2537 / 9694 Time remaining: 5s Progress 2538 / 9694 Time remaining: 5s Progress 2539 / 9694 Time remaining: 5s Progress 2540 / 9694 Time remaining: 5s Progress 2541 / 9694 Time remaining: 5s Progress 2542 / 9694 Time remaining: 5s Progress 2543 / 9694 Time remaining: 5s Progress 2544 / 9694 Time remaining: 5s Progress 2545 / 9694 Time remaining: 5s Progress 2546 / 9694 Time remaining: 5s Progress 2547 / 9694 Time remaining: 5s Progress 2548 / 9694 Time remaining: 5s Progress 2549 / 9694 Time remaining: 5s Progress 2550 / 9694 Time remaining: 5s Progress 2551 / 9694 Time remaining: 5s Progress 2552 / 9694 Time remaining: 5s Progress 2553 / 9694 Time remaining: 5s Progress 2554 / 9694 Time remaining: 5s Progress 2555 / 9694 Time remaining: 5s Progress 2556 / 9694 Time remaining: 5s Progress 2557 / 9694 Time remaining: 5s Progress 2558 / 9694 Time remaining: 5s Progress 2559 / 9694 Time remaining: 5s Progress 2560 / 9694 Time remaining: 5s Progress 2561 / 9694 Time remaining: 5s Progress 2562 / 9694 Time remaining: 5s Progress 2563 / 9694 Time remaining: 5s Progress 2564 / 9694 Time remaining: 5s Progress 2565 / 9694 Time remaining: 5s Progress 2566 / 9694 Time remaining: 5s Progress 2567 / 9694 Time remaining: 5s Progress 2568 / 9694 Time remaining: 5s Progress 2569 / 9694 Time remaining: 5s Progress 2570 / 9694 Time remaining: 5s Progress 2571 / 9694 Time remaining: 5s Progress 2572 / 9694 Time remaining: 5s Progress 2573 / 9694 Time remaining: 5s Progress 2574 / 9694 Time remaining: 5s Progress 2575 / 9694 Time remaining: 5s Progress 2576 / 9694 Time remaining: 5s Progress 2577 / 9694 Time remaining: 5s Progress 2578 / 9694 Time remaining: 5s Progress 2579 / 9694 Time remaining: 5s Progress 2580 / 9694 Time remaining: 5s Progress 2581 / 9694 Time remaining: 5s Progress 2582 / 9694 Time remaining: 5s Progress 2583 / 9694 Time remaining: 5s Progress 2584 / 9694 Time remaining: 5s Progress 2585 / 9694 Time remaining: 5s Progress 2586 / 9694 Time remaining: 5s Progress 2587 / 9694 Time remaining: 5s Progress 2588 / 9694 Time remaining: 5s Progress 2589 / 9694 Time remaining: 5s Progress 2590 / 9694 Time remaining: 5s Progress 2591 / 9694 Time remaining: 5s Progress 2592 / 9694 Time remaining: 5s Progress 2593 / 9694 Time remaining: 5s Progress 2594 / 9694 Time remaining: 5s Progress 2595 / 9694 Time remaining: 5s Progress 2596 / 9694 Time remaining: 5s Progress 2597 / 9694 Time remaining: 5s Progress 2598 / 9694 Time remaining: 5s Progress 2599 / 9694 Time remaining: 5s Progress 2600 / 9694 Time remaining: 5s Progress 2601 / 9694 Time remaining: 5s Progress 2602 / 9694 Time remaining: 5s Progress 2603 / 9694 Time remaining: 5s Progress 2604 / 9694 Time remaining: 5s Progress 2605 / 9694 Time remaining: 5s Progress 2606 / 9694 Time remaining: 5s Progress 2607 / 9694 Time remaining: 5s Progress 2608 / 9694 Time remaining: 5s Progress 2609 / 9694 Time remaining: 5s Progress 2610 / 9694 Time remaining: 5s Progress 2611 / 9694 Time remaining: 5s Progress 2612 / 9694 Time remaining: 5s Progress 2613 / 9694 Time remaining: 5s Progress 2614 / 9694 Time remaining: 5s Progress 2615 / 9694 Time remaining: 5s Progress 2616 / 9694 Time remaining: 5s Progress 2617 / 9694 Time remaining: 5s Progress 2618 / 9694 Time remaining: 5s Progress 2619 / 9694 Time remaining: 5s Progress 2620 / 9694 Time remaining: 5s Progress 2621 / 9694 Time remaining: 5s Progress 2622 / 9694 Time remaining: 5s Progress 2623 / 9694 Time remaining: 5s Progress 2624 / 9694 Time remaining: 5s Progress 2625 / 9694 Time remaining: 5s Progress 2626 / 9694 Time remaining: 5s Progress 2627 / 9694 Time remaining: 5s Progress 2628 / 9694 Time remaining: 5s Progress 2629 / 9694 Time remaining: 5s Progress 2630 / 9694 Time remaining: 5s Progress 2631 / 9694 Time remaining: 5s Progress 2632 / 9694 Time remaining: 5s Progress 2633 / 9694 Time remaining: 5s Progress 2634 / 9694 Time remaining: 5s Progress 2635 / 9694 Time remaining: 5s Progress 2636 / 9694 Time remaining: 5s Progress 2637 / 9694 Time remaining: 5s Progress 2638 / 9694 Time remaining: 5s Progress 2639 / 9694 Time remaining: 5s Progress 2640 / 9694 Time remaining: 5s Progress 2641 / 9694 Time remaining: 5s Progress 2642 / 9694 Time remaining: 5s Progress 2643 / 9694 Time remaining: 5s Progress 2644 / 9694 Time remaining: 5s Progress 2645 / 9694 Time remaining: 5s Progress 2646 / 9694 Time remaining: 5s Progress 2647 / 9694 Time remaining: 5s Progress 2648 / 9694 Time remaining: 5s Progress 2649 / 9694 Time remaining: 5s Progress 2650 / 9694 Time remaining: 5s Progress 2651 / 9694 Time remaining: 5s Progress 2652 / 9694 Time remaining: 5s Progress 2653 / 9694 Time remaining: 5s Progress 2654 / 9694 Time remaining: 5s Progress 2655 / 9694 Time remaining: 5s Progress 2656 / 9694 Time remaining: 5s Progress 2657 / 9694 Time remaining: 5s Progress 2658 / 9694 Time remaining: 5s Progress 2659 / 9694 Time remaining: 5s Progress 2660 / 9694 Time remaining: 5s Progress 2661 / 9694 Time remaining: 5s Progress 2662 / 9694 Time remaining: 5s Progress 2663 / 9694 Time remaining: 5s Progress 2664 / 9694 Time remaining: 5s Progress 2665 / 9694 Time remaining: 5s Progress 2666 / 9694 Time remaining: 5s Progress 2667 / 9694 Time remaining: 5s Progress 2668 / 9694 Time remaining: 5s Progress 2669 / 9694 Time remaining: 5s Progress 2670 / 9694 Time remaining: 5s Progress 2671 / 9694 Time remaining: 5s Progress 2672 / 9694 Time remaining: 5s Progress 2673 / 9694 Time remaining: 5s Progress 2674 / 9694 Time remaining: 5s Progress 2675 / 9694 Time remaining: 5s Progress 2676 / 9694 Time remaining: 5s Progress 2677 / 9694 Time remaining: 5s Progress 2678 / 9694 Time remaining: 5s Progress 2679 / 9694 Time remaining: 5s Progress 2680 / 9694 Time remaining: 4s Progress 2681 / 9694 Time remaining: 4s Progress 2682 / 9694 Time remaining: 4s Progress 2683 / 9694 Time remaining: 4s Progress 2684 / 9694 Time remaining: 4s Progress 2685 / 9694 Time remaining: 4s Progress 2686 / 9694 Time remaining: 4s Progress 2687 / 9694 Time remaining: 4s Progress 2688 / 9694 Time remaining: 4s Progress 2689 / 9694 Time remaining: 4s Progress 2690 / 9694 Time remaining: 4s Progress 2691 / 9694 Time remaining: 4s Progress 2692 / 9694 Time remaining: 4s Progress 2693 / 9694 Time remaining: 4s Progress 2694 / 9694 Time remaining: 4s Progress 2695 / 9694 Time remaining: 4s Progress 2696 / 9694 Time remaining: 4s Progress 2697 / 9694 Time remaining: 4s Progress 2698 / 9694 Time remaining: 4s Progress 2699 / 9694 Time remaining: 4s Progress 2700 / 9694 Time remaining: 4s Progress 2701 / 9694 Time remaining: 4s Progress 2702 / 9694 Time remaining: 4s Progress 2703 / 9694 Time remaining: 4s Progress 2704 / 9694 Time remaining: 4s Progress 2705 / 9694 Time remaining: 4s Progress 2706 / 9694 Time remaining: 4s Progress 2707 / 9694 Time remaining: 4s Progress 2708 / 9694 Time remaining: 4s Progress 2709 / 9694 Time remaining: 4s Progress 2710 / 9694 Time remaining: 4s Progress 2711 / 9694 Time remaining: 4s Progress 2712 / 9694 Time remaining: 4s Progress 2713 / 9694 Time remaining: 4s Progress 2714 / 9694 Time remaining: 4s Progress 2715 / 9694 Time remaining: 4s Progress 2716 / 9694 Time remaining: 4s Progress 2717 / 9694 Time remaining: 4s Progress 2718 / 9694 Time remaining: 4s Progress 2719 / 9694 Time remaining: 4s Progress 2720 / 9694 Time remaining: 4s Progress 2721 / 9694 Time remaining: 4s Progress 2722 / 9694 Time remaining: 4s Progress 2723 / 9694 Time remaining: 4s Progress 2724 / 9694 Time remaining: 4s Progress 2725 / 9694 Time remaining: 4s Progress 2726 / 9694 Time remaining: 4s Progress 2727 / 9694 Time remaining: 4s Progress 2728 / 9694 Time remaining: 4s Progress 2729 / 9694 Time remaining: 4s Progress 2730 / 9694 Time remaining: 4s Progress 2731 / 9694 Time remaining: 4s Progress 2732 / 9694 Time remaining: 4s Progress 2733 / 9694 Time remaining: 4s Progress 2734 / 9694 Time remaining: 4s Progress 2735 / 9694 Time remaining: 4s Progress 2736 / 9694 Time remaining: 4s Progress 2737 / 9694 Time remaining: 4s Progress 2738 / 9694 Time remaining: 4s Progress 2739 / 9694 Time remaining: 4s Progress 2740 / 9694 Time remaining: 4s Progress 2741 / 9694 Time remaining: 4s Progress 2742 / 9694 Time remaining: 4s Progress 2743 / 9694 Time remaining: 4s Progress 2744 / 9694 Time remaining: 4s Progress 2745 / 9694 Time remaining: 4s Progress 2746 / 9694 Time remaining: 4s Progress 2747 / 9694 Time remaining: 4s Progress 2748 / 9694 Time remaining: 4s Progress 2749 / 9694 Time remaining: 4s Progress 2750 / 9694 Time remaining: 4s Progress 2751 / 9694 Time remaining: 4s Progress 2752 / 9694 Time remaining: 4s Progress 2753 / 9694 Time remaining: 4s Progress 2754 / 9694 Time remaining: 4s Progress 2755 / 9694 Time remaining: 4s Progress 2756 / 9694 Time remaining: 4s Progress 2757 / 9694 Time remaining: 4s Progress 2758 / 9694 Time remaining: 4s Progress 2759 / 9694 Time remaining: 4s Progress 2760 / 9694 Time remaining: 4s Progress 2761 / 9694 Time remaining: 4s Progress 2762 / 9694 Time remaining: 4s Progress 2763 / 9694 Time remaining: 4s Progress 2764 / 9694 Time remaining: 4s Progress 2765 / 9694 Time remaining: 4s Progress 2766 / 9694 Time remaining: 4s Progress 2767 / 9694 Time remaining: 4s Progress 2768 / 9694 Time remaining: 4s Progress 2769 / 9694 Time remaining: 4s Progress 2770 / 9694 Time remaining: 4s Progress 2771 / 9694 Time remaining: 4s Progress 2772 / 9694 Time remaining: 4s Progress 2773 / 9694 Time remaining: 4s Progress 2774 / 9694 Time remaining: 4s Progress 2775 / 9694 Time remaining: 4s Progress 2776 / 9694 Time remaining: 4s Progress 2777 / 9694 Time remaining: 4s Progress 2778 / 9694 Time remaining: 4s Progress 2779 / 9694 Time remaining: 4s Progress 2780 / 9694 Time remaining: 4s Progress 2781 / 9694 Time remaining: 4s Progress 2782 / 9694 Time remaining: 4s Progress 2783 / 9694 Time remaining: 4s Progress 2784 / 9694 Time remaining: 4s Progress 2785 / 9694 Time remaining: 4s Progress 2786 / 9694 Time remaining: 4s Progress 2787 / 9694 Time remaining: 4s Progress 2788 / 9694 Time remaining: 4s Progress 2789 / 9694 Time remaining: 4s Progress 2790 / 9694 Time remaining: 4s Progress 2791 / 9694 Time remaining: 4s Progress 2792 / 9694 Time remaining: 4s Progress 2793 / 9694 Time remaining: 4s Progress 2794 / 9694 Time remaining: 4s Progress 2795 / 9694 Time remaining: 4s Progress 2796 / 9694 Time remaining: 4s Progress 2797 / 9694 Time remaining: 4s Progress 2798 / 9694 Time remaining: 4s Progress 2799 / 9694 Time remaining: 4s Progress 2800 / 9694 Time remaining: 4s Progress 2801 / 9694 Time remaining: 4s Progress 2802 / 9694 Time remaining: 4s Progress 2803 / 9694 Time remaining: 4s Progress 2804 / 9694 Time remaining: 4s Progress 2805 / 9694 Time remaining: 4s Progress 2806 / 9694 Time remaining: 4s Progress 2807 / 9694 Time remaining: 4s Progress 2808 / 9694 Time remaining: 4s Progress 2809 / 9694 Time remaining: 4s Progress 2810 / 9694 Time remaining: 4s Progress 2811 / 9694 Time remaining: 4s Progress 2812 / 9694 Time remaining: 4s Progress 2813 / 9694 Time remaining: 4s Progress 2814 / 9694 Time remaining: 4s Progress 2815 / 9694 Time remaining: 4s Progress 2816 / 9694 Time remaining: 4s Progress 2817 / 9694 Time remaining: 4s Progress 2818 / 9694 Time remaining: 4s Progress 2819 / 9694 Time remaining: 4s Progress 2820 / 9694 Time remaining: 4s Progress 2821 / 9694 Time remaining: 4s Progress 2822 / 9694 Time remaining: 4s Progress 2823 / 9694 Time remaining: 4s Progress 2824 / 9694 Time remaining: 4s Progress 2825 / 9694 Time remaining: 4s Progress 2826 / 9694 Time remaining: 4s Progress 2827 / 9694 Time remaining: 4s Progress 2828 / 9694 Time remaining: 4s Progress 2829 / 9694 Time remaining: 4s Progress 2830 / 9694 Time remaining: 4s Progress 2831 / 9694 Time remaining: 4s Progress 2832 / 9694 Time remaining: 4s Progress 2833 / 9694 Time remaining: 4s Progress 2834 / 9694 Time remaining: 4s Progress 2835 / 9694 Time remaining: 4s Progress 2836 / 9694 Time remaining: 4s Progress 2837 / 9694 Time remaining: 4s Progress 2838 / 9694 Time remaining: 4s Progress 2839 / 9694 Time remaining: 4s Progress 2840 / 9694 Time remaining: 4s Progress 2841 / 9694 Time remaining: 4s Progress 2842 / 9694 Time remaining: 4s Progress 2843 / 9694 Time remaining: 4s Progress 2844 / 9694 Time remaining: 4s Progress 2845 / 9694 Time remaining: 4s Progress 2846 / 9694 Time remaining: 4s Progress 2847 / 9694 Time remaining: 4s Progress 2848 / 9694 Time remaining: 4s Progress 2849 / 9694 Time remaining: 4s Progress 2850 / 9694 Time remaining: 4s Progress 2851 / 9694 Time remaining: 4s Progress 2852 / 9694 Time remaining: 4s Progress 2853 / 9694 Time remaining: 4s Progress 2854 / 9694 Time remaining: 4s Progress 2855 / 9694 Time remaining: 4s Progress 2856 / 9694 Time remaining: 4s Progress 2857 / 9694 Time remaining: 4s Progress 2858 / 9694 Time remaining: 4s Progress 2859 / 9694 Time remaining: 4s Progress 2860 / 9694 Time remaining: 4s Progress 2861 / 9694 Time remaining: 4s Progress 2862 / 9694 Time remaining: 4s Progress 2863 / 9694 Time remaining: 4s Progress 2864 / 9694 Time remaining: 4s Progress 2865 / 9694 Time remaining: 4s Progress 2866 / 9694 Time remaining: 4s Progress 2867 / 9694 Time remaining: 4s Progress 2868 / 9694 Time remaining: 4s Progress 2869 / 9694 Time remaining: 4s Progress 2870 / 9694 Time remaining: 4s Progress 2871 / 9694 Time remaining: 4s Progress 2872 / 9694 Time remaining: 4s Progress 2873 / 9694 Time remaining: 4s Progress 2874 / 9694 Time remaining: 4s Progress 2875 / 9694 Time remaining: 4s Progress 2876 / 9694 Time remaining: 4s Progress 2877 / 9694 Time remaining: 4s Progress 2878 / 9694 Time remaining: 4s Progress 2879 / 9694 Time remaining: 4s Progress 2880 / 9694 Time remaining: 4s Progress 2881 / 9694 Time remaining: 4s Progress 2882 / 9694 Time remaining: 4s Progress 2883 / 9694 Time remaining: 4s Progress 2884 / 9694 Time remaining: 4s Progress 2885 / 9694 Time remaining: 4s Progress 2886 / 9694 Time remaining: 4s Progress 2887 / 9694 Time remaining: 4s Progress 2888 / 9694 Time remaining: 4s Progress 2889 / 9694 Time remaining: 4s Progress 2890 / 9694 Time remaining: 4s Progress 2891 / 9694 Time remaining: 4s Progress 2892 / 9694 Time remaining: 4s Progress 2893 / 9694 Time remaining: 4s Progress 2894 / 9694 Time remaining: 4s Progress 2895 / 9694 Time remaining: 4s Progress 2896 / 9694 Time remaining: 4s Progress 2897 / 9694 Time remaining: 4s Progress 2898 / 9694 Time remaining: 4s Progress 2899 / 9694 Time remaining: 4s Progress 2900 / 9694 Time remaining: 4s Progress 2901 / 9694 Time remaining: 4s Progress 2902 / 9694 Time remaining: 4s Progress 2903 / 9694 Time remaining: 4s Progress 2904 / 9694 Time remaining: 4s Progress 2905 / 9694 Time remaining: 4s Progress 2906 / 9694 Time remaining: 4s Progress 2907 / 9694 Time remaining: 4s Progress 2908 / 9694 Time remaining: 4s Progress 2909 / 9694 Time remaining: 4s Progress 2910 / 9694 Time remaining: 4s Progress 2911 / 9694 Time remaining: 4s Progress 2912 / 9694 Time remaining: 4s Progress 2913 / 9694 Time remaining: 4s Progress 2914 / 9694 Time remaining: 4s Progress 2915 / 9694 Time remaining: 4s Progress 2916 / 9694 Time remaining: 4s Progress 2917 / 9694 Time remaining: 4s Progress 2918 / 9694 Time remaining: 4s Progress 2919 / 9694 Time remaining: 4s Progress 2920 / 9694 Time remaining: 4s Progress 2921 / 9694 Time remaining: 4s Progress 2922 / 9694 Time remaining: 4s Progress 2923 / 9694 Time remaining: 4s Progress 2924 / 9694 Time remaining: 4s Progress 2925 / 9694 Time remaining: 4s Progress 2926 / 9694 Time remaining: 4s Progress 2927 / 9694 Time remaining: 4s Progress 2928 / 9694 Time remaining: 4s Progress 2929 / 9694 Time remaining: 4s Progress 2930 / 9694 Time remaining: 4s Progress 2931 / 9694 Time remaining: 4s Progress 2932 / 9694 Time remaining: 4s Progress 2933 / 9694 Time remaining: 4s Progress 2934 / 9694 Time remaining: 4s Progress 2935 / 9694 Time remaining: 4s Progress 2936 / 9694 Time remaining: 4s Progress 2937 / 9694 Time remaining: 4s Progress 2938 / 9694 Time remaining: 4s Progress 2939 / 9694 Time remaining: 4s Progress 2940 / 9694 Time remaining: 4s Progress 2941 / 9694 Time remaining: 4s Progress 2942 / 9694 Time remaining: 4s Progress 2943 / 9694 Time remaining: 4s Progress 2944 / 9694 Time remaining: 4s Progress 2945 / 9694 Time remaining: 4s Progress 2946 / 9694 Time remaining: 4s Progress 2947 / 9694 Time remaining: 4s Progress 2948 / 9694 Time remaining: 4s Progress 2949 / 9694 Time remaining: 4s Progress 2950 / 9694 Time remaining: 4s Progress 2951 / 9694 Time remaining: 4s Progress 2952 / 9694 Time remaining: 4s Progress 2953 / 9694 Time remaining: 4s Progress 2954 / 9694 Time remaining: 4s Progress 2955 / 9694 Time remaining: 4s Progress 2956 / 9694 Time remaining: 4s Progress 2957 / 9694 Time remaining: 4s Progress 2958 / 9694 Time remaining: 4s Progress 2959 / 9694 Time remaining: 4s Progress 2960 / 9694 Time remaining: 4s Progress 2961 / 9694 Time remaining: 4s Progress 2962 / 9694 Time remaining: 4s Progress 2963 / 9694 Time remaining: 4s Progress 2964 / 9694 Time remaining: 4s Progress 2965 / 9694 Time remaining: 4s Progress 2966 / 9694 Time remaining: 4s Progress 2967 / 9694 Time remaining: 4s Progress 2968 / 9694 Time remaining: 4s Progress 2969 / 9694 Time remaining: 4s Progress 2970 / 9694 Time remaining: 4s Progress 2971 / 9694 Time remaining: 4s Progress 2972 / 9694 Time remaining: 4s Progress 2973 / 9694 Time remaining: 4s Progress 2974 / 9694 Time remaining: 4s Progress 2975 / 9694 Time remaining: 4s Progress 2976 / 9694 Time remaining: 4s Progress 2977 / 9694 Time remaining: 4s Progress 2978 / 9694 Time remaining: 4s Progress 2979 / 9694 Time remaining: 4s Progress 2980 / 9694 Time remaining: 4s Progress 2981 / 9694 Time remaining: 4s Progress 2982 / 9694 Time remaining: 4s Progress 2983 / 9694 Time remaining: 4s Progress 2984 / 9694 Time remaining: 4s Progress 2985 / 9694 Time remaining: 4s Progress 2986 / 9694 Time remaining: 4s Progress 2987 / 9694 Time remaining: 4s Progress 2988 / 9694 Time remaining: 4s Progress 2989 / 9694 Time remaining: 4s Progress 2990 / 9694 Time remaining: 4s Progress 2991 / 9694 Time remaining: 4s Progress 2992 / 9694 Time remaining: 4s Progress 2993 / 9694 Time remaining: 4s Progress 2994 / 9694 Time remaining: 4s Progress 2995 / 9694 Time remaining: 4s Progress 2996 / 9694 Time remaining: 4s Progress 2997 / 9694 Time remaining: 4s Progress 2998 / 9694 Time remaining: 4s Progress 2999 / 9694 Time remaining: 4s Progress 3000 / 9694 Time remaining: 4s Progress 3001 / 9694 Time remaining: 4s Progress 3002 / 9694 Time remaining: 4s Progress 3003 / 9694 Time remaining: 4s Progress 3004 / 9694 Time remaining: 4s Progress 3005 / 9694 Time remaining: 4s Progress 3006 / 9694 Time remaining: 4s Progress 3007 / 9694 Time remaining: 4s Progress 3008 / 9694 Time remaining: 4s Progress 3009 / 9694 Time remaining: 4s Progress 3010 / 9694 Time remaining: 4s Progress 3011 / 9694 Time remaining: 4s Progress 3012 / 9694 Time remaining: 4s Progress 3013 / 9694 Time remaining: 4s Progress 3014 / 9694 Time remaining: 4s Progress 3015 / 9694 Time remaining: 4s Progress 3016 / 9694 Time remaining: 4s Progress 3017 / 9694 Time remaining: 4s Progress 3018 / 9694 Time remaining: 4s Progress 3019 / 9694 Time remaining: 4s Progress 3020 / 9694 Time remaining: 4s Progress 3021 / 9694 Time remaining: 4s Progress 3022 / 9694 Time remaining: 4s Progress 3023 / 9694 Time remaining: 4s Progress 3024 / 9694 Time remaining: 4s Progress 3025 / 9694 Time remaining: 4s Progress 3026 / 9694 Time remaining: 4s Progress 3027 / 9694 Time remaining: 4s Progress 3028 / 9694 Time remaining: 4s Progress 3029 / 9694 Time remaining: 4s Progress 3030 / 9694 Time remaining: 4s Progress 3031 / 9694 Time remaining: 4s Progress 3032 / 9694 Time remaining: 4s Progress 3033 / 9694 Time remaining: 4s Progress 3034 / 9694 Time remaining: 4s Progress 3035 / 9694 Time remaining: 4s Progress 3036 / 9694 Time remaining: 4s Progress 3037 / 9694 Time remaining: 4s Progress 3038 / 9694 Time remaining: 4s Progress 3039 / 9694 Time remaining: 4s Progress 3040 / 9694 Time remaining: 4s Progress 3041 / 9694 Time remaining: 4s Progress 3042 / 9694 Time remaining: 4s Progress 3043 / 9694 Time remaining: 4s Progress 3044 / 9694 Time remaining: 4s Progress 3045 / 9694 Time remaining: 4s Progress 3046 / 9694 Time remaining: 4s Progress 3047 / 9694 Time remaining: 4s Progress 3048 / 9694 Time remaining: 4s Progress 3049 / 9694 Time remaining: 4s Progress 3050 / 9694 Time remaining: 4s Progress 3051 / 9694 Time remaining: 4s Progress 3052 / 9694 Time remaining: 4s Progress 3053 / 9694 Time remaining: 4s Progress 3054 / 9694 Time remaining: 4s Progress 3055 / 9694 Time remaining: 4s Progress 3056 / 9694 Time remaining: 4s Progress 3057 / 9694 Time remaining: 4s Progress 3058 / 9694 Time remaining: 4s Progress 3059 / 9694 Time remaining: 4s Progress 3060 / 9694 Time remaining: 4s Progress 3061 / 9694 Time remaining: 4s Progress 3062 / 9694 Time remaining: 4s Progress 3063 / 9694 Time remaining: 4s Progress 3064 / 9694 Time remaining: 4s Progress 3065 / 9694 Time remaining: 4s Progress 3066 / 9694 Time remaining: 4s Progress 3067 / 9694 Time remaining: 4s Progress 3068 / 9694 Time remaining: 4s Progress 3069 / 9694 Time remaining: 4s Progress 3070 / 9694 Time remaining: 4s Progress 3071 / 9694 Time remaining: 4s Progress 3072 / 9694 Time remaining: 4s Progress 3073 / 9694 Time remaining: 4s Progress 3074 / 9694 Time remaining: 4s Progress 3075 / 9694 Time remaining: 4s Progress 3076 / 9694 Time remaining: 4s Progress 3077 / 9694 Time remaining: 4s Progress 3078 / 9694 Time remaining: 4s Progress 3079 / 9694 Time remaining: 4s Progress 3080 / 9694 Time remaining: 4s Progress 3081 / 9694 Time remaining: 4s Progress 3082 / 9694 Time remaining: 4s Progress 3083 / 9694 Time remaining: 4s Progress 3084 / 9694 Time remaining: 4s Progress 3085 / 9694 Time remaining: 4s Progress 3086 / 9694 Time remaining: 4s Progress 3087 / 9694 Time remaining: 4s Progress 3088 / 9694 Time remaining: 4s Progress 3089 / 9694 Time remaining: 4s Progress 3090 / 9694 Time remaining: 4s Progress 3091 / 9694 Time remaining: 4s Progress 3092 / 9694 Time remaining: 4s Progress 3093 / 9694 Time remaining: 4s Progress 3094 / 9694 Time remaining: 4s Progress 3095 / 9694 Time remaining: 4s Progress 3096 / 9694 Time remaining: 4s Progress 3097 / 9694 Time remaining: 4s Progress 3098 / 9694 Time remaining: 4s Progress 3099 / 9694 Time remaining: 4s Progress 3100 / 9694 Time remaining: 4s Progress 3101 / 9694 Time remaining: 4s Progress 3102 / 9694 Time remaining: 4s Progress 3103 / 9694 Time remaining: 4s Progress 3104 / 9694 Time remaining: 4s Progress 3105 / 9694 Time remaining: 4s Progress 3106 / 9694 Time remaining: 4s Progress 3107 / 9694 Time remaining: 4s Progress 3108 / 9694 Time remaining: 4s Progress 3109 / 9694 Time remaining: 4s Progress 3110 / 9694 Time remaining: 4s Progress 3111 / 9694 Time remaining: 4s Progress 3112 / 9694 Time remaining: 4s Progress 3113 / 9694 Time remaining: 4s Progress 3114 / 9694 Time remaining: 4s Progress 3115 / 9694 Time remaining: 4s Progress 3116 / 9694 Time remaining: 4s Progress 3117 / 9694 Time remaining: 4s Progress 3118 / 9694 Time remaining: 4s Progress 3119 / 9694 Time remaining: 4s Progress 3120 / 9694 Time remaining: 4s Progress 3121 / 9694 Time remaining: 4s Progress 3122 / 9694 Time remaining: 4s Progress 3123 / 9694 Time remaining: 4s Progress 3124 / 9694 Time remaining: 4s Progress 3125 / 9694 Time remaining: 4s Progress 3126 / 9694 Time remaining: 4s Progress 3127 / 9694 Time remaining: 4s Progress 3128 / 9694 Time remaining: 4s Progress 3129 / 9694 Time remaining: 4s Progress 3130 / 9694 Time remaining: 4s Progress 3131 / 9694 Time remaining: 4s Progress 3132 / 9694 Time remaining: 4s Progress 3133 / 9694 Time remaining: 4s Progress 3134 / 9694 Time remaining: 4s Progress 3135 / 9694 Time remaining: 4s Progress 3136 / 9694 Time remaining: 4s Progress 3137 / 9694 Time remaining: 4s Progress 3138 / 9694 Time remaining: 4s Progress 3139 / 9694 Time remaining: 4s Progress 3140 / 9694 Time remaining: 4s Progress 3141 / 9694 Time remaining: 4s Progress 3142 / 9694 Time remaining: 4s Progress 3143 / 9694 Time remaining: 4s Progress 3144 / 9694 Time remaining: 4s Progress 3145 / 9694 Time remaining: 4s Progress 3146 / 9694 Time remaining: 4s Progress 3147 / 9694 Time remaining: 4s Progress 3148 / 9694 Time remaining: 4s Progress 3149 / 9694 Time remaining: 4s Progress 3150 / 9694 Time remaining: 4s Progress 3151 / 9694 Time remaining: 4s Progress 3152 / 9694 Time remaining: 4s Progress 3153 / 9694 Time remaining: 4s Progress 3154 / 9694 Time remaining: 4s Progress 3155 / 9694 Time remaining: 4s Progress 3156 / 9694 Time remaining: 4s Progress 3157 / 9694 Time remaining: 4s Progress 3158 / 9694 Time remaining: 4s Progress 3159 / 9694 Time remaining: 4s Progress 3160 / 9694 Time remaining: 4s Progress 3161 / 9694 Time remaining: 4s Progress 3162 / 9694 Time remaining: 4s Progress 3163 / 9694 Time remaining: 4s Progress 3164 / 9694 Time remaining: 4s Progress 3165 / 9694 Time remaining: 4s Progress 3166 / 9694 Time remaining: 4s Progress 3167 / 9694 Time remaining: 4s Progress 3168 / 9694 Time remaining: 4s Progress 3169 / 9694 Time remaining: 4s Progress 3170 / 9694 Time remaining: 4s Progress 3171 / 9694 Time remaining: 4s Progress 3172 / 9694 Time remaining: 4s Progress 3173 / 9694 Time remaining: 4s Progress 3174 / 9694 Time remaining: 4s Progress 3175 / 9694 Time remaining: 4s Progress 3176 / 9694 Time remaining: 4s Progress 3177 / 9694 Time remaining: 4s Progress 3178 / 9694 Time remaining: 4s Progress 3179 / 9694 Time remaining: 4s Progress 3180 / 9694 Time remaining: 4s Progress 3181 / 9694 Time remaining: 4s Progress 3182 / 9694 Time remaining: 4s Progress 3183 / 9694 Time remaining: 4s Progress 3184 / 9694 Time remaining: 4s Progress 3185 / 9694 Time remaining: 4s Progress 3186 / 9694 Time remaining: 4s Progress 3187 / 9694 Time remaining: 4s Progress 3188 / 9694 Time remaining: 4s Progress 3189 / 9694 Time remaining: 4s Progress 3190 / 9694 Time remaining: 4s Progress 3191 / 9694 Time remaining: 4s Progress 3192 / 9694 Time remaining: 4s Progress 3193 / 9694 Time remaining: 4s Progress 3194 / 9694 Time remaining: 4s Progress 3195 / 9694 Time remaining: 4s Progress 3196 / 9694 Time remaining: 4s Progress 3197 / 9694 Time remaining: 4s Progress 3198 / 9694 Time remaining: 4s Progress 3199 / 9694 Time remaining: 4s Progress 3200 / 9694 Time remaining: 4s Progress 3201 / 9694 Time remaining: 4s Progress 3202 / 9694 Time remaining: 4s Progress 3203 / 9694 Time remaining: 4s Progress 3204 / 9694 Time remaining: 4s Progress 3205 / 9694 Time remaining: 4s Progress 3206 / 9694 Time remaining: 4s Progress 3207 / 9694 Time remaining: 4s Progress 3208 / 9694 Time remaining: 4s Progress 3209 / 9694 Time remaining: 4s Progress 3210 / 9694 Time remaining: 4s Progress 3211 / 9694 Time remaining: 4s Progress 3212 / 9694 Time remaining: 4s Progress 3213 / 9694 Time remaining: 4s Progress 3214 / 9694 Time remaining: 4s Progress 3215 / 9694 Time remaining: 4s Progress 3216 / 9694 Time remaining: 4s Progress 3217 / 9694 Time remaining: 4s Progress 3218 / 9694 Time remaining: 4s Progress 3219 / 9694 Time remaining: 4s Progress 3220 / 9694 Time remaining: 4s Progress 3221 / 9694 Time remaining: 4s Progress 3222 / 9694 Time remaining: 4s Progress 3223 / 9694 Time remaining: 4s Progress 3224 / 9694 Time remaining: 4s Progress 3225 / 9694 Time remaining: 4s Progress 3226 / 9694 Time remaining: 4s Progress 3227 / 9694 Time remaining: 4s Progress 3228 / 9694 Time remaining: 4s Progress 3229 / 9694 Time remaining: 4s Progress 3230 / 9694 Time remaining: 4s Progress 3231 / 9694 Time remaining: 4s Progress 3232 / 9694 Time remaining: 4s Progress 3233 / 9694 Time remaining: 4s Progress 3234 / 9694 Time remaining: 4s Progress 3235 / 9694 Time remaining: 4s Progress 3236 / 9694 Time remaining: 4s Progress 3237 / 9694 Time remaining: 4s Progress 3238 / 9694 Time remaining: 4s Progress 3239 / 9694 Time remaining: 4s Progress 3240 / 9694 Time remaining: 4s Progress 3241 / 9694 Time remaining: 4s Progress 3242 / 9694 Time remaining: 4s Progress 3243 / 9694 Time remaining: 4s Progress 3244 / 9694 Time remaining: 4s Progress 3245 / 9694 Time remaining: 4s Progress 3246 / 9694 Time remaining: 4s Progress 3247 / 9694 Time remaining: 4s Progress 3248 / 9694 Time remaining: 4s Progress 3249 / 9694 Time remaining: 4s Progress 3250 / 9694 Time remaining: 4s Progress 3251 / 9694 Time remaining: 4s Progress 3252 / 9694 Time remaining: 4s Progress 3253 / 9694 Time remaining: 4s Progress 3254 / 9694 Time remaining: 4s Progress 3255 / 9694 Time remaining: 4s Progress 3256 / 9694 Time remaining: 4s Progress 3257 / 9694 Time remaining: 4s Progress 3258 / 9694 Time remaining: 4s Progress 3259 / 9694 Time remaining: 4s Progress 3260 / 9694 Time remaining: 4s Progress 3261 / 9694 Time remaining: 4s Progress 3262 / 9694 Time remaining: 4s Progress 3263 / 9694 Time remaining: 4s Progress 3264 / 9694 Time remaining: 4s Progress 3265 / 9694 Time remaining: 4s Progress 3266 / 9694 Time remaining: 4s Progress 3267 / 9694 Time remaining: 4s Progress 3268 / 9694 Time remaining: 4s Progress 3269 / 9694 Time remaining: 4s Progress 3270 / 9694 Time remaining: 4s Progress 3271 / 9694 Time remaining: 4s Progress 3272 / 9694 Time remaining: 4s Progress 3273 / 9694 Time remaining: 4s Progress 3274 / 9694 Time remaining: 4s Progress 3275 / 9694 Time remaining: 4s Progress 3276 / 9694 Time remaining: 4s Progress 3277 / 9694 Time remaining: 4s Progress 3278 / 9694 Time remaining: 4s Progress 3279 / 9694 Time remaining: 4s Progress 3280 / 9694 Time remaining: 4s Progress 3281 / 9694 Time remaining: 4s Progress 3282 / 9694 Time remaining: 4s Progress 3283 / 9694 Time remaining: 4s Progress 3284 / 9694 Time remaining: 4s Progress 3285 / 9694 Time remaining: 4s Progress 3286 / 9694 Time remaining: 4s Progress 3287 / 9694 Time remaining: 4s Progress 3288 / 9694 Time remaining: 4s Progress 3289 / 9694 Time remaining: 4s Progress 3290 / 9694 Time remaining: 4s Progress 3291 / 9694 Time remaining: 4s Progress 3292 / 9694 Time remaining: 4s Progress 3293 / 9694 Time remaining: 4s Progress 3294 / 9694 Time remaining: 4s Progress 3295 / 9694 Time remaining: 4s Progress 3296 / 9694 Time remaining: 4s Progress 3297 / 9694 Time remaining: 4s Progress 3298 / 9694 Time remaining: 4s Progress 3299 / 9694 Time remaining: 4s Progress 3300 / 9694 Time remaining: 4s Progress 3301 / 9694 Time remaining: 4s Progress 3302 / 9694 Time remaining: 4s Progress 3303 / 9694 Time remaining: 4s Progress 3304 / 9694 Time remaining: 4s Progress 3305 / 9694 Time remaining: 4s Progress 3306 / 9694 Time remaining: 4s Progress 3307 / 9694 Time remaining: 4s Progress 3308 / 9694 Time remaining: 4s Progress 3309 / 9694 Time remaining: 4s Progress 3310 / 9694 Time remaining: 4s Progress 3311 / 9694 Time remaining: 4s Progress 3312 / 9694 Time remaining: 4s Progress 3313 / 9694 Time remaining: 4s Progress 3314 / 9694 Time remaining: 4s Progress 3315 / 9694 Time remaining: 4s Progress 3316 / 9694 Time remaining: 4s Progress 3317 / 9694 Time remaining: 4s Progress 3318 / 9694 Time remaining: 4s Progress 3319 / 9694 Time remaining: 4s Progress 3320 / 9694 Time remaining: 4s Progress 3321 / 9694 Time remaining: 4s Progress 3322 / 9694 Time remaining: 4s Progress 3323 / 9694 Time remaining: 4s Progress 3324 / 9694 Time remaining: 4s Progress 3325 / 9694 Time remaining: 4s Progress 3326 / 9694 Time remaining: 4s Progress 3327 / 9694 Time remaining: 4s Progress 3328 / 9694 Time remaining: 4s Progress 3329 / 9694 Time remaining: 4s Progress 3330 / 9694 Time remaining: 4s Progress 3331 / 9694 Time remaining: 4s Progress 3332 / 9694 Time remaining: 4s Progress 3333 / 9694 Time remaining: 4s Progress 3334 / 9694 Time remaining: 4s Progress 3335 / 9694 Time remaining: 4s Progress 3336 / 9694 Time remaining: 4s Progress 3337 / 9694 Time remaining: 4s Progress 3338 / 9694 Time remaining: 4s Progress 3339 / 9694 Time remaining: 4s Progress 3340 / 9694 Time remaining: 4s Progress 3341 / 9694 Time remaining: 4s Progress 3342 / 9694 Time remaining: 4s Progress 3343 / 9694 Time remaining: 4s Progress 3344 / 9694 Time remaining: 4s Progress 3345 / 9694 Time remaining: 4s Progress 3346 / 9694 Time remaining: 4s Progress 3347 / 9694 Time remaining: 4s Progress 3348 / 9694 Time remaining: 4s Progress 3349 / 9694 Time remaining: 4s Progress 3350 / 9694 Time remaining: 4s Progress 3351 / 9694 Time remaining: 4s Progress 3352 / 9694 Time remaining: 4s Progress 3353 / 9694 Time remaining: 4s Progress 3354 / 9694 Time remaining: 4s Progress 3355 / 9694 Time remaining: 4s Progress 3356 / 9694 Time remaining: 4s Progress 3357 / 9694 Time remaining: 4s Progress 3358 / 9694 Time remaining: 4s Progress 3359 / 9694 Time remaining: 4s Progress 3360 / 9694 Time remaining: 4s Progress 3361 / 9694 Time remaining: 4s Progress 3362 / 9694 Time remaining: 4s Progress 3363 / 9694 Time remaining: 4s Progress 3364 / 9694 Time remaining: 4s Progress 3365 / 9694 Time remaining: 4s Progress 3366 / 9694 Time remaining: 4s Progress 3367 / 9694 Time remaining: 4s Progress 3368 / 9694 Time remaining: 4s Progress 3369 / 9694 Time remaining: 4s Progress 3370 / 9694 Time remaining: 4s Progress 3371 / 9694 Time remaining: 4s Progress 3372 / 9694 Time remaining: 4s Progress 3373 / 9694 Time remaining: 4s Progress 3374 / 9694 Time remaining: 4s Progress 3375 / 9694 Time remaining: 4s Progress 3376 / 9694 Time remaining: 4s Progress 3377 / 9694 Time remaining: 4s Progress 3378 / 9694 Time remaining: 4s Progress 3379 / 9694 Time remaining: 4s Progress 3380 / 9694 Time remaining: 4s Progress 3381 / 9694 Time remaining: 4s Progress 3382 / 9694 Time remaining: 4s Progress 3383 / 9694 Time remaining: 4s Progress 3384 / 9694 Time remaining: 4s Progress 3385 / 9694 Time remaining: 4s Progress 3386 / 9694 Time remaining: 4s Progress 3387 / 9694 Time remaining: 4s Progress 3388 / 9694 Time remaining: 4s Progress 3389 / 9694 Time remaining: 4s Progress 3390 / 9694 Time remaining: 4s Progress 3391 / 9694 Time remaining: 4s Progress 3392 / 9694 Time remaining: 4s Progress 3393 / 9694 Time remaining: 4s Progress 3394 / 9694 Time remaining: 4s Progress 3395 / 9694 Time remaining: 4s Progress 3396 / 9694 Time remaining: 4s Progress 3397 / 9694 Time remaining: 4s Progress 3398 / 9694 Time remaining: 4s Progress 3399 / 9694 Time remaining: 4s Progress 3400 / 9694 Time remaining: 4s Progress 3401 / 9694 Time remaining: 4s Progress 3402 / 9694 Time remaining: 4s Progress 3403 / 9694 Time remaining: 4s Progress 3404 / 9694 Time remaining: 4s Progress 3405 / 9694 Time remaining: 4s Progress 3406 / 9694 Time remaining: 4s Progress 3407 / 9694 Time remaining: 4s Progress 3408 / 9694 Time remaining: 4s Progress 3409 / 9694 Time remaining: 4s Progress 3410 / 9694 Time remaining: 4s Progress 3411 / 9694 Time remaining: 4s Progress 3412 / 9694 Time remaining: 4s Progress 3413 / 9694 Time remaining: 4s Progress 3414 / 9694 Time remaining: 4s Progress 3415 / 9694 Time remaining: 4s Progress 3416 / 9694 Time remaining: 4s Progress 3417 / 9694 Time remaining: 4s Progress 3418 / 9694 Time remaining: 4s Progress 3419 / 9694 Time remaining: 4s Progress 3420 / 9694 Time remaining: 4s Progress 3421 / 9694 Time remaining: 4s Progress 3422 / 9694 Time remaining: 4s Progress 3423 / 9694 Time remaining: 4s Progress 3424 / 9694 Time remaining: 4s Progress 3425 / 9694 Time remaining: 4s Progress 3426 / 9694 Time remaining: 4s Progress 3427 / 9694 Time remaining: 4s Progress 3428 / 9694 Time remaining: 4s Progress 3429 / 9694 Time remaining: 4s Progress 3430 / 9694 Time remaining: 4s Progress 3431 / 9694 Time remaining: 4s Progress 3432 / 9694 Time remaining: 4s Progress 3433 / 9694 Time remaining: 4s Progress 3434 / 9694 Time remaining: 4s Progress 3435 / 9694 Time remaining: 4s Progress 3436 / 9694 Time remaining: 4s Progress 3437 / 9694 Time remaining: 4s Progress 3438 / 9694 Time remaining: 4s Progress 3439 / 9694 Time remaining: 4s Progress 3440 / 9694 Time remaining: 4s Progress 3441 / 9694 Time remaining: 4s Progress 3442 / 9694 Time remaining: 4s Progress 3443 / 9694 Time remaining: 4s Progress 3444 / 9694 Time remaining: 4s Progress 3445 / 9694 Time remaining: 4s Progress 3446 / 9694 Time remaining: 4s Progress 3447 / 9694 Time remaining: 4s Progress 3448 / 9694 Time remaining: 4s Progress 3449 / 9694 Time remaining: 4s Progress 3450 / 9694 Time remaining: 4s Progress 3451 / 9694 Time remaining: 4s Progress 3452 / 9694 Time remaining: 4s Progress 3453 / 9694 Time remaining: 4s Progress 3454 / 9694 Time remaining: 4s Progress 3455 / 9694 Time remaining: 4s Progress 3456 / 9694 Time remaining: 4s Progress 3457 / 9694 Time remaining: 4s Progress 3458 / 9694 Time remaining: 4s Progress 3459 / 9694 Time remaining: 4s Progress 3460 / 9694 Time remaining: 4s Progress 3461 / 9694 Time remaining: 4s Progress 3462 / 9694 Time remaining: 4s Progress 3463 / 9694 Time remaining: 4s Progress 3464 / 9694 Time remaining: 4s Progress 3465 / 9694 Time remaining: 4s Progress 3466 / 9694 Time remaining: 4s Progress 3467 / 9694 Time remaining: 4s Progress 3468 / 9694 Time remaining: 4s Progress 3469 / 9694 Time remaining: 4s Progress 3470 / 9694 Time remaining: 4s Progress 3471 / 9694 Time remaining: 4s Progress 3472 / 9694 Time remaining: 4s Progress 3473 / 9694 Time remaining: 4s Progress 3474 / 9694 Time remaining: 4s Progress 3475 / 9694 Time remaining: 4s Progress 3476 / 9694 Time remaining: 4s Progress 3477 / 9694 Time remaining: 4s Progress 3478 / 9694 Time remaining: 4s Progress 3479 / 9694 Time remaining: 4s Progress 3480 / 9694 Time remaining: 4s Progress 3481 / 9694 Time remaining: 4s Progress 3482 / 9694 Time remaining: 4s Progress 3483 / 9694 Time remaining: 4s Progress 3484 / 9694 Time remaining: 4s Progress 3485 / 9694 Time remaining: 4s Progress 3486 / 9694 Time remaining: 4s Progress 3487 / 9694 Time remaining: 4s Progress 3488 / 9694 Time remaining: 4s Progress 3489 / 9694 Time remaining: 4s Progress 3490 / 9694 Time remaining: 4s Progress 3491 / 9694 Time remaining: 4s Progress 3492 / 9694 Time remaining: 4s Progress 3493 / 9694 Time remaining: 4s Progress 3494 / 9694 Time remaining: 4s Progress 3495 / 9694 Time remaining: 4s Progress 3496 / 9694 Time remaining: 4s Progress 3497 / 9694 Time remaining: 4s Progress 3498 / 9694 Time remaining: 4s Progress 3499 / 9694 Time remaining: 4s Progress 3500 / 9694 Time remaining: 4s Progress 3501 / 9694 Time remaining: 4s Progress 3502 / 9694 Time remaining: 4s Progress 3503 / 9694 Time remaining: 4s Progress 3504 / 9694 Time remaining: 4s Progress 3505 / 9694 Time remaining: 4s Progress 3506 / 9694 Time remaining: 4s Progress 3507 / 9694 Time remaining: 4s Progress 3508 / 9694 Time remaining: 4s Progress 3509 / 9694 Time remaining: 4s Progress 3510 / 9694 Time remaining: 4s Progress 3511 / 9694 Time remaining: 4s Progress 3512 / 9694 Time remaining: 4s Progress 3513 / 9694 Time remaining: 4s Progress 3514 / 9694 Time remaining: 4s Progress 3515 / 9694 Time remaining: 4s Progress 3516 / 9694 Time remaining: 4s Progress 3517 / 9694 Time remaining: 4s Progress 3518 / 9694 Time remaining: 4s Progress 3519 / 9694 Time remaining: 4s Progress 3520 / 9694 Time remaining: 4s Progress 3521 / 9694 Time remaining: 4s Progress 3522 / 9694 Time remaining: 4s Progress 3523 / 9694 Time remaining: 4s Progress 3524 / 9694 Time remaining: 4s Progress 3525 / 9694 Time remaining: 4s Progress 3526 / 9694 Time remaining: 4s Progress 3527 / 9694 Time remaining: 4s Progress 3528 / 9694 Time remaining: 4s Progress 3529 / 9694 Time remaining: 4s Progress 3530 / 9694 Time remaining: 4s Progress 3531 / 9694 Time remaining: 4s Progress 3532 / 9694 Time remaining: 4s Progress 3533 / 9694 Time remaining: 4s Progress 3534 / 9694 Time remaining: 4s Progress 3535 / 9694 Time remaining: 4s Progress 3536 / 9694 Time remaining: 4s Progress 3537 / 9694 Time remaining: 4s Progress 3538 / 9694 Time remaining: 4s Progress 3539 / 9694 Time remaining: 4s Progress 3540 / 9694 Time remaining: 4s Progress 3541 / 9694 Time remaining: 4s Progress 3542 / 9694 Time remaining: 4s Progress 3543 / 9694 Time remaining: 4s Progress 3544 / 9694 Time remaining: 4s Progress 3545 / 9694 Time remaining: 4s Progress 3546 / 9694 Time remaining: 4s Progress 3547 / 9694 Time remaining: 4s Progress 3548 / 9694 Time remaining: 4s Progress 3549 / 9694 Time remaining: 4s Progress 3550 / 9694 Time remaining: 4s Progress 3551 / 9694 Time remaining: 4s Progress 3552 / 9694 Time remaining: 4s Progress 3553 / 9694 Time remaining: 4s Progress 3554 / 9694 Time remaining: 4s Progress 3555 / 9694 Time remaining: 4s Progress 3556 / 9694 Time remaining: 4s Progress 3557 / 9694 Time remaining: 4s Progress 3558 / 9694 Time remaining: 4s Progress 3559 / 9694 Time remaining: 4s Progress 3560 / 9694 Time remaining: 4s Progress 3561 / 9694 Time remaining: 4s Progress 3562 / 9694 Time remaining: 4s Progress 3563 / 9694 Time remaining: 4s Progress 3564 / 9694 Time remaining: 4s Progress 3565 / 9694 Time remaining: 4s Progress 3566 / 9694 Time remaining: 4s Progress 3567 / 9694 Time remaining: 4s Progress 3568 / 9694 Time remaining: 4s Progress 3569 / 9694 Time remaining: 4s Progress 3570 / 9694 Time remaining: 4s Progress 3571 / 9694 Time remaining: 4s Progress 3572 / 9694 Time remaining: 4s Progress 3573 / 9694 Time remaining: 4s Progress 3574 / 9694 Time remaining: 4s Progress 3575 / 9694 Time remaining: 4s Progress 3576 / 9694 Time remaining: 4s Progress 3577 / 9694 Time remaining: 4s Progress 3578 / 9694 Time remaining: 4s Progress 3579 / 9694 Time remaining: 4s Progress 3580 / 9694 Time remaining: 4s Progress 3581 / 9694 Time remaining: 4s Progress 3582 / 9694 Time remaining: 4s Progress 3583 / 9694 Time remaining: 4s Progress 3584 / 9694 Time remaining: 4s Progress 3585 / 9694 Time remaining: 4s Progress 3586 / 9694 Time remaining: 4s Progress 3587 / 9694 Time remaining: 4s Progress 3588 / 9694 Time remaining: 4s Progress 3589 / 9694 Time remaining: 4s Progress 3590 / 9694 Time remaining: 4s Progress 3591 / 9694 Time remaining: 4s Progress 3592 / 9694 Time remaining: 4s Progress 3593 / 9694 Time remaining: 4s Progress 3594 / 9694 Time remaining: 4s Progress 3595 / 9694 Time remaining: 4s Progress 3596 / 9694 Time remaining: 4s Progress 3597 / 9694 Time remaining: 4s Progress 3598 / 9694 Time remaining: 4s Progress 3599 / 9694 Time remaining: 4s Progress 3600 / 9694 Time remaining: 4s Progress 3601 / 9694 Time remaining: 4s Progress 3602 / 9694 Time remaining: 4s Progress 3603 / 9694 Time remaining: 4s Progress 3604 / 9694 Time remaining: 4s Progress 3605 / 9694 Time remaining: 4s Progress 3606 / 9694 Time remaining: 4s Progress 3607 / 9694 Time remaining: 4s Progress 3608 / 9694 Time remaining: 4s Progress 3609 / 9694 Time remaining: 4s Progress 3610 / 9694 Time remaining: 4s Progress 3611 / 9694 Time remaining: 4s Progress 3612 / 9694 Time remaining: 4s Progress 3613 / 9694 Time remaining: 4s Progress 3614 / 9694 Time remaining: 4s Progress 3615 / 9694 Time remaining: 4s Progress 3616 / 9694 Time remaining: 4s Progress 3617 / 9694 Time remaining: 4s Progress 3618 / 9694 Time remaining: 4s Progress 3619 / 9694 Time remaining: 4s Progress 3620 / 9694 Time remaining: 4s Progress 3621 / 9694 Time remaining: 4s Progress 3622 / 9694 Time remaining: 4s Progress 3623 / 9694 Time remaining: 4s Progress 3624 / 9694 Time remaining: 4s Progress 3625 / 9694 Time remaining: 4s Progress 3626 / 9694 Time remaining: 4s Progress 3627 / 9694 Time remaining: 4s Progress 3628 / 9694 Time remaining: 4s Progress 3629 / 9694 Time remaining: 4s Progress 3630 / 9694 Time remaining: 4s Progress 3631 / 9694 Time remaining: 4s Progress 3632 / 9694 Time remaining: 4s Progress 3633 / 9694 Time remaining: 4s Progress 3634 / 9694 Time remaining: 4s Progress 3635 / 9694 Time remaining: 4s Progress 3636 / 9694 Time remaining: 4s Progress 3637 / 9694 Time remaining: 4s Progress 3638 / 9694 Time remaining: 4s Progress 3639 / 9694 Time remaining: 4s Progress 3640 / 9694 Time remaining: 4s Progress 3641 / 9694 Time remaining: 4s Progress 3642 / 9694 Time remaining: 4s Progress 3643 / 9694 Time remaining: 4s Progress 3644 / 9694 Time remaining: 4s Progress 3645 / 9694 Time remaining: 4s Progress 3646 / 9694 Time remaining: 4s Progress 3647 / 9694 Time remaining: 4s Progress 3648 / 9694 Time remaining: 4s Progress 3649 / 9694 Time remaining: 4s Progress 3650 / 9694 Time remaining: 4s Progress 3651 / 9694 Time remaining: 4s Progress 3652 / 9694 Time remaining: 4s Progress 3653 / 9694 Time remaining: 4s Progress 3654 / 9694 Time remaining: 4s Progress 3655 / 9694 Time remaining: 4s Progress 3656 / 9694 Time remaining: 4s Progress 3657 / 9694 Time remaining: 4s Progress 3658 / 9694 Time remaining: 4s Progress 3659 / 9694 Time remaining: 4s Progress 3660 / 9694 Time remaining: 4s Progress 3661 / 9694 Time remaining: 4s Progress 3662 / 9694 Time remaining: 4s Progress 3663 / 9694 Time remaining: 4s Progress 3664 / 9694 Time remaining: 4s Progress 3665 / 9694 Time remaining: 4s Progress 3666 / 9694 Time remaining: 4s Progress 3667 / 9694 Time remaining: 4s Progress 3668 / 9694 Time remaining: 4s Progress 3669 / 9694 Time remaining: 4s Progress 3670 / 9694 Time remaining: 4s Progress 3671 / 9694 Time remaining: 4s Progress 3672 / 9694 Time remaining: 4s Progress 3673 / 9694 Time remaining: 4s Progress 3674 / 9694 Time remaining: 4s Progress 3675 / 9694 Time remaining: 4s Progress 3676 / 9694 Time remaining: 4s Progress 3677 / 9694 Time remaining: 4s Progress 3678 / 9694 Time remaining: 4s Progress 3679 / 9694 Time remaining: 4s Progress 3680 / 9694 Time remaining: 4s Progress 3681 / 9694 Time remaining: 4s Progress 3682 / 9694 Time remaining: 4s Progress 3683 / 9694 Time remaining: 4s Progress 3684 / 9694 Time remaining: 4s Progress 3685 / 9694 Time remaining: 4s Progress 3686 / 9694 Time remaining: 4s Progress 3687 / 9694 Time remaining: 4s Progress 3688 / 9694 Time remaining: 4s Progress 3689 / 9694 Time remaining: 4s Progress 3690 / 9694 Time remaining: 4s Progress 3691 / 9694 Time remaining: 4s Progress 3692 / 9694 Time remaining: 4s Progress 3693 / 9694 Time remaining: 4s Progress 3694 / 9694 Time remaining: 4s Progress 3695 / 9694 Time remaining: 4s Progress 3696 / 9694 Time remaining: 4s Progress 3697 / 9694 Time remaining: 4s Progress 3698 / 9694 Time remaining: 4s Progress 3699 / 9694 Time remaining: 4s Progress 3700 / 9694 Time remaining: 4s Progress 3701 / 9694 Time remaining: 4s Progress 3702 / 9694 Time remaining: 4s Progress 3703 / 9694 Time remaining: 4s Progress 3704 / 9694 Time remaining: 4s Progress 3705 / 9694 Time remaining: 4s Progress 3706 / 9694 Time remaining: 4s Progress 3707 / 9694 Time remaining: 4s Progress 3708 / 9694 Time remaining: 4s Progress 3709 / 9694 Time remaining: 4s Progress 3710 / 9694 Time remaining: 4s Progress 3711 / 9694 Time remaining: 4s Progress 3712 / 9694 Time remaining: 4s Progress 3713 / 9694 Time remaining: 4s Progress 3714 / 9694 Time remaining: 4s Progress 3715 / 9694 Time remaining: 4s Progress 3716 / 9694 Time remaining: 4s Progress 3717 / 9694 Time remaining: 4s Progress 3718 / 9694 Time remaining: 4s Progress 3719 / 9694 Time remaining: 4s Progress 3720 / 9694 Time remaining: 4s Progress 3721 / 9694 Time remaining: 4s Progress 3722 / 9694 Time remaining: 4s Progress 3723 / 9694 Time remaining: 4s Progress 3724 / 9694 Time remaining: 4s Progress 3725 / 9694 Time remaining: 4s Progress 3726 / 9694 Time remaining: 4s Progress 3727 / 9694 Time remaining: 4s Progress 3728 / 9694 Time remaining: 4s Progress 3729 / 9694 Time remaining: 4s Progress 3730 / 9694 Time remaining: 4s Progress 3731 / 9694 Time remaining: 4s Progress 3732 / 9694 Time remaining: 4s Progress 3733 / 9694 Time remaining: 4s Progress 3734 / 9694 Time remaining: 4s Progress 3735 / 9694 Time remaining: 4s Progress 3736 / 9694 Time remaining: 4s Progress 3737 / 9694 Time remaining: 4s Progress 3738 / 9694 Time remaining: 4s Progress 3739 / 9694 Time remaining: 4s Progress 3740 / 9694 Time remaining: 4s Progress 3741 / 9694 Time remaining: 4s Progress 3742 / 9694 Time remaining: 4s Progress 3743 / 9694 Time remaining: 4s Progress 3744 / 9694 Time remaining: 4s Progress 3745 / 9694 Time remaining: 4s Progress 3746 / 9694 Time remaining: 4s Progress 3747 / 9694 Time remaining: 4s Progress 3748 / 9694 Time remaining: 4s Progress 3749 / 9694 Time remaining: 4s Progress 3750 / 9694 Time remaining: 4s Progress 3751 / 9694 Time remaining: 4s Progress 3752 / 9694 Time remaining: 4s Progress 3753 / 9694 Time remaining: 4s Progress 3754 / 9694 Time remaining: 4s Progress 3755 / 9694 Time remaining: 4s Progress 3756 / 9694 Time remaining: 4s Progress 3757 / 9694 Time remaining: 4s Progress 3758 / 9694 Time remaining: 4s Progress 3759 / 9694 Time remaining: 4s Progress 3760 / 9694 Time remaining: 4s Progress 3761 / 9694 Time remaining: 4s Progress 3762 / 9694 Time remaining: 4s Progress 3763 / 9694 Time remaining: 4s Progress 3764 / 9694 Time remaining: 4s Progress 3765 / 9694 Time remaining: 4s Progress 3766 / 9694 Time remaining: 4s Progress 3767 / 9694 Time remaining: 4s Progress 3768 / 9694 Time remaining: 4s Progress 3769 / 9694 Time remaining: 4s Progress 3770 / 9694 Time remaining: 4s Progress 3771 / 9694 Time remaining: 4s Progress 3772 / 9694 Time remaining: 4s Progress 3773 / 9694 Time remaining: 4s Progress 3774 / 9694 Time remaining: 4s Progress 3775 / 9694 Time remaining: 4s Progress 3776 / 9694 Time remaining: 4s Progress 3777 / 9694 Time remaining: 4s Progress 3778 / 9694 Time remaining: 4s Progress 3779 / 9694 Time remaining: 4s Progress 3780 / 9694 Time remaining: 4s Progress 3781 / 9694 Time remaining: 4s Progress 3782 / 9694 Time remaining: 4s Progress 3783 / 9694 Time remaining: 4s Progress 3784 / 9694 Time remaining: 4s Progress 3785 / 9694 Time remaining: 4s Progress 3786 / 9694 Time remaining: 4s Progress 3787 / 9694 Time remaining: 4s Progress 3788 / 9694 Time remaining: 4s Progress 3789 / 9694 Time remaining: 4s Progress 3790 / 9694 Time remaining: 4s Progress 3791 / 9694 Time remaining: 4s Progress 3792 / 9694 Time remaining: 4s Progress 3793 / 9694 Time remaining: 4s Progress 3794 / 9694 Time remaining: 4s Progress 3795 / 9694 Time remaining: 4s Progress 3796 / 9694 Time remaining: 4s Progress 3797 / 9694 Time remaining: 4s Progress 3798 / 9694 Time remaining: 4s Progress 3799 / 9694 Time remaining: 4s Progress 3800 / 9694 Time remaining: 4s Progress 3801 / 9694 Time remaining: 4s Progress 3802 / 9694 Time remaining: 4s Progress 3803 / 9694 Time remaining: 4s Progress 3804 / 9694 Time remaining: 4s Progress 3805 / 9694 Time remaining: 4s Progress 3806 / 9694 Time remaining: 4s Progress 3807 / 9694 Time remaining: 4s Progress 3808 / 9694 Time remaining: 4s Progress 3809 / 9694 Time remaining: 4s Progress 3810 / 9694 Time remaining: 4s Progress 3811 / 9694 Time remaining: 4s Progress 3812 / 9694 Time remaining: 4s Progress 3813 / 9694 Time remaining: 4s Progress 3814 / 9694 Time remaining: 4s Progress 3815 / 9694 Time remaining: 4s Progress 3816 / 9694 Time remaining: 4s Progress 3817 / 9694 Time remaining: 4s Progress 3818 / 9694 Time remaining: 4s Progress 3819 / 9694 Time remaining: 4s Progress 3820 / 9694 Time remaining: 4s Progress 3821 / 9694 Time remaining: 4s Progress 3822 / 9694 Time remaining: 4s Progress 3823 / 9694 Time remaining: 4s Progress 3824 / 9694 Time remaining: 4s Progress 3825 / 9694 Time remaining: 4s Progress 3826 / 9694 Time remaining: 4s Progress 3827 / 9694 Time remaining: 4s Progress 3828 / 9694 Time remaining: 4s Progress 3829 / 9694 Time remaining: 4s Progress 3830 / 9694 Time remaining: 4s Progress 3831 / 9694 Time remaining: 4s Progress 3832 / 9694 Time remaining: 4s Progress 3833 / 9694 Time remaining: 4s Progress 3834 / 9694 Time remaining: 4s Progress 3835 / 9694 Time remaining: 4s Progress 3836 / 9694 Time remaining: 4s Progress 3837 / 9694 Time remaining: 4s Progress 3838 / 9694 Time remaining: 4s Progress 3839 / 9694 Time remaining: 4s Progress 3840 / 9694 Time remaining: 4s Progress 3841 / 9694 Time remaining: 4s Progress 3842 / 9694 Time remaining: 4s Progress 3843 / 9694 Time remaining: 4s Progress 3844 / 9694 Time remaining: 4s Progress 3845 / 9694 Time remaining: 4s Progress 3846 / 9694 Time remaining: 4s Progress 3847 / 9694 Time remaining: 4s Progress 3848 / 9694 Time remaining: 4s Progress 3849 / 9694 Time remaining: 4s Progress 3850 / 9694 Time remaining: 4s Progress 3851 / 9694 Time remaining: 4s Progress 3852 / 9694 Time remaining: 4s Progress 3853 / 9694 Time remaining: 4s Progress 3854 / 9694 Time remaining: 4s Progress 3855 / 9694 Time remaining: 4s Progress 3856 / 9694 Time remaining: 4s Progress 3857 / 9694 Time remaining: 4s Progress 3858 / 9694 Time remaining: 4s Progress 3859 / 9694 Time remaining: 4s Progress 3860 / 9694 Time remaining: 4s Progress 3861 / 9694 Time remaining: 4s Progress 3862 / 9694 Time remaining: 4s Progress 3863 / 9694 Time remaining: 4s Progress 3864 / 9694 Time remaining: 4s Progress 3865 / 9694 Time remaining: 4s Progress 3866 / 9694 Time remaining: 4s Progress 3867 / 9694 Time remaining: 4s Progress 3868 / 9694 Time remaining: 4s Progress 3869 / 9694 Time remaining: 4s Progress 3870 / 9694 Time remaining: 4s Progress 3871 / 9694 Time remaining: 4s Progress 3872 / 9694 Time remaining: 4s Progress 3873 / 9694 Time remaining: 4s Progress 3874 / 9694 Time remaining: 4s Progress 3875 / 9694 Time remaining: 4s Progress 3876 / 9694 Time remaining: 4s Progress 3877 / 9694 Time remaining: 4s Progress 3878 / 9694 Time remaining: 4s Progress 3879 / 9694 Time remaining: 4s Progress 3880 / 9694 Time remaining: 4s Progress 3881 / 9694 Time remaining: 4s Progress 3882 / 9694 Time remaining: 4s Progress 3883 / 9694 Time remaining: 4s Progress 3884 / 9694 Time remaining: 4s Progress 3885 / 9694 Time remaining: 4s Progress 3886 / 9694 Time remaining: 4s Progress 3887 / 9694 Time remaining: 4s Progress 3888 / 9694 Time remaining: 4s Progress 3889 / 9694 Time remaining: 4s Progress 3890 / 9694 Time remaining: 4s Progress 3891 / 9694 Time remaining: 4s Progress 3892 / 9694 Time remaining: 4s Progress 3893 / 9694 Time remaining: 4s Progress 3894 / 9694 Time remaining: 4s Progress 3895 / 9694 Time remaining: 4s Progress 3896 / 9694 Time remaining: 4s Progress 3897 / 9694 Time remaining: 4s Progress 3898 / 9694 Time remaining: 4s Progress 3899 / 9694 Time remaining: 4s Progress 3900 / 9694 Time remaining: 4s Progress 3901 / 9694 Time remaining: 4s Progress 3902 / 9694 Time remaining: 4s Progress 3903 / 9694 Time remaining: 4s Progress 3904 / 9694 Time remaining: 4s Progress 3905 / 9694 Time remaining: 4s Progress 3906 / 9694 Time remaining: 4s Progress 3907 / 9694 Time remaining: 4s Progress 3908 / 9694 Time remaining: 4s Progress 3909 / 9694 Time remaining: 4s Progress 3910 / 9694 Time remaining: 4s Progress 3911 / 9694 Time remaining: 4s Progress 3912 / 9694 Time remaining: 4s Progress 3913 / 9694 Time remaining: 4s Progress 3914 / 9694 Time remaining: 4s Progress 3915 / 9694 Time remaining: 4s Progress 3916 / 9694 Time remaining: 4s Progress 3917 / 9694 Time remaining: 4s Progress 3918 / 9694 Time remaining: 4s Progress 3919 / 9694 Time remaining: 4s Progress 3920 / 9694 Time remaining: 4s Progress 3921 / 9694 Time remaining: 4s Progress 3922 / 9694 Time remaining: 4s Progress 3923 / 9694 Time remaining: 4s Progress 3924 / 9694 Time remaining: 4s Progress 3925 / 9694 Time remaining: 4s Progress 3926 / 9694 Time remaining: 4s Progress 3927 / 9694 Time remaining: 4s Progress 3928 / 9694 Time remaining: 4s Progress 3929 / 9694 Time remaining: 4s Progress 3930 / 9694 Time remaining: 4s Progress 3931 / 9694 Time remaining: 4s Progress 3932 / 9694 Time remaining: 4s Progress 3933 / 9694 Time remaining: 4s Progress 3934 / 9694 Time remaining: 4s Progress 3935 / 9694 Time remaining: 4s Progress 3936 / 9694 Time remaining: 4s Progress 3937 / 9694 Time remaining: 4s Progress 3938 / 9694 Time remaining: 4s Progress 3939 / 9694 Time remaining: 4s Progress 3940 / 9694 Time remaining: 4s Progress 3941 / 9694 Time remaining: 4s Progress 3942 / 9694 Time remaining: 4s Progress 3943 / 9694 Time remaining: 4s Progress 3944 / 9694 Time remaining: 4s Progress 3945 / 9694 Time remaining: 4s Progress 3946 / 9694 Time remaining: 4s Progress 3947 / 9694 Time remaining: 4s Progress 3948 / 9694 Time remaining: 4s Progress 3949 / 9694 Time remaining: 4s Progress 3950 / 9694 Time remaining: 4s Progress 3951 / 9694 Time remaining: 4s Progress 3952 / 9694 Time remaining: 4s Progress 3953 / 9694 Time remaining: 4s Progress 3954 / 9694 Time remaining: 4s Progress 3955 / 9694 Time remaining: 4s Progress 3956 / 9694 Time remaining: 4s Progress 3957 / 9694 Time remaining: 4s Progress 3958 / 9694 Time remaining: 4s Progress 3959 / 9694 Time remaining: 4s Progress 3960 / 9694 Time remaining: 4s Progress 3961 / 9694 Time remaining: 4s Progress 3962 / 9694 Time remaining: 4s Progress 3963 / 9694 Time remaining: 4s Progress 3964 / 9694 Time remaining: 4s Progress 3965 / 9694 Time remaining: 4s Progress 3966 / 9694 Time remaining: 4s Progress 3967 / 9694 Time remaining: 4s Progress 3968 / 9694 Time remaining: 4s Progress 3969 / 9694 Time remaining: 4s Progress 3970 / 9694 Time remaining: 4s Progress 3971 / 9694 Time remaining: 4s Progress 3972 / 9694 Time remaining: 4s Progress 3973 / 9694 Time remaining: 4s Progress 3974 / 9694 Time remaining: 4s Progress 3975 / 9694 Time remaining: 4s Progress 3976 / 9694 Time remaining: 4s Progress 3977 / 9694 Time remaining: 4s Progress 3978 / 9694 Time remaining: 4s Progress 3979 / 9694 Time remaining: 4s Progress 3980 / 9694 Time remaining: 4s Progress 3981 / 9694 Time remaining: 4s Progress 3982 / 9694 Time remaining: 4s Progress 3983 / 9694 Time remaining: 4s Progress 3984 / 9694 Time remaining: 4s Progress 3985 / 9694 Time remaining: 4s Progress 3986 / 9694 Time remaining: 4s Progress 3987 / 9694 Time remaining: 4s Progress 3988 / 9694 Time remaining: 4s Progress 3989 / 9694 Time remaining: 4s Progress 3990 / 9694 Time remaining: 4s Progress 3991 / 9694 Time remaining: 4s Progress 3992 / 9694 Time remaining: 4s Progress 3993 / 9694 Time remaining: 4s Progress 3994 / 9694 Time remaining: 4s Progress 3995 / 9694 Time remaining: 4s Progress 3996 / 9694 Time remaining: 4s Progress 3997 / 9694 Time remaining: 4s Progress 3998 / 9694 Time remaining: 4s Progress 3999 / 9694 Time remaining: 4s Progress 4000 / 9694 Time remaining: 4s Progress 4001 / 9694 Time remaining: 4s Progress 4002 / 9694 Time remaining: 4s Progress 4003 / 9694 Time remaining: 4s Progress 4004 / 9694 Time remaining: 4s Progress 4005 / 9694 Time remaining: 4s Progress 4006 / 9694 Time remaining: 4s Progress 4007 / 9694 Time remaining: 4s Progress 4008 / 9694 Time remaining: 4s Progress 4009 / 9694 Time remaining: 4s Progress 4010 / 9694 Time remaining: 4s Progress 4011 / 9694 Time remaining: 4s Progress 4012 / 9694 Time remaining: 4s Progress 4013 / 9694 Time remaining: 4s Progress 4014 / 9694 Time remaining: 4s Progress 4015 / 9694 Time remaining: 4s Progress 4016 / 9694 Time remaining: 4s Progress 4017 / 9694 Time remaining: 4s Progress 4018 / 9694 Time remaining: 4s Progress 4019 / 9694 Time remaining: 4s Progress 4020 / 9694 Time remaining: 4s Progress 4021 / 9694 Time remaining: 4s Progress 4022 / 9694 Time remaining: 4s Progress 4023 / 9694 Time remaining: 4s Progress 4024 / 9694 Time remaining: 4s Progress 4025 / 9694 Time remaining: 4s Progress 4026 / 9694 Time remaining: 4s Progress 4027 / 9694 Time remaining: 4s Progress 4028 / 9694 Time remaining: 4s Progress 4029 / 9694 Time remaining: 4s Progress 4030 / 9694 Time remaining: 4s Progress 4031 / 9694 Time remaining: 4s Progress 4032 / 9694 Time remaining: 4s Progress 4033 / 9694 Time remaining: 4s Progress 4034 / 9694 Time remaining: 4s Progress 4035 / 9694 Time remaining: 4s Progress 4036 / 9694 Time remaining: 4s Progress 4037 / 9694 Time remaining: 4s Progress 4038 / 9694 Time remaining: 4s Progress 4039 / 9694 Time remaining: 4s Progress 4040 / 9694 Time remaining: 4s Progress 4041 / 9694 Time remaining: 4s Progress 4042 / 9694 Time remaining: 4s Progress 4043 / 9694 Time remaining: 4s Progress 4044 / 9694 Time remaining: 4s Progress 4045 / 9694 Time remaining: 4s Progress 4046 / 9694 Time remaining: 4s Progress 4047 / 9694 Time remaining: 4s Progress 4048 / 9694 Time remaining: 4s Progress 4049 / 9694 Time remaining: 4s Progress 4050 / 9694 Time remaining: 4s Progress 4051 / 9694 Time remaining: 4s Progress 4052 / 9694 Time remaining: 4s Progress 4053 / 9694 Time remaining: 4s Progress 4054 / 9694 Time remaining: 4s Progress 4055 / 9694 Time remaining: 4s Progress 4056 / 9694 Time remaining: 4s Progress 4057 / 9694 Time remaining: 4s Progress 4058 / 9694 Time remaining: 4s Progress 4059 / 9694 Time remaining: 4s Progress 4060 / 9694 Time remaining: 4s Progress 4061 / 9694 Time remaining: 4s Progress 4062 / 9694 Time remaining: 4s Progress 4063 / 9694 Time remaining: 4s Progress 4064 / 9694 Time remaining: 4s Progress 4065 / 9694 Time remaining: 4s Progress 4066 / 9694 Time remaining: 4s Progress 4067 / 9694 Time remaining: 4s Progress 4068 / 9694 Time remaining: 4s Progress 4069 / 9694 Time remaining: 4s Progress 4070 / 9694 Time remaining: 4s Progress 4071 / 9694 Time remaining: 4s Progress 4072 / 9694 Time remaining: 4s Progress 4073 / 9694 Time remaining: 4s Progress 4074 / 9694 Time remaining: 4s Progress 4075 / 9694 Time remaining: 4s Progress 4076 / 9694 Time remaining: 4s Progress 4077 / 9694 Time remaining: 4s Progress 4078 / 9694 Time remaining: 4s Progress 4079 / 9694 Time remaining: 4s Progress 4080 / 9694 Time remaining: 4s Progress 4081 / 9694 Time remaining: 4s Progress 4082 / 9694 Time remaining: 4s Progress 4083 / 9694 Time remaining: 3s Progress 4084 / 9694 Time remaining: 3s Progress 4085 / 9694 Time remaining: 3s Progress 4086 / 9694 Time remaining: 3s Progress 4087 / 9694 Time remaining: 3s Progress 4088 / 9694 Time remaining: 3s Progress 4089 / 9694 Time remaining: 3s Progress 4090 / 9694 Time remaining: 3s Progress 4091 / 9694 Time remaining: 3s Progress 4092 / 9694 Time remaining: 3s Progress 4093 / 9694 Time remaining: 3s Progress 4094 / 9694 Time remaining: 3s Progress 4095 / 9694 Time remaining: 3s Progress 4096 / 9694 Time remaining: 3s Progress 4097 / 9694 Time remaining: 3s Progress 4098 / 9694 Time remaining: 3s Progress 4099 / 9694 Time remaining: 3s Progress 4100 / 9694 Time remaining: 3s Progress 4101 / 9694 Time remaining: 3s Progress 4102 / 9694 Time remaining: 3s Progress 4103 / 9694 Time remaining: 3s Progress 4104 / 9694 Time remaining: 3s Progress 4105 / 9694 Time remaining: 3s Progress 4106 / 9694 Time remaining: 3s Progress 4107 / 9694 Time remaining: 3s Progress 4108 / 9694 Time remaining: 3s Progress 4109 / 9694 Time remaining: 3s Progress 4110 / 9694 Time remaining: 3s Progress 4111 / 9694 Time remaining: 3s Progress 4112 / 9694 Time remaining: 3s Progress 4113 / 9694 Time remaining: 3s Progress 4114 / 9694 Time remaining: 3s Progress 4115 / 9694 Time remaining: 3s Progress 4116 / 9694 Time remaining: 3s Progress 4117 / 9694 Time remaining: 3s Progress 4118 / 9694 Time remaining: 3s Progress 4119 / 9694 Time remaining: 3s Progress 4120 / 9694 Time remaining: 3s Progress 4121 / 9694 Time remaining: 3s Progress 4122 / 9694 Time remaining: 3s Progress 4123 / 9694 Time remaining: 3s Progress 4124 / 9694 Time remaining: 3s Progress 4125 / 9694 Time remaining: 3s Progress 4126 / 9694 Time remaining: 3s Progress 4127 / 9694 Time remaining: 3s Progress 4128 / 9694 Time remaining: 3s Progress 4129 / 9694 Time remaining: 3s Progress 4130 / 9694 Time remaining: 3s Progress 4131 / 9694 Time remaining: 3s Progress 4132 / 9694 Time remaining: 3s Progress 4133 / 9694 Time remaining: 3s Progress 4134 / 9694 Time remaining: 3s Progress 4135 / 9694 Time remaining: 3s Progress 4136 / 9694 Time remaining: 3s Progress 4137 / 9694 Time remaining: 3s Progress 4138 / 9694 Time remaining: 3s Progress 4139 / 9694 Time remaining: 3s Progress 4140 / 9694 Time remaining: 3s Progress 4141 / 9694 Time remaining: 3s Progress 4142 / 9694 Time remaining: 3s Progress 4143 / 9694 Time remaining: 3s Progress 4144 / 9694 Time remaining: 3s Progress 4145 / 9694 Time remaining: 3s Progress 4146 / 9694 Time remaining: 3s Progress 4147 / 9694 Time remaining: 3s Progress 4148 / 9694 Time remaining: 3s Progress 4149 / 9694 Time remaining: 3s Progress 4150 / 9694 Time remaining: 3s Progress 4151 / 9694 Time remaining: 3s Progress 4152 / 9694 Time remaining: 3s Progress 4153 / 9694 Time remaining: 3s Progress 4154 / 9694 Time remaining: 3s Progress 4155 / 9694 Time remaining: 3s Progress 4156 / 9694 Time remaining: 3s Progress 4157 / 9694 Time remaining: 3s Progress 4158 / 9694 Time remaining: 3s Progress 4159 / 9694 Time remaining: 3s Progress 4160 / 9694 Time remaining: 3s Progress 4161 / 9694 Time remaining: 3s Progress 4162 / 9694 Time remaining: 3s Progress 4163 / 9694 Time remaining: 3s Progress 4164 / 9694 Time remaining: 3s Progress 4165 / 9694 Time remaining: 3s Progress 4166 / 9694 Time remaining: 3s Progress 4167 / 9694 Time remaining: 3s Progress 4168 / 9694 Time remaining: 3s Progress 4169 / 9694 Time remaining: 3s Progress 4170 / 9694 Time remaining: 3s Progress 4171 / 9694 Time remaining: 3s Progress 4172 / 9694 Time remaining: 3s Progress 4173 / 9694 Time remaining: 3s Progress 4174 / 9694 Time remaining: 3s Progress 4175 / 9694 Time remaining: 3s Progress 4176 / 9694 Time remaining: 3s Progress 4177 / 9694 Time remaining: 3s Progress 4178 / 9694 Time remaining: 3s Progress 4179 / 9694 Time remaining: 3s Progress 4180 / 9694 Time remaining: 3s Progress 4181 / 9694 Time remaining: 3s Progress 4182 / 9694 Time remaining: 3s Progress 4183 / 9694 Time remaining: 3s Progress 4184 / 9694 Time remaining: 3s Progress 4185 / 9694 Time remaining: 3s Progress 4186 / 9694 Time remaining: 3s Progress 4187 / 9694 Time remaining: 3s Progress 4188 / 9694 Time remaining: 3s Progress 4189 / 9694 Time remaining: 3s Progress 4190 / 9694 Time remaining: 3s Progress 4191 / 9694 Time remaining: 3s Progress 4192 / 9694 Time remaining: 3s Progress 4193 / 9694 Time remaining: 3s Progress 4194 / 9694 Time remaining: 3s Progress 4195 / 9694 Time remaining: 3s Progress 4196 / 9694 Time remaining: 3s Progress 4197 / 9694 Time remaining: 3s Progress 4198 / 9694 Time remaining: 3s Progress 4199 / 9694 Time remaining: 3s Progress 4200 / 9694 Time remaining: 3s Progress 4201 / 9694 Time remaining: 3s Progress 4202 / 9694 Time remaining: 3s Progress 4203 / 9694 Time remaining: 3s Progress 4204 / 9694 Time remaining: 3s Progress 4205 / 9694 Time remaining: 3s Progress 4206 / 9694 Time remaining: 3s Progress 4207 / 9694 Time remaining: 3s Progress 4208 / 9694 Time remaining: 3s Progress 4209 / 9694 Time remaining: 3s Progress 4210 / 9694 Time remaining: 3s Progress 4211 / 9694 Time remaining: 3s Progress 4212 / 9694 Time remaining: 3s Progress 4213 / 9694 Time remaining: 3s Progress 4214 / 9694 Time remaining: 3s Progress 4215 / 9694 Time remaining: 3s Progress 4216 / 9694 Time remaining: 3s Progress 4217 / 9694 Time remaining: 3s Progress 4218 / 9694 Time remaining: 3s Progress 4219 / 9694 Time remaining: 3s Progress 4220 / 9694 Time remaining: 3s Progress 4221 / 9694 Time remaining: 3s Progress 4222 / 9694 Time remaining: 3s Progress 4223 / 9694 Time remaining: 3s Progress 4224 / 9694 Time remaining: 3s Progress 4225 / 9694 Time remaining: 3s Progress 4226 / 9694 Time remaining: 3s Progress 4227 / 9694 Time remaining: 3s Progress 4228 / 9694 Time remaining: 3s Progress 4229 / 9694 Time remaining: 3s Progress 4230 / 9694 Time remaining: 3s Progress 4231 / 9694 Time remaining: 3s Progress 4232 / 9694 Time remaining: 3s Progress 4233 / 9694 Time remaining: 3s Progress 4234 / 9694 Time remaining: 3s Progress 4235 / 9694 Time remaining: 3s Progress 4236 / 9694 Time remaining: 3s Progress 4237 / 9694 Time remaining: 3s Progress 4238 / 9694 Time remaining: 3s Progress 4239 / 9694 Time remaining: 3s Progress 4240 / 9694 Time remaining: 3s Progress 4241 / 9694 Time remaining: 3s Progress 4242 / 9694 Time remaining: 3s Progress 4243 / 9694 Time remaining: 3s Progress 4244 / 9694 Time remaining: 3s Progress 4245 / 9694 Time remaining: 3s Progress 4246 / 9694 Time remaining: 3s Progress 4247 / 9694 Time remaining: 3s Progress 4248 / 9694 Time remaining: 3s Progress 4249 / 9694 Time remaining: 3s Progress 4250 / 9694 Time remaining: 3s Progress 4251 / 9694 Time remaining: 3s Progress 4252 / 9694 Time remaining: 3s Progress 4253 / 9694 Time remaining: 3s Progress 4254 / 9694 Time remaining: 3s Progress 4255 / 9694 Time remaining: 3s Progress 4256 / 9694 Time remaining: 3s Progress 4257 / 9694 Time remaining: 3s Progress 4258 / 9694 Time remaining: 3s Progress 4259 / 9694 Time remaining: 3s Progress 4260 / 9694 Time remaining: 3s Progress 4261 / 9694 Time remaining: 3s Progress 4262 / 9694 Time remaining: 3s Progress 4263 / 9694 Time remaining: 3s Progress 4264 / 9694 Time remaining: 3s Progress 4265 / 9694 Time remaining: 3s Progress 4266 / 9694 Time remaining: 3s Progress 4267 / 9694 Time remaining: 3s Progress 4268 / 9694 Time remaining: 3s Progress 4269 / 9694 Time remaining: 3s Progress 4270 / 9694 Time remaining: 3s Progress 4271 / 9694 Time remaining: 3s Progress 4272 / 9694 Time remaining: 3s Progress 4273 / 9694 Time remaining: 3s Progress 4274 / 9694 Time remaining: 3s Progress 4275 / 9694 Time remaining: 3s Progress 4276 / 9694 Time remaining: 3s Progress 4277 / 9694 Time remaining: 3s Progress 4278 / 9694 Time remaining: 3s Progress 4279 / 9694 Time remaining: 3s Progress 4280 / 9694 Time remaining: 3s Progress 4281 / 9694 Time remaining: 3s Progress 4282 / 9694 Time remaining: 3s Progress 4283 / 9694 Time remaining: 3s Progress 4284 / 9694 Time remaining: 3s Progress 4285 / 9694 Time remaining: 3s Progress 4286 / 9694 Time remaining: 3s Progress 4287 / 9694 Time remaining: 3s Progress 4288 / 9694 Time remaining: 3s Progress 4289 / 9694 Time remaining: 3s Progress 4290 / 9694 Time remaining: 3s Progress 4291 / 9694 Time remaining: 3s Progress 4292 / 9694 Time remaining: 3s Progress 4293 / 9694 Time remaining: 3s Progress 4294 / 9694 Time remaining: 3s Progress 4295 / 9694 Time remaining: 3s Progress 4296 / 9694 Time remaining: 3s Progress 4297 / 9694 Time remaining: 3s Progress 4298 / 9694 Time remaining: 3s Progress 4299 / 9694 Time remaining: 3s Progress 4300 / 9694 Time remaining: 3s Progress 4301 / 9694 Time remaining: 3s Progress 4302 / 9694 Time remaining: 3s Progress 4303 / 9694 Time remaining: 3s Progress 4304 / 9694 Time remaining: 3s Progress 4305 / 9694 Time remaining: 3s Progress 4306 / 9694 Time remaining: 3s Progress 4307 / 9694 Time remaining: 3s Progress 4308 / 9694 Time remaining: 3s Progress 4309 / 9694 Time remaining: 3s Progress 4310 / 9694 Time remaining: 3s Progress 4311 / 9694 Time remaining: 3s Progress 4312 / 9694 Time remaining: 3s Progress 4313 / 9694 Time remaining: 3s Progress 4314 / 9694 Time remaining: 3s Progress 4315 / 9694 Time remaining: 3s Progress 4316 / 9694 Time remaining: 3s Progress 4317 / 9694 Time remaining: 3s Progress 4318 / 9694 Time remaining: 3s Progress 4319 / 9694 Time remaining: 3s Progress 4320 / 9694 Time remaining: 3s Progress 4321 / 9694 Time remaining: 3s Progress 4322 / 9694 Time remaining: 3s Progress 4323 / 9694 Time remaining: 3s Progress 4324 / 9694 Time remaining: 3s Progress 4325 / 9694 Time remaining: 3s Progress 4326 / 9694 Time remaining: 3s Progress 4327 / 9694 Time remaining: 3s Progress 4328 / 9694 Time remaining: 3s Progress 4329 / 9694 Time remaining: 3s Progress 4330 / 9694 Time remaining: 3s Progress 4331 / 9694 Time remaining: 3s Progress 4332 / 9694 Time remaining: 3s Progress 4333 / 9694 Time remaining: 3s Progress 4334 / 9694 Time remaining: 3s Progress 4335 / 9694 Time remaining: 3s Progress 4336 / 9694 Time remaining: 3s Progress 4337 / 9694 Time remaining: 3s Progress 4338 / 9694 Time remaining: 3s Progress 4339 / 9694 Time remaining: 3s Progress 4340 / 9694 Time remaining: 3s Progress 4341 / 9694 Time remaining: 3s Progress 4342 / 9694 Time remaining: 3s Progress 4343 / 9694 Time remaining: 3s Progress 4344 / 9694 Time remaining: 3s Progress 4345 / 9694 Time remaining: 3s Progress 4346 / 9694 Time remaining: 3s Progress 4347 / 9694 Time remaining: 3s Progress 4348 / 9694 Time remaining: 3s Progress 4349 / 9694 Time remaining: 3s Progress 4350 / 9694 Time remaining: 3s Progress 4351 / 9694 Time remaining: 3s Progress 4352 / 9694 Time remaining: 3s Progress 4353 / 9694 Time remaining: 3s Progress 4354 / 9694 Time remaining: 3s Progress 4355 / 9694 Time remaining: 3s Progress 4356 / 9694 Time remaining: 3s Progress 4357 / 9694 Time remaining: 3s Progress 4358 / 9694 Time remaining: 3s Progress 4359 / 9694 Time remaining: 3s Progress 4360 / 9694 Time remaining: 3s Progress 4361 / 9694 Time remaining: 3s Progress 4362 / 9694 Time remaining: 3s Progress 4363 / 9694 Time remaining: 3s Progress 4364 / 9694 Time remaining: 3s Progress 4365 / 9694 Time remaining: 3s Progress 4366 / 9694 Time remaining: 3s Progress 4367 / 9694 Time remaining: 3s Progress 4368 / 9694 Time remaining: 3s Progress 4369 / 9694 Time remaining: 3s Progress 4370 / 9694 Time remaining: 3s Progress 4371 / 9694 Time remaining: 3s Progress 4372 / 9694 Time remaining: 3s Progress 4373 / 9694 Time remaining: 3s Progress 4374 / 9694 Time remaining: 3s Progress 4375 / 9694 Time remaining: 3s Progress 4376 / 9694 Time remaining: 3s Progress 4377 / 9694 Time remaining: 3s Progress 4378 / 9694 Time remaining: 3s Progress 4379 / 9694 Time remaining: 3s Progress 4380 / 9694 Time remaining: 3s Progress 4381 / 9694 Time remaining: 3s Progress 4382 / 9694 Time remaining: 3s Progress 4383 / 9694 Time remaining: 3s Progress 4384 / 9694 Time remaining: 3s Progress 4385 / 9694 Time remaining: 3s Progress 4386 / 9694 Time remaining: 3s Progress 4387 / 9694 Time remaining: 3s Progress 4388 / 9694 Time remaining: 3s Progress 4389 / 9694 Time remaining: 3s Progress 4390 / 9694 Time remaining: 3s Progress 4391 / 9694 Time remaining: 3s Progress 4392 / 9694 Time remaining: 3s Progress 4393 / 9694 Time remaining: 3s Progress 4394 / 9694 Time remaining: 3s Progress 4395 / 9694 Time remaining: 3s Progress 4396 / 9694 Time remaining: 3s Progress 4397 / 9694 Time remaining: 3s Progress 4398 / 9694 Time remaining: 3s Progress 4399 / 9694 Time remaining: 3s Progress 4400 / 9694 Time remaining: 3s Progress 4401 / 9694 Time remaining: 3s Progress 4402 / 9694 Time remaining: 3s Progress 4403 / 9694 Time remaining: 3s Progress 4404 / 9694 Time remaining: 3s Progress 4405 / 9694 Time remaining: 3s Progress 4406 / 9694 Time remaining: 3s Progress 4407 / 9694 Time remaining: 3s Progress 4408 / 9694 Time remaining: 3s Progress 4409 / 9694 Time remaining: 3s Progress 4410 / 9694 Time remaining: 3s Progress 4411 / 9694 Time remaining: 3s Progress 4412 / 9694 Time remaining: 3s Progress 4413 / 9694 Time remaining: 3s Progress 4414 / 9694 Time remaining: 3s Progress 4415 / 9694 Time remaining: 3s Progress 4416 / 9694 Time remaining: 3s Progress 4417 / 9694 Time remaining: 3s Progress 4418 / 9694 Time remaining: 3s Progress 4419 / 9694 Time remaining: 3s Progress 4420 / 9694 Time remaining: 3s Progress 4421 / 9694 Time remaining: 3s Progress 4422 / 9694 Time remaining: 3s Progress 4423 / 9694 Time remaining: 3s Progress 4424 / 9694 Time remaining: 3s Progress 4425 / 9694 Time remaining: 3s Progress 4426 / 9694 Time remaining: 3s Progress 4427 / 9694 Time remaining: 3s Progress 4428 / 9694 Time remaining: 3s Progress 4429 / 9694 Time remaining: 3s Progress 4430 / 9694 Time remaining: 3s Progress 4431 / 9694 Time remaining: 3s Progress 4432 / 9694 Time remaining: 3s Progress 4433 / 9694 Time remaining: 3s Progress 4434 / 9694 Time remaining: 3s Progress 4435 / 9694 Time remaining: 3s Progress 4436 / 9694 Time remaining: 3s Progress 4437 / 9694 Time remaining: 3s Progress 4438 / 9694 Time remaining: 3s Progress 4439 / 9694 Time remaining: 3s Progress 4440 / 9694 Time remaining: 3s Progress 4441 / 9694 Time remaining: 3s Progress 4442 / 9694 Time remaining: 3s Progress 4443 / 9694 Time remaining: 3s Progress 4444 / 9694 Time remaining: 3s Progress 4445 / 9694 Time remaining: 3s Progress 4446 / 9694 Time remaining: 3s Progress 4447 / 9694 Time remaining: 3s Progress 4448 / 9694 Time remaining: 3s Progress 4449 / 9694 Time remaining: 3s Progress 4450 / 9694 Time remaining: 3s Progress 4451 / 9694 Time remaining: 3s Progress 4452 / 9694 Time remaining: 3s Progress 4453 / 9694 Time remaining: 3s Progress 4454 / 9694 Time remaining: 3s Progress 4455 / 9694 Time remaining: 3s Progress 4456 / 9694 Time remaining: 3s Progress 4457 / 9694 Time remaining: 3s Progress 4458 / 9694 Time remaining: 3s Progress 4459 / 9694 Time remaining: 3s Progress 4460 / 9694 Time remaining: 3s Progress 4461 / 9694 Time remaining: 3s Progress 4462 / 9694 Time remaining: 3s Progress 4463 / 9694 Time remaining: 3s Progress 4464 / 9694 Time remaining: 3s Progress 4465 / 9694 Time remaining: 3s Progress 4466 / 9694 Time remaining: 3s Progress 4467 / 9694 Time remaining: 3s Progress 4468 / 9694 Time remaining: 3s Progress 4469 / 9694 Time remaining: 3s Progress 4470 / 9694 Time remaining: 3s Progress 4471 / 9694 Time remaining: 3s Progress 4472 / 9694 Time remaining: 3s Progress 4473 / 9694 Time remaining: 3s Progress 4474 / 9694 Time remaining: 3s Progress 4475 / 9694 Time remaining: 3s Progress 4476 / 9694 Time remaining: 3s Progress 4477 / 9694 Time remaining: 3s Progress 4478 / 9694 Time remaining: 3s Progress 4479 / 9694 Time remaining: 3s Progress 4480 / 9694 Time remaining: 3s Progress 4481 / 9694 Time remaining: 3s Progress 4482 / 9694 Time remaining: 3s Progress 4483 / 9694 Time remaining: 3s Progress 4484 / 9694 Time remaining: 3s Progress 4485 / 9694 Time remaining: 3s Progress 4486 / 9694 Time remaining: 3s Progress 4487 / 9694 Time remaining: 3s Progress 4488 / 9694 Time remaining: 3s Progress 4489 / 9694 Time remaining: 3s Progress 4490 / 9694 Time remaining: 3s Progress 4491 / 9694 Time remaining: 3s Progress 4492 / 9694 Time remaining: 3s Progress 4493 / 9694 Time remaining: 3s Progress 4494 / 9694 Time remaining: 3s Progress 4495 / 9694 Time remaining: 3s Progress 4496 / 9694 Time remaining: 3s Progress 4497 / 9694 Time remaining: 3s Progress 4498 / 9694 Time remaining: 3s Progress 4499 / 9694 Time remaining: 3s Progress 4500 / 9694 Time remaining: 3s Progress 4501 / 9694 Time remaining: 3s Progress 4502 / 9694 Time remaining: 3s Progress 4503 / 9694 Time remaining: 3s Progress 4504 / 9694 Time remaining: 3s Progress 4505 / 9694 Time remaining: 3s Progress 4506 / 9694 Time remaining: 3s Progress 4507 / 9694 Time remaining: 3s Progress 4508 / 9694 Time remaining: 3s Progress 4509 / 9694 Time remaining: 3s Progress 4510 / 9694 Time remaining: 3s Progress 4511 / 9694 Time remaining: 3s Progress 4512 / 9694 Time remaining: 3s Progress 4513 / 9694 Time remaining: 3s Progress 4514 / 9694 Time remaining: 3s Progress 4515 / 9694 Time remaining: 3s Progress 4516 / 9694 Time remaining: 3s Progress 4517 / 9694 Time remaining: 3s Progress 4518 / 9694 Time remaining: 3s Progress 4519 / 9694 Time remaining: 3s Progress 4520 / 9694 Time remaining: 3s Progress 4521 / 9694 Time remaining: 3s Progress 4522 / 9694 Time remaining: 3s Progress 4523 / 9694 Time remaining: 3s Progress 4524 / 9694 Time remaining: 3s Progress 4525 / 9694 Time remaining: 3s Progress 4526 / 9694 Time remaining: 3s Progress 4527 / 9694 Time remaining: 3s Progress 4528 / 9694 Time remaining: 3s Progress 4529 / 9694 Time remaining: 3s Progress 4530 / 9694 Time remaining: 3s Progress 4531 / 9694 Time remaining: 3s Progress 4532 / 9694 Time remaining: 3s Progress 4533 / 9694 Time remaining: 3s Progress 4534 / 9694 Time remaining: 3s Progress 4535 / 9694 Time remaining: 3s Progress 4536 / 9694 Time remaining: 3s Progress 4537 / 9694 Time remaining: 3s Progress 4538 / 9694 Time remaining: 3s Progress 4539 / 9694 Time remaining: 3s Progress 4540 / 9694 Time remaining: 3s Progress 4541 / 9694 Time remaining: 3s Progress 4542 / 9694 Time remaining: 3s Progress 4543 / 9694 Time remaining: 3s Progress 4544 / 9694 Time remaining: 3s Progress 4545 / 9694 Time remaining: 3s Progress 4546 / 9694 Time remaining: 3s Progress 4547 / 9694 Time remaining: 3s Progress 4548 / 9694 Time remaining: 3s Progress 4549 / 9694 Time remaining: 3s Progress 4550 / 9694 Time remaining: 3s Progress 4551 / 9694 Time remaining: 3s Progress 4552 / 9694 Time remaining: 3s Progress 4553 / 9694 Time remaining: 3s Progress 4554 / 9694 Time remaining: 3s Progress 4555 / 9694 Time remaining: 3s Progress 4556 / 9694 Time remaining: 3s Progress 4557 / 9694 Time remaining: 3s Progress 4558 / 9694 Time remaining: 3s Progress 4559 / 9694 Time remaining: 3s Progress 4560 / 9694 Time remaining: 3s Progress 4561 / 9694 Time remaining: 3s Progress 4562 / 9694 Time remaining: 3s Progress 4563 / 9694 Time remaining: 3s Progress 4564 / 9694 Time remaining: 3s Progress 4565 / 9694 Time remaining: 3s Progress 4566 / 9694 Time remaining: 3s Progress 4567 / 9694 Time remaining: 3s Progress 4568 / 9694 Time remaining: 3s Progress 4569 / 9694 Time remaining: 3s Progress 4570 / 9694 Time remaining: 3s Progress 4571 / 9694 Time remaining: 3s Progress 4572 / 9694 Time remaining: 3s Progress 4573 / 9694 Time remaining: 3s Progress 4574 / 9694 Time remaining: 3s Progress 4575 / 9694 Time remaining: 3s Progress 4576 / 9694 Time remaining: 3s Progress 4577 / 9694 Time remaining: 3s Progress 4578 / 9694 Time remaining: 3s Progress 4579 / 9694 Time remaining: 3s Progress 4580 / 9694 Time remaining: 3s Progress 4581 / 9694 Time remaining: 3s Progress 4582 / 9694 Time remaining: 3s Progress 4583 / 9694 Time remaining: 3s Progress 4584 / 9694 Time remaining: 3s Progress 4585 / 9694 Time remaining: 3s Progress 4586 / 9694 Time remaining: 3s Progress 4587 / 9694 Time remaining: 3s Progress 4588 / 9694 Time remaining: 3s Progress 4589 / 9694 Time remaining: 3s Progress 4590 / 9694 Time remaining: 3s Progress 4591 / 9694 Time remaining: 3s Progress 4592 / 9694 Time remaining: 3s Progress 4593 / 9694 Time remaining: 3s Progress 4594 / 9694 Time remaining: 3s Progress 4595 / 9694 Time remaining: 3s Progress 4596 / 9694 Time remaining: 3s Progress 4597 / 9694 Time remaining: 3s Progress 4598 / 9694 Time remaining: 3s Progress 4599 / 9694 Time remaining: 3s Progress 4600 / 9694 Time remaining: 3s Progress 4601 / 9694 Time remaining: 3s Progress 4602 / 9694 Time remaining: 3s Progress 4603 / 9694 Time remaining: 3s Progress 4604 / 9694 Time remaining: 3s Progress 4605 / 9694 Time remaining: 3s Progress 4606 / 9694 Time remaining: 3s Progress 4607 / 9694 Time remaining: 3s Progress 4608 / 9694 Time remaining: 3s Progress 4609 / 9694 Time remaining: 3s Progress 4610 / 9694 Time remaining: 3s Progress 4611 / 9694 Time remaining: 3s Progress 4612 / 9694 Time remaining: 3s Progress 4613 / 9694 Time remaining: 3s Progress 4614 / 9694 Time remaining: 3s Progress 4615 / 9694 Time remaining: 3s Progress 4616 / 9694 Time remaining: 3s Progress 4617 / 9694 Time remaining: 3s Progress 4618 / 9694 Time remaining: 3s Progress 4619 / 9694 Time remaining: 3s Progress 4620 / 9694 Time remaining: 3s Progress 4621 / 9694 Time remaining: 3s Progress 4622 / 9694 Time remaining: 3s Progress 4623 / 9694 Time remaining: 3s Progress 4624 / 9694 Time remaining: 3s Progress 4625 / 9694 Time remaining: 3s Progress 4626 / 9694 Time remaining: 3s Progress 4627 / 9694 Time remaining: 3s Progress 4628 / 9694 Time remaining: 3s Progress 4629 / 9694 Time remaining: 3s Progress 4630 / 9694 Time remaining: 3s Progress 4631 / 9694 Time remaining: 3s Progress 4632 / 9694 Time remaining: 3s Progress 4633 / 9694 Time remaining: 3s Progress 4634 / 9694 Time remaining: 3s Progress 4635 / 9694 Time remaining: 3s Progress 4636 / 9694 Time remaining: 3s Progress 4637 / 9694 Time remaining: 3s Progress 4638 / 9694 Time remaining: 3s Progress 4639 / 9694 Time remaining: 3s Progress 4640 / 9694 Time remaining: 3s Progress 4641 / 9694 Time remaining: 3s Progress 4642 / 9694 Time remaining: 3s Progress 4643 / 9694 Time remaining: 3s Progress 4644 / 9694 Time remaining: 3s Progress 4645 / 9694 Time remaining: 3s Progress 4646 / 9694 Time remaining: 3s Progress 4647 / 9694 Time remaining: 3s Progress 4648 / 9694 Time remaining: 3s Progress 4649 / 9694 Time remaining: 3s Progress 4650 / 9694 Time remaining: 3s Progress 4651 / 9694 Time remaining: 3s Progress 4652 / 9694 Time remaining: 3s Progress 4653 / 9694 Time remaining: 3s Progress 4654 / 9694 Time remaining: 3s Progress 4655 / 9694 Time remaining: 3s Progress 4656 / 9694 Time remaining: 3s Progress 4657 / 9694 Time remaining: 3s Progress 4658 / 9694 Time remaining: 3s Progress 4659 / 9694 Time remaining: 3s Progress 4660 / 9694 Time remaining: 3s Progress 4661 / 9694 Time remaining: 3s Progress 4662 / 9694 Time remaining: 3s Progress 4663 / 9694 Time remaining: 3s Progress 4664 / 9694 Time remaining: 3s Progress 4665 / 9694 Time remaining: 3s Progress 4666 / 9694 Time remaining: 3s Progress 4667 / 9694 Time remaining: 3s Progress 4668 / 9694 Time remaining: 3s Progress 4669 / 9694 Time remaining: 3s Progress 4670 / 9694 Time remaining: 3s Progress 4671 / 9694 Time remaining: 3s Progress 4672 / 9694 Time remaining: 3s Progress 4673 / 9694 Time remaining: 3s Progress 4674 / 9694 Time remaining: 3s Progress 4675 / 9694 Time remaining: 3s Progress 4676 / 9694 Time remaining: 3s Progress 4677 / 9694 Time remaining: 3s Progress 4678 / 9694 Time remaining: 3s Progress 4679 / 9694 Time remaining: 3s Progress 4680 / 9694 Time remaining: 3s Progress 4681 / 9694 Time remaining: 3s Progress 4682 / 9694 Time remaining: 3s Progress 4683 / 9694 Time remaining: 3s Progress 4684 / 9694 Time remaining: 3s Progress 4685 / 9694 Time remaining: 3s Progress 4686 / 9694 Time remaining: 3s Progress 4687 / 9694 Time remaining: 3s Progress 4688 / 9694 Time remaining: 3s Progress 4689 / 9694 Time remaining: 3s Progress 4690 / 9694 Time remaining: 3s Progress 4691 / 9694 Time remaining: 3s Progress 4692 / 9694 Time remaining: 3s Progress 4693 / 9694 Time remaining: 3s Progress 4694 / 9694 Time remaining: 3s Progress 4695 / 9694 Time remaining: 3s Progress 4696 / 9694 Time remaining: 3s Progress 4697 / 9694 Time remaining: 3s Progress 4698 / 9694 Time remaining: 3s Progress 4699 / 9694 Time remaining: 3s Progress 4700 / 9694 Time remaining: 3s Progress 4701 / 9694 Time remaining: 3s Progress 4702 / 9694 Time remaining: 3s Progress 4703 / 9694 Time remaining: 3s Progress 4704 / 9694 Time remaining: 3s Progress 4705 / 9694 Time remaining: 3s Progress 4706 / 9694 Time remaining: 3s Progress 4707 / 9694 Time remaining: 3s Progress 4708 / 9694 Time remaining: 3s Progress 4709 / 9694 Time remaining: 3s Progress 4710 / 9694 Time remaining: 3s Progress 4711 / 9694 Time remaining: 3s Progress 4712 / 9694 Time remaining: 3s Progress 4713 / 9694 Time remaining: 3s Progress 4714 / 9694 Time remaining: 3s Progress 4715 / 9694 Time remaining: 3s Progress 4716 / 9694 Time remaining: 3s Progress 4717 / 9694 Time remaining: 3s Progress 4718 / 9694 Time remaining: 3s Progress 4719 / 9694 Time remaining: 3s Progress 4720 / 9694 Time remaining: 3s Progress 4721 / 9694 Time remaining: 3s Progress 4722 / 9694 Time remaining: 3s Progress 4723 / 9694 Time remaining: 3s Progress 4724 / 9694 Time remaining: 3s Progress 4725 / 9694 Time remaining: 3s Progress 4726 / 9694 Time remaining: 3s Progress 4727 / 9694 Time remaining: 3s Progress 4728 / 9694 Time remaining: 3s Progress 4729 / 9694 Time remaining: 3s Progress 4730 / 9694 Time remaining: 3s Progress 4731 / 9694 Time remaining: 3s Progress 4732 / 9694 Time remaining: 3s Progress 4733 / 9694 Time remaining: 3s Progress 4734 / 9694 Time remaining: 3s Progress 4735 / 9694 Time remaining: 3s Progress 4736 / 9694 Time remaining: 3s Progress 4737 / 9694 Time remaining: 3s Progress 4738 / 9694 Time remaining: 3s Progress 4739 / 9694 Time remaining: 3s Progress 4740 / 9694 Time remaining: 3s Progress 4741 / 9694 Time remaining: 3s Progress 4742 / 9694 Time remaining: 3s Progress 4743 / 9694 Time remaining: 3s Progress 4744 / 9694 Time remaining: 3s Progress 4745 / 9694 Time remaining: 3s Progress 4746 / 9694 Time remaining: 3s Progress 4747 / 9694 Time remaining: 3s Progress 4748 / 9694 Time remaining: 3s Progress 4749 / 9694 Time remaining: 3s Progress 4750 / 9694 Time remaining: 3s Progress 4751 / 9694 Time remaining: 3s Progress 4752 / 9694 Time remaining: 3s Progress 4753 / 9694 Time remaining: 3s Progress 4754 / 9694 Time remaining: 3s Progress 4755 / 9694 Time remaining: 3s Progress 4756 / 9694 Time remaining: 3s Progress 4757 / 9694 Time remaining: 3s Progress 4758 / 9694 Time remaining: 3s Progress 4759 / 9694 Time remaining: 3s Progress 4760 / 9694 Time remaining: 3s Progress 4761 / 9694 Time remaining: 3s Progress 4762 / 9694 Time remaining: 3s Progress 4763 / 9694 Time remaining: 3s Progress 4764 / 9694 Time remaining: 3s Progress 4765 / 9694 Time remaining: 3s Progress 4766 / 9694 Time remaining: 3s Progress 4767 / 9694 Time remaining: 3s Progress 4768 / 9694 Time remaining: 3s Progress 4769 / 9694 Time remaining: 3s Progress 4770 / 9694 Time remaining: 3s Progress 4771 / 9694 Time remaining: 3s Progress 4772 / 9694 Time remaining: 3s Progress 4773 / 9694 Time remaining: 3s Progress 4774 / 9694 Time remaining: 3s Progress 4775 / 9694 Time remaining: 3s Progress 4776 / 9694 Time remaining: 3s Progress 4777 / 9694 Time remaining: 3s Progress 4778 / 9694 Time remaining: 3s Progress 4779 / 9694 Time remaining: 3s Progress 4780 / 9694 Time remaining: 3s Progress 4781 / 9694 Time remaining: 3s Progress 4782 / 9694 Time remaining: 3s Progress 4783 / 9694 Time remaining: 3s Progress 4784 / 9694 Time remaining: 3s Progress 4785 / 9694 Time remaining: 3s Progress 4786 / 9694 Time remaining: 3s Progress 4787 / 9694 Time remaining: 3s Progress 4788 / 9694 Time remaining: 3s Progress 4789 / 9694 Time remaining: 3s Progress 4790 / 9694 Time remaining: 3s Progress 4791 / 9694 Time remaining: 3s Progress 4792 / 9694 Time remaining: 3s Progress 4793 / 9694 Time remaining: 3s Progress 4794 / 9694 Time remaining: 3s Progress 4795 / 9694 Time remaining: 3s Progress 4796 / 9694 Time remaining: 3s Progress 4797 / 9694 Time remaining: 3s Progress 4798 / 9694 Time remaining: 3s Progress 4799 / 9694 Time remaining: 3s Progress 4800 / 9694 Time remaining: 3s Progress 4801 / 9694 Time remaining: 3s Progress 4802 / 9694 Time remaining: 3s Progress 4803 / 9694 Time remaining: 3s Progress 4804 / 9694 Time remaining: 3s Progress 4805 / 9694 Time remaining: 3s Progress 4806 / 9694 Time remaining: 3s Progress 4807 / 9694 Time remaining: 3s Progress 4808 / 9694 Time remaining: 3s Progress 4809 / 9694 Time remaining: 3s Progress 4810 / 9694 Time remaining: 3s Progress 4811 / 9694 Time remaining: 3s Progress 4812 / 9694 Time remaining: 3s Progress 4813 / 9694 Time remaining: 3s Progress 4814 / 9694 Time remaining: 3s Progress 4815 / 9694 Time remaining: 3s Progress 4816 / 9694 Time remaining: 3s Progress 4817 / 9694 Time remaining: 3s Progress 4818 / 9694 Time remaining: 3s Progress 4819 / 9694 Time remaining: 3s Progress 4820 / 9694 Time remaining: 3s Progress 4821 / 9694 Time remaining: 3s Progress 4822 / 9694 Time remaining: 3s Progress 4823 / 9694 Time remaining: 3s Progress 4824 / 9694 Time remaining: 3s Progress 4825 / 9694 Time remaining: 3s Progress 4826 / 9694 Time remaining: 3s Progress 4827 / 9694 Time remaining: 3s Progress 4828 / 9694 Time remaining: 3s Progress 4829 / 9694 Time remaining: 3s Progress 4830 / 9694 Time remaining: 3s Progress 4831 / 9694 Time remaining: 3s Progress 4832 / 9694 Time remaining: 3s Progress 4833 / 9694 Time remaining: 3s Progress 4834 / 9694 Time remaining: 3s Progress 4835 / 9694 Time remaining: 3s Progress 4836 / 9694 Time remaining: 3s Progress 4837 / 9694 Time remaining: 3s Progress 4838 / 9694 Time remaining: 3s Progress 4839 / 9694 Time remaining: 3s Progress 4840 / 9694 Time remaining: 3s Progress 4841 / 9694 Time remaining: 3s Progress 4842 / 9694 Time remaining: 3s Progress 4843 / 9694 Time remaining: 3s Progress 4844 / 9694 Time remaining: 3s Progress 4845 / 9694 Time remaining: 3s Progress 4846 / 9694 Time remaining: 3s Progress 4847 / 9694 Time remaining: 3s Progress 4848 / 9694 Time remaining: 3s Progress 4849 / 9694 Time remaining: 3s Progress 4850 / 9694 Time remaining: 3s Progress 4851 / 9694 Time remaining: 3s Progress 4852 / 9694 Time remaining: 3s Progress 4853 / 9694 Time remaining: 3s Progress 4854 / 9694 Time remaining: 3s Progress 4855 / 9694 Time remaining: 3s Progress 4856 / 9694 Time remaining: 3s Progress 4857 / 9694 Time remaining: 3s Progress 4858 / 9694 Time remaining: 3s Progress 4859 / 9694 Time remaining: 3s Progress 4860 / 9694 Time remaining: 3s Progress 4861 / 9694 Time remaining: 3s Progress 4862 / 9694 Time remaining: 3s Progress 4863 / 9694 Time remaining: 3s Progress 4864 / 9694 Time remaining: 3s Progress 4865 / 9694 Time remaining: 3s Progress 4866 / 9694 Time remaining: 3s Progress 4867 / 9694 Time remaining: 3s Progress 4868 / 9694 Time remaining: 3s Progress 4869 / 9694 Time remaining: 3s Progress 4870 / 9694 Time remaining: 3s Progress 4871 / 9694 Time remaining: 3s Progress 4872 / 9694 Time remaining: 3s Progress 4873 / 9694 Time remaining: 3s Progress 4874 / 9694 Time remaining: 3s Progress 4875 / 9694 Time remaining: 3s Progress 4876 / 9694 Time remaining: 3s Progress 4877 / 9694 Time remaining: 3s Progress 4878 / 9694 Time remaining: 3s Progress 4879 / 9694 Time remaining: 3s Progress 4880 / 9694 Time remaining: 3s Progress 4881 / 9694 Time remaining: 3s Progress 4882 / 9694 Time remaining: 3s Progress 4883 / 9694 Time remaining: 3s Progress 4884 / 9694 Time remaining: 3s Progress 4885 / 9694 Time remaining: 3s Progress 4886 / 9694 Time remaining: 3s Progress 4887 / 9694 Time remaining: 3s Progress 4888 / 9694 Time remaining: 3s Progress 4889 / 9694 Time remaining: 3s Progress 4890 / 9694 Time remaining: 3s Progress 4891 / 9694 Time remaining: 3s Progress 4892 / 9694 Time remaining: 3s Progress 4893 / 9694 Time remaining: 3s Progress 4894 / 9694 Time remaining: 3s Progress 4895 / 9694 Time remaining: 3s Progress 4896 / 9694 Time remaining: 3s Progress 4897 / 9694 Time remaining: 3s Progress 4898 / 9694 Time remaining: 3s Progress 4899 / 9694 Time remaining: 3s Progress 4900 / 9694 Time remaining: 3s Progress 4901 / 9694 Time remaining: 3s Progress 4902 / 9694 Time remaining: 3s Progress 4903 / 9694 Time remaining: 3s Progress 4904 / 9694 Time remaining: 3s Progress 4905 / 9694 Time remaining: 3s Progress 4906 / 9694 Time remaining: 3s Progress 4907 / 9694 Time remaining: 3s Progress 4908 / 9694 Time remaining: 3s Progress 4909 / 9694 Time remaining: 3s Progress 4910 / 9694 Time remaining: 3s Progress 4911 / 9694 Time remaining: 3s Progress 4912 / 9694 Time remaining: 3s Progress 4913 / 9694 Time remaining: 3s Progress 4914 / 9694 Time remaining: 3s Progress 4915 / 9694 Time remaining: 3s Progress 4916 / 9694 Time remaining: 3s Progress 4917 / 9694 Time remaining: 3s Progress 4918 / 9694 Time remaining: 3s Progress 4919 / 9694 Time remaining: 3s Progress 4920 / 9694 Time remaining: 3s Progress 4921 / 9694 Time remaining: 3s Progress 4922 / 9694 Time remaining: 3s Progress 4923 / 9694 Time remaining: 3s Progress 4924 / 9694 Time remaining: 3s Progress 4925 / 9694 Time remaining: 3s Progress 4926 / 9694 Time remaining: 3s Progress 4927 / 9694 Time remaining: 3s Progress 4928 / 9694 Time remaining: 3s Progress 4929 / 9694 Time remaining: 3s Progress 4930 / 9694 Time remaining: 3s Progress 4931 / 9694 Time remaining: 3s Progress 4932 / 9694 Time remaining: 3s Progress 4933 / 9694 Time remaining: 3s Progress 4934 / 9694 Time remaining: 3s Progress 4935 / 9694 Time remaining: 3s Progress 4936 / 9694 Time remaining: 3s Progress 4937 / 9694 Time remaining: 3s Progress 4938 / 9694 Time remaining: 3s Progress 4939 / 9694 Time remaining: 3s Progress 4940 / 9694 Time remaining: 3s Progress 4941 / 9694 Time remaining: 3s Progress 4942 / 9694 Time remaining: 3s Progress 4943 / 9694 Time remaining: 3s Progress 4944 / 9694 Time remaining: 3s Progress 4945 / 9694 Time remaining: 3s Progress 4946 / 9694 Time remaining: 3s Progress 4947 / 9694 Time remaining: 3s Progress 4948 / 9694 Time remaining: 3s Progress 4949 / 9694 Time remaining: 3s Progress 4950 / 9694 Time remaining: 3s Progress 4951 / 9694 Time remaining: 3s Progress 4952 / 9694 Time remaining: 3s Progress 4953 / 9694 Time remaining: 3s Progress 4954 / 9694 Time remaining: 3s Progress 4955 / 9694 Time remaining: 3s Progress 4956 / 9694 Time remaining: 3s Progress 4957 / 9694 Time remaining: 3s Progress 4958 / 9694 Time remaining: 3s Progress 4959 / 9694 Time remaining: 3s Progress 4960 / 9694 Time remaining: 3s Progress 4961 / 9694 Time remaining: 3s Progress 4962 / 9694 Time remaining: 3s Progress 4963 / 9694 Time remaining: 3s Progress 4964 / 9694 Time remaining: 3s Progress 4965 / 9694 Time remaining: 3s Progress 4966 / 9694 Time remaining: 3s Progress 4967 / 9694 Time remaining: 3s Progress 4968 / 9694 Time remaining: 3s Progress 4969 / 9694 Time remaining: 3s Progress 4970 / 9694 Time remaining: 3s Progress 4971 / 9694 Time remaining: 3s Progress 4972 / 9694 Time remaining: 3s Progress 4973 / 9694 Time remaining: 3s Progress 4974 / 9694 Time remaining: 3s Progress 4975 / 9694 Time remaining: 3s Progress 4976 / 9694 Time remaining: 3s Progress 4977 / 9694 Time remaining: 3s Progress 4978 / 9694 Time remaining: 3s Progress 4979 / 9694 Time remaining: 3s Progress 4980 / 9694 Time remaining: 3s Progress 4981 / 9694 Time remaining: 3s Progress 4982 / 9694 Time remaining: 3s Progress 4983 / 9694 Time remaining: 3s Progress 4984 / 9694 Time remaining: 3s Progress 4985 / 9694 Time remaining: 3s Progress 4986 / 9694 Time remaining: 3s Progress 4987 / 9694 Time remaining: 3s Progress 4988 / 9694 Time remaining: 3s Progress 4989 / 9694 Time remaining: 3s Progress 4990 / 9694 Time remaining: 3s Progress 4991 / 9694 Time remaining: 3s Progress 4992 / 9694 Time remaining: 3s Progress 4993 / 9694 Time remaining: 3s Progress 4994 / 9694 Time remaining: 3s Progress 4995 / 9694 Time remaining: 3s Progress 4996 / 9694 Time remaining: 3s Progress 4997 / 9694 Time remaining: 3s Progress 4998 / 9694 Time remaining: 3s Progress 4999 / 9694 Time remaining: 3s Progress 5000 / 9694 Time remaining: 3s Progress 5001 / 9694 Time remaining: 3s Progress 5002 / 9694 Time remaining: 3s Progress 5003 / 9694 Time remaining: 3s Progress 5004 / 9694 Time remaining: 3s Progress 5005 / 9694 Time remaining: 3s Progress 5006 / 9694 Time remaining: 3s Progress 5007 / 9694 Time remaining: 3s Progress 5008 / 9694 Time remaining: 3s Progress 5009 / 9694 Time remaining: 3s Progress 5010 / 9694 Time remaining: 3s Progress 5011 / 9694 Time remaining: 3s Progress 5012 / 9694 Time remaining: 3s Progress 5013 / 9694 Time remaining: 3s Progress 5014 / 9694 Time remaining: 3s Progress 5015 / 9694 Time remaining: 3s Progress 5016 / 9694 Time remaining: 3s Progress 5017 / 9694 Time remaining: 3s Progress 5018 / 9694 Time remaining: 3s Progress 5019 / 9694 Time remaining: 3s Progress 5020 / 9694 Time remaining: 3s Progress 5021 / 9694 Time remaining: 3s Progress 5022 / 9694 Time remaining: 3s Progress 5023 / 9694 Time remaining: 3s Progress 5024 / 9694 Time remaining: 3s Progress 5025 / 9694 Time remaining: 3s Progress 5026 / 9694 Time remaining: 3s Progress 5027 / 9694 Time remaining: 3s Progress 5028 / 9694 Time remaining: 3s Progress 5029 / 9694 Time remaining: 3s Progress 5030 / 9694 Time remaining: 3s Progress 5031 / 9694 Time remaining: 3s Progress 5032 / 9694 Time remaining: 3s Progress 5033 / 9694 Time remaining: 3s Progress 5034 / 9694 Time remaining: 3s Progress 5035 / 9694 Time remaining: 3s Progress 5036 / 9694 Time remaining: 3s Progress 5037 / 9694 Time remaining: 3s Progress 5038 / 9694 Time remaining: 3s Progress 5039 / 9694 Time remaining: 3s Progress 5040 / 9694 Time remaining: 3s Progress 5041 / 9694 Time remaining: 3s Progress 5042 / 9694 Time remaining: 3s Progress 5043 / 9694 Time remaining: 3s Progress 5044 / 9694 Time remaining: 3s Progress 5045 / 9694 Time remaining: 3s Progress 5046 / 9694 Time remaining: 3s Progress 5047 / 9694 Time remaining: 3s Progress 5048 / 9694 Time remaining: 3s Progress 5049 / 9694 Time remaining: 3s Progress 5050 / 9694 Time remaining: 3s Progress 5051 / 9694 Time remaining: 3s Progress 5052 / 9694 Time remaining: 3s Progress 5053 / 9694 Time remaining: 3s Progress 5054 / 9694 Time remaining: 3s Progress 5055 / 9694 Time remaining: 3s Progress 5056 / 9694 Time remaining: 3s Progress 5057 / 9694 Time remaining: 3s Progress 5058 / 9694 Time remaining: 3s Progress 5059 / 9694 Time remaining: 3s Progress 5060 / 9694 Time remaining: 3s Progress 5061 / 9694 Time remaining: 3s Progress 5062 / 9694 Time remaining: 3s Progress 5063 / 9694 Time remaining: 3s Progress 5064 / 9694 Time remaining: 3s Progress 5065 / 9694 Time remaining: 3s Progress 5066 / 9694 Time remaining: 3s Progress 5067 / 9694 Time remaining: 3s Progress 5068 / 9694 Time remaining: 3s Progress 5069 / 9694 Time remaining: 3s Progress 5070 / 9694 Time remaining: 3s Progress 5071 / 9694 Time remaining: 3s Progress 5072 / 9694 Time remaining: 3s Progress 5073 / 9694 Time remaining: 3s Progress 5074 / 9694 Time remaining: 3s Progress 5075 / 9694 Time remaining: 3s Progress 5076 / 9694 Time remaining: 3s Progress 5077 / 9694 Time remaining: 3s Progress 5078 / 9694 Time remaining: 3s Progress 5079 / 9694 Time remaining: 3s Progress 5080 / 9694 Time remaining: 3s Progress 5081 / 9694 Time remaining: 3s Progress 5082 / 9694 Time remaining: 3s Progress 5083 / 9694 Time remaining: 3s Progress 5084 / 9694 Time remaining: 3s Progress 5085 / 9694 Time remaining: 3s Progress 5086 / 9694 Time remaining: 3s Progress 5087 / 9694 Time remaining: 3s Progress 5088 / 9694 Time remaining: 3s Progress 5089 / 9694 Time remaining: 3s Progress 5090 / 9694 Time remaining: 3s Progress 5091 / 9694 Time remaining: 3s Progress 5092 / 9694 Time remaining: 3s Progress 5093 / 9694 Time remaining: 3s Progress 5094 / 9694 Time remaining: 3s Progress 5095 / 9694 Time remaining: 3s Progress 5096 / 9694 Time remaining: 3s Progress 5097 / 9694 Time remaining: 3s Progress 5098 / 9694 Time remaining: 3s Progress 5099 / 9694 Time remaining: 3s Progress 5100 / 9694 Time remaining: 3s Progress 5101 / 9694 Time remaining: 3s Progress 5102 / 9694 Time remaining: 3s Progress 5103 / 9694 Time remaining: 3s Progress 5104 / 9694 Time remaining: 3s Progress 5105 / 9694 Time remaining: 3s Progress 5106 / 9694 Time remaining: 3s Progress 5107 / 9694 Time remaining: 3s Progress 5108 / 9694 Time remaining: 3s Progress 5109 / 9694 Time remaining: 3s Progress 5110 / 9694 Time remaining: 3s Progress 5111 / 9694 Time remaining: 3s Progress 5112 / 9694 Time remaining: 3s Progress 5113 / 9694 Time remaining: 3s Progress 5114 / 9694 Time remaining: 3s Progress 5115 / 9694 Time remaining: 3s Progress 5116 / 9694 Time remaining: 3s Progress 5117 / 9694 Time remaining: 3s Progress 5118 / 9694 Time remaining: 3s Progress 5119 / 9694 Time remaining: 3s Progress 5120 / 9694 Time remaining: 3s Progress 5121 / 9694 Time remaining: 3s Progress 5122 / 9694 Time remaining: 3s Progress 5123 / 9694 Time remaining: 3s Progress 5124 / 9694 Time remaining: 3s Progress 5125 / 9694 Time remaining: 3s Progress 5126 / 9694 Time remaining: 3s Progress 5127 / 9694 Time remaining: 3s Progress 5128 / 9694 Time remaining: 3s Progress 5129 / 9694 Time remaining: 3s Progress 5130 / 9694 Time remaining: 3s Progress 5131 / 9694 Time remaining: 3s Progress 5132 / 9694 Time remaining: 3s Progress 5133 / 9694 Time remaining: 3s Progress 5134 / 9694 Time remaining: 3s Progress 5135 / 9694 Time remaining: 3s Progress 5136 / 9694 Time remaining: 3s Progress 5137 / 9694 Time remaining: 3s Progress 5138 / 9694 Time remaining: 3s Progress 5139 / 9694 Time remaining: 3s Progress 5140 / 9694 Time remaining: 3s Progress 5141 / 9694 Time remaining: 3s Progress 5142 / 9694 Time remaining: 3s Progress 5143 / 9694 Time remaining: 3s Progress 5144 / 9694 Time remaining: 3s Progress 5145 / 9694 Time remaining: 3s Progress 5146 / 9694 Time remaining: 3s Progress 5147 / 9694 Time remaining: 3s Progress 5148 / 9694 Time remaining: 3s Progress 5149 / 9694 Time remaining: 3s Progress 5150 / 9694 Time remaining: 3s Progress 5151 / 9694 Time remaining: 3s Progress 5152 / 9694 Time remaining: 3s Progress 5153 / 9694 Time remaining: 3s Progress 5154 / 9694 Time remaining: 3s Progress 5155 / 9694 Time remaining: 3s Progress 5156 / 9694 Time remaining: 3s Progress 5157 / 9694 Time remaining: 3s Progress 5158 / 9694 Time remaining: 3s Progress 5159 / 9694 Time remaining: 3s Progress 5160 / 9694 Time remaining: 3s Progress 5161 / 9694 Time remaining: 3s Progress 5162 / 9694 Time remaining: 3s Progress 5163 / 9694 Time remaining: 3s Progress 5164 / 9694 Time remaining: 3s Progress 5165 / 9694 Time remaining: 3s Progress 5166 / 9694 Time remaining: 3s Progress 5167 / 9694 Time remaining: 3s Progress 5168 / 9694 Time remaining: 3s Progress 5169 / 9694 Time remaining: 3s Progress 5170 / 9694 Time remaining: 3s Progress 5171 / 9694 Time remaining: 3s Progress 5172 / 9694 Time remaining: 3s Progress 5173 / 9694 Time remaining: 3s Progress 5174 / 9694 Time remaining: 3s Progress 5175 / 9694 Time remaining: 3s Progress 5176 / 9694 Time remaining: 3s Progress 5177 / 9694 Time remaining: 3s Progress 5178 / 9694 Time remaining: 3s Progress 5179 / 9694 Time remaining: 3s Progress 5180 / 9694 Time remaining: 3s Progress 5181 / 9694 Time remaining: 3s Progress 5182 / 9694 Time remaining: 3s Progress 5183 / 9694 Time remaining: 3s Progress 5184 / 9694 Time remaining: 3s Progress 5185 / 9694 Time remaining: 3s Progress 5186 / 9694 Time remaining: 3s Progress 5187 / 9694 Time remaining: 3s Progress 5188 / 9694 Time remaining: 3s Progress 5189 / 9694 Time remaining: 3s Progress 5190 / 9694 Time remaining: 3s Progress 5191 / 9694 Time remaining: 3s Progress 5192 / 9694 Time remaining: 3s Progress 5193 / 9694 Time remaining: 3s Progress 5194 / 9694 Time remaining: 3s Progress 5195 / 9694 Time remaining: 3s Progress 5196 / 9694 Time remaining: 3s Progress 5197 / 9694 Time remaining: 3s Progress 5198 / 9694 Time remaining: 3s Progress 5199 / 9694 Time remaining: 3s Progress 5200 / 9694 Time remaining: 3s Progress 5201 / 9694 Time remaining: 3s Progress 5202 / 9694 Time remaining: 3s Progress 5203 / 9694 Time remaining: 3s Progress 5204 / 9694 Time remaining: 3s Progress 5205 / 9694 Time remaining: 3s Progress 5206 / 9694 Time remaining: 3s Progress 5207 / 9694 Time remaining: 3s Progress 5208 / 9694 Time remaining: 3s Progress 5209 / 9694 Time remaining: 3s Progress 5210 / 9694 Time remaining: 3s Progress 5211 / 9694 Time remaining: 3s Progress 5212 / 9694 Time remaining: 3s Progress 5213 / 9694 Time remaining: 3s Progress 5214 / 9694 Time remaining: 3s Progress 5215 / 9694 Time remaining: 3s Progress 5216 / 9694 Time remaining: 3s Progress 5217 / 9694 Time remaining: 3s Progress 5218 / 9694 Time remaining: 3s Progress 5219 / 9694 Time remaining: 3s Progress 5220 / 9694 Time remaining: 3s Progress 5221 / 9694 Time remaining: 3s Progress 5222 / 9694 Time remaining: 3s Progress 5223 / 9694 Time remaining: 3s Progress 5224 / 9694 Time remaining: 3s Progress 5225 / 9694 Time remaining: 3s Progress 5226 / 9694 Time remaining: 3s Progress 5227 / 9694 Time remaining: 3s Progress 5228 / 9694 Time remaining: 3s Progress 5229 / 9694 Time remaining: 3s Progress 5230 / 9694 Time remaining: 3s Progress 5231 / 9694 Time remaining: 3s Progress 5232 / 9694 Time remaining: 3s Progress 5233 / 9694 Time remaining: 3s Progress 5234 / 9694 Time remaining: 3s Progress 5235 / 9694 Time remaining: 3s Progress 5236 / 9694 Time remaining: 3s Progress 5237 / 9694 Time remaining: 3s Progress 5238 / 9694 Time remaining: 3s Progress 5239 / 9694 Time remaining: 3s Progress 5240 / 9694 Time remaining: 3s Progress 5241 / 9694 Time remaining: 3s Progress 5242 / 9694 Time remaining: 3s Progress 5243 / 9694 Time remaining: 3s Progress 5244 / 9694 Time remaining: 3s Progress 5245 / 9694 Time remaining: 3s Progress 5246 / 9694 Time remaining: 3s Progress 5247 / 9694 Time remaining: 3s Progress 5248 / 9694 Time remaining: 3s Progress 5249 / 9694 Time remaining: 3s Progress 5250 / 9694 Time remaining: 3s Progress 5251 / 9694 Time remaining: 3s Progress 5252 / 9694 Time remaining: 3s Progress 5253 / 9694 Time remaining: 3s Progress 5254 / 9694 Time remaining: 3s Progress 5255 / 9694 Time remaining: 3s Progress 5256 / 9694 Time remaining: 3s Progress 5257 / 9694 Time remaining: 3s Progress 5258 / 9694 Time remaining: 3s Progress 5259 / 9694 Time remaining: 3s Progress 5260 / 9694 Time remaining: 3s Progress 5261 / 9694 Time remaining: 3s Progress 5262 / 9694 Time remaining: 3s Progress 5263 / 9694 Time remaining: 3s Progress 5264 / 9694 Time remaining: 3s Progress 5265 / 9694 Time remaining: 3s Progress 5266 / 9694 Time remaining: 3s Progress 5267 / 9694 Time remaining: 3s Progress 5268 / 9694 Time remaining: 3s Progress 5269 / 9694 Time remaining: 3s Progress 5270 / 9694 Time remaining: 3s Progress 5271 / 9694 Time remaining: 3s Progress 5272 / 9694 Time remaining: 3s Progress 5273 / 9694 Time remaining: 3s Progress 5274 / 9694 Time remaining: 3s Progress 5275 / 9694 Time remaining: 3s Progress 5276 / 9694 Time remaining: 3s Progress 5277 / 9694 Time remaining: 3s Progress 5278 / 9694 Time remaining: 3s Progress 5279 / 9694 Time remaining: 3s Progress 5280 / 9694 Time remaining: 3s Progress 5281 / 9694 Time remaining: 3s Progress 5282 / 9694 Time remaining: 3s Progress 5283 / 9694 Time remaining: 3s Progress 5284 / 9694 Time remaining: 3s Progress 5285 / 9694 Time remaining: 3s Progress 5286 / 9694 Time remaining: 3s Progress 5287 / 9694 Time remaining: 3s Progress 5288 / 9694 Time remaining: 3s Progress 5289 / 9694 Time remaining: 3s Progress 5290 / 9694 Time remaining: 3s Progress 5291 / 9694 Time remaining: 3s Progress 5292 / 9694 Time remaining: 3s Progress 5293 / 9694 Time remaining: 3s Progress 5294 / 9694 Time remaining: 3s Progress 5295 / 9694 Time remaining: 3s Progress 5296 / 9694 Time remaining: 3s Progress 5297 / 9694 Time remaining: 3s Progress 5298 / 9694 Time remaining: 3s Progress 5299 / 9694 Time remaining: 3s Progress 5300 / 9694 Time remaining: 3s Progress 5301 / 9694 Time remaining: 3s Progress 5302 / 9694 Time remaining: 3s Progress 5303 / 9694 Time remaining: 3s Progress 5304 / 9694 Time remaining: 3s Progress 5305 / 9694 Time remaining: 3s Progress 5306 / 9694 Time remaining: 3s Progress 5307 / 9694 Time remaining: 3s Progress 5308 / 9694 Time remaining: 3s Progress 5309 / 9694 Time remaining: 3s Progress 5310 / 9694 Time remaining: 3s Progress 5311 / 9694 Time remaining: 3s Progress 5312 / 9694 Time remaining: 3s Progress 5313 / 9694 Time remaining: 3s Progress 5314 / 9694 Time remaining: 3s Progress 5315 / 9694 Time remaining: 3s Progress 5316 / 9694 Time remaining: 3s Progress 5317 / 9694 Time remaining: 3s Progress 5318 / 9694 Time remaining: 3s Progress 5319 / 9694 Time remaining: 3s Progress 5320 / 9694 Time remaining: 3s Progress 5321 / 9694 Time remaining: 3s Progress 5322 / 9694 Time remaining: 3s Progress 5323 / 9694 Time remaining: 3s Progress 5324 / 9694 Time remaining: 3s Progress 5325 / 9694 Time remaining: 3s Progress 5326 / 9694 Time remaining: 3s Progress 5327 / 9694 Time remaining: 3s Progress 5328 / 9694 Time remaining: 3s Progress 5329 / 9694 Time remaining: 3s Progress 5330 / 9694 Time remaining: 3s Progress 5331 / 9694 Time remaining: 3s Progress 5332 / 9694 Time remaining: 3s Progress 5333 / 9694 Time remaining: 3s Progress 5334 / 9694 Time remaining: 3s Progress 5335 / 9694 Time remaining: 3s Progress 5336 / 9694 Time remaining: 3s Progress 5337 / 9694 Time remaining: 3s Progress 5338 / 9694 Time remaining: 3s Progress 5339 / 9694 Time remaining: 3s Progress 5340 / 9694 Time remaining: 3s Progress 5341 / 9694 Time remaining: 3s Progress 5342 / 9694 Time remaining: 3s Progress 5343 / 9694 Time remaining: 3s Progress 5344 / 9694 Time remaining: 3s Progress 5345 / 9694 Time remaining: 3s Progress 5346 / 9694 Time remaining: 3s Progress 5347 / 9694 Time remaining: 3s Progress 5348 / 9694 Time remaining: 3s Progress 5349 / 9694 Time remaining: 3s Progress 5350 / 9694 Time remaining: 3s Progress 5351 / 9694 Time remaining: 3s Progress 5352 / 9694 Time remaining: 3s Progress 5353 / 9694 Time remaining: 3s Progress 5354 / 9694 Time remaining: 3s Progress 5355 / 9694 Time remaining: 3s Progress 5356 / 9694 Time remaining: 3s Progress 5357 / 9694 Time remaining: 3s Progress 5358 / 9694 Time remaining: 3s Progress 5359 / 9694 Time remaining: 3s Progress 5360 / 9694 Time remaining: 3s Progress 5361 / 9694 Time remaining: 3s Progress 5362 / 9694 Time remaining: 3s Progress 5363 / 9694 Time remaining: 3s Progress 5364 / 9694 Time remaining: 3s Progress 5365 / 9694 Time remaining: 3s Progress 5366 / 9694 Time remaining: 3s Progress 5367 / 9694 Time remaining: 3s Progress 5368 / 9694 Time remaining: 3s Progress 5369 / 9694 Time remaining: 3s Progress 5370 / 9694 Time remaining: 3s Progress 5371 / 9694 Time remaining: 3s Progress 5372 / 9694 Time remaining: 3s Progress 5373 / 9694 Time remaining: 3s Progress 5374 / 9694 Time remaining: 3s Progress 5375 / 9694 Time remaining: 3s Progress 5376 / 9694 Time remaining: 3s Progress 5377 / 9694 Time remaining: 3s Progress 5378 / 9694 Time remaining: 3s Progress 5379 / 9694 Time remaining: 3s Progress 5380 / 9694 Time remaining: 3s Progress 5381 / 9694 Time remaining: 3s Progress 5382 / 9694 Time remaining: 3s Progress 5383 / 9694 Time remaining: 3s Progress 5384 / 9694 Time remaining: 3s Progress 5385 / 9694 Time remaining: 3s Progress 5386 / 9694 Time remaining: 3s Progress 5387 / 9694 Time remaining: 3s Progress 5388 / 9694 Time remaining: 3s Progress 5389 / 9694 Time remaining: 3s Progress 5390 / 9694 Time remaining: 3s Progress 5391 / 9694 Time remaining: 3s Progress 5392 / 9694 Time remaining: 3s Progress 5393 / 9694 Time remaining: 3s Progress 5394 / 9694 Time remaining: 3s Progress 5395 / 9694 Time remaining: 3s Progress 5396 / 9694 Time remaining: 3s Progress 5397 / 9694 Time remaining: 3s Progress 5398 / 9694 Time remaining: 3s Progress 5399 / 9694 Time remaining: 3s Progress 5400 / 9694 Time remaining: 3s Progress 5401 / 9694 Time remaining: 3s Progress 5402 / 9694 Time remaining: 3s Progress 5403 / 9694 Time remaining: 3s Progress 5404 / 9694 Time remaining: 3s Progress 5405 / 9694 Time remaining: 3s Progress 5406 / 9694 Time remaining: 3s Progress 5407 / 9694 Time remaining: 3s Progress 5408 / 9694 Time remaining: 3s Progress 5409 / 9694 Time remaining: 3s Progress 5410 / 9694 Time remaining: 3s Progress 5411 / 9694 Time remaining: 3s Progress 5412 / 9694 Time remaining: 3s Progress 5413 / 9694 Time remaining: 3s Progress 5414 / 9694 Time remaining: 3s Progress 5415 / 9694 Time remaining: 3s Progress 5416 / 9694 Time remaining: 3s Progress 5417 / 9694 Time remaining: 3s Progress 5418 / 9694 Time remaining: 3s Progress 5419 / 9694 Time remaining: 3s Progress 5420 / 9694 Time remaining: 3s Progress 5421 / 9694 Time remaining: 3s Progress 5422 / 9694 Time remaining: 3s Progress 5423 / 9694 Time remaining: 3s Progress 5424 / 9694 Time remaining: 3s Progress 5425 / 9694 Time remaining: 3s Progress 5426 / 9694 Time remaining: 3s Progress 5427 / 9694 Time remaining: 3s Progress 5428 / 9694 Time remaining: 3s Progress 5429 / 9694 Time remaining: 3s Progress 5430 / 9694 Time remaining: 3s Progress 5431 / 9694 Time remaining: 3s Progress 5432 / 9694 Time remaining: 3s Progress 5433 / 9694 Time remaining: 3s Progress 5434 / 9694 Time remaining: 3s Progress 5435 / 9694 Time remaining: 3s Progress 5436 / 9694 Time remaining: 3s Progress 5437 / 9694 Time remaining: 3s Progress 5438 / 9694 Time remaining: 3s Progress 5439 / 9694 Time remaining: 3s Progress 5440 / 9694 Time remaining: 3s Progress 5441 / 9694 Time remaining: 3s Progress 5442 / 9694 Time remaining: 3s Progress 5443 / 9694 Time remaining: 3s Progress 5444 / 9694 Time remaining: 3s Progress 5445 / 9694 Time remaining: 3s Progress 5446 / 9694 Time remaining: 3s Progress 5447 / 9694 Time remaining: 3s Progress 5448 / 9694 Time remaining: 3s Progress 5449 / 9694 Time remaining: 3s Progress 5450 / 9694 Time remaining: 3s Progress 5451 / 9694 Time remaining: 3s Progress 5452 / 9694 Time remaining: 3s Progress 5453 / 9694 Time remaining: 3s Progress 5454 / 9694 Time remaining: 3s Progress 5455 / 9694 Time remaining: 3s Progress 5456 / 9694 Time remaining: 3s Progress 5457 / 9694 Time remaining: 3s Progress 5458 / 9694 Time remaining: 3s Progress 5459 / 9694 Time remaining: 3s Progress 5460 / 9694 Time remaining: 3s Progress 5461 / 9694 Time remaining: 3s Progress 5462 / 9694 Time remaining: 3s Progress 5463 / 9694 Time remaining: 3s Progress 5464 / 9694 Time remaining: 3s Progress 5465 / 9694 Time remaining: 3s Progress 5466 / 9694 Time remaining: 3s Progress 5467 / 9694 Time remaining: 3s Progress 5468 / 9694 Time remaining: 3s Progress 5469 / 9694 Time remaining: 3s Progress 5470 / 9694 Time remaining: 3s Progress 5471 / 9694 Time remaining: 3s Progress 5472 / 9694 Time remaining: 3s Progress 5473 / 9694 Time remaining: 3s Progress 5474 / 9694 Time remaining: 3s Progress 5475 / 9694 Time remaining: 3s Progress 5476 / 9694 Time remaining: 3s Progress 5477 / 9694 Time remaining: 3s Progress 5478 / 9694 Time remaining: 3s Progress 5479 / 9694 Time remaining: 3s Progress 5480 / 9694 Time remaining: 3s Progress 5481 / 9694 Time remaining: 3s Progress 5482 / 9694 Time remaining: 3s Progress 5483 / 9694 Time remaining: 3s Progress 5484 / 9694 Time remaining: 3s Progress 5485 / 9694 Time remaining: 3s Progress 5486 / 9694 Time remaining: 2s Progress 5487 / 9694 Time remaining: 2s Progress 5488 / 9694 Time remaining: 2s Progress 5489 / 9694 Time remaining: 2s Progress 5490 / 9694 Time remaining: 2s Progress 5491 / 9694 Time remaining: 2s Progress 5492 / 9694 Time remaining: 2s Progress 5493 / 9694 Time remaining: 2s Progress 5494 / 9694 Time remaining: 2s Progress 5495 / 9694 Time remaining: 2s Progress 5496 / 9694 Time remaining: 2s Progress 5497 / 9694 Time remaining: 2s Progress 5498 / 9694 Time remaining: 2s Progress 5499 / 9694 Time remaining: 2s Progress 5500 / 9694 Time remaining: 2s Progress 5501 / 9694 Time remaining: 2s Progress 5502 / 9694 Time remaining: 2s Progress 5503 / 9694 Time remaining: 2s Progress 5504 / 9694 Time remaining: 2s Progress 5505 / 9694 Time remaining: 2s Progress 5506 / 9694 Time remaining: 2s Progress 5507 / 9694 Time remaining: 2s Progress 5508 / 9694 Time remaining: 2s Progress 5509 / 9694 Time remaining: 2s Progress 5510 / 9694 Time remaining: 2s Progress 5511 / 9694 Time remaining: 2s Progress 5512 / 9694 Time remaining: 2s Progress 5513 / 9694 Time remaining: 2s Progress 5514 / 9694 Time remaining: 2s Progress 5515 / 9694 Time remaining: 2s Progress 5516 / 9694 Time remaining: 2s Progress 5517 / 9694 Time remaining: 2s Progress 5518 / 9694 Time remaining: 2s Progress 5519 / 9694 Time remaining: 2s Progress 5520 / 9694 Time remaining: 2s Progress 5521 / 9694 Time remaining: 2s Progress 5522 / 9694 Time remaining: 2s Progress 5523 / 9694 Time remaining: 2s Progress 5524 / 9694 Time remaining: 2s Progress 5525 / 9694 Time remaining: 2s Progress 5526 / 9694 Time remaining: 2s Progress 5527 / 9694 Time remaining: 2s Progress 5528 / 9694 Time remaining: 2s Progress 5529 / 9694 Time remaining: 2s Progress 5530 / 9694 Time remaining: 2s Progress 5531 / 9694 Time remaining: 2s Progress 5532 / 9694 Time remaining: 2s Progress 5533 / 9694 Time remaining: 2s Progress 5534 / 9694 Time remaining: 2s Progress 5535 / 9694 Time remaining: 2s Progress 5536 / 9694 Time remaining: 2s Progress 5537 / 9694 Time remaining: 2s Progress 5538 / 9694 Time remaining: 2s Progress 5539 / 9694 Time remaining: 2s Progress 5540 / 9694 Time remaining: 2s Progress 5541 / 9694 Time remaining: 2s Progress 5542 / 9694 Time remaining: 2s Progress 5543 / 9694 Time remaining: 2s Progress 5544 / 9694 Time remaining: 2s Progress 5545 / 9694 Time remaining: 2s Progress 5546 / 9694 Time remaining: 2s Progress 5547 / 9694 Time remaining: 2s Progress 5548 / 9694 Time remaining: 2s Progress 5549 / 9694 Time remaining: 2s Progress 5550 / 9694 Time remaining: 2s Progress 5551 / 9694 Time remaining: 2s Progress 5552 / 9694 Time remaining: 2s Progress 5553 / 9694 Time remaining: 2s Progress 5554 / 9694 Time remaining: 2s Progress 5555 / 9694 Time remaining: 2s Progress 5556 / 9694 Time remaining: 2s Progress 5557 / 9694 Time remaining: 2s Progress 5558 / 9694 Time remaining: 2s Progress 5559 / 9694 Time remaining: 2s Progress 5560 / 9694 Time remaining: 2s Progress 5561 / 9694 Time remaining: 2s Progress 5562 / 9694 Time remaining: 2s Progress 5563 / 9694 Time remaining: 2s Progress 5564 / 9694 Time remaining: 2s Progress 5565 / 9694 Time remaining: 2s Progress 5566 / 9694 Time remaining: 2s Progress 5567 / 9694 Time remaining: 2s Progress 5568 / 9694 Time remaining: 2s Progress 5569 / 9694 Time remaining: 2s Progress 5570 / 9694 Time remaining: 2s Progress 5571 / 9694 Time remaining: 2s Progress 5572 / 9694 Time remaining: 2s Progress 5573 / 9694 Time remaining: 2s Progress 5574 / 9694 Time remaining: 2s Progress 5575 / 9694 Time remaining: 2s Progress 5576 / 9694 Time remaining: 2s Progress 5577 / 9694 Time remaining: 2s Progress 5578 / 9694 Time remaining: 2s Progress 5579 / 9694 Time remaining: 2s Progress 5580 / 9694 Time remaining: 2s Progress 5581 / 9694 Time remaining: 2s Progress 5582 / 9694 Time remaining: 2s Progress 5583 / 9694 Time remaining: 2s Progress 5584 / 9694 Time remaining: 2s Progress 5585 / 9694 Time remaining: 2s Progress 5586 / 9694 Time remaining: 2s Progress 5587 / 9694 Time remaining: 2s Progress 5588 / 9694 Time remaining: 2s Progress 5589 / 9694 Time remaining: 2s Progress 5590 / 9694 Time remaining: 2s Progress 5591 / 9694 Time remaining: 2s Progress 5592 / 9694 Time remaining: 2s Progress 5593 / 9694 Time remaining: 2s Progress 5594 / 9694 Time remaining: 2s Progress 5595 / 9694 Time remaining: 2s Progress 5596 / 9694 Time remaining: 2s Progress 5597 / 9694 Time remaining: 2s Progress 5598 / 9694 Time remaining: 2s Progress 5599 / 9694 Time remaining: 2s Progress 5600 / 9694 Time remaining: 2s Progress 5601 / 9694 Time remaining: 2s Progress 5602 / 9694 Time remaining: 2s Progress 5603 / 9694 Time remaining: 2s Progress 5604 / 9694 Time remaining: 2s Progress 5605 / 9694 Time remaining: 2s Progress 5606 / 9694 Time remaining: 2s Progress 5607 / 9694 Time remaining: 2s Progress 5608 / 9694 Time remaining: 2s Progress 5609 / 9694 Time remaining: 2s Progress 5610 / 9694 Time remaining: 2s Progress 5611 / 9694 Time remaining: 2s Progress 5612 / 9694 Time remaining: 2s Progress 5613 / 9694 Time remaining: 2s Progress 5614 / 9694 Time remaining: 2s Progress 5615 / 9694 Time remaining: 2s Progress 5616 / 9694 Time remaining: 2s Progress 5617 / 9694 Time remaining: 2s Progress 5618 / 9694 Time remaining: 2s Progress 5619 / 9694 Time remaining: 2s Progress 5620 / 9694 Time remaining: 2s Progress 5621 / 9694 Time remaining: 2s Progress 5622 / 9694 Time remaining: 2s Progress 5623 / 9694 Time remaining: 2s Progress 5624 / 9694 Time remaining: 2s Progress 5625 / 9694 Time remaining: 2s Progress 5626 / 9694 Time remaining: 2s Progress 5627 / 9694 Time remaining: 2s Progress 5628 / 9694 Time remaining: 2s Progress 5629 / 9694 Time remaining: 2s Progress 5630 / 9694 Time remaining: 2s Progress 5631 / 9694 Time remaining: 2s Progress 5632 / 9694 Time remaining: 2s Progress 5633 / 9694 Time remaining: 2s Progress 5634 / 9694 Time remaining: 2s Progress 5635 / 9694 Time remaining: 2s Progress 5636 / 9694 Time remaining: 2s Progress 5637 / 9694 Time remaining: 2s Progress 5638 / 9694 Time remaining: 2s Progress 5639 / 9694 Time remaining: 2s Progress 5640 / 9694 Time remaining: 2s Progress 5641 / 9694 Time remaining: 2s Progress 5642 / 9694 Time remaining: 2s Progress 5643 / 9694 Time remaining: 2s Progress 5644 / 9694 Time remaining: 2s Progress 5645 / 9694 Time remaining: 2s Progress 5646 / 9694 Time remaining: 2s Progress 5647 / 9694 Time remaining: 2s Progress 5648 / 9694 Time remaining: 2s Progress 5649 / 9694 Time remaining: 2s Progress 5650 / 9694 Time remaining: 2s Progress 5651 / 9694 Time remaining: 2s Progress 5652 / 9694 Time remaining: 2s Progress 5653 / 9694 Time remaining: 2s Progress 5654 / 9694 Time remaining: 2s Progress 5655 / 9694 Time remaining: 2s Progress 5656 / 9694 Time remaining: 2s Progress 5657 / 9694 Time remaining: 2s Progress 5658 / 9694 Time remaining: 2s Progress 5659 / 9694 Time remaining: 2s Progress 5660 / 9694 Time remaining: 2s Progress 5661 / 9694 Time remaining: 2s Progress 5662 / 9694 Time remaining: 2s Progress 5663 / 9694 Time remaining: 2s Progress 5664 / 9694 Time remaining: 2s Progress 5665 / 9694 Time remaining: 2s Progress 5666 / 9694 Time remaining: 2s Progress 5667 / 9694 Time remaining: 2s Progress 5668 / 9694 Time remaining: 2s Progress 5669 / 9694 Time remaining: 2s Progress 5670 / 9694 Time remaining: 2s Progress 5671 / 9694 Time remaining: 2s Progress 5672 / 9694 Time remaining: 2s Progress 5673 / 9694 Time remaining: 2s Progress 5674 / 9694 Time remaining: 2s Progress 5675 / 9694 Time remaining: 2s Progress 5676 / 9694 Time remaining: 2s Progress 5677 / 9694 Time remaining: 2s Progress 5678 / 9694 Time remaining: 2s Progress 5679 / 9694 Time remaining: 2s Progress 5680 / 9694 Time remaining: 2s Progress 5681 / 9694 Time remaining: 2s Progress 5682 / 9694 Time remaining: 2s Progress 5683 / 9694 Time remaining: 2s Progress 5684 / 9694 Time remaining: 2s Progress 5685 / 9694 Time remaining: 2s Progress 5686 / 9694 Time remaining: 2s Progress 5687 / 9694 Time remaining: 2s Progress 5688 / 9694 Time remaining: 2s Progress 5689 / 9694 Time remaining: 2s Progress 5690 / 9694 Time remaining: 2s Progress 5691 / 9694 Time remaining: 2s Progress 5692 / 9694 Time remaining: 2s Progress 5693 / 9694 Time remaining: 2s Progress 5694 / 9694 Time remaining: 2s Progress 5695 / 9694 Time remaining: 2s Progress 5696 / 9694 Time remaining: 2s Progress 5697 / 9694 Time remaining: 2s Progress 5698 / 9694 Time remaining: 2s Progress 5699 / 9694 Time remaining: 2s Progress 5700 / 9694 Time remaining: 2s Progress 5701 / 9694 Time remaining: 2s Progress 5702 / 9694 Time remaining: 2s Progress 5703 / 9694 Time remaining: 2s Progress 5704 / 9694 Time remaining: 2s Progress 5705 / 9694 Time remaining: 2s Progress 5706 / 9694 Time remaining: 2s Progress 5707 / 9694 Time remaining: 2s Progress 5708 / 9694 Time remaining: 2s Progress 5709 / 9694 Time remaining: 2s Progress 5710 / 9694 Time remaining: 2s Progress 5711 / 9694 Time remaining: 2s Progress 5712 / 9694 Time remaining: 2s Progress 5713 / 9694 Time remaining: 2s Progress 5714 / 9694 Time remaining: 2s Progress 5715 / 9694 Time remaining: 2s Progress 5716 / 9694 Time remaining: 2s Progress 5717 / 9694 Time remaining: 2s Progress 5718 / 9694 Time remaining: 2s Progress 5719 / 9694 Time remaining: 2s Progress 5720 / 9694 Time remaining: 2s Progress 5721 / 9694 Time remaining: 2s Progress 5722 / 9694 Time remaining: 2s Progress 5723 / 9694 Time remaining: 2s Progress 5724 / 9694 Time remaining: 2s Progress 5725 / 9694 Time remaining: 2s Progress 5726 / 9694 Time remaining: 2s Progress 5727 / 9694 Time remaining: 2s Progress 5728 / 9694 Time remaining: 2s Progress 5729 / 9694 Time remaining: 2s Progress 5730 / 9694 Time remaining: 2s Progress 5731 / 9694 Time remaining: 2s Progress 5732 / 9694 Time remaining: 2s Progress 5733 / 9694 Time remaining: 2s Progress 5734 / 9694 Time remaining: 2s Progress 5735 / 9694 Time remaining: 2s Progress 5736 / 9694 Time remaining: 2s Progress 5737 / 9694 Time remaining: 2s Progress 5738 / 9694 Time remaining: 2s Progress 5739 / 9694 Time remaining: 2s Progress 5740 / 9694 Time remaining: 2s Progress 5741 / 9694 Time remaining: 2s Progress 5742 / 9694 Time remaining: 2s Progress 5743 / 9694 Time remaining: 2s Progress 5744 / 9694 Time remaining: 2s Progress 5745 / 9694 Time remaining: 2s Progress 5746 / 9694 Time remaining: 2s Progress 5747 / 9694 Time remaining: 2s Progress 5748 / 9694 Time remaining: 2s Progress 5749 / 9694 Time remaining: 2s Progress 5750 / 9694 Time remaining: 2s Progress 5751 / 9694 Time remaining: 2s Progress 5752 / 9694 Time remaining: 2s Progress 5753 / 9694 Time remaining: 2s Progress 5754 / 9694 Time remaining: 2s Progress 5755 / 9694 Time remaining: 2s Progress 5756 / 9694 Time remaining: 2s Progress 5757 / 9694 Time remaining: 2s Progress 5758 / 9694 Time remaining: 2s Progress 5759 / 9694 Time remaining: 2s Progress 5760 / 9694 Time remaining: 2s Progress 5761 / 9694 Time remaining: 2s Progress 5762 / 9694 Time remaining: 2s Progress 5763 / 9694 Time remaining: 2s Progress 5764 / 9694 Time remaining: 2s Progress 5765 / 9694 Time remaining: 2s Progress 5766 / 9694 Time remaining: 2s Progress 5767 / 9694 Time remaining: 2s Progress 5768 / 9694 Time remaining: 2s Progress 5769 / 9694 Time remaining: 2s Progress 5770 / 9694 Time remaining: 2s Progress 5771 / 9694 Time remaining: 2s Progress 5772 / 9694 Time remaining: 2s Progress 5773 / 9694 Time remaining: 2s Progress 5774 / 9694 Time remaining: 2s Progress 5775 / 9694 Time remaining: 2s Progress 5776 / 9694 Time remaining: 2s Progress 5777 / 9694 Time remaining: 2s Progress 5778 / 9694 Time remaining: 2s Progress 5779 / 9694 Time remaining: 2s Progress 5780 / 9694 Time remaining: 2s Progress 5781 / 9694 Time remaining: 2s Progress 5782 / 9694 Time remaining: 2s Progress 5783 / 9694 Time remaining: 2s Progress 5784 / 9694 Time remaining: 2s Progress 5785 / 9694 Time remaining: 2s Progress 5786 / 9694 Time remaining: 2s Progress 5787 / 9694 Time remaining: 2s Progress 5788 / 9694 Time remaining: 2s Progress 5789 / 9694 Time remaining: 2s Progress 5790 / 9694 Time remaining: 2s Progress 5791 / 9694 Time remaining: 2s Progress 5792 / 9694 Time remaining: 2s Progress 5793 / 9694 Time remaining: 2s Progress 5794 / 9694 Time remaining: 2s Progress 5795 / 9694 Time remaining: 2s Progress 5796 / 9694 Time remaining: 2s Progress 5797 / 9694 Time remaining: 2s Progress 5798 / 9694 Time remaining: 2s Progress 5799 / 9694 Time remaining: 2s Progress 5800 / 9694 Time remaining: 2s Progress 5801 / 9694 Time remaining: 2s Progress 5802 / 9694 Time remaining: 2s Progress 5803 / 9694 Time remaining: 2s Progress 5804 / 9694 Time remaining: 2s Progress 5805 / 9694 Time remaining: 2s Progress 5806 / 9694 Time remaining: 2s Progress 5807 / 9694 Time remaining: 2s Progress 5808 / 9694 Time remaining: 2s Progress 5809 / 9694 Time remaining: 2s Progress 5810 / 9694 Time remaining: 2s Progress 5811 / 9694 Time remaining: 2s Progress 5812 / 9694 Time remaining: 2s Progress 5813 / 9694 Time remaining: 2s Progress 5814 / 9694 Time remaining: 2s Progress 5815 / 9694 Time remaining: 2s Progress 5816 / 9694 Time remaining: 2s Progress 5817 / 9694 Time remaining: 2s Progress 5818 / 9694 Time remaining: 2s Progress 5819 / 9694 Time remaining: 2s Progress 5820 / 9694 Time remaining: 2s Progress 5821 / 9694 Time remaining: 2s Progress 5822 / 9694 Time remaining: 2s Progress 5823 / 9694 Time remaining: 2s Progress 5824 / 9694 Time remaining: 2s Progress 5825 / 9694 Time remaining: 2s Progress 5826 / 9694 Time remaining: 2s Progress 5827 / 9694 Time remaining: 2s Progress 5828 / 9694 Time remaining: 2s Progress 5829 / 9694 Time remaining: 2s Progress 5830 / 9694 Time remaining: 2s Progress 5831 / 9694 Time remaining: 2s Progress 5832 / 9694 Time remaining: 2s Progress 5833 / 9694 Time remaining: 2s Progress 5834 / 9694 Time remaining: 2s Progress 5835 / 9694 Time remaining: 2s Progress 5836 / 9694 Time remaining: 2s Progress 5837 / 9694 Time remaining: 2s Progress 5838 / 9694 Time remaining: 2s Progress 5839 / 9694 Time remaining: 2s Progress 5840 / 9694 Time remaining: 2s Progress 5841 / 9694 Time remaining: 2s Progress 5842 / 9694 Time remaining: 2s Progress 5843 / 9694 Time remaining: 2s Progress 5844 / 9694 Time remaining: 2s Progress 5845 / 9694 Time remaining: 2s Progress 5846 / 9694 Time remaining: 2s Progress 5847 / 9694 Time remaining: 2s Progress 5848 / 9694 Time remaining: 2s Progress 5849 / 9694 Time remaining: 2s Progress 5850 / 9694 Time remaining: 2s Progress 5851 / 9694 Time remaining: 2s Progress 5852 / 9694 Time remaining: 2s Progress 5853 / 9694 Time remaining: 2s Progress 5854 / 9694 Time remaining: 2s Progress 5855 / 9694 Time remaining: 2s Progress 5856 / 9694 Time remaining: 2s Progress 5857 / 9694 Time remaining: 2s Progress 5858 / 9694 Time remaining: 2s Progress 5859 / 9694 Time remaining: 2s Progress 5860 / 9694 Time remaining: 2s Progress 5861 / 9694 Time remaining: 2s Progress 5862 / 9694 Time remaining: 2s Progress 5863 / 9694 Time remaining: 2s Progress 5864 / 9694 Time remaining: 2s Progress 5865 / 9694 Time remaining: 2s Progress 5866 / 9694 Time remaining: 2s Progress 5867 / 9694 Time remaining: 2s Progress 5868 / 9694 Time remaining: 2s Progress 5869 / 9694 Time remaining: 2s Progress 5870 / 9694 Time remaining: 2s Progress 5871 / 9694 Time remaining: 2s Progress 5872 / 9694 Time remaining: 2s Progress 5873 / 9694 Time remaining: 2s Progress 5874 / 9694 Time remaining: 2s Progress 5875 / 9694 Time remaining: 2s Progress 5876 / 9694 Time remaining: 2s Progress 5877 / 9694 Time remaining: 2s Progress 5878 / 9694 Time remaining: 2s Progress 5879 / 9694 Time remaining: 2s Progress 5880 / 9694 Time remaining: 2s Progress 5881 / 9694 Time remaining: 2s Progress 5882 / 9694 Time remaining: 2s Progress 5883 / 9694 Time remaining: 2s Progress 5884 / 9694 Time remaining: 2s Progress 5885 / 9694 Time remaining: 2s Progress 5886 / 9694 Time remaining: 2s Progress 5887 / 9694 Time remaining: 2s Progress 5888 / 9694 Time remaining: 2s Progress 5889 / 9694 Time remaining: 2s Progress 5890 / 9694 Time remaining: 2s Progress 5891 / 9694 Time remaining: 2s Progress 5892 / 9694 Time remaining: 2s Progress 5893 / 9694 Time remaining: 2s Progress 5894 / 9694 Time remaining: 2s Progress 5895 / 9694 Time remaining: 2s Progress 5896 / 9694 Time remaining: 2s Progress 5897 / 9694 Time remaining: 2s Progress 5898 / 9694 Time remaining: 2s Progress 5899 / 9694 Time remaining: 2s Progress 5900 / 9694 Time remaining: 2s Progress 5901 / 9694 Time remaining: 2s Progress 5902 / 9694 Time remaining: 2s Progress 5903 / 9694 Time remaining: 2s Progress 5904 / 9694 Time remaining: 2s Progress 5905 / 9694 Time remaining: 2s Progress 5906 / 9694 Time remaining: 2s Progress 5907 / 9694 Time remaining: 2s Progress 5908 / 9694 Time remaining: 2s Progress 5909 / 9694 Time remaining: 2s Progress 5910 / 9694 Time remaining: 2s Progress 5911 / 9694 Time remaining: 2s Progress 5912 / 9694 Time remaining: 2s Progress 5913 / 9694 Time remaining: 2s Progress 5914 / 9694 Time remaining: 2s Progress 5915 / 9694 Time remaining: 2s Progress 5916 / 9694 Time remaining: 2s Progress 5917 / 9694 Time remaining: 2s Progress 5918 / 9694 Time remaining: 2s Progress 5919 / 9694 Time remaining: 2s Progress 5920 / 9694 Time remaining: 2s Progress 5921 / 9694 Time remaining: 2s Progress 5922 / 9694 Time remaining: 2s Progress 5923 / 9694 Time remaining: 2s Progress 5924 / 9694 Time remaining: 2s Progress 5925 / 9694 Time remaining: 2s Progress 5926 / 9694 Time remaining: 2s Progress 5927 / 9694 Time remaining: 2s Progress 5928 / 9694 Time remaining: 2s Progress 5929 / 9694 Time remaining: 2s Progress 5930 / 9694 Time remaining: 2s Progress 5931 / 9694 Time remaining: 2s Progress 5932 / 9694 Time remaining: 2s Progress 5933 / 9694 Time remaining: 2s Progress 5934 / 9694 Time remaining: 2s Progress 5935 / 9694 Time remaining: 2s Progress 5936 / 9694 Time remaining: 2s Progress 5937 / 9694 Time remaining: 2s Progress 5938 / 9694 Time remaining: 2s Progress 5939 / 9694 Time remaining: 2s Progress 5940 / 9694 Time remaining: 2s Progress 5941 / 9694 Time remaining: 2s Progress 5942 / 9694 Time remaining: 2s Progress 5943 / 9694 Time remaining: 2s Progress 5944 / 9694 Time remaining: 2s Progress 5945 / 9694 Time remaining: 2s Progress 5946 / 9694 Time remaining: 2s Progress 5947 / 9694 Time remaining: 2s Progress 5948 / 9694 Time remaining: 2s Progress 5949 / 9694 Time remaining: 2s Progress 5950 / 9694 Time remaining: 2s Progress 5951 / 9694 Time remaining: 2s Progress 5952 / 9694 Time remaining: 2s Progress 5953 / 9694 Time remaining: 2s Progress 5954 / 9694 Time remaining: 2s Progress 5955 / 9694 Time remaining: 2s Progress 5956 / 9694 Time remaining: 2s Progress 5957 / 9694 Time remaining: 2s Progress 5958 / 9694 Time remaining: 2s Progress 5959 / 9694 Time remaining: 2s Progress 5960 / 9694 Time remaining: 2s Progress 5961 / 9694 Time remaining: 2s Progress 5962 / 9694 Time remaining: 2s Progress 5963 / 9694 Time remaining: 2s Progress 5964 / 9694 Time remaining: 2s Progress 5965 / 9694 Time remaining: 2s Progress 5966 / 9694 Time remaining: 2s Progress 5967 / 9694 Time remaining: 2s Progress 5968 / 9694 Time remaining: 2s Progress 5969 / 9694 Time remaining: 2s Progress 5970 / 9694 Time remaining: 2s Progress 5971 / 9694 Time remaining: 2s Progress 5972 / 9694 Time remaining: 2s Progress 5973 / 9694 Time remaining: 2s Progress 5974 / 9694 Time remaining: 2s Progress 5975 / 9694 Time remaining: 2s Progress 5976 / 9694 Time remaining: 2s Progress 5977 / 9694 Time remaining: 2s Progress 5978 / 9694 Time remaining: 2s Progress 5979 / 9694 Time remaining: 2s Progress 5980 / 9694 Time remaining: 2s Progress 5981 / 9694 Time remaining: 2s Progress 5982 / 9694 Time remaining: 2s Progress 5983 / 9694 Time remaining: 2s Progress 5984 / 9694 Time remaining: 2s Progress 5985 / 9694 Time remaining: 2s Progress 5986 / 9694 Time remaining: 2s Progress 5987 / 9694 Time remaining: 2s Progress 5988 / 9694 Time remaining: 2s Progress 5989 / 9694 Time remaining: 2s Progress 5990 / 9694 Time remaining: 2s Progress 5991 / 9694 Time remaining: 2s Progress 5992 / 9694 Time remaining: 2s Progress 5993 / 9694 Time remaining: 2s Progress 5994 / 9694 Time remaining: 2s Progress 5995 / 9694 Time remaining: 2s Progress 5996 / 9694 Time remaining: 2s Progress 5997 / 9694 Time remaining: 2s Progress 5998 / 9694 Time remaining: 2s Progress 5999 / 9694 Time remaining: 2s Progress 6000 / 9694 Time remaining: 2s Progress 6001 / 9694 Time remaining: 2s Progress 6002 / 9694 Time remaining: 2s Progress 6003 / 9694 Time remaining: 2s Progress 6004 / 9694 Time remaining: 2s Progress 6005 / 9694 Time remaining: 2s Progress 6006 / 9694 Time remaining: 2s Progress 6007 / 9694 Time remaining: 2s Progress 6008 / 9694 Time remaining: 2s Progress 6009 / 9694 Time remaining: 2s Progress 6010 / 9694 Time remaining: 2s Progress 6011 / 9694 Time remaining: 2s Progress 6012 / 9694 Time remaining: 2s Progress 6013 / 9694 Time remaining: 2s Progress 6014 / 9694 Time remaining: 2s Progress 6015 / 9694 Time remaining: 2s Progress 6016 / 9694 Time remaining: 2s Progress 6017 / 9694 Time remaining: 2s Progress 6018 / 9694 Time remaining: 2s Progress 6019 / 9694 Time remaining: 2s Progress 6020 / 9694 Time remaining: 2s Progress 6021 / 9694 Time remaining: 2s Progress 6022 / 9694 Time remaining: 2s Progress 6023 / 9694 Time remaining: 2s Progress 6024 / 9694 Time remaining: 2s Progress 6025 / 9694 Time remaining: 2s Progress 6026 / 9694 Time remaining: 2s Progress 6027 / 9694 Time remaining: 2s Progress 6028 / 9694 Time remaining: 2s Progress 6029 / 9694 Time remaining: 2s Progress 6030 / 9694 Time remaining: 2s Progress 6031 / 9694 Time remaining: 2s Progress 6032 / 9694 Time remaining: 2s Progress 6033 / 9694 Time remaining: 2s Progress 6034 / 9694 Time remaining: 2s Progress 6035 / 9694 Time remaining: 2s Progress 6036 / 9694 Time remaining: 2s Progress 6037 / 9694 Time remaining: 2s Progress 6038 / 9694 Time remaining: 2s Progress 6039 / 9694 Time remaining: 2s Progress 6040 / 9694 Time remaining: 2s Progress 6041 / 9694 Time remaining: 2s Progress 6042 / 9694 Time remaining: 2s Progress 6043 / 9694 Time remaining: 2s Progress 6044 / 9694 Time remaining: 2s Progress 6045 / 9694 Time remaining: 2s Progress 6046 / 9694 Time remaining: 2s Progress 6047 / 9694 Time remaining: 2s Progress 6048 / 9694 Time remaining: 2s Progress 6049 / 9694 Time remaining: 2s Progress 6050 / 9694 Time remaining: 2s Progress 6051 / 9694 Time remaining: 2s Progress 6052 / 9694 Time remaining: 2s Progress 6053 / 9694 Time remaining: 2s Progress 6054 / 9694 Time remaining: 2s Progress 6055 / 9694 Time remaining: 2s Progress 6056 / 9694 Time remaining: 2s Progress 6057 / 9694 Time remaining: 2s Progress 6058 / 9694 Time remaining: 2s Progress 6059 / 9694 Time remaining: 2s Progress 6060 / 9694 Time remaining: 2s Progress 6061 / 9694 Time remaining: 2s Progress 6062 / 9694 Time remaining: 2s Progress 6063 / 9694 Time remaining: 2s Progress 6064 / 9694 Time remaining: 2s Progress 6065 / 9694 Time remaining: 2s Progress 6066 / 9694 Time remaining: 2s Progress 6067 / 9694 Time remaining: 2s Progress 6068 / 9694 Time remaining: 2s Progress 6069 / 9694 Time remaining: 2s Progress 6070 / 9694 Time remaining: 2s Progress 6071 / 9694 Time remaining: 2s Progress 6072 / 9694 Time remaining: 2s Progress 6073 / 9694 Time remaining: 2s Progress 6074 / 9694 Time remaining: 2s Progress 6075 / 9694 Time remaining: 2s Progress 6076 / 9694 Time remaining: 2s Progress 6077 / 9694 Time remaining: 2s Progress 6078 / 9694 Time remaining: 2s Progress 6079 / 9694 Time remaining: 2s Progress 6080 / 9694 Time remaining: 2s Progress 6081 / 9694 Time remaining: 2s Progress 6082 / 9694 Time remaining: 2s Progress 6083 / 9694 Time remaining: 2s Progress 6084 / 9694 Time remaining: 2s Progress 6085 / 9694 Time remaining: 2s Progress 6086 / 9694 Time remaining: 2s Progress 6087 / 9694 Time remaining: 2s Progress 6088 / 9694 Time remaining: 2s Progress 6089 / 9694 Time remaining: 2s Progress 6090 / 9694 Time remaining: 2s Progress 6091 / 9694 Time remaining: 2s Progress 6092 / 9694 Time remaining: 2s Progress 6093 / 9694 Time remaining: 2s Progress 6094 / 9694 Time remaining: 2s Progress 6095 / 9694 Time remaining: 2s Progress 6096 / 9694 Time remaining: 2s Progress 6097 / 9694 Time remaining: 2s Progress 6098 / 9694 Time remaining: 2s Progress 6099 / 9694 Time remaining: 2s Progress 6100 / 9694 Time remaining: 2s Progress 6101 / 9694 Time remaining: 2s Progress 6102 / 9694 Time remaining: 2s Progress 6103 / 9694 Time remaining: 2s Progress 6104 / 9694 Time remaining: 2s Progress 6105 / 9694 Time remaining: 2s Progress 6106 / 9694 Time remaining: 2s Progress 6107 / 9694 Time remaining: 2s Progress 6108 / 9694 Time remaining: 2s Progress 6109 / 9694 Time remaining: 2s Progress 6110 / 9694 Time remaining: 2s Progress 6111 / 9694 Time remaining: 2s Progress 6112 / 9694 Time remaining: 2s Progress 6113 / 9694 Time remaining: 2s Progress 6114 / 9694 Time remaining: 2s Progress 6115 / 9694 Time remaining: 2s Progress 6116 / 9694 Time remaining: 2s Progress 6117 / 9694 Time remaining: 2s Progress 6118 / 9694 Time remaining: 2s Progress 6119 / 9694 Time remaining: 2s Progress 6120 / 9694 Time remaining: 2s Progress 6121 / 9694 Time remaining: 2s Progress 6122 / 9694 Time remaining: 2s Progress 6123 / 9694 Time remaining: 2s Progress 6124 / 9694 Time remaining: 2s Progress 6125 / 9694 Time remaining: 2s Progress 6126 / 9694 Time remaining: 2s Progress 6127 / 9694 Time remaining: 2s Progress 6128 / 9694 Time remaining: 2s Progress 6129 / 9694 Time remaining: 2s Progress 6130 / 9694 Time remaining: 2s Progress 6131 / 9694 Time remaining: 2s Progress 6132 / 9694 Time remaining: 2s Progress 6133 / 9694 Time remaining: 2s Progress 6134 / 9694 Time remaining: 2s Progress 6135 / 9694 Time remaining: 2s Progress 6136 / 9694 Time remaining: 2s Progress 6137 / 9694 Time remaining: 2s Progress 6138 / 9694 Time remaining: 2s Progress 6139 / 9694 Time remaining: 2s Progress 6140 / 9694 Time remaining: 2s Progress 6141 / 9694 Time remaining: 2s Progress 6142 / 9694 Time remaining: 2s Progress 6143 / 9694 Time remaining: 2s Progress 6144 / 9694 Time remaining: 2s Progress 6145 / 9694 Time remaining: 2s Progress 6146 / 9694 Time remaining: 2s Progress 6147 / 9694 Time remaining: 2s Progress 6148 / 9694 Time remaining: 2s Progress 6149 / 9694 Time remaining: 2s Progress 6150 / 9694 Time remaining: 2s Progress 6151 / 9694 Time remaining: 2s Progress 6152 / 9694 Time remaining: 2s Progress 6153 / 9694 Time remaining: 2s Progress 6154 / 9694 Time remaining: 2s Progress 6155 / 9694 Time remaining: 2s Progress 6156 / 9694 Time remaining: 2s Progress 6157 / 9694 Time remaining: 2s Progress 6158 / 9694 Time remaining: 2s Progress 6159 / 9694 Time remaining: 2s Progress 6160 / 9694 Time remaining: 2s Progress 6161 / 9694 Time remaining: 2s Progress 6162 / 9694 Time remaining: 2s Progress 6163 / 9694 Time remaining: 2s Progress 6164 / 9694 Time remaining: 2s Progress 6165 / 9694 Time remaining: 2s Progress 6166 / 9694 Time remaining: 2s Progress 6167 / 9694 Time remaining: 2s Progress 6168 / 9694 Time remaining: 2s Progress 6169 / 9694 Time remaining: 2s Progress 6170 / 9694 Time remaining: 2s Progress 6171 / 9694 Time remaining: 2s Progress 6172 / 9694 Time remaining: 2s Progress 6173 / 9694 Time remaining: 2s Progress 6174 / 9694 Time remaining: 2s Progress 6175 / 9694 Time remaining: 2s Progress 6176 / 9694 Time remaining: 2s Progress 6177 / 9694 Time remaining: 2s Progress 6178 / 9694 Time remaining: 2s Progress 6179 / 9694 Time remaining: 2s Progress 6180 / 9694 Time remaining: 2s Progress 6181 / 9694 Time remaining: 2s Progress 6182 / 9694 Time remaining: 2s Progress 6183 / 9694 Time remaining: 2s Progress 6184 / 9694 Time remaining: 2s Progress 6185 / 9694 Time remaining: 2s Progress 6186 / 9694 Time remaining: 2s Progress 6187 / 9694 Time remaining: 2s Progress 6188 / 9694 Time remaining: 2s Progress 6189 / 9694 Time remaining: 2s Progress 6190 / 9694 Time remaining: 2s Progress 6191 / 9694 Time remaining: 2s Progress 6192 / 9694 Time remaining: 2s Progress 6193 / 9694 Time remaining: 2s Progress 6194 / 9694 Time remaining: 2s Progress 6195 / 9694 Time remaining: 2s Progress 6196 / 9694 Time remaining: 2s Progress 6197 / 9694 Time remaining: 2s Progress 6198 / 9694 Time remaining: 2s Progress 6199 / 9694 Time remaining: 2s Progress 6200 / 9694 Time remaining: 2s Progress 6201 / 9694 Time remaining: 2s Progress 6202 / 9694 Time remaining: 2s Progress 6203 / 9694 Time remaining: 2s Progress 6204 / 9694 Time remaining: 2s Progress 6205 / 9694 Time remaining: 2s Progress 6206 / 9694 Time remaining: 2s Progress 6207 / 9694 Time remaining: 2s Progress 6208 / 9694 Time remaining: 2s Progress 6209 / 9694 Time remaining: 2s Progress 6210 / 9694 Time remaining: 2s Progress 6211 / 9694 Time remaining: 2s Progress 6212 / 9694 Time remaining: 2s Progress 6213 / 9694 Time remaining: 2s Progress 6214 / 9694 Time remaining: 2s Progress 6215 / 9694 Time remaining: 2s Progress 6216 / 9694 Time remaining: 2s Progress 6217 / 9694 Time remaining: 2s Progress 6218 / 9694 Time remaining: 2s Progress 6219 / 9694 Time remaining: 2s Progress 6220 / 9694 Time remaining: 2s Progress 6221 / 9694 Time remaining: 2s Progress 6222 / 9694 Time remaining: 2s Progress 6223 / 9694 Time remaining: 2s Progress 6224 / 9694 Time remaining: 2s Progress 6225 / 9694 Time remaining: 2s Progress 6226 / 9694 Time remaining: 2s Progress 6227 / 9694 Time remaining: 2s Progress 6228 / 9694 Time remaining: 2s Progress 6229 / 9694 Time remaining: 2s Progress 6230 / 9694 Time remaining: 2s Progress 6231 / 9694 Time remaining: 2s Progress 6232 / 9694 Time remaining: 2s Progress 6233 / 9694 Time remaining: 2s Progress 6234 / 9694 Time remaining: 2s Progress 6235 / 9694 Time remaining: 2s Progress 6236 / 9694 Time remaining: 2s Progress 6237 / 9694 Time remaining: 2s Progress 6238 / 9694 Time remaining: 2s Progress 6239 / 9694 Time remaining: 2s Progress 6240 / 9694 Time remaining: 2s Progress 6241 / 9694 Time remaining: 2s Progress 6242 / 9694 Time remaining: 2s Progress 6243 / 9694 Time remaining: 2s Progress 6244 / 9694 Time remaining: 2s Progress 6245 / 9694 Time remaining: 2s Progress 6246 / 9694 Time remaining: 2s Progress 6247 / 9694 Time remaining: 2s Progress 6248 / 9694 Time remaining: 2s Progress 6249 / 9694 Time remaining: 2s Progress 6250 / 9694 Time remaining: 2s Progress 6251 / 9694 Time remaining: 2s Progress 6252 / 9694 Time remaining: 2s Progress 6253 / 9694 Time remaining: 2s Progress 6254 / 9694 Time remaining: 2s Progress 6255 / 9694 Time remaining: 2s Progress 6256 / 9694 Time remaining: 2s Progress 6257 / 9694 Time remaining: 2s Progress 6258 / 9694 Time remaining: 2s Progress 6259 / 9694 Time remaining: 2s Progress 6260 / 9694 Time remaining: 2s Progress 6261 / 9694 Time remaining: 2s Progress 6262 / 9694 Time remaining: 2s Progress 6263 / 9694 Time remaining: 2s Progress 6264 / 9694 Time remaining: 2s Progress 6265 / 9694 Time remaining: 2s Progress 6266 / 9694 Time remaining: 2s Progress 6267 / 9694 Time remaining: 2s Progress 6268 / 9694 Time remaining: 2s Progress 6269 / 9694 Time remaining: 2s Progress 6270 / 9694 Time remaining: 2s Progress 6271 / 9694 Time remaining: 2s Progress 6272 / 9694 Time remaining: 2s Progress 6273 / 9694 Time remaining: 2s Progress 6274 / 9694 Time remaining: 2s Progress 6275 / 9694 Time remaining: 2s Progress 6276 / 9694 Time remaining: 2s Progress 6277 / 9694 Time remaining: 2s Progress 6278 / 9694 Time remaining: 2s Progress 6279 / 9694 Time remaining: 2s Progress 6280 / 9694 Time remaining: 2s Progress 6281 / 9694 Time remaining: 2s Progress 6282 / 9694 Time remaining: 2s Progress 6283 / 9694 Time remaining: 2s Progress 6284 / 9694 Time remaining: 2s Progress 6285 / 9694 Time remaining: 2s Progress 6286 / 9694 Time remaining: 2s Progress 6287 / 9694 Time remaining: 2s Progress 6288 / 9694 Time remaining: 2s Progress 6289 / 9694 Time remaining: 2s Progress 6290 / 9694 Time remaining: 2s Progress 6291 / 9694 Time remaining: 2s Progress 6292 / 9694 Time remaining: 2s Progress 6293 / 9694 Time remaining: 2s Progress 6294 / 9694 Time remaining: 2s Progress 6295 / 9694 Time remaining: 2s Progress 6296 / 9694 Time remaining: 2s Progress 6297 / 9694 Time remaining: 2s Progress 6298 / 9694 Time remaining: 2s Progress 6299 / 9694 Time remaining: 2s Progress 6300 / 9694 Time remaining: 2s Progress 6301 / 9694 Time remaining: 2s Progress 6302 / 9694 Time remaining: 2s Progress 6303 / 9694 Time remaining: 2s Progress 6304 / 9694 Time remaining: 2s Progress 6305 / 9694 Time remaining: 2s Progress 6306 / 9694 Time remaining: 2s Progress 6307 / 9694 Time remaining: 2s Progress 6308 / 9694 Time remaining: 2s Progress 6309 / 9694 Time remaining: 2s Progress 6310 / 9694 Time remaining: 2s Progress 6311 / 9694 Time remaining: 2s Progress 6312 / 9694 Time remaining: 2s Progress 6313 / 9694 Time remaining: 2s Progress 6314 / 9694 Time remaining: 2s Progress 6315 / 9694 Time remaining: 2s Progress 6316 / 9694 Time remaining: 2s Progress 6317 / 9694 Time remaining: 2s Progress 6318 / 9694 Time remaining: 2s Progress 6319 / 9694 Time remaining: 2s Progress 6320 / 9694 Time remaining: 2s Progress 6321 / 9694 Time remaining: 2s Progress 6322 / 9694 Time remaining: 2s Progress 6323 / 9694 Time remaining: 2s Progress 6324 / 9694 Time remaining: 2s Progress 6325 / 9694 Time remaining: 2s Progress 6326 / 9694 Time remaining: 2s Progress 6327 / 9694 Time remaining: 2s Progress 6328 / 9694 Time remaining: 2s Progress 6329 / 9694 Time remaining: 2s Progress 6330 / 9694 Time remaining: 2s Progress 6331 / 9694 Time remaining: 2s Progress 6332 / 9694 Time remaining: 2s Progress 6333 / 9694 Time remaining: 2s Progress 6334 / 9694 Time remaining: 2s Progress 6335 / 9694 Time remaining: 2s Progress 6336 / 9694 Time remaining: 2s Progress 6337 / 9694 Time remaining: 2s Progress 6338 / 9694 Time remaining: 2s Progress 6339 / 9694 Time remaining: 2s Progress 6340 / 9694 Time remaining: 2s Progress 6341 / 9694 Time remaining: 2s Progress 6342 / 9694 Time remaining: 2s Progress 6343 / 9694 Time remaining: 2s Progress 6344 / 9694 Time remaining: 2s Progress 6345 / 9694 Time remaining: 2s Progress 6346 / 9694 Time remaining: 2s Progress 6347 / 9694 Time remaining: 2s Progress 6348 / 9694 Time remaining: 2s Progress 6349 / 9694 Time remaining: 2s Progress 6350 / 9694 Time remaining: 2s Progress 6351 / 9694 Time remaining: 2s Progress 6352 / 9694 Time remaining: 2s Progress 6353 / 9694 Time remaining: 2s Progress 6354 / 9694 Time remaining: 2s Progress 6355 / 9694 Time remaining: 2s Progress 6356 / 9694 Time remaining: 2s Progress 6357 / 9694 Time remaining: 2s Progress 6358 / 9694 Time remaining: 2s Progress 6359 / 9694 Time remaining: 2s Progress 6360 / 9694 Time remaining: 2s Progress 6361 / 9694 Time remaining: 2s Progress 6362 / 9694 Time remaining: 2s Progress 6363 / 9694 Time remaining: 2s Progress 6364 / 9694 Time remaining: 2s Progress 6365 / 9694 Time remaining: 2s Progress 6366 / 9694 Time remaining: 2s Progress 6367 / 9694 Time remaining: 2s Progress 6368 / 9694 Time remaining: 2s Progress 6369 / 9694 Time remaining: 2s Progress 6370 / 9694 Time remaining: 2s Progress 6371 / 9694 Time remaining: 2s Progress 6372 / 9694 Time remaining: 2s Progress 6373 / 9694 Time remaining: 2s Progress 6374 / 9694 Time remaining: 2s Progress 6375 / 9694 Time remaining: 2s Progress 6376 / 9694 Time remaining: 2s Progress 6377 / 9694 Time remaining: 2s Progress 6378 / 9694 Time remaining: 2s Progress 6379 / 9694 Time remaining: 2s Progress 6380 / 9694 Time remaining: 2s Progress 6381 / 9694 Time remaining: 2s Progress 6382 / 9694 Time remaining: 2s Progress 6383 / 9694 Time remaining: 2s Progress 6384 / 9694 Time remaining: 2s Progress 6385 / 9694 Time remaining: 2s Progress 6386 / 9694 Time remaining: 2s Progress 6387 / 9694 Time remaining: 2s Progress 6388 / 9694 Time remaining: 2s Progress 6389 / 9694 Time remaining: 2s Progress 6390 / 9694 Time remaining: 2s Progress 6391 / 9694 Time remaining: 2s Progress 6392 / 9694 Time remaining: 2s Progress 6393 / 9694 Time remaining: 2s Progress 6394 / 9694 Time remaining: 2s Progress 6395 / 9694 Time remaining: 2s Progress 6396 / 9694 Time remaining: 2s Progress 6397 / 9694 Time remaining: 2s Progress 6398 / 9694 Time remaining: 2s Progress 6399 / 9694 Time remaining: 2s Progress 6400 / 9694 Time remaining: 2s Progress 6401 / 9694 Time remaining: 2s Progress 6402 / 9694 Time remaining: 2s Progress 6403 / 9694 Time remaining: 2s Progress 6404 / 9694 Time remaining: 2s Progress 6405 / 9694 Time remaining: 2s Progress 6406 / 9694 Time remaining: 2s Progress 6407 / 9694 Time remaining: 2s Progress 6408 / 9694 Time remaining: 2s Progress 6409 / 9694 Time remaining: 2s Progress 6410 / 9694 Time remaining: 2s Progress 6411 / 9694 Time remaining: 2s Progress 6412 / 9694 Time remaining: 2s Progress 6413 / 9694 Time remaining: 2s Progress 6414 / 9694 Time remaining: 2s Progress 6415 / 9694 Time remaining: 2s Progress 6416 / 9694 Time remaining: 2s Progress 6417 / 9694 Time remaining: 2s Progress 6418 / 9694 Time remaining: 2s Progress 6419 / 9694 Time remaining: 2s Progress 6420 / 9694 Time remaining: 2s Progress 6421 / 9694 Time remaining: 2s Progress 6422 / 9694 Time remaining: 2s Progress 6423 / 9694 Time remaining: 2s Progress 6424 / 9694 Time remaining: 2s Progress 6425 / 9694 Time remaining: 2s Progress 6426 / 9694 Time remaining: 2s Progress 6427 / 9694 Time remaining: 2s Progress 6428 / 9694 Time remaining: 2s Progress 6429 / 9694 Time remaining: 2s Progress 6430 / 9694 Time remaining: 2s Progress 6431 / 9694 Time remaining: 2s Progress 6432 / 9694 Time remaining: 2s Progress 6433 / 9694 Time remaining: 2s Progress 6434 / 9694 Time remaining: 2s Progress 6435 / 9694 Time remaining: 2s Progress 6436 / 9694 Time remaining: 2s Progress 6437 / 9694 Time remaining: 2s Progress 6438 / 9694 Time remaining: 2s Progress 6439 / 9694 Time remaining: 2s Progress 6440 / 9694 Time remaining: 2s Progress 6441 / 9694 Time remaining: 2s Progress 6442 / 9694 Time remaining: 2s Progress 6443 / 9694 Time remaining: 2s Progress 6444 / 9694 Time remaining: 2s Progress 6445 / 9694 Time remaining: 2s Progress 6446 / 9694 Time remaining: 2s Progress 6447 / 9694 Time remaining: 2s Progress 6448 / 9694 Time remaining: 2s Progress 6449 / 9694 Time remaining: 2s Progress 6450 / 9694 Time remaining: 2s Progress 6451 / 9694 Time remaining: 2s Progress 6452 / 9694 Time remaining: 2s Progress 6453 / 9694 Time remaining: 2s Progress 6454 / 9694 Time remaining: 2s Progress 6455 / 9694 Time remaining: 2s Progress 6456 / 9694 Time remaining: 2s Progress 6457 / 9694 Time remaining: 2s Progress 6458 / 9694 Time remaining: 2s Progress 6459 / 9694 Time remaining: 2s Progress 6460 / 9694 Time remaining: 2s Progress 6461 / 9694 Time remaining: 2s Progress 6462 / 9694 Time remaining: 2s Progress 6463 / 9694 Time remaining: 2s Progress 6464 / 9694 Time remaining: 2s Progress 6465 / 9694 Time remaining: 2s Progress 6466 / 9694 Time remaining: 2s Progress 6467 / 9694 Time remaining: 2s Progress 6468 / 9694 Time remaining: 2s Progress 6469 / 9694 Time remaining: 2s Progress 6470 / 9694 Time remaining: 2s Progress 6471 / 9694 Time remaining: 2s Progress 6472 / 9694 Time remaining: 2s Progress 6473 / 9694 Time remaining: 2s Progress 6474 / 9694 Time remaining: 2s Progress 6475 / 9694 Time remaining: 2s Progress 6476 / 9694 Time remaining: 2s Progress 6477 / 9694 Time remaining: 2s Progress 6478 / 9694 Time remaining: 2s Progress 6479 / 9694 Time remaining: 2s Progress 6480 / 9694 Time remaining: 2s Progress 6481 / 9694 Time remaining: 2s Progress 6482 / 9694 Time remaining: 2s Progress 6483 / 9694 Time remaining: 2s Progress 6484 / 9694 Time remaining: 2s Progress 6485 / 9694 Time remaining: 2s Progress 6486 / 9694 Time remaining: 2s Progress 6487 / 9694 Time remaining: 2s Progress 6488 / 9694 Time remaining: 2s Progress 6489 / 9694 Time remaining: 2s Progress 6490 / 9694 Time remaining: 2s Progress 6491 / 9694 Time remaining: 2s Progress 6492 / 9694 Time remaining: 2s Progress 6493 / 9694 Time remaining: 2s Progress 6494 / 9694 Time remaining: 2s Progress 6495 / 9694 Time remaining: 2s Progress 6496 / 9694 Time remaining: 2s Progress 6497 / 9694 Time remaining: 2s Progress 6498 / 9694 Time remaining: 2s Progress 6499 / 9694 Time remaining: 2s Progress 6500 / 9694 Time remaining: 2s Progress 6501 / 9694 Time remaining: 2s Progress 6502 / 9694 Time remaining: 2s Progress 6503 / 9694 Time remaining: 2s Progress 6504 / 9694 Time remaining: 2s Progress 6505 / 9694 Time remaining: 2s Progress 6506 / 9694 Time remaining: 2s Progress 6507 / 9694 Time remaining: 2s Progress 6508 / 9694 Time remaining: 2s Progress 6509 / 9694 Time remaining: 2s Progress 6510 / 9694 Time remaining: 2s Progress 6511 / 9694 Time remaining: 2s Progress 6512 / 9694 Time remaining: 2s Progress 6513 / 9694 Time remaining: 2s Progress 6514 / 9694 Time remaining: 2s Progress 6515 / 9694 Time remaining: 2s Progress 6516 / 9694 Time remaining: 2s Progress 6517 / 9694 Time remaining: 2s Progress 6518 / 9694 Time remaining: 2s Progress 6519 / 9694 Time remaining: 2s Progress 6520 / 9694 Time remaining: 2s Progress 6521 / 9694 Time remaining: 2s Progress 6522 / 9694 Time remaining: 2s Progress 6523 / 9694 Time remaining: 2s Progress 6524 / 9694 Time remaining: 2s Progress 6525 / 9694 Time remaining: 2s Progress 6526 / 9694 Time remaining: 2s Progress 6527 / 9694 Time remaining: 2s Progress 6528 / 9694 Time remaining: 2s Progress 6529 / 9694 Time remaining: 2s Progress 6530 / 9694 Time remaining: 2s Progress 6531 / 9694 Time remaining: 2s Progress 6532 / 9694 Time remaining: 2s Progress 6533 / 9694 Time remaining: 2s Progress 6534 / 9694 Time remaining: 2s Progress 6535 / 9694 Time remaining: 2s Progress 6536 / 9694 Time remaining: 2s Progress 6537 / 9694 Time remaining: 2s Progress 6538 / 9694 Time remaining: 2s Progress 6539 / 9694 Time remaining: 2s Progress 6540 / 9694 Time remaining: 2s Progress 6541 / 9694 Time remaining: 2s Progress 6542 / 9694 Time remaining: 2s Progress 6543 / 9694 Time remaining: 2s Progress 6544 / 9694 Time remaining: 2s Progress 6545 / 9694 Time remaining: 2s Progress 6546 / 9694 Time remaining: 2s Progress 6547 / 9694 Time remaining: 2s Progress 6548 / 9694 Time remaining: 2s Progress 6549 / 9694 Time remaining: 2s Progress 6550 / 9694 Time remaining: 2s Progress 6551 / 9694 Time remaining: 2s Progress 6552 / 9694 Time remaining: 2s Progress 6553 / 9694 Time remaining: 2s Progress 6554 / 9694 Time remaining: 2s Progress 6555 / 9694 Time remaining: 2s Progress 6556 / 9694 Time remaining: 2s Progress 6557 / 9694 Time remaining: 2s Progress 6558 / 9694 Time remaining: 2s Progress 6559 / 9694 Time remaining: 2s Progress 6560 / 9694 Time remaining: 2s Progress 6561 / 9694 Time remaining: 2s Progress 6562 / 9694 Time remaining: 2s Progress 6563 / 9694 Time remaining: 2s Progress 6564 / 9694 Time remaining: 2s Progress 6565 / 9694 Time remaining: 2s Progress 6566 / 9694 Time remaining: 2s Progress 6567 / 9694 Time remaining: 2s Progress 6568 / 9694 Time remaining: 2s Progress 6569 / 9694 Time remaining: 2s Progress 6570 / 9694 Time remaining: 2s Progress 6571 / 9694 Time remaining: 2s Progress 6572 / 9694 Time remaining: 2s Progress 6573 / 9694 Time remaining: 2s Progress 6574 / 9694 Time remaining: 2s Progress 6575 / 9694 Time remaining: 2s Progress 6576 / 9694 Time remaining: 2s Progress 6577 / 9694 Time remaining: 2s Progress 6578 / 9694 Time remaining: 2s Progress 6579 / 9694 Time remaining: 2s Progress 6580 / 9694 Time remaining: 2s Progress 6581 / 9694 Time remaining: 2s Progress 6582 / 9694 Time remaining: 2s Progress 6583 / 9694 Time remaining: 2s Progress 6584 / 9694 Time remaining: 2s Progress 6585 / 9694 Time remaining: 2s Progress 6586 / 9694 Time remaining: 2s Progress 6587 / 9694 Time remaining: 2s Progress 6588 / 9694 Time remaining: 2s Progress 6589 / 9694 Time remaining: 2s Progress 6590 / 9694 Time remaining: 2s Progress 6591 / 9694 Time remaining: 2s Progress 6592 / 9694 Time remaining: 2s Progress 6593 / 9694 Time remaining: 2s Progress 6594 / 9694 Time remaining: 2s Progress 6595 / 9694 Time remaining: 2s Progress 6596 / 9694 Time remaining: 2s Progress 6597 / 9694 Time remaining: 2s Progress 6598 / 9694 Time remaining: 2s Progress 6599 / 9694 Time remaining: 2s Progress 6600 / 9694 Time remaining: 2s Progress 6601 / 9694 Time remaining: 2s Progress 6602 / 9694 Time remaining: 2s Progress 6603 / 9694 Time remaining: 2s Progress 6604 / 9694 Time remaining: 2s Progress 6605 / 9694 Time remaining: 2s Progress 6606 / 9694 Time remaining: 2s Progress 6607 / 9694 Time remaining: 2s Progress 6608 / 9694 Time remaining: 2s Progress 6609 / 9694 Time remaining: 2s Progress 6610 / 9694 Time remaining: 2s Progress 6611 / 9694 Time remaining: 2s Progress 6612 / 9694 Time remaining: 2s Progress 6613 / 9694 Time remaining: 2s Progress 6614 / 9694 Time remaining: 2s Progress 6615 / 9694 Time remaining: 2s Progress 6616 / 9694 Time remaining: 2s Progress 6617 / 9694 Time remaining: 2s Progress 6618 / 9694 Time remaining: 2s Progress 6619 / 9694 Time remaining: 2s Progress 6620 / 9694 Time remaining: 2s Progress 6621 / 9694 Time remaining: 2s Progress 6622 / 9694 Time remaining: 2s Progress 6623 / 9694 Time remaining: 2s Progress 6624 / 9694 Time remaining: 2s Progress 6625 / 9694 Time remaining: 2s Progress 6626 / 9694 Time remaining: 2s Progress 6627 / 9694 Time remaining: 2s Progress 6628 / 9694 Time remaining: 2s Progress 6629 / 9694 Time remaining: 2s Progress 6630 / 9694 Time remaining: 2s Progress 6631 / 9694 Time remaining: 2s Progress 6632 / 9694 Time remaining: 2s Progress 6633 / 9694 Time remaining: 2s Progress 6634 / 9694 Time remaining: 2s Progress 6635 / 9694 Time remaining: 2s Progress 6636 / 9694 Time remaining: 2s Progress 6637 / 9694 Time remaining: 2s Progress 6638 / 9694 Time remaining: 2s Progress 6639 / 9694 Time remaining: 2s Progress 6640 / 9694 Time remaining: 2s Progress 6641 / 9694 Time remaining: 2s Progress 6642 / 9694 Time remaining: 2s Progress 6643 / 9694 Time remaining: 2s Progress 6644 / 9694 Time remaining: 2s Progress 6645 / 9694 Time remaining: 2s Progress 6646 / 9694 Time remaining: 2s Progress 6647 / 9694 Time remaining: 2s Progress 6648 / 9694 Time remaining: 2s Progress 6649 / 9694 Time remaining: 2s Progress 6650 / 9694 Time remaining: 2s Progress 6651 / 9694 Time remaining: 2s Progress 6652 / 9694 Time remaining: 2s Progress 6653 / 9694 Time remaining: 2s Progress 6654 / 9694 Time remaining: 2s Progress 6655 / 9694 Time remaining: 2s Progress 6656 / 9694 Time remaining: 2s Progress 6657 / 9694 Time remaining: 2s Progress 6658 / 9694 Time remaining: 2s Progress 6659 / 9694 Time remaining: 2s Progress 6660 / 9694 Time remaining: 2s Progress 6661 / 9694 Time remaining: 2s Progress 6662 / 9694 Time remaining: 2s Progress 6663 / 9694 Time remaining: 2s Progress 6664 / 9694 Time remaining: 2s Progress 6665 / 9694 Time remaining: 2s Progress 6666 / 9694 Time remaining: 2s Progress 6667 / 9694 Time remaining: 2s Progress 6668 / 9694 Time remaining: 2s Progress 6669 / 9694 Time remaining: 2s Progress 6670 / 9694 Time remaining: 2s Progress 6671 / 9694 Time remaining: 2s Progress 6672 / 9694 Time remaining: 2s Progress 6673 / 9694 Time remaining: 2s Progress 6674 / 9694 Time remaining: 2s Progress 6675 / 9694 Time remaining: 2s Progress 6676 / 9694 Time remaining: 2s Progress 6677 / 9694 Time remaining: 2s Progress 6678 / 9694 Time remaining: 2s Progress 6679 / 9694 Time remaining: 2s Progress 6680 / 9694 Time remaining: 2s Progress 6681 / 9694 Time remaining: 2s Progress 6682 / 9694 Time remaining: 2s Progress 6683 / 9694 Time remaining: 2s Progress 6684 / 9694 Time remaining: 2s Progress 6685 / 9694 Time remaining: 2s Progress 6686 / 9694 Time remaining: 2s Progress 6687 / 9694 Time remaining: 2s Progress 6688 / 9694 Time remaining: 2s Progress 6689 / 9694 Time remaining: 2s Progress 6690 / 9694 Time remaining: 2s Progress 6691 / 9694 Time remaining: 2s Progress 6692 / 9694 Time remaining: 2s Progress 6693 / 9694 Time remaining: 2s Progress 6694 / 9694 Time remaining: 2s Progress 6695 / 9694 Time remaining: 2s Progress 6696 / 9694 Time remaining: 2s Progress 6697 / 9694 Time remaining: 2s Progress 6698 / 9694 Time remaining: 2s Progress 6699 / 9694 Time remaining: 2s Progress 6700 / 9694 Time remaining: 2s Progress 6701 / 9694 Time remaining: 2s Progress 6702 / 9694 Time remaining: 2s Progress 6703 / 9694 Time remaining: 2s Progress 6704 / 9694 Time remaining: 2s Progress 6705 / 9694 Time remaining: 2s Progress 6706 / 9694 Time remaining: 2s Progress 6707 / 9694 Time remaining: 2s Progress 6708 / 9694 Time remaining: 2s Progress 6709 / 9694 Time remaining: 2s Progress 6710 / 9694 Time remaining: 2s Progress 6711 / 9694 Time remaining: 2s Progress 6712 / 9694 Time remaining: 2s Progress 6713 / 9694 Time remaining: 2s Progress 6714 / 9694 Time remaining: 2s Progress 6715 / 9694 Time remaining: 2s Progress 6716 / 9694 Time remaining: 2s Progress 6717 / 9694 Time remaining: 2s Progress 6718 / 9694 Time remaining: 2s Progress 6719 / 9694 Time remaining: 2s Progress 6720 / 9694 Time remaining: 2s Progress 6721 / 9694 Time remaining: 2s Progress 6722 / 9694 Time remaining: 2s Progress 6723 / 9694 Time remaining: 2s Progress 6724 / 9694 Time remaining: 2s Progress 6725 / 9694 Time remaining: 2s Progress 6726 / 9694 Time remaining: 2s Progress 6727 / 9694 Time remaining: 2s Progress 6728 / 9694 Time remaining: 2s Progress 6729 / 9694 Time remaining: 2s Progress 6730 / 9694 Time remaining: 2s Progress 6731 / 9694 Time remaining: 2s Progress 6732 / 9694 Time remaining: 2s Progress 6733 / 9694 Time remaining: 2s Progress 6734 / 9694 Time remaining: 2s Progress 6735 / 9694 Time remaining: 2s Progress 6736 / 9694 Time remaining: 2s Progress 6737 / 9694 Time remaining: 2s Progress 6738 / 9694 Time remaining: 2s Progress 6739 / 9694 Time remaining: 2s Progress 6740 / 9694 Time remaining: 2s Progress 6741 / 9694 Time remaining: 2s Progress 6742 / 9694 Time remaining: 2s Progress 6743 / 9694 Time remaining: 2s Progress 6744 / 9694 Time remaining: 2s Progress 6745 / 9694 Time remaining: 2s Progress 6746 / 9694 Time remaining: 2s Progress 6747 / 9694 Time remaining: 2s Progress 6748 / 9694 Time remaining: 2s Progress 6749 / 9694 Time remaining: 2s Progress 6750 / 9694 Time remaining: 2s Progress 6751 / 9694 Time remaining: 2s Progress 6752 / 9694 Time remaining: 2s Progress 6753 / 9694 Time remaining: 2s Progress 6754 / 9694 Time remaining: 2s Progress 6755 / 9694 Time remaining: 2s Progress 6756 / 9694 Time remaining: 2s Progress 6757 / 9694 Time remaining: 2s Progress 6758 / 9694 Time remaining: 2s Progress 6759 / 9694 Time remaining: 2s Progress 6760 / 9694 Time remaining: 2s Progress 6761 / 9694 Time remaining: 2s Progress 6762 / 9694 Time remaining: 2s Progress 6763 / 9694 Time remaining: 2s Progress 6764 / 9694 Time remaining: 2s Progress 6765 / 9694 Time remaining: 2s Progress 6766 / 9694 Time remaining: 2s Progress 6767 / 9694 Time remaining: 2s Progress 6768 / 9694 Time remaining: 2s Progress 6769 / 9694 Time remaining: 2s Progress 6770 / 9694 Time remaining: 2s Progress 6771 / 9694 Time remaining: 2s Progress 6772 / 9694 Time remaining: 2s Progress 6773 / 9694 Time remaining: 2s Progress 6774 / 9694 Time remaining: 2s Progress 6775 / 9694 Time remaining: 2s Progress 6776 / 9694 Time remaining: 2s Progress 6777 / 9694 Time remaining: 2s Progress 6778 / 9694 Time remaining: 2s Progress 6779 / 9694 Time remaining: 2s Progress 6780 / 9694 Time remaining: 2s Progress 6781 / 9694 Time remaining: 2s Progress 6782 / 9694 Time remaining: 2s Progress 6783 / 9694 Time remaining: 2s Progress 6784 / 9694 Time remaining: 2s Progress 6785 / 9694 Time remaining: 2s Progress 6786 / 9694 Time remaining: 2s Progress 6787 / 9694 Time remaining: 2s Progress 6788 / 9694 Time remaining: 2s Progress 6789 / 9694 Time remaining: 2s Progress 6790 / 9694 Time remaining: 2s Progress 6791 / 9694 Time remaining: 2s Progress 6792 / 9694 Time remaining: 2s Progress 6793 / 9694 Time remaining: 2s Progress 6794 / 9694 Time remaining: 2s Progress 6795 / 9694 Time remaining: 2s Progress 6796 / 9694 Time remaining: 2s Progress 6797 / 9694 Time remaining: 2s Progress 6798 / 9694 Time remaining: 2s Progress 6799 / 9694 Time remaining: 2s Progress 6800 / 9694 Time remaining: 2s Progress 6801 / 9694 Time remaining: 2s Progress 6802 / 9694 Time remaining: 2s Progress 6803 / 9694 Time remaining: 2s Progress 6804 / 9694 Time remaining: 2s Progress 6805 / 9694 Time remaining: 2s Progress 6806 / 9694 Time remaining: 2s Progress 6807 / 9694 Time remaining: 2s Progress 6808 / 9694 Time remaining: 2s Progress 6809 / 9694 Time remaining: 2s Progress 6810 / 9694 Time remaining: 2s Progress 6811 / 9694 Time remaining: 2s Progress 6812 / 9694 Time remaining: 2s Progress 6813 / 9694 Time remaining: 2s Progress 6814 / 9694 Time remaining: 2s Progress 6815 / 9694 Time remaining: 2s Progress 6816 / 9694 Time remaining: 2s Progress 6817 / 9694 Time remaining: 2s Progress 6818 / 9694 Time remaining: 2s Progress 6819 / 9694 Time remaining: 2s Progress 6820 / 9694 Time remaining: 2s Progress 6821 / 9694 Time remaining: 2s Progress 6822 / 9694 Time remaining: 2s Progress 6823 / 9694 Time remaining: 2s Progress 6824 / 9694 Time remaining: 2s Progress 6825 / 9694 Time remaining: 2s Progress 6826 / 9694 Time remaining: 2s Progress 6827 / 9694 Time remaining: 2s Progress 6828 / 9694 Time remaining: 2s Progress 6829 / 9694 Time remaining: 2s Progress 6830 / 9694 Time remaining: 2s Progress 6831 / 9694 Time remaining: 2s Progress 6832 / 9694 Time remaining: 2s Progress 6833 / 9694 Time remaining: 2s Progress 6834 / 9694 Time remaining: 2s Progress 6835 / 9694 Time remaining: 2s Progress 6836 / 9694 Time remaining: 2s Progress 6837 / 9694 Time remaining: 2s Progress 6838 / 9694 Time remaining: 2s Progress 6839 / 9694 Time remaining: 2s Progress 6840 / 9694 Time remaining: 2s Progress 6841 / 9694 Time remaining: 2s Progress 6842 / 9694 Time remaining: 2s Progress 6843 / 9694 Time remaining: 2s Progress 6844 / 9694 Time remaining: 2s Progress 6845 / 9694 Time remaining: 2s Progress 6846 / 9694 Time remaining: 2s Progress 6847 / 9694 Time remaining: 2s Progress 6848 / 9694 Time remaining: 2s Progress 6849 / 9694 Time remaining: 2s Progress 6850 / 9694 Time remaining: 2s Progress 6851 / 9694 Time remaining: 2s Progress 6852 / 9694 Time remaining: 2s Progress 6853 / 9694 Time remaining: 2s Progress 6854 / 9694 Time remaining: 2s Progress 6855 / 9694 Time remaining: 2s Progress 6856 / 9694 Time remaining: 2s Progress 6857 / 9694 Time remaining: 2s Progress 6858 / 9694 Time remaining: 2s Progress 6859 / 9694 Time remaining: 2s Progress 6860 / 9694 Time remaining: 2s Progress 6861 / 9694 Time remaining: 2s Progress 6862 / 9694 Time remaining: 2s Progress 6863 / 9694 Time remaining: 2s Progress 6864 / 9694 Time remaining: 2s Progress 6865 / 9694 Time remaining: 2s Progress 6866 / 9694 Time remaining: 2s Progress 6867 / 9694 Time remaining: 2s Progress 6868 / 9694 Time remaining: 2s Progress 6869 / 9694 Time remaining: 2s Progress 6870 / 9694 Time remaining: 2s Progress 6871 / 9694 Time remaining: 2s Progress 6872 / 9694 Time remaining: 2s Progress 6873 / 9694 Time remaining: 2s Progress 6874 / 9694 Time remaining: 2s Progress 6875 / 9694 Time remaining: 2s Progress 6876 / 9694 Time remaining: 2s Progress 6877 / 9694 Time remaining: 2s Progress 6878 / 9694 Time remaining: 2s Progress 6879 / 9694 Time remaining: 2s Progress 6880 / 9694 Time remaining: 2s Progress 6881 / 9694 Time remaining: 2s Progress 6882 / 9694 Time remaining: 2s Progress 6883 / 9694 Time remaining: 2s Progress 6884 / 9694 Time remaining: 2s Progress 6885 / 9694 Time remaining: 2s Progress 6886 / 9694 Time remaining: 1s Progress 6887 / 9694 Time remaining: 1s Progress 6888 / 9694 Time remaining: 1s Progress 6889 / 9694 Time remaining: 1s Progress 6890 / 9694 Time remaining: 1s Progress 6891 / 9694 Time remaining: 1s Progress 6892 / 9694 Time remaining: 1s Progress 6893 / 9694 Time remaining: 1s Progress 6894 / 9694 Time remaining: 1s Progress 6895 / 9694 Time remaining: 1s Progress 6896 / 9694 Time remaining: 1s Progress 6897 / 9694 Time remaining: 1s Progress 6898 / 9694 Time remaining: 1s Progress 6899 / 9694 Time remaining: 1s Progress 6900 / 9694 Time remaining: 1s Progress 6901 / 9694 Time remaining: 1s Progress 6902 / 9694 Time remaining: 1s Progress 6903 / 9694 Time remaining: 1s Progress 6904 / 9694 Time remaining: 1s Progress 6905 / 9694 Time remaining: 1s Progress 6906 / 9694 Time remaining: 1s Progress 6907 / 9694 Time remaining: 1s Progress 6908 / 9694 Time remaining: 1s Progress 6909 / 9694 Time remaining: 1s Progress 6910 / 9694 Time remaining: 1s Progress 6911 / 9694 Time remaining: 1s Progress 6912 / 9694 Time remaining: 1s Progress 6913 / 9694 Time remaining: 1s Progress 6914 / 9694 Time remaining: 1s Progress 6915 / 9694 Time remaining: 1s Progress 6916 / 9694 Time remaining: 1s Progress 6917 / 9694 Time remaining: 1s Progress 6918 / 9694 Time remaining: 1s Progress 6919 / 9694 Time remaining: 1s Progress 6920 / 9694 Time remaining: 1s Progress 6921 / 9694 Time remaining: 1s Progress 6922 / 9694 Time remaining: 1s Progress 6923 / 9694 Time remaining: 1s Progress 6924 / 9694 Time remaining: 1s Progress 6925 / 9694 Time remaining: 1s Progress 6926 / 9694 Time remaining: 1s Progress 6927 / 9694 Time remaining: 1s Progress 6928 / 9694 Time remaining: 1s Progress 6929 / 9694 Time remaining: 1s Progress 6930 / 9694 Time remaining: 1s Progress 6931 / 9694 Time remaining: 1s Progress 6932 / 9694 Time remaining: 1s Progress 6933 / 9694 Time remaining: 1s Progress 6934 / 9694 Time remaining: 1s Progress 6935 / 9694 Time remaining: 1s Progress 6936 / 9694 Time remaining: 1s Progress 6937 / 9694 Time remaining: 1s Progress 6938 / 9694 Time remaining: 1s Progress 6939 / 9694 Time remaining: 1s Progress 6940 / 9694 Time remaining: 1s Progress 6941 / 9694 Time remaining: 1s Progress 6942 / 9694 Time remaining: 1s Progress 6943 / 9694 Time remaining: 1s Progress 6944 / 9694 Time remaining: 1s Progress 6945 / 9694 Time remaining: 1s Progress 6946 / 9694 Time remaining: 1s Progress 6947 / 9694 Time remaining: 1s Progress 6948 / 9694 Time remaining: 1s Progress 6949 / 9694 Time remaining: 1s Progress 6950 / 9694 Time remaining: 1s Progress 6951 / 9694 Time remaining: 1s Progress 6952 / 9694 Time remaining: 1s Progress 6953 / 9694 Time remaining: 1s Progress 6954 / 9694 Time remaining: 1s Progress 6955 / 9694 Time remaining: 1s Progress 6956 / 9694 Time remaining: 1s Progress 6957 / 9694 Time remaining: 1s Progress 6958 / 9694 Time remaining: 1s Progress 6959 / 9694 Time remaining: 1s Progress 6960 / 9694 Time remaining: 1s Progress 6961 / 9694 Time remaining: 1s Progress 6962 / 9694 Time remaining: 1s Progress 6963 / 9694 Time remaining: 1s Progress 6964 / 9694 Time remaining: 1s Progress 6965 / 9694 Time remaining: 1s Progress 6966 / 9694 Time remaining: 1s Progress 6967 / 9694 Time remaining: 1s Progress 6968 / 9694 Time remaining: 1s Progress 6969 / 9694 Time remaining: 1s Progress 6970 / 9694 Time remaining: 1s Progress 6971 / 9694 Time remaining: 1s Progress 6972 / 9694 Time remaining: 1s Progress 6973 / 9694 Time remaining: 1s Progress 6974 / 9694 Time remaining: 1s Progress 6975 / 9694 Time remaining: 1s Progress 6976 / 9694 Time remaining: 1s Progress 6977 / 9694 Time remaining: 1s Progress 6978 / 9694 Time remaining: 1s Progress 6979 / 9694 Time remaining: 1s Progress 6980 / 9694 Time remaining: 1s Progress 6981 / 9694 Time remaining: 1s Progress 6982 / 9694 Time remaining: 1s Progress 6983 / 9694 Time remaining: 1s Progress 6984 / 9694 Time remaining: 1s Progress 6985 / 9694 Time remaining: 1s Progress 6986 / 9694 Time remaining: 1s Progress 6987 / 9694 Time remaining: 1s Progress 6988 / 9694 Time remaining: 1s Progress 6989 / 9694 Time remaining: 1s Progress 6990 / 9694 Time remaining: 1s Progress 6991 / 9694 Time remaining: 1s Progress 6992 / 9694 Time remaining: 1s Progress 6993 / 9694 Time remaining: 1s Progress 6994 / 9694 Time remaining: 1s Progress 6995 / 9694 Time remaining: 1s Progress 6996 / 9694 Time remaining: 1s Progress 6997 / 9694 Time remaining: 1s Progress 6998 / 9694 Time remaining: 1s Progress 6999 / 9694 Time remaining: 1s Progress 7000 / 9694 Time remaining: 1s Progress 7001 / 9694 Time remaining: 1s Progress 7002 / 9694 Time remaining: 1s Progress 7003 / 9694 Time remaining: 1s Progress 7004 / 9694 Time remaining: 1s Progress 7005 / 9694 Time remaining: 1s Progress 7006 / 9694 Time remaining: 1s Progress 7007 / 9694 Time remaining: 1s Progress 7008 / 9694 Time remaining: 1s Progress 7009 / 9694 Time remaining: 1s Progress 7010 / 9694 Time remaining: 1s Progress 7011 / 9694 Time remaining: 1s Progress 7012 / 9694 Time remaining: 1s Progress 7013 / 9694 Time remaining: 1s Progress 7014 / 9694 Time remaining: 1s Progress 7015 / 9694 Time remaining: 1s Progress 7016 / 9694 Time remaining: 1s Progress 7017 / 9694 Time remaining: 1s Progress 7018 / 9694 Time remaining: 1s Progress 7019 / 9694 Time remaining: 1s Progress 7020 / 9694 Time remaining: 1s Progress 7021 / 9694 Time remaining: 1s Progress 7022 / 9694 Time remaining: 1s Progress 7023 / 9694 Time remaining: 1s Progress 7024 / 9694 Time remaining: 1s Progress 7025 / 9694 Time remaining: 1s Progress 7026 / 9694 Time remaining: 1s Progress 7027 / 9694 Time remaining: 1s Progress 7028 / 9694 Time remaining: 1s Progress 7029 / 9694 Time remaining: 1s Progress 7030 / 9694 Time remaining: 1s Progress 7031 / 9694 Time remaining: 1s Progress 7032 / 9694 Time remaining: 1s Progress 7033 / 9694 Time remaining: 1s Progress 7034 / 9694 Time remaining: 1s Progress 7035 / 9694 Time remaining: 1s Progress 7036 / 9694 Time remaining: 1s Progress 7037 / 9694 Time remaining: 1s Progress 7038 / 9694 Time remaining: 1s Progress 7039 / 9694 Time remaining: 1s Progress 7040 / 9694 Time remaining: 1s Progress 7041 / 9694 Time remaining: 1s Progress 7042 / 9694 Time remaining: 1s Progress 7043 / 9694 Time remaining: 1s Progress 7044 / 9694 Time remaining: 1s Progress 7045 / 9694 Time remaining: 1s Progress 7046 / 9694 Time remaining: 1s Progress 7047 / 9694 Time remaining: 1s Progress 7048 / 9694 Time remaining: 1s Progress 7049 / 9694 Time remaining: 1s Progress 7050 / 9694 Time remaining: 1s Progress 7051 / 9694 Time remaining: 1s Progress 7052 / 9694 Time remaining: 1s Progress 7053 / 9694 Time remaining: 1s Progress 7054 / 9694 Time remaining: 1s Progress 7055 / 9694 Time remaining: 1s Progress 7056 / 9694 Time remaining: 1s Progress 7057 / 9694 Time remaining: 1s Progress 7058 / 9694 Time remaining: 1s Progress 7059 / 9694 Time remaining: 1s Progress 7060 / 9694 Time remaining: 1s Progress 7061 / 9694 Time remaining: 1s Progress 7062 / 9694 Time remaining: 1s Progress 7063 / 9694 Time remaining: 1s Progress 7064 / 9694 Time remaining: 1s Progress 7065 / 9694 Time remaining: 1s Progress 7066 / 9694 Time remaining: 1s Progress 7067 / 9694 Time remaining: 1s Progress 7068 / 9694 Time remaining: 1s Progress 7069 / 9694 Time remaining: 1s Progress 7070 / 9694 Time remaining: 1s Progress 7071 / 9694 Time remaining: 1s Progress 7072 / 9694 Time remaining: 1s Progress 7073 / 9694 Time remaining: 1s Progress 7074 / 9694 Time remaining: 1s Progress 7075 / 9694 Time remaining: 1s Progress 7076 / 9694 Time remaining: 1s Progress 7077 / 9694 Time remaining: 1s Progress 7078 / 9694 Time remaining: 1s Progress 7079 / 9694 Time remaining: 1s Progress 7080 / 9694 Time remaining: 1s Progress 7081 / 9694 Time remaining: 1s Progress 7082 / 9694 Time remaining: 1s Progress 7083 / 9694 Time remaining: 1s Progress 7084 / 9694 Time remaining: 1s Progress 7085 / 9694 Time remaining: 1s Progress 7086 / 9694 Time remaining: 1s Progress 7087 / 9694 Time remaining: 1s Progress 7088 / 9694 Time remaining: 1s Progress 7089 / 9694 Time remaining: 1s Progress 7090 / 9694 Time remaining: 1s Progress 7091 / 9694 Time remaining: 1s Progress 7092 / 9694 Time remaining: 1s Progress 7093 / 9694 Time remaining: 1s Progress 7094 / 9694 Time remaining: 1s Progress 7095 / 9694 Time remaining: 1s Progress 7096 / 9694 Time remaining: 1s Progress 7097 / 9694 Time remaining: 1s Progress 7098 / 9694 Time remaining: 1s Progress 7099 / 9694 Time remaining: 1s Progress 7100 / 9694 Time remaining: 1s Progress 7101 / 9694 Time remaining: 1s Progress 7102 / 9694 Time remaining: 1s Progress 7103 / 9694 Time remaining: 1s Progress 7104 / 9694 Time remaining: 1s Progress 7105 / 9694 Time remaining: 1s Progress 7106 / 9694 Time remaining: 1s Progress 7107 / 9694 Time remaining: 1s Progress 7108 / 9694 Time remaining: 1s Progress 7109 / 9694 Time remaining: 1s Progress 7110 / 9694 Time remaining: 1s Progress 7111 / 9694 Time remaining: 1s Progress 7112 / 9694 Time remaining: 1s Progress 7113 / 9694 Time remaining: 1s Progress 7114 / 9694 Time remaining: 1s Progress 7115 / 9694 Time remaining: 1s Progress 7116 / 9694 Time remaining: 1s Progress 7117 / 9694 Time remaining: 1s Progress 7118 / 9694 Time remaining: 1s Progress 7119 / 9694 Time remaining: 1s Progress 7120 / 9694 Time remaining: 1s Progress 7121 / 9694 Time remaining: 1s Progress 7122 / 9694 Time remaining: 1s Progress 7123 / 9694 Time remaining: 1s Progress 7124 / 9694 Time remaining: 1s Progress 7125 / 9694 Time remaining: 1s Progress 7126 / 9694 Time remaining: 1s Progress 7127 / 9694 Time remaining: 1s Progress 7128 / 9694 Time remaining: 1s Progress 7129 / 9694 Time remaining: 1s Progress 7130 / 9694 Time remaining: 1s Progress 7131 / 9694 Time remaining: 1s Progress 7132 / 9694 Time remaining: 1s Progress 7133 / 9694 Time remaining: 1s Progress 7134 / 9694 Time remaining: 1s Progress 7135 / 9694 Time remaining: 1s Progress 7136 / 9694 Time remaining: 1s Progress 7137 / 9694 Time remaining: 1s Progress 7138 / 9694 Time remaining: 1s Progress 7139 / 9694 Time remaining: 1s Progress 7140 / 9694 Time remaining: 1s Progress 7141 / 9694 Time remaining: 1s Progress 7142 / 9694 Time remaining: 1s Progress 7143 / 9694 Time remaining: 1s Progress 7144 / 9694 Time remaining: 1s Progress 7145 / 9694 Time remaining: 1s Progress 7146 / 9694 Time remaining: 1s Progress 7147 / 9694 Time remaining: 1s Progress 7148 / 9694 Time remaining: 1s Progress 7149 / 9694 Time remaining: 1s Progress 7150 / 9694 Time remaining: 1s Progress 7151 / 9694 Time remaining: 1s Progress 7152 / 9694 Time remaining: 1s Progress 7153 / 9694 Time remaining: 1s Progress 7154 / 9694 Time remaining: 1s Progress 7155 / 9694 Time remaining: 1s Progress 7156 / 9694 Time remaining: 1s Progress 7157 / 9694 Time remaining: 1s Progress 7158 / 9694 Time remaining: 1s Progress 7159 / 9694 Time remaining: 1s Progress 7160 / 9694 Time remaining: 1s Progress 7161 / 9694 Time remaining: 1s Progress 7162 / 9694 Time remaining: 1s Progress 7163 / 9694 Time remaining: 1s Progress 7164 / 9694 Time remaining: 1s Progress 7165 / 9694 Time remaining: 1s Progress 7166 / 9694 Time remaining: 1s Progress 7167 / 9694 Time remaining: 1s Progress 7168 / 9694 Time remaining: 1s Progress 7169 / 9694 Time remaining: 1s Progress 7170 / 9694 Time remaining: 1s Progress 7171 / 9694 Time remaining: 1s Progress 7172 / 9694 Time remaining: 1s Progress 7173 / 9694 Time remaining: 1s Progress 7174 / 9694 Time remaining: 1s Progress 7175 / 9694 Time remaining: 1s Progress 7176 / 9694 Time remaining: 1s Progress 7177 / 9694 Time remaining: 1s Progress 7178 / 9694 Time remaining: 1s Progress 7179 / 9694 Time remaining: 1s Progress 7180 / 9694 Time remaining: 1s Progress 7181 / 9694 Time remaining: 1s Progress 7182 / 9694 Time remaining: 1s Progress 7183 / 9694 Time remaining: 1s Progress 7184 / 9694 Time remaining: 1s Progress 7185 / 9694 Time remaining: 1s Progress 7186 / 9694 Time remaining: 1s Progress 7187 / 9694 Time remaining: 1s Progress 7188 / 9694 Time remaining: 1s Progress 7189 / 9694 Time remaining: 1s Progress 7190 / 9694 Time remaining: 1s Progress 7191 / 9694 Time remaining: 1s Progress 7192 / 9694 Time remaining: 1s Progress 7193 / 9694 Time remaining: 1s Progress 7194 / 9694 Time remaining: 1s Progress 7195 / 9694 Time remaining: 1s Progress 7196 / 9694 Time remaining: 1s Progress 7197 / 9694 Time remaining: 1s Progress 7198 / 9694 Time remaining: 1s Progress 7199 / 9694 Time remaining: 1s Progress 7200 / 9694 Time remaining: 1s Progress 7201 / 9694 Time remaining: 1s Progress 7202 / 9694 Time remaining: 1s Progress 7203 / 9694 Time remaining: 1s Progress 7204 / 9694 Time remaining: 1s Progress 7205 / 9694 Time remaining: 1s Progress 7206 / 9694 Time remaining: 1s Progress 7207 / 9694 Time remaining: 1s Progress 7208 / 9694 Time remaining: 1s Progress 7209 / 9694 Time remaining: 1s Progress 7210 / 9694 Time remaining: 1s Progress 7211 / 9694 Time remaining: 1s Progress 7212 / 9694 Time remaining: 1s Progress 7213 / 9694 Time remaining: 1s Progress 7214 / 9694 Time remaining: 1s Progress 7215 / 9694 Time remaining: 1s Progress 7216 / 9694 Time remaining: 1s Progress 7217 / 9694 Time remaining: 1s Progress 7218 / 9694 Time remaining: 1s Progress 7219 / 9694 Time remaining: 1s Progress 7220 / 9694 Time remaining: 1s Progress 7221 / 9694 Time remaining: 1s Progress 7222 / 9694 Time remaining: 1s Progress 7223 / 9694 Time remaining: 1s Progress 7224 / 9694 Time remaining: 1s Progress 7225 / 9694 Time remaining: 1s Progress 7226 / 9694 Time remaining: 1s Progress 7227 / 9694 Time remaining: 1s Progress 7228 / 9694 Time remaining: 1s Progress 7229 / 9694 Time remaining: 1s Progress 7230 / 9694 Time remaining: 1s Progress 7231 / 9694 Time remaining: 1s Progress 7232 / 9694 Time remaining: 1s Progress 7233 / 9694 Time remaining: 1s Progress 7234 / 9694 Time remaining: 1s Progress 7235 / 9694 Time remaining: 1s Progress 7236 / 9694 Time remaining: 1s Progress 7237 / 9694 Time remaining: 1s Progress 7238 / 9694 Time remaining: 1s Progress 7239 / 9694 Time remaining: 1s Progress 7240 / 9694 Time remaining: 1s Progress 7241 / 9694 Time remaining: 1s Progress 7242 / 9694 Time remaining: 1s Progress 7243 / 9694 Time remaining: 1s Progress 7244 / 9694 Time remaining: 1s Progress 7245 / 9694 Time remaining: 1s Progress 7246 / 9694 Time remaining: 1s Progress 7247 / 9694 Time remaining: 1s Progress 7248 / 9694 Time remaining: 1s Progress 7249 / 9694 Time remaining: 1s Progress 7250 / 9694 Time remaining: 1s Progress 7251 / 9694 Time remaining: 1s Progress 7252 / 9694 Time remaining: 1s Progress 7253 / 9694 Time remaining: 1s Progress 7254 / 9694 Time remaining: 1s Progress 7255 / 9694 Time remaining: 1s Progress 7256 / 9694 Time remaining: 1s Progress 7257 / 9694 Time remaining: 1s Progress 7258 / 9694 Time remaining: 1s Progress 7259 / 9694 Time remaining: 1s Progress 7260 / 9694 Time remaining: 1s Progress 7261 / 9694 Time remaining: 1s Progress 7262 / 9694 Time remaining: 1s Progress 7263 / 9694 Time remaining: 1s Progress 7264 / 9694 Time remaining: 1s Progress 7265 / 9694 Time remaining: 1s Progress 7266 / 9694 Time remaining: 1s Progress 7267 / 9694 Time remaining: 1s Progress 7268 / 9694 Time remaining: 1s Progress 7269 / 9694 Time remaining: 1s Progress 7270 / 9694 Time remaining: 1s Progress 7271 / 9694 Time remaining: 1s Progress 7272 / 9694 Time remaining: 1s Progress 7273 / 9694 Time remaining: 1s Progress 7274 / 9694 Time remaining: 1s Progress 7275 / 9694 Time remaining: 1s Progress 7276 / 9694 Time remaining: 1s Progress 7277 / 9694 Time remaining: 1s Progress 7278 / 9694 Time remaining: 1s Progress 7279 / 9694 Time remaining: 1s Progress 7280 / 9694 Time remaining: 1s Progress 7281 / 9694 Time remaining: 1s Progress 7282 / 9694 Time remaining: 1s Progress 7283 / 9694 Time remaining: 1s Progress 7284 / 9694 Time remaining: 1s Progress 7285 / 9694 Time remaining: 1s Progress 7286 / 9694 Time remaining: 1s Progress 7287 / 9694 Time remaining: 1s Progress 7288 / 9694 Time remaining: 1s Progress 7289 / 9694 Time remaining: 1s Progress 7290 / 9694 Time remaining: 1s Progress 7291 / 9694 Time remaining: 1s Progress 7292 / 9694 Time remaining: 1s Progress 7293 / 9694 Time remaining: 1s Progress 7294 / 9694 Time remaining: 1s Progress 7295 / 9694 Time remaining: 1s Progress 7296 / 9694 Time remaining: 1s Progress 7297 / 9694 Time remaining: 1s Progress 7298 / 9694 Time remaining: 1s Progress 7299 / 9694 Time remaining: 1s Progress 7300 / 9694 Time remaining: 1s Progress 7301 / 9694 Time remaining: 1s Progress 7302 / 9694 Time remaining: 1s Progress 7303 / 9694 Time remaining: 1s Progress 7304 / 9694 Time remaining: 1s Progress 7305 / 9694 Time remaining: 1s Progress 7306 / 9694 Time remaining: 1s Progress 7307 / 9694 Time remaining: 1s Progress 7308 / 9694 Time remaining: 1s Progress 7309 / 9694 Time remaining: 1s Progress 7310 / 9694 Time remaining: 1s Progress 7311 / 9694 Time remaining: 1s Progress 7312 / 9694 Time remaining: 1s Progress 7313 / 9694 Time remaining: 1s Progress 7314 / 9694 Time remaining: 1s Progress 7315 / 9694 Time remaining: 1s Progress 7316 / 9694 Time remaining: 1s Progress 7317 / 9694 Time remaining: 1s Progress 7318 / 9694 Time remaining: 1s Progress 7319 / 9694 Time remaining: 1s Progress 7320 / 9694 Time remaining: 1s Progress 7321 / 9694 Time remaining: 1s Progress 7322 / 9694 Time remaining: 1s Progress 7323 / 9694 Time remaining: 1s Progress 7324 / 9694 Time remaining: 1s Progress 7325 / 9694 Time remaining: 1s Progress 7326 / 9694 Time remaining: 1s Progress 7327 / 9694 Time remaining: 1s Progress 7328 / 9694 Time remaining: 1s Progress 7329 / 9694 Time remaining: 1s Progress 7330 / 9694 Time remaining: 1s Progress 7331 / 9694 Time remaining: 1s Progress 7332 / 9694 Time remaining: 1s Progress 7333 / 9694 Time remaining: 1s Progress 7334 / 9694 Time remaining: 1s Progress 7335 / 9694 Time remaining: 1s Progress 7336 / 9694 Time remaining: 1s Progress 7337 / 9694 Time remaining: 1s Progress 7338 / 9694 Time remaining: 1s Progress 7339 / 9694 Time remaining: 1s Progress 7340 / 9694 Time remaining: 1s Progress 7341 / 9694 Time remaining: 1s Progress 7342 / 9694 Time remaining: 1s Progress 7343 / 9694 Time remaining: 1s Progress 7344 / 9694 Time remaining: 1s Progress 7345 / 9694 Time remaining: 1s Progress 7346 / 9694 Time remaining: 1s Progress 7347 / 9694 Time remaining: 1s Progress 7348 / 9694 Time remaining: 1s Progress 7349 / 9694 Time remaining: 1s Progress 7350 / 9694 Time remaining: 1s Progress 7351 / 9694 Time remaining: 1s Progress 7352 / 9694 Time remaining: 1s Progress 7353 / 9694 Time remaining: 1s Progress 7354 / 9694 Time remaining: 1s Progress 7355 / 9694 Time remaining: 1s Progress 7356 / 9694 Time remaining: 1s Progress 7357 / 9694 Time remaining: 1s Progress 7358 / 9694 Time remaining: 1s Progress 7359 / 9694 Time remaining: 1s Progress 7360 / 9694 Time remaining: 1s Progress 7361 / 9694 Time remaining: 1s Progress 7362 / 9694 Time remaining: 1s Progress 7363 / 9694 Time remaining: 1s Progress 7364 / 9694 Time remaining: 1s Progress 7365 / 9694 Time remaining: 1s Progress 7366 / 9694 Time remaining: 1s Progress 7367 / 9694 Time remaining: 1s Progress 7368 / 9694 Time remaining: 1s Progress 7369 / 9694 Time remaining: 1s Progress 7370 / 9694 Time remaining: 1s Progress 7371 / 9694 Time remaining: 1s Progress 7372 / 9694 Time remaining: 1s Progress 7373 / 9694 Time remaining: 1s Progress 7374 / 9694 Time remaining: 1s Progress 7375 / 9694 Time remaining: 1s Progress 7376 / 9694 Time remaining: 1s Progress 7377 / 9694 Time remaining: 1s Progress 7378 / 9694 Time remaining: 1s Progress 7379 / 9694 Time remaining: 1s Progress 7380 / 9694 Time remaining: 1s Progress 7381 / 9694 Time remaining: 1s Progress 7382 / 9694 Time remaining: 1s Progress 7383 / 9694 Time remaining: 1s Progress 7384 / 9694 Time remaining: 1s Progress 7385 / 9694 Time remaining: 1s Progress 7386 / 9694 Time remaining: 1s Progress 7387 / 9694 Time remaining: 1s Progress 7388 / 9694 Time remaining: 1s Progress 7389 / 9694 Time remaining: 1s Progress 7390 / 9694 Time remaining: 1s Progress 7391 / 9694 Time remaining: 1s Progress 7392 / 9694 Time remaining: 1s Progress 7393 / 9694 Time remaining: 1s Progress 7394 / 9694 Time remaining: 1s Progress 7395 / 9694 Time remaining: 1s Progress 7396 / 9694 Time remaining: 1s Progress 7397 / 9694 Time remaining: 1s Progress 7398 / 9694 Time remaining: 1s Progress 7399 / 9694 Time remaining: 1s Progress 7400 / 9694 Time remaining: 1s Progress 7401 / 9694 Time remaining: 1s Progress 7402 / 9694 Time remaining: 1s Progress 7403 / 9694 Time remaining: 1s Progress 7404 / 9694 Time remaining: 1s Progress 7405 / 9694 Time remaining: 1s Progress 7406 / 9694 Time remaining: 1s Progress 7407 / 9694 Time remaining: 1s Progress 7408 / 9694 Time remaining: 1s Progress 7409 / 9694 Time remaining: 1s Progress 7410 / 9694 Time remaining: 1s Progress 7411 / 9694 Time remaining: 1s Progress 7412 / 9694 Time remaining: 1s Progress 7413 / 9694 Time remaining: 1s Progress 7414 / 9694 Time remaining: 1s Progress 7415 / 9694 Time remaining: 1s Progress 7416 / 9694 Time remaining: 1s Progress 7417 / 9694 Time remaining: 1s Progress 7418 / 9694 Time remaining: 1s Progress 7419 / 9694 Time remaining: 1s Progress 7420 / 9694 Time remaining: 1s Progress 7421 / 9694 Time remaining: 1s Progress 7422 / 9694 Time remaining: 1s Progress 7423 / 9694 Time remaining: 1s Progress 7424 / 9694 Time remaining: 1s Progress 7425 / 9694 Time remaining: 1s Progress 7426 / 9694 Time remaining: 1s Progress 7427 / 9694 Time remaining: 1s Progress 7428 / 9694 Time remaining: 1s Progress 7429 / 9694 Time remaining: 1s Progress 7430 / 9694 Time remaining: 1s Progress 7431 / 9694 Time remaining: 1s Progress 7432 / 9694 Time remaining: 1s Progress 7433 / 9694 Time remaining: 1s Progress 7434 / 9694 Time remaining: 1s Progress 7435 / 9694 Time remaining: 1s Progress 7436 / 9694 Time remaining: 1s Progress 7437 / 9694 Time remaining: 1s Progress 7438 / 9694 Time remaining: 1s Progress 7439 / 9694 Time remaining: 1s Progress 7440 / 9694 Time remaining: 1s Progress 7441 / 9694 Time remaining: 1s Progress 7442 / 9694 Time remaining: 1s Progress 7443 / 9694 Time remaining: 1s Progress 7444 / 9694 Time remaining: 1s Progress 7445 / 9694 Time remaining: 1s Progress 7446 / 9694 Time remaining: 1s Progress 7447 / 9694 Time remaining: 1s Progress 7448 / 9694 Time remaining: 1s Progress 7449 / 9694 Time remaining: 1s Progress 7450 / 9694 Time remaining: 1s Progress 7451 / 9694 Time remaining: 1s Progress 7452 / 9694 Time remaining: 1s Progress 7453 / 9694 Time remaining: 1s Progress 7454 / 9694 Time remaining: 1s Progress 7455 / 9694 Time remaining: 1s Progress 7456 / 9694 Time remaining: 1s Progress 7457 / 9694 Time remaining: 1s Progress 7458 / 9694 Time remaining: 1s Progress 7459 / 9694 Time remaining: 1s Progress 7460 / 9694 Time remaining: 1s Progress 7461 / 9694 Time remaining: 1s Progress 7462 / 9694 Time remaining: 1s Progress 7463 / 9694 Time remaining: 1s Progress 7464 / 9694 Time remaining: 1s Progress 7465 / 9694 Time remaining: 1s Progress 7466 / 9694 Time remaining: 1s Progress 7467 / 9694 Time remaining: 1s Progress 7468 / 9694 Time remaining: 1s Progress 7469 / 9694 Time remaining: 1s Progress 7470 / 9694 Time remaining: 1s Progress 7471 / 9694 Time remaining: 1s Progress 7472 / 9694 Time remaining: 1s Progress 7473 / 9694 Time remaining: 1s Progress 7474 / 9694 Time remaining: 1s Progress 7475 / 9694 Time remaining: 1s Progress 7476 / 9694 Time remaining: 1s Progress 7477 / 9694 Time remaining: 1s Progress 7478 / 9694 Time remaining: 1s Progress 7479 / 9694 Time remaining: 1s Progress 7480 / 9694 Time remaining: 1s Progress 7481 / 9694 Time remaining: 1s Progress 7482 / 9694 Time remaining: 1s Progress 7483 / 9694 Time remaining: 1s Progress 7484 / 9694 Time remaining: 1s Progress 7485 / 9694 Time remaining: 1s Progress 7486 / 9694 Time remaining: 1s Progress 7487 / 9694 Time remaining: 1s Progress 7488 / 9694 Time remaining: 1s Progress 7489 / 9694 Time remaining: 1s Progress 7490 / 9694 Time remaining: 1s Progress 7491 / 9694 Time remaining: 1s Progress 7492 / 9694 Time remaining: 1s Progress 7493 / 9694 Time remaining: 1s Progress 7494 / 9694 Time remaining: 1s Progress 7495 / 9694 Time remaining: 1s Progress 7496 / 9694 Time remaining: 1s Progress 7497 / 9694 Time remaining: 1s Progress 7498 / 9694 Time remaining: 1s Progress 7499 / 9694 Time remaining: 1s Progress 7500 / 9694 Time remaining: 1s Progress 7501 / 9694 Time remaining: 1s Progress 7502 / 9694 Time remaining: 1s Progress 7503 / 9694 Time remaining: 1s Progress 7504 / 9694 Time remaining: 1s Progress 7505 / 9694 Time remaining: 1s Progress 7506 / 9694 Time remaining: 1s Progress 7507 / 9694 Time remaining: 1s Progress 7508 / 9694 Time remaining: 1s Progress 7509 / 9694 Time remaining: 1s Progress 7510 / 9694 Time remaining: 1s Progress 7511 / 9694 Time remaining: 1s Progress 7512 / 9694 Time remaining: 1s Progress 7513 / 9694 Time remaining: 1s Progress 7514 / 9694 Time remaining: 1s Progress 7515 / 9694 Time remaining: 1s Progress 7516 / 9694 Time remaining: 1s Progress 7517 / 9694 Time remaining: 1s Progress 7518 / 9694 Time remaining: 1s Progress 7519 / 9694 Time remaining: 1s Progress 7520 / 9694 Time remaining: 1s Progress 7521 / 9694 Time remaining: 1s Progress 7522 / 9694 Time remaining: 1s Progress 7523 / 9694 Time remaining: 1s Progress 7524 / 9694 Time remaining: 1s Progress 7525 / 9694 Time remaining: 1s Progress 7526 / 9694 Time remaining: 1s Progress 7527 / 9694 Time remaining: 1s Progress 7528 / 9694 Time remaining: 1s Progress 7529 / 9694 Time remaining: 1s Progress 7530 / 9694 Time remaining: 1s Progress 7531 / 9694 Time remaining: 1s Progress 7532 / 9694 Time remaining: 1s Progress 7533 / 9694 Time remaining: 1s Progress 7534 / 9694 Time remaining: 1s Progress 7535 / 9694 Time remaining: 1s Progress 7536 / 9694 Time remaining: 1s Progress 7537 / 9694 Time remaining: 1s Progress 7538 / 9694 Time remaining: 1s Progress 7539 / 9694 Time remaining: 1s Progress 7540 / 9694 Time remaining: 1s Progress 7541 / 9694 Time remaining: 1s Progress 7542 / 9694 Time remaining: 1s Progress 7543 / 9694 Time remaining: 1s Progress 7544 / 9694 Time remaining: 1s Progress 7545 / 9694 Time remaining: 1s Progress 7546 / 9694 Time remaining: 1s Progress 7547 / 9694 Time remaining: 1s Progress 7548 / 9694 Time remaining: 1s Progress 7549 / 9694 Time remaining: 1s Progress 7550 / 9694 Time remaining: 1s Progress 7551 / 9694 Time remaining: 1s Progress 7552 / 9694 Time remaining: 1s Progress 7553 / 9694 Time remaining: 1s Progress 7554 / 9694 Time remaining: 1s Progress 7555 / 9694 Time remaining: 1s Progress 7556 / 9694 Time remaining: 1s Progress 7557 / 9694 Time remaining: 1s Progress 7558 / 9694 Time remaining: 1s Progress 7559 / 9694 Time remaining: 1s Progress 7560 / 9694 Time remaining: 1s Progress 7561 / 9694 Time remaining: 1s Progress 7562 / 9694 Time remaining: 1s Progress 7563 / 9694 Time remaining: 1s Progress 7564 / 9694 Time remaining: 1s Progress 7565 / 9694 Time remaining: 1s Progress 7566 / 9694 Time remaining: 1s Progress 7567 / 9694 Time remaining: 1s Progress 7568 / 9694 Time remaining: 1s Progress 7569 / 9694 Time remaining: 1s Progress 7570 / 9694 Time remaining: 1s Progress 7571 / 9694 Time remaining: 1s Progress 7572 / 9694 Time remaining: 1s Progress 7573 / 9694 Time remaining: 1s Progress 7574 / 9694 Time remaining: 1s Progress 7575 / 9694 Time remaining: 1s Progress 7576 / 9694 Time remaining: 1s Progress 7577 / 9694 Time remaining: 1s Progress 7578 / 9694 Time remaining: 1s Progress 7579 / 9694 Time remaining: 1s Progress 7580 / 9694 Time remaining: 1s Progress 7581 / 9694 Time remaining: 1s Progress 7582 / 9694 Time remaining: 1s Progress 7583 / 9694 Time remaining: 1s Progress 7584 / 9694 Time remaining: 1s Progress 7585 / 9694 Time remaining: 1s Progress 7586 / 9694 Time remaining: 1s Progress 7587 / 9694 Time remaining: 1s Progress 7588 / 9694 Time remaining: 1s Progress 7589 / 9694 Time remaining: 1s Progress 7590 / 9694 Time remaining: 1s Progress 7591 / 9694 Time remaining: 1s Progress 7592 / 9694 Time remaining: 1s Progress 7593 / 9694 Time remaining: 1s Progress 7594 / 9694 Time remaining: 1s Progress 7595 / 9694 Time remaining: 1s Progress 7596 / 9694 Time remaining: 1s Progress 7597 / 9694 Time remaining: 1s Progress 7598 / 9694 Time remaining: 1s Progress 7599 / 9694 Time remaining: 1s Progress 7600 / 9694 Time remaining: 1s Progress 7601 / 9694 Time remaining: 1s Progress 7602 / 9694 Time remaining: 1s Progress 7603 / 9694 Time remaining: 1s Progress 7604 / 9694 Time remaining: 1s Progress 7605 / 9694 Time remaining: 1s Progress 7606 / 9694 Time remaining: 1s Progress 7607 / 9694 Time remaining: 1s Progress 7608 / 9694 Time remaining: 1s Progress 7609 / 9694 Time remaining: 1s Progress 7610 / 9694 Time remaining: 1s Progress 7611 / 9694 Time remaining: 1s Progress 7612 / 9694 Time remaining: 1s Progress 7613 / 9694 Time remaining: 1s Progress 7614 / 9694 Time remaining: 1s Progress 7615 / 9694 Time remaining: 1s Progress 7616 / 9694 Time remaining: 1s Progress 7617 / 9694 Time remaining: 1s Progress 7618 / 9694 Time remaining: 1s Progress 7619 / 9694 Time remaining: 1s Progress 7620 / 9694 Time remaining: 1s Progress 7621 / 9694 Time remaining: 1s Progress 7622 / 9694 Time remaining: 1s Progress 7623 / 9694 Time remaining: 1s Progress 7624 / 9694 Time remaining: 1s Progress 7625 / 9694 Time remaining: 1s Progress 7626 / 9694 Time remaining: 1s Progress 7627 / 9694 Time remaining: 1s Progress 7628 / 9694 Time remaining: 1s Progress 7629 / 9694 Time remaining: 1s Progress 7630 / 9694 Time remaining: 1s Progress 7631 / 9694 Time remaining: 1s Progress 7632 / 9694 Time remaining: 1s Progress 7633 / 9694 Time remaining: 1s Progress 7634 / 9694 Time remaining: 1s Progress 7635 / 9694 Time remaining: 1s Progress 7636 / 9694 Time remaining: 1s Progress 7637 / 9694 Time remaining: 1s Progress 7638 / 9694 Time remaining: 1s Progress 7639 / 9694 Time remaining: 1s Progress 7640 / 9694 Time remaining: 1s Progress 7641 / 9694 Time remaining: 1s Progress 7642 / 9694 Time remaining: 1s Progress 7643 / 9694 Time remaining: 1s Progress 7644 / 9694 Time remaining: 1s Progress 7645 / 9694 Time remaining: 1s Progress 7646 / 9694 Time remaining: 1s Progress 7647 / 9694 Time remaining: 1s Progress 7648 / 9694 Time remaining: 1s Progress 7649 / 9694 Time remaining: 1s Progress 7650 / 9694 Time remaining: 1s Progress 7651 / 9694 Time remaining: 1s Progress 7652 / 9694 Time remaining: 1s Progress 7653 / 9694 Time remaining: 1s Progress 7654 / 9694 Time remaining: 1s Progress 7655 / 9694 Time remaining: 1s Progress 7656 / 9694 Time remaining: 1s Progress 7657 / 9694 Time remaining: 1s Progress 7658 / 9694 Time remaining: 1s Progress 7659 / 9694 Time remaining: 1s Progress 7660 / 9694 Time remaining: 1s Progress 7661 / 9694 Time remaining: 1s Progress 7662 / 9694 Time remaining: 1s Progress 7663 / 9694 Time remaining: 1s Progress 7664 / 9694 Time remaining: 1s Progress 7665 / 9694 Time remaining: 1s Progress 7666 / 9694 Time remaining: 1s Progress 7667 / 9694 Time remaining: 1s Progress 7668 / 9694 Time remaining: 1s Progress 7669 / 9694 Time remaining: 1s Progress 7670 / 9694 Time remaining: 1s Progress 7671 / 9694 Time remaining: 1s Progress 7672 / 9694 Time remaining: 1s Progress 7673 / 9694 Time remaining: 1s Progress 7674 / 9694 Time remaining: 1s Progress 7675 / 9694 Time remaining: 1s Progress 7676 / 9694 Time remaining: 1s Progress 7677 / 9694 Time remaining: 1s Progress 7678 / 9694 Time remaining: 1s Progress 7679 / 9694 Time remaining: 1s Progress 7680 / 9694 Time remaining: 1s Progress 7681 / 9694 Time remaining: 1s Progress 7682 / 9694 Time remaining: 1s Progress 7683 / 9694 Time remaining: 1s Progress 7684 / 9694 Time remaining: 1s Progress 7685 / 9694 Time remaining: 1s Progress 7686 / 9694 Time remaining: 1s Progress 7687 / 9694 Time remaining: 1s Progress 7688 / 9694 Time remaining: 1s Progress 7689 / 9694 Time remaining: 1s Progress 7690 / 9694 Time remaining: 1s Progress 7691 / 9694 Time remaining: 1s Progress 7692 / 9694 Time remaining: 1s Progress 7693 / 9694 Time remaining: 1s Progress 7694 / 9694 Time remaining: 1s Progress 7695 / 9694 Time remaining: 1s Progress 7696 / 9694 Time remaining: 1s Progress 7697 / 9694 Time remaining: 1s Progress 7698 / 9694 Time remaining: 1s Progress 7699 / 9694 Time remaining: 1s Progress 7700 / 9694 Time remaining: 1s Progress 7701 / 9694 Time remaining: 1s Progress 7702 / 9694 Time remaining: 1s Progress 7703 / 9694 Time remaining: 1s Progress 7704 / 9694 Time remaining: 1s Progress 7705 / 9694 Time remaining: 1s Progress 7706 / 9694 Time remaining: 1s Progress 7707 / 9694 Time remaining: 1s Progress 7708 / 9694 Time remaining: 1s Progress 7709 / 9694 Time remaining: 1s Progress 7710 / 9694 Time remaining: 1s Progress 7711 / 9694 Time remaining: 1s Progress 7712 / 9694 Time remaining: 1s Progress 7713 / 9694 Time remaining: 1s Progress 7714 / 9694 Time remaining: 1s Progress 7715 / 9694 Time remaining: 1s Progress 7716 / 9694 Time remaining: 1s Progress 7717 / 9694 Time remaining: 1s Progress 7718 / 9694 Time remaining: 1s Progress 7719 / 9694 Time remaining: 1s Progress 7720 / 9694 Time remaining: 1s Progress 7721 / 9694 Time remaining: 1s Progress 7722 / 9694 Time remaining: 1s Progress 7723 / 9694 Time remaining: 1s Progress 7724 / 9694 Time remaining: 1s Progress 7725 / 9694 Time remaining: 1s Progress 7726 / 9694 Time remaining: 1s Progress 7727 / 9694 Time remaining: 1s Progress 7728 / 9694 Time remaining: 1s Progress 7729 / 9694 Time remaining: 1s Progress 7730 / 9694 Time remaining: 1s Progress 7731 / 9694 Time remaining: 1s Progress 7732 / 9694 Time remaining: 1s Progress 7733 / 9694 Time remaining: 1s Progress 7734 / 9694 Time remaining: 1s Progress 7735 / 9694 Time remaining: 1s Progress 7736 / 9694 Time remaining: 1s Progress 7737 / 9694 Time remaining: 1s Progress 7738 / 9694 Time remaining: 1s Progress 7739 / 9694 Time remaining: 1s Progress 7740 / 9694 Time remaining: 1s Progress 7741 / 9694 Time remaining: 1s Progress 7742 / 9694 Time remaining: 1s Progress 7743 / 9694 Time remaining: 1s Progress 7744 / 9694 Time remaining: 1s Progress 7745 / 9694 Time remaining: 1s Progress 7746 / 9694 Time remaining: 1s Progress 7747 / 9694 Time remaining: 1s Progress 7748 / 9694 Time remaining: 1s Progress 7749 / 9694 Time remaining: 1s Progress 7750 / 9694 Time remaining: 1s Progress 7751 / 9694 Time remaining: 1s Progress 7752 / 9694 Time remaining: 1s Progress 7753 / 9694 Time remaining: 1s Progress 7754 / 9694 Time remaining: 1s Progress 7755 / 9694 Time remaining: 1s Progress 7756 / 9694 Time remaining: 1s Progress 7757 / 9694 Time remaining: 1s Progress 7758 / 9694 Time remaining: 1s Progress 7759 / 9694 Time remaining: 1s Progress 7760 / 9694 Time remaining: 1s Progress 7761 / 9694 Time remaining: 1s Progress 7762 / 9694 Time remaining: 1s Progress 7763 / 9694 Time remaining: 1s Progress 7764 / 9694 Time remaining: 1s Progress 7765 / 9694 Time remaining: 1s Progress 7766 / 9694 Time remaining: 1s Progress 7767 / 9694 Time remaining: 1s Progress 7768 / 9694 Time remaining: 1s Progress 7769 / 9694 Time remaining: 1s Progress 7770 / 9694 Time remaining: 1s Progress 7771 / 9694 Time remaining: 1s Progress 7772 / 9694 Time remaining: 1s Progress 7773 / 9694 Time remaining: 1s Progress 7774 / 9694 Time remaining: 1s Progress 7775 / 9694 Time remaining: 1s Progress 7776 / 9694 Time remaining: 1s Progress 7777 / 9694 Time remaining: 1s Progress 7778 / 9694 Time remaining: 1s Progress 7779 / 9694 Time remaining: 1s Progress 7780 / 9694 Time remaining: 1s Progress 7781 / 9694 Time remaining: 1s Progress 7782 / 9694 Time remaining: 1s Progress 7783 / 9694 Time remaining: 1s Progress 7784 / 9694 Time remaining: 1s Progress 7785 / 9694 Time remaining: 1s Progress 7786 / 9694 Time remaining: 1s Progress 7787 / 9694 Time remaining: 1s Progress 7788 / 9694 Time remaining: 1s Progress 7789 / 9694 Time remaining: 1s Progress 7790 / 9694 Time remaining: 1s Progress 7791 / 9694 Time remaining: 1s Progress 7792 / 9694 Time remaining: 1s Progress 7793 / 9694 Time remaining: 1s Progress 7794 / 9694 Time remaining: 1s Progress 7795 / 9694 Time remaining: 1s Progress 7796 / 9694 Time remaining: 1s Progress 7797 / 9694 Time remaining: 1s Progress 7798 / 9694 Time remaining: 1s Progress 7799 / 9694 Time remaining: 1s Progress 7800 / 9694 Time remaining: 1s Progress 7801 / 9694 Time remaining: 1s Progress 7802 / 9694 Time remaining: 1s Progress 7803 / 9694 Time remaining: 1s Progress 7804 / 9694 Time remaining: 1s Progress 7805 / 9694 Time remaining: 1s Progress 7806 / 9694 Time remaining: 1s Progress 7807 / 9694 Time remaining: 1s Progress 7808 / 9694 Time remaining: 1s Progress 7809 / 9694 Time remaining: 1s Progress 7810 / 9694 Time remaining: 1s Progress 7811 / 9694 Time remaining: 1s Progress 7812 / 9694 Time remaining: 1s Progress 7813 / 9694 Time remaining: 1s Progress 7814 / 9694 Time remaining: 1s Progress 7815 / 9694 Time remaining: 1s Progress 7816 / 9694 Time remaining: 1s Progress 7817 / 9694 Time remaining: 1s Progress 7818 / 9694 Time remaining: 1s Progress 7819 / 9694 Time remaining: 1s Progress 7820 / 9694 Time remaining: 1s Progress 7821 / 9694 Time remaining: 1s Progress 7822 / 9694 Time remaining: 1s Progress 7823 / 9694 Time remaining: 1s Progress 7824 / 9694 Time remaining: 1s Progress 7825 / 9694 Time remaining: 1s Progress 7826 / 9694 Time remaining: 1s Progress 7827 / 9694 Time remaining: 1s Progress 7828 / 9694 Time remaining: 1s Progress 7829 / 9694 Time remaining: 1s Progress 7830 / 9694 Time remaining: 1s Progress 7831 / 9694 Time remaining: 1s Progress 7832 / 9694 Time remaining: 1s Progress 7833 / 9694 Time remaining: 1s Progress 7834 / 9694 Time remaining: 1s Progress 7835 / 9694 Time remaining: 1s Progress 7836 / 9694 Time remaining: 1s Progress 7837 / 9694 Time remaining: 1s Progress 7838 / 9694 Time remaining: 1s Progress 7839 / 9694 Time remaining: 1s Progress 7840 / 9694 Time remaining: 1s Progress 7841 / 9694 Time remaining: 1s Progress 7842 / 9694 Time remaining: 1s Progress 7843 / 9694 Time remaining: 1s Progress 7844 / 9694 Time remaining: 1s Progress 7845 / 9694 Time remaining: 1s Progress 7846 / 9694 Time remaining: 1s Progress 7847 / 9694 Time remaining: 1s Progress 7848 / 9694 Time remaining: 1s Progress 7849 / 9694 Time remaining: 1s Progress 7850 / 9694 Time remaining: 1s Progress 7851 / 9694 Time remaining: 1s Progress 7852 / 9694 Time remaining: 1s Progress 7853 / 9694 Time remaining: 1s Progress 7854 / 9694 Time remaining: 1s Progress 7855 / 9694 Time remaining: 1s Progress 7856 / 9694 Time remaining: 1s Progress 7857 / 9694 Time remaining: 1s Progress 7858 / 9694 Time remaining: 1s Progress 7859 / 9694 Time remaining: 1s Progress 7860 / 9694 Time remaining: 1s Progress 7861 / 9694 Time remaining: 1s Progress 7862 / 9694 Time remaining: 1s Progress 7863 / 9694 Time remaining: 1s Progress 7864 / 9694 Time remaining: 1s Progress 7865 / 9694 Time remaining: 1s Progress 7866 / 9694 Time remaining: 1s Progress 7867 / 9694 Time remaining: 1s Progress 7868 / 9694 Time remaining: 1s Progress 7869 / 9694 Time remaining: 1s Progress 7870 / 9694 Time remaining: 1s Progress 7871 / 9694 Time remaining: 1s Progress 7872 / 9694 Time remaining: 1s Progress 7873 / 9694 Time remaining: 1s Progress 7874 / 9694 Time remaining: 1s Progress 7875 / 9694 Time remaining: 1s Progress 7876 / 9694 Time remaining: 1s Progress 7877 / 9694 Time remaining: 1s Progress 7878 / 9694 Time remaining: 1s Progress 7879 / 9694 Time remaining: 1s Progress 7880 / 9694 Time remaining: 1s Progress 7881 / 9694 Time remaining: 1s Progress 7882 / 9694 Time remaining: 1s Progress 7883 / 9694 Time remaining: 1s Progress 7884 / 9694 Time remaining: 1s Progress 7885 / 9694 Time remaining: 1s Progress 7886 / 9694 Time remaining: 1s Progress 7887 / 9694 Time remaining: 1s Progress 7888 / 9694 Time remaining: 1s Progress 7889 / 9694 Time remaining: 1s Progress 7890 / 9694 Time remaining: 1s Progress 7891 / 9694 Time remaining: 1s Progress 7892 / 9694 Time remaining: 1s Progress 7893 / 9694 Time remaining: 1s Progress 7894 / 9694 Time remaining: 1s Progress 7895 / 9694 Time remaining: 1s Progress 7896 / 9694 Time remaining: 1s Progress 7897 / 9694 Time remaining: 1s Progress 7898 / 9694 Time remaining: 1s Progress 7899 / 9694 Time remaining: 1s Progress 7900 / 9694 Time remaining: 1s Progress 7901 / 9694 Time remaining: 1s Progress 7902 / 9694 Time remaining: 1s Progress 7903 / 9694 Time remaining: 1s Progress 7904 / 9694 Time remaining: 1s Progress 7905 / 9694 Time remaining: 1s Progress 7906 / 9694 Time remaining: 1s Progress 7907 / 9694 Time remaining: 1s Progress 7908 / 9694 Time remaining: 1s Progress 7909 / 9694 Time remaining: 1s Progress 7910 / 9694 Time remaining: 1s Progress 7911 / 9694 Time remaining: 1s Progress 7912 / 9694 Time remaining: 1s Progress 7913 / 9694 Time remaining: 1s Progress 7914 / 9694 Time remaining: 1s Progress 7915 / 9694 Time remaining: 1s Progress 7916 / 9694 Time remaining: 1s Progress 7917 / 9694 Time remaining: 1s Progress 7918 / 9694 Time remaining: 1s Progress 7919 / 9694 Time remaining: 1s Progress 7920 / 9694 Time remaining: 1s Progress 7921 / 9694 Time remaining: 1s Progress 7922 / 9694 Time remaining: 1s Progress 7923 / 9694 Time remaining: 1s Progress 7924 / 9694 Time remaining: 1s Progress 7925 / 9694 Time remaining: 1s Progress 7926 / 9694 Time remaining: 1s Progress 7927 / 9694 Time remaining: 1s Progress 7928 / 9694 Time remaining: 1s Progress 7929 / 9694 Time remaining: 1s Progress 7930 / 9694 Time remaining: 1s Progress 7931 / 9694 Time remaining: 1s Progress 7932 / 9694 Time remaining: 1s Progress 7933 / 9694 Time remaining: 1s Progress 7934 / 9694 Time remaining: 1s Progress 7935 / 9694 Time remaining: 1s Progress 7936 / 9694 Time remaining: 1s Progress 7937 / 9694 Time remaining: 1s Progress 7938 / 9694 Time remaining: 1s Progress 7939 / 9694 Time remaining: 1s Progress 7940 / 9694 Time remaining: 1s Progress 7941 / 9694 Time remaining: 1s Progress 7942 / 9694 Time remaining: 1s Progress 7943 / 9694 Time remaining: 1s Progress 7944 / 9694 Time remaining: 1s Progress 7945 / 9694 Time remaining: 1s Progress 7946 / 9694 Time remaining: 1s Progress 7947 / 9694 Time remaining: 1s Progress 7948 / 9694 Time remaining: 1s Progress 7949 / 9694 Time remaining: 1s Progress 7950 / 9694 Time remaining: 1s Progress 7951 / 9694 Time remaining: 1s Progress 7952 / 9694 Time remaining: 1s Progress 7953 / 9694 Time remaining: 1s Progress 7954 / 9694 Time remaining: 1s Progress 7955 / 9694 Time remaining: 1s Progress 7956 / 9694 Time remaining: 1s Progress 7957 / 9694 Time remaining: 1s Progress 7958 / 9694 Time remaining: 1s Progress 7959 / 9694 Time remaining: 1s Progress 7960 / 9694 Time remaining: 1s Progress 7961 / 9694 Time remaining: 1s Progress 7962 / 9694 Time remaining: 1s Progress 7963 / 9694 Time remaining: 1s Progress 7964 / 9694 Time remaining: 1s Progress 7965 / 9694 Time remaining: 1s Progress 7966 / 9694 Time remaining: 1s Progress 7967 / 9694 Time remaining: 1s Progress 7968 / 9694 Time remaining: 1s Progress 7969 / 9694 Time remaining: 1s Progress 7970 / 9694 Time remaining: 1s Progress 7971 / 9694 Time remaining: 1s Progress 7972 / 9694 Time remaining: 1s Progress 7973 / 9694 Time remaining: 1s Progress 7974 / 9694 Time remaining: 1s Progress 7975 / 9694 Time remaining: 1s Progress 7976 / 9694 Time remaining: 1s Progress 7977 / 9694 Time remaining: 1s Progress 7978 / 9694 Time remaining: 1s Progress 7979 / 9694 Time remaining: 1s Progress 7980 / 9694 Time remaining: 1s Progress 7981 / 9694 Time remaining: 1s Progress 7982 / 9694 Time remaining: 1s Progress 7983 / 9694 Time remaining: 1s Progress 7984 / 9694 Time remaining: 1s Progress 7985 / 9694 Time remaining: 1s Progress 7986 / 9694 Time remaining: 1s Progress 7987 / 9694 Time remaining: 1s Progress 7988 / 9694 Time remaining: 1s Progress 7989 / 9694 Time remaining: 1s Progress 7990 / 9694 Time remaining: 1s Progress 7991 / 9694 Time remaining: 1s Progress 7992 / 9694 Time remaining: 1s Progress 7993 / 9694 Time remaining: 1s Progress 7994 / 9694 Time remaining: 1s Progress 7995 / 9694 Time remaining: 1s Progress 7996 / 9694 Time remaining: 1s Progress 7997 / 9694 Time remaining: 1s Progress 7998 / 9694 Time remaining: 1s Progress 7999 / 9694 Time remaining: 1s Progress 8000 / 9694 Time remaining: 1s Progress 8001 / 9694 Time remaining: 1s Progress 8002 / 9694 Time remaining: 1s Progress 8003 / 9694 Time remaining: 1s Progress 8004 / 9694 Time remaining: 1s Progress 8005 / 9694 Time remaining: 1s Progress 8006 / 9694 Time remaining: 1s Progress 8007 / 9694 Time remaining: 1s Progress 8008 / 9694 Time remaining: 1s Progress 8009 / 9694 Time remaining: 1s Progress 8010 / 9694 Time remaining: 1s Progress 8011 / 9694 Time remaining: 1s Progress 8012 / 9694 Time remaining: 1s Progress 8013 / 9694 Time remaining: 1s Progress 8014 / 9694 Time remaining: 1s Progress 8015 / 9694 Time remaining: 1s Progress 8016 / 9694 Time remaining: 1s Progress 8017 / 9694 Time remaining: 1s Progress 8018 / 9694 Time remaining: 1s Progress 8019 / 9694 Time remaining: 1s Progress 8020 / 9694 Time remaining: 1s Progress 8021 / 9694 Time remaining: 1s Progress 8022 / 9694 Time remaining: 1s Progress 8023 / 9694 Time remaining: 1s Progress 8024 / 9694 Time remaining: 1s Progress 8025 / 9694 Time remaining: 1s Progress 8026 / 9694 Time remaining: 1s Progress 8027 / 9694 Time remaining: 1s Progress 8028 / 9694 Time remaining: 1s Progress 8029 / 9694 Time remaining: 1s Progress 8030 / 9694 Time remaining: 1s Progress 8031 / 9694 Time remaining: 1s Progress 8032 / 9694 Time remaining: 1s Progress 8033 / 9694 Time remaining: 1s Progress 8034 / 9694 Time remaining: 1s Progress 8035 / 9694 Time remaining: 1s Progress 8036 / 9694 Time remaining: 1s Progress 8037 / 9694 Time remaining: 1s Progress 8038 / 9694 Time remaining: 1s Progress 8039 / 9694 Time remaining: 1s Progress 8040 / 9694 Time remaining: 1s Progress 8041 / 9694 Time remaining: 1s Progress 8042 / 9694 Time remaining: 1s Progress 8043 / 9694 Time remaining: 1s Progress 8044 / 9694 Time remaining: 1s Progress 8045 / 9694 Time remaining: 1s Progress 8046 / 9694 Time remaining: 1s Progress 8047 / 9694 Time remaining: 1s Progress 8048 / 9694 Time remaining: 1s Progress 8049 / 9694 Time remaining: 1s Progress 8050 / 9694 Time remaining: 1s Progress 8051 / 9694 Time remaining: 1s Progress 8052 / 9694 Time remaining: 1s Progress 8053 / 9694 Time remaining: 1s Progress 8054 / 9694 Time remaining: 1s Progress 8055 / 9694 Time remaining: 1s Progress 8056 / 9694 Time remaining: 1s Progress 8057 / 9694 Time remaining: 1s Progress 8058 / 9694 Time remaining: 1s Progress 8059 / 9694 Time remaining: 1s Progress 8060 / 9694 Time remaining: 1s Progress 8061 / 9694 Time remaining: 1s Progress 8062 / 9694 Time remaining: 1s Progress 8063 / 9694 Time remaining: 1s Progress 8064 / 9694 Time remaining: 1s Progress 8065 / 9694 Time remaining: 1s Progress 8066 / 9694 Time remaining: 1s Progress 8067 / 9694 Time remaining: 1s Progress 8068 / 9694 Time remaining: 1s Progress 8069 / 9694 Time remaining: 1s Progress 8070 / 9694 Time remaining: 1s Progress 8071 / 9694 Time remaining: 1s Progress 8072 / 9694 Time remaining: 1s Progress 8073 / 9694 Time remaining: 1s Progress 8074 / 9694 Time remaining: 1s Progress 8075 / 9694 Time remaining: 1s Progress 8076 / 9694 Time remaining: 1s Progress 8077 / 9694 Time remaining: 1s Progress 8078 / 9694 Time remaining: 1s Progress 8079 / 9694 Time remaining: 1s Progress 8080 / 9694 Time remaining: 1s Progress 8081 / 9694 Time remaining: 1s Progress 8082 / 9694 Time remaining: 1s Progress 8083 / 9694 Time remaining: 1s Progress 8084 / 9694 Time remaining: 1s Progress 8085 / 9694 Time remaining: 1s Progress 8086 / 9694 Time remaining: 1s Progress 8087 / 9694 Time remaining: 1s Progress 8088 / 9694 Time remaining: 1s Progress 8089 / 9694 Time remaining: 1s Progress 8090 / 9694 Time remaining: 1s Progress 8091 / 9694 Time remaining: 1s Progress 8092 / 9694 Time remaining: 1s Progress 8093 / 9694 Time remaining: 1s Progress 8094 / 9694 Time remaining: 1s Progress 8095 / 9694 Time remaining: 1s Progress 8096 / 9694 Time remaining: 1s Progress 8097 / 9694 Time remaining: 1s Progress 8098 / 9694 Time remaining: 1s Progress 8099 / 9694 Time remaining: 1s Progress 8100 / 9694 Time remaining: 1s Progress 8101 / 9694 Time remaining: 1s Progress 8102 / 9694 Time remaining: 1s Progress 8103 / 9694 Time remaining: 1s Progress 8104 / 9694 Time remaining: 1s Progress 8105 / 9694 Time remaining: 1s Progress 8106 / 9694 Time remaining: 1s Progress 8107 / 9694 Time remaining: 1s Progress 8108 / 9694 Time remaining: 1s Progress 8109 / 9694 Time remaining: 1s Progress 8110 / 9694 Time remaining: 1s Progress 8111 / 9694 Time remaining: 1s Progress 8112 / 9694 Time remaining: 1s Progress 8113 / 9694 Time remaining: 1s Progress 8114 / 9694 Time remaining: 1s Progress 8115 / 9694 Time remaining: 1s Progress 8116 / 9694 Time remaining: 1s Progress 8117 / 9694 Time remaining: 1s Progress 8118 / 9694 Time remaining: 1s Progress 8119 / 9694 Time remaining: 1s Progress 8120 / 9694 Time remaining: 1s Progress 8121 / 9694 Time remaining: 1s Progress 8122 / 9694 Time remaining: 1s Progress 8123 / 9694 Time remaining: 1s Progress 8124 / 9694 Time remaining: 1s Progress 8125 / 9694 Time remaining: 1s Progress 8126 / 9694 Time remaining: 1s Progress 8127 / 9694 Time remaining: 1s Progress 8128 / 9694 Time remaining: 1s Progress 8129 / 9694 Time remaining: 1s Progress 8130 / 9694 Time remaining: 1s Progress 8131 / 9694 Time remaining: 1s Progress 8132 / 9694 Time remaining: 1s Progress 8133 / 9694 Time remaining: 1s Progress 8134 / 9694 Time remaining: 1s Progress 8135 / 9694 Time remaining: 1s Progress 8136 / 9694 Time remaining: 1s Progress 8137 / 9694 Time remaining: 1s Progress 8138 / 9694 Time remaining: 1s Progress 8139 / 9694 Time remaining: 1s Progress 8140 / 9694 Time remaining: 1s Progress 8141 / 9694 Time remaining: 1s Progress 8142 / 9694 Time remaining: 1s Progress 8143 / 9694 Time remaining: 1s Progress 8144 / 9694 Time remaining: 1s Progress 8145 / 9694 Time remaining: 1s Progress 8146 / 9694 Time remaining: 1s Progress 8147 / 9694 Time remaining: 1s Progress 8148 / 9694 Time remaining: 1s Progress 8149 / 9694 Time remaining: 1s Progress 8150 / 9694 Time remaining: 1s Progress 8151 / 9694 Time remaining: 1s Progress 8152 / 9694 Time remaining: 1s Progress 8153 / 9694 Time remaining: 1s Progress 8154 / 9694 Time remaining: 1s Progress 8155 / 9694 Time remaining: 1s Progress 8156 / 9694 Time remaining: 1s Progress 8157 / 9694 Time remaining: 1s Progress 8158 / 9694 Time remaining: 1s Progress 8159 / 9694 Time remaining: 1s Progress 8160 / 9694 Time remaining: 1s Progress 8161 / 9694 Time remaining: 1s Progress 8162 / 9694 Time remaining: 1s Progress 8163 / 9694 Time remaining: 1s Progress 8164 / 9694 Time remaining: 1s Progress 8165 / 9694 Time remaining: 1s Progress 8166 / 9694 Time remaining: 1s Progress 8167 / 9694 Time remaining: 1s Progress 8168 / 9694 Time remaining: 1s Progress 8169 / 9694 Time remaining: 1s Progress 8170 / 9694 Time remaining: 1s Progress 8171 / 9694 Time remaining: 1s Progress 8172 / 9694 Time remaining: 1s Progress 8173 / 9694 Time remaining: 1s Progress 8174 / 9694 Time remaining: 1s Progress 8175 / 9694 Time remaining: 1s Progress 8176 / 9694 Time remaining: 1s Progress 8177 / 9694 Time remaining: 1s Progress 8178 / 9694 Time remaining: 1s Progress 8179 / 9694 Time remaining: 1s Progress 8180 / 9694 Time remaining: 1s Progress 8181 / 9694 Time remaining: 1s Progress 8182 / 9694 Time remaining: 1s Progress 8183 / 9694 Time remaining: 1s Progress 8184 / 9694 Time remaining: 1s Progress 8185 / 9694 Time remaining: 1s Progress 8186 / 9694 Time remaining: 1s Progress 8187 / 9694 Time remaining: 1s Progress 8188 / 9694 Time remaining: 1s Progress 8189 / 9694 Time remaining: 1s Progress 8190 / 9694 Time remaining: 1s Progress 8191 / 9694 Time remaining: 1s Progress 8192 / 9694 Time remaining: 1s Progress 8193 / 9694 Time remaining: 1s Progress 8194 / 9694 Time remaining: 1s Progress 8195 / 9694 Time remaining: 1s Progress 8196 / 9694 Time remaining: 1s Progress 8197 / 9694 Time remaining: 1s Progress 8198 / 9694 Time remaining: 1s Progress 8199 / 9694 Time remaining: 1s Progress 8200 / 9694 Time remaining: 1s Progress 8201 / 9694 Time remaining: 1s Progress 8202 / 9694 Time remaining: 1s Progress 8203 / 9694 Time remaining: 1s Progress 8204 / 9694 Time remaining: 1s Progress 8205 / 9694 Time remaining: 1s Progress 8206 / 9694 Time remaining: 1s Progress 8207 / 9694 Time remaining: 1s Progress 8208 / 9694 Time remaining: 1s Progress 8209 / 9694 Time remaining: 1s Progress 8210 / 9694 Time remaining: 1s Progress 8211 / 9694 Time remaining: 1s Progress 8212 / 9694 Time remaining: 1s Progress 8213 / 9694 Time remaining: 1s Progress 8214 / 9694 Time remaining: 1s Progress 8215 / 9694 Time remaining: 1s Progress 8216 / 9694 Time remaining: 1s Progress 8217 / 9694 Time remaining: 1s Progress 8218 / 9694 Time remaining: 1s Progress 8219 / 9694 Time remaining: 1s Progress 8220 / 9694 Time remaining: 1s Progress 8221 / 9694 Time remaining: 1s Progress 8222 / 9694 Time remaining: 1s Progress 8223 / 9694 Time remaining: 1s Progress 8224 / 9694 Time remaining: 1s Progress 8225 / 9694 Time remaining: 1s Progress 8226 / 9694 Time remaining: 1s Progress 8227 / 9694 Time remaining: 1s Progress 8228 / 9694 Time remaining: 1s Progress 8229 / 9694 Time remaining: 1s Progress 8230 / 9694 Time remaining: 1s Progress 8231 / 9694 Time remaining: 1s Progress 8232 / 9694 Time remaining: 1s Progress 8233 / 9694 Time remaining: 1s Progress 8234 / 9694 Time remaining: 1s Progress 8235 / 9694 Time remaining: 1s Progress 8236 / 9694 Time remaining: 1s Progress 8237 / 9694 Time remaining: 1s Progress 8238 / 9694 Time remaining: 1s Progress 8239 / 9694 Time remaining: 1s Progress 8240 / 9694 Time remaining: 1s Progress 8241 / 9694 Time remaining: 1s Progress 8242 / 9694 Time remaining: 1s Progress 8243 / 9694 Time remaining: 1s Progress 8244 / 9694 Time remaining: 1s Progress 8245 / 9694 Time remaining: 1s Progress 8246 / 9694 Time remaining: 1s Progress 8247 / 9694 Time remaining: 1s Progress 8248 / 9694 Time remaining: 1s Progress 8249 / 9694 Time remaining: 1s Progress 8250 / 9694 Time remaining: 1s Progress 8251 / 9694 Time remaining: 1s Progress 8252 / 9694 Time remaining: 1s Progress 8253 / 9694 Time remaining: 1s Progress 8254 / 9694 Time remaining: 1s Progress 8255 / 9694 Time remaining: 1s Progress 8256 / 9694 Time remaining: 1s Progress 8257 / 9694 Time remaining: 1s Progress 8258 / 9694 Time remaining: 1s Progress 8259 / 9694 Time remaining: 1s Progress 8260 / 9694 Time remaining: 1s Progress 8261 / 9694 Time remaining: 1s Progress 8262 / 9694 Time remaining: 1s Progress 8263 / 9694 Time remaining: 1s Progress 8264 / 9694 Time remaining: 1s Progress 8265 / 9694 Time remaining: 1s Progress 8266 / 9694 Time remaining: 1s Progress 8267 / 9694 Time remaining: 1s Progress 8268 / 9694 Time remaining: 1s Progress 8269 / 9694 Time remaining: 1s Progress 8270 / 9694 Time remaining: 1s Progress 8271 / 9694 Time remaining: 1s Progress 8272 / 9694 Time remaining: 1s Progress 8273 / 9694 Time remaining: 1s Progress 8274 / 9694 Time remaining: 1s Progress 8275 / 9694 Time remaining: 1s Progress 8276 / 9694 Time remaining: 1s Progress 8277 / 9694 Time remaining: 1s Progress 8278 / 9694 Time remaining: 1s Progress 8279 / 9694 Time remaining: 1s Progress 8280 / 9694 Time remaining: 1s Progress 8281 / 9694 Time remaining: 1s Progress 8282 / 9694 Time remaining: 1s Progress 8283 / 9694 Time remaining: 1s Progress 8284 / 9694 Time remaining: 1s Progress 8285 / 9694 Time remaining: 1s Progress 8286 / 9694 Time remaining: 1s Progress 8287 / 9694 Time remaining: 1s Progress 8288 / 9694 Time remaining: 1s Progress 8289 / 9694 Time remaining: 1s Progress 8290 / 9694 Time remaining: 1s Progress 8291 / 9694 Time remaining: 0s Progress 8292 / 9694 Time remaining: 0s Progress 8293 / 9694 Time remaining: 0s Progress 8294 / 9694 Time remaining: 0s Progress 8295 / 9694 Time remaining: 0s Progress 8296 / 9694 Time remaining: 0s Progress 8297 / 9694 Time remaining: 0s Progress 8298 / 9694 Time remaining: 0s Progress 8299 / 9694 Time remaining: 0s Progress 8300 / 9694 Time remaining: 0s Progress 8301 / 9694 Time remaining: 0s Progress 8302 / 9694 Time remaining: 0s Progress 8303 / 9694 Time remaining: 0s Progress 8304 / 9694 Time remaining: 0s Progress 8305 / 9694 Time remaining: 0s Progress 8306 / 9694 Time remaining: 0s Progress 8307 / 9694 Time remaining: 0s Progress 8308 / 9694 Time remaining: 0s Progress 8309 / 9694 Time remaining: 0s Progress 8310 / 9694 Time remaining: 0s Progress 8311 / 9694 Time remaining: 0s Progress 8312 / 9694 Time remaining: 0s Progress 8313 / 9694 Time remaining: 0s Progress 8314 / 9694 Time remaining: 0s Progress 8315 / 9694 Time remaining: 0s Progress 8316 / 9694 Time remaining: 0s Progress 8317 / 9694 Time remaining: 0s Progress 8318 / 9694 Time remaining: 0s Progress 8319 / 9694 Time remaining: 0s Progress 8320 / 9694 Time remaining: 0s Progress 8321 / 9694 Time remaining: 0s Progress 8322 / 9694 Time remaining: 0s Progress 8323 / 9694 Time remaining: 0s Progress 8324 / 9694 Time remaining: 0s Progress 8325 / 9694 Time remaining: 0s Progress 8326 / 9694 Time remaining: 0s Progress 8327 / 9694 Time remaining: 0s Progress 8328 / 9694 Time remaining: 0s Progress 8329 / 9694 Time remaining: 0s Progress 8330 / 9694 Time remaining: 0s Progress 8331 / 9694 Time remaining: 0s Progress 8332 / 9694 Time remaining: 0s Progress 8333 / 9694 Time remaining: 0s Progress 8334 / 9694 Time remaining: 0s Progress 8335 / 9694 Time remaining: 0s Progress 8336 / 9694 Time remaining: 0s Progress 8337 / 9694 Time remaining: 0s Progress 8338 / 9694 Time remaining: 0s Progress 8339 / 9694 Time remaining: 0s Progress 8340 / 9694 Time remaining: 0s Progress 8341 / 9694 Time remaining: 0s Progress 8342 / 9694 Time remaining: 0s Progress 8343 / 9694 Time remaining: 0s Progress 8344 / 9694 Time remaining: 0s Progress 8345 / 9694 Time remaining: 0s Progress 8346 / 9694 Time remaining: 0s Progress 8347 / 9694 Time remaining: 0s Progress 8348 / 9694 Time remaining: 0s Progress 8349 / 9694 Time remaining: 0s Progress 8350 / 9694 Time remaining: 0s Progress 8351 / 9694 Time remaining: 0s Progress 8352 / 9694 Time remaining: 0s Progress 8353 / 9694 Time remaining: 0s Progress 8354 / 9694 Time remaining: 0s Progress 8355 / 9694 Time remaining: 0s Progress 8356 / 9694 Time remaining: 0s Progress 8357 / 9694 Time remaining: 0s Progress 8358 / 9694 Time remaining: 0s Progress 8359 / 9694 Time remaining: 0s Progress 8360 / 9694 Time remaining: 0s Progress 8361 / 9694 Time remaining: 0s Progress 8362 / 9694 Time remaining: 0s Progress 8363 / 9694 Time remaining: 0s Progress 8364 / 9694 Time remaining: 0s Progress 8365 / 9694 Time remaining: 0s Progress 8366 / 9694 Time remaining: 0s Progress 8367 / 9694 Time remaining: 0s Progress 8368 / 9694 Time remaining: 0s Progress 8369 / 9694 Time remaining: 0s Progress 8370 / 9694 Time remaining: 0s Progress 8371 / 9694 Time remaining: 0s Progress 8372 / 9694 Time remaining: 0s Progress 8373 / 9694 Time remaining: 0s Progress 8374 / 9694 Time remaining: 0s Progress 8375 / 9694 Time remaining: 0s Progress 8376 / 9694 Time remaining: 0s Progress 8377 / 9694 Time remaining: 0s Progress 8378 / 9694 Time remaining: 0s Progress 8379 / 9694 Time remaining: 0s Progress 8380 / 9694 Time remaining: 0s Progress 8381 / 9694 Time remaining: 0s Progress 8382 / 9694 Time remaining: 0s Progress 8383 / 9694 Time remaining: 0s Progress 8384 / 9694 Time remaining: 0s Progress 8385 / 9694 Time remaining: 0s Progress 8386 / 9694 Time remaining: 0s Progress 8387 / 9694 Time remaining: 0s Progress 8388 / 9694 Time remaining: 0s Progress 8389 / 9694 Time remaining: 0s Progress 8390 / 9694 Time remaining: 0s Progress 8391 / 9694 Time remaining: 0s Progress 8392 / 9694 Time remaining: 0s Progress 8393 / 9694 Time remaining: 0s Progress 8394 / 9694 Time remaining: 0s Progress 8395 / 9694 Time remaining: 0s Progress 8396 / 9694 Time remaining: 0s Progress 8397 / 9694 Time remaining: 0s Progress 8398 / 9694 Time remaining: 0s Progress 8399 / 9694 Time remaining: 0s Progress 8400 / 9694 Time remaining: 0s Progress 8401 / 9694 Time remaining: 0s Progress 8402 / 9694 Time remaining: 0s Progress 8403 / 9694 Time remaining: 0s Progress 8404 / 9694 Time remaining: 0s Progress 8405 / 9694 Time remaining: 0s Progress 8406 / 9694 Time remaining: 0s Progress 8407 / 9694 Time remaining: 0s Progress 8408 / 9694 Time remaining: 0s Progress 8409 / 9694 Time remaining: 0s Progress 8410 / 9694 Time remaining: 0s Progress 8411 / 9694 Time remaining: 0s Progress 8412 / 9694 Time remaining: 0s Progress 8413 / 9694 Time remaining: 0s Progress 8414 / 9694 Time remaining: 0s Progress 8415 / 9694 Time remaining: 0s Progress 8416 / 9694 Time remaining: 0s Progress 8417 / 9694 Time remaining: 0s Progress 8418 / 9694 Time remaining: 0s Progress 8419 / 9694 Time remaining: 0s Progress 8420 / 9694 Time remaining: 0s Progress 8421 / 9694 Time remaining: 0s Progress 8422 / 9694 Time remaining: 0s Progress 8423 / 9694 Time remaining: 0s Progress 8424 / 9694 Time remaining: 0s Progress 8425 / 9694 Time remaining: 0s Progress 8426 / 9694 Time remaining: 0s Progress 8427 / 9694 Time remaining: 0s Progress 8428 / 9694 Time remaining: 0s Progress 8429 / 9694 Time remaining: 0s Progress 8430 / 9694 Time remaining: 0s Progress 8431 / 9694 Time remaining: 0s Progress 8432 / 9694 Time remaining: 0s Progress 8433 / 9694 Time remaining: 0s Progress 8434 / 9694 Time remaining: 0s Progress 8435 / 9694 Time remaining: 0s Progress 8436 / 9694 Time remaining: 0s Progress 8437 / 9694 Time remaining: 0s Progress 8438 / 9694 Time remaining: 0s Progress 8439 / 9694 Time remaining: 0s Progress 8440 / 9694 Time remaining: 0s Progress 8441 / 9694 Time remaining: 0s Progress 8442 / 9694 Time remaining: 0s Progress 8443 / 9694 Time remaining: 0s Progress 8444 / 9694 Time remaining: 0s Progress 8445 / 9694 Time remaining: 0s Progress 8446 / 9694 Time remaining: 0s Progress 8447 / 9694 Time remaining: 0s Progress 8448 / 9694 Time remaining: 0s Progress 8449 / 9694 Time remaining: 0s Progress 8450 / 9694 Time remaining: 0s Progress 8451 / 9694 Time remaining: 0s Progress 8452 / 9694 Time remaining: 0s Progress 8453 / 9694 Time remaining: 0s Progress 8454 / 9694 Time remaining: 0s Progress 8455 / 9694 Time remaining: 0s Progress 8456 / 9694 Time remaining: 0s Progress 8457 / 9694 Time remaining: 0s Progress 8458 / 9694 Time remaining: 0s Progress 8459 / 9694 Time remaining: 0s Progress 8460 / 9694 Time remaining: 0s Progress 8461 / 9694 Time remaining: 0s Progress 8462 / 9694 Time remaining: 0s Progress 8463 / 9694 Time remaining: 0s Progress 8464 / 9694 Time remaining: 0s Progress 8465 / 9694 Time remaining: 0s Progress 8466 / 9694 Time remaining: 0s Progress 8467 / 9694 Time remaining: 0s Progress 8468 / 9694 Time remaining: 0s Progress 8469 / 9694 Time remaining: 0s Progress 8470 / 9694 Time remaining: 0s Progress 8471 / 9694 Time remaining: 0s Progress 8472 / 9694 Time remaining: 0s Progress 8473 / 9694 Time remaining: 0s Progress 8474 / 9694 Time remaining: 0s Progress 8475 / 9694 Time remaining: 0s Progress 8476 / 9694 Time remaining: 0s Progress 8477 / 9694 Time remaining: 0s Progress 8478 / 9694 Time remaining: 0s Progress 8479 / 9694 Time remaining: 0s Progress 8480 / 9694 Time remaining: 0s Progress 8481 / 9694 Time remaining: 0s Progress 8482 / 9694 Time remaining: 0s Progress 8483 / 9694 Time remaining: 0s Progress 8484 / 9694 Time remaining: 0s Progress 8485 / 9694 Time remaining: 0s Progress 8486 / 9694 Time remaining: 0s Progress 8487 / 9694 Time remaining: 0s Progress 8488 / 9694 Time remaining: 0s Progress 8489 / 9694 Time remaining: 0s Progress 8490 / 9694 Time remaining: 0s Progress 8491 / 9694 Time remaining: 0s Progress 8492 / 9694 Time remaining: 0s Progress 8493 / 9694 Time remaining: 0s Progress 8494 / 9694 Time remaining: 0s Progress 8495 / 9694 Time remaining: 0s Progress 8496 / 9694 Time remaining: 0s Progress 8497 / 9694 Time remaining: 0s Progress 8498 / 9694 Time remaining: 0s Progress 8499 / 9694 Time remaining: 0s Progress 8500 / 9694 Time remaining: 0s Progress 8501 / 9694 Time remaining: 0s Progress 8502 / 9694 Time remaining: 0s Progress 8503 / 9694 Time remaining: 0s Progress 8504 / 9694 Time remaining: 0s Progress 8505 / 9694 Time remaining: 0s Progress 8506 / 9694 Time remaining: 0s Progress 8507 / 9694 Time remaining: 0s Progress 8508 / 9694 Time remaining: 0s Progress 8509 / 9694 Time remaining: 0s Progress 8510 / 9694 Time remaining: 0s Progress 8511 / 9694 Time remaining: 0s Progress 8512 / 9694 Time remaining: 0s Progress 8513 / 9694 Time remaining: 0s Progress 8514 / 9694 Time remaining: 0s Progress 8515 / 9694 Time remaining: 0s Progress 8516 / 9694 Time remaining: 0s Progress 8517 / 9694 Time remaining: 0s Progress 8518 / 9694 Time remaining: 0s Progress 8519 / 9694 Time remaining: 0s Progress 8520 / 9694 Time remaining: 0s Progress 8521 / 9694 Time remaining: 0s Progress 8522 / 9694 Time remaining: 0s Progress 8523 / 9694 Time remaining: 0s Progress 8524 / 9694 Time remaining: 0s Progress 8525 / 9694 Time remaining: 0s Progress 8526 / 9694 Time remaining: 0s Progress 8527 / 9694 Time remaining: 0s Progress 8528 / 9694 Time remaining: 0s Progress 8529 / 9694 Time remaining: 0s Progress 8530 / 9694 Time remaining: 0s Progress 8531 / 9694 Time remaining: 0s Progress 8532 / 9694 Time remaining: 0s Progress 8533 / 9694 Time remaining: 0s Progress 8534 / 9694 Time remaining: 0s Progress 8535 / 9694 Time remaining: 0s Progress 8536 / 9694 Time remaining: 0s Progress 8537 / 9694 Time remaining: 0s Progress 8538 / 9694 Time remaining: 0s Progress 8539 / 9694 Time remaining: 0s Progress 8540 / 9694 Time remaining: 0s Progress 8541 / 9694 Time remaining: 0s Progress 8542 / 9694 Time remaining: 0s Progress 8543 / 9694 Time remaining: 0s Progress 8544 / 9694 Time remaining: 0s Progress 8545 / 9694 Time remaining: 0s Progress 8546 / 9694 Time remaining: 0s Progress 8547 / 9694 Time remaining: 0s Progress 8548 / 9694 Time remaining: 0s Progress 8549 / 9694 Time remaining: 0s Progress 8550 / 9694 Time remaining: 0s Progress 8551 / 9694 Time remaining: 0s Progress 8552 / 9694 Time remaining: 0s Progress 8553 / 9694 Time remaining: 0s Progress 8554 / 9694 Time remaining: 0s Progress 8555 / 9694 Time remaining: 0s Progress 8556 / 9694 Time remaining: 0s Progress 8557 / 9694 Time remaining: 0s Progress 8558 / 9694 Time remaining: 0s Progress 8559 / 9694 Time remaining: 0s Progress 8560 / 9694 Time remaining: 0s Progress 8561 / 9694 Time remaining: 0s Progress 8562 / 9694 Time remaining: 0s Progress 8563 / 9694 Time remaining: 0s Progress 8564 / 9694 Time remaining: 0s Progress 8565 / 9694 Time remaining: 0s Progress 8566 / 9694 Time remaining: 0s Progress 8567 / 9694 Time remaining: 0s Progress 8568 / 9694 Time remaining: 0s Progress 8569 / 9694 Time remaining: 0s Progress 8570 / 9694 Time remaining: 0s Progress 8571 / 9694 Time remaining: 0s Progress 8572 / 9694 Time remaining: 0s Progress 8573 / 9694 Time remaining: 0s Progress 8574 / 9694 Time remaining: 0s Progress 8575 / 9694 Time remaining: 0s Progress 8576 / 9694 Time remaining: 0s Progress 8577 / 9694 Time remaining: 0s Progress 8578 / 9694 Time remaining: 0s Progress 8579 / 9694 Time remaining: 0s Progress 8580 / 9694 Time remaining: 0s Progress 8581 / 9694 Time remaining: 0s Progress 8582 / 9694 Time remaining: 0s Progress 8583 / 9694 Time remaining: 0s Progress 8584 / 9694 Time remaining: 0s Progress 8585 / 9694 Time remaining: 0s Progress 8586 / 9694 Time remaining: 0s Progress 8587 / 9694 Time remaining: 0s Progress 8588 / 9694 Time remaining: 0s Progress 8589 / 9694 Time remaining: 0s Progress 8590 / 9694 Time remaining: 0s Progress 8591 / 9694 Time remaining: 0s Progress 8592 / 9694 Time remaining: 0s Progress 8593 / 9694 Time remaining: 0s Progress 8594 / 9694 Time remaining: 0s Progress 8595 / 9694 Time remaining: 0s Progress 8596 / 9694 Time remaining: 0s Progress 8597 / 9694 Time remaining: 0s Progress 8598 / 9694 Time remaining: 0s Progress 8599 / 9694 Time remaining: 0s Progress 8600 / 9694 Time remaining: 0s Progress 8601 / 9694 Time remaining: 0s Progress 8602 / 9694 Time remaining: 0s Progress 8603 / 9694 Time remaining: 0s Progress 8604 / 9694 Time remaining: 0s Progress 8605 / 9694 Time remaining: 0s Progress 8606 / 9694 Time remaining: 0s Progress 8607 / 9694 Time remaining: 0s Progress 8608 / 9694 Time remaining: 0s Progress 8609 / 9694 Time remaining: 0s Progress 8610 / 9694 Time remaining: 0s Progress 8611 / 9694 Time remaining: 0s Progress 8612 / 9694 Time remaining: 0s Progress 8613 / 9694 Time remaining: 0s Progress 8614 / 9694 Time remaining: 0s Progress 8615 / 9694 Time remaining: 0s Progress 8616 / 9694 Time remaining: 0s Progress 8617 / 9694 Time remaining: 0s Progress 8618 / 9694 Time remaining: 0s Progress 8619 / 9694 Time remaining: 0s Progress 8620 / 9694 Time remaining: 0s Progress 8621 / 9694 Time remaining: 0s Progress 8622 / 9694 Time remaining: 0s Progress 8623 / 9694 Time remaining: 0s Progress 8624 / 9694 Time remaining: 0s Progress 8625 / 9694 Time remaining: 0s Progress 8626 / 9694 Time remaining: 0s Progress 8627 / 9694 Time remaining: 0s Progress 8628 / 9694 Time remaining: 0s Progress 8629 / 9694 Time remaining: 0s Progress 8630 / 9694 Time remaining: 0s Progress 8631 / 9694 Time remaining: 0s Progress 8632 / 9694 Time remaining: 0s Progress 8633 / 9694 Time remaining: 0s Progress 8634 / 9694 Time remaining: 0s Progress 8635 / 9694 Time remaining: 0s Progress 8636 / 9694 Time remaining: 0s Progress 8637 / 9694 Time remaining: 0s Progress 8638 / 9694 Time remaining: 0s Progress 8639 / 9694 Time remaining: 0s Progress 8640 / 9694 Time remaining: 0s Progress 8641 / 9694 Time remaining: 0s Progress 8642 / 9694 Time remaining: 0s Progress 8643 / 9694 Time remaining: 0s Progress 8644 / 9694 Time remaining: 0s Progress 8645 / 9694 Time remaining: 0s Progress 8646 / 9694 Time remaining: 0s Progress 8647 / 9694 Time remaining: 0s Progress 8648 / 9694 Time remaining: 0s Progress 8649 / 9694 Time remaining: 0s Progress 8650 / 9694 Time remaining: 0s Progress 8651 / 9694 Time remaining: 0s Progress 8652 / 9694 Time remaining: 0s Progress 8653 / 9694 Time remaining: 0s Progress 8654 / 9694 Time remaining: 0s Progress 8655 / 9694 Time remaining: 0s Progress 8656 / 9694 Time remaining: 0s Progress 8657 / 9694 Time remaining: 0s Progress 8658 / 9694 Time remaining: 0s Progress 8659 / 9694 Time remaining: 0s Progress 8660 / 9694 Time remaining: 0s Progress 8661 / 9694 Time remaining: 0s Progress 8662 / 9694 Time remaining: 0s Progress 8663 / 9694 Time remaining: 0s Progress 8664 / 9694 Time remaining: 0s Progress 8665 / 9694 Time remaining: 0s Progress 8666 / 9694 Time remaining: 0s Progress 8667 / 9694 Time remaining: 0s Progress 8668 / 9694 Time remaining: 0s Progress 8669 / 9694 Time remaining: 0s Progress 8670 / 9694 Time remaining: 0s Progress 8671 / 9694 Time remaining: 0s Progress 8672 / 9694 Time remaining: 0s Progress 8673 / 9694 Time remaining: 0s Progress 8674 / 9694 Time remaining: 0s Progress 8675 / 9694 Time remaining: 0s Progress 8676 / 9694 Time remaining: 0s Progress 8677 / 9694 Time remaining: 0s Progress 8678 / 9694 Time remaining: 0s Progress 8679 / 9694 Time remaining: 0s Progress 8680 / 9694 Time remaining: 0s Progress 8681 / 9694 Time remaining: 0s Progress 8682 / 9694 Time remaining: 0s Progress 8683 / 9694 Time remaining: 0s Progress 8684 / 9694 Time remaining: 0s Progress 8685 / 9694 Time remaining: 0s Progress 8686 / 9694 Time remaining: 0s Progress 8687 / 9694 Time remaining: 0s Progress 8688 / 9694 Time remaining: 0s Progress 8689 / 9694 Time remaining: 0s Progress 8690 / 9694 Time remaining: 0s Progress 8691 / 9694 Time remaining: 0s Progress 8692 / 9694 Time remaining: 0s Progress 8693 / 9694 Time remaining: 0s Progress 8694 / 9694 Time remaining: 0s Progress 8695 / 9694 Time remaining: 0s Progress 8696 / 9694 Time remaining: 0s Progress 8697 / 9694 Time remaining: 0s Progress 8698 / 9694 Time remaining: 0s Progress 8699 / 9694 Time remaining: 0s Progress 8700 / 9694 Time remaining: 0s Progress 8701 / 9694 Time remaining: 0s Progress 8702 / 9694 Time remaining: 0s Progress 8703 / 9694 Time remaining: 0s Progress 8704 / 9694 Time remaining: 0s Progress 8705 / 9694 Time remaining: 0s Progress 8706 / 9694 Time remaining: 0s Progress 8707 / 9694 Time remaining: 0s Progress 8708 / 9694 Time remaining: 0s Progress 8709 / 9694 Time remaining: 0s Progress 8710 / 9694 Time remaining: 0s Progress 8711 / 9694 Time remaining: 0s Progress 8712 / 9694 Time remaining: 0s Progress 8713 / 9694 Time remaining: 0s Progress 8714 / 9694 Time remaining: 0s Progress 8715 / 9694 Time remaining: 0s Progress 8716 / 9694 Time remaining: 0s Progress 8717 / 9694 Time remaining: 0s Progress 8718 / 9694 Time remaining: 0s Progress 8719 / 9694 Time remaining: 0s Progress 8720 / 9694 Time remaining: 0s Progress 8721 / 9694 Time remaining: 0s Progress 8722 / 9694 Time remaining: 0s Progress 8723 / 9694 Time remaining: 0s Progress 8724 / 9694 Time remaining: 0s Progress 8725 / 9694 Time remaining: 0s Progress 8726 / 9694 Time remaining: 0s Progress 8727 / 9694 Time remaining: 0s Progress 8728 / 9694 Time remaining: 0s Progress 8729 / 9694 Time remaining: 0s Progress 8730 / 9694 Time remaining: 0s Progress 8731 / 9694 Time remaining: 0s Progress 8732 / 9694 Time remaining: 0s Progress 8733 / 9694 Time remaining: 0s Progress 8734 / 9694 Time remaining: 0s Progress 8735 / 9694 Time remaining: 0s Progress 8736 / 9694 Time remaining: 0s Progress 8737 / 9694 Time remaining: 0s Progress 8738 / 9694 Time remaining: 0s Progress 8739 / 9694 Time remaining: 0s Progress 8740 / 9694 Time remaining: 0s Progress 8741 / 9694 Time remaining: 0s Progress 8742 / 9694 Time remaining: 0s Progress 8743 / 9694 Time remaining: 0s Progress 8744 / 9694 Time remaining: 0s Progress 8745 / 9694 Time remaining: 0s Progress 8746 / 9694 Time remaining: 0s Progress 8747 / 9694 Time remaining: 0s Progress 8748 / 9694 Time remaining: 0s Progress 8749 / 9694 Time remaining: 0s Progress 8750 / 9694 Time remaining: 0s Progress 8751 / 9694 Time remaining: 0s Progress 8752 / 9694 Time remaining: 0s Progress 8753 / 9694 Time remaining: 0s Progress 8754 / 9694 Time remaining: 0s Progress 8755 / 9694 Time remaining: 0s Progress 8756 / 9694 Time remaining: 0s Progress 8757 / 9694 Time remaining: 0s Progress 8758 / 9694 Time remaining: 0s Progress 8759 / 9694 Time remaining: 0s Progress 8760 / 9694 Time remaining: 0s Progress 8761 / 9694 Time remaining: 0s Progress 8762 / 9694 Time remaining: 0s Progress 8763 / 9694 Time remaining: 0s Progress 8764 / 9694 Time remaining: 0s Progress 8765 / 9694 Time remaining: 0s Progress 8766 / 9694 Time remaining: 0s Progress 8767 / 9694 Time remaining: 0s Progress 8768 / 9694 Time remaining: 0s Progress 8769 / 9694 Time remaining: 0s Progress 8770 / 9694 Time remaining: 0s Progress 8771 / 9694 Time remaining: 0s Progress 8772 / 9694 Time remaining: 0s Progress 8773 / 9694 Time remaining: 0s Progress 8774 / 9694 Time remaining: 0s Progress 8775 / 9694 Time remaining: 0s Progress 8776 / 9694 Time remaining: 0s Progress 8777 / 9694 Time remaining: 0s Progress 8778 / 9694 Time remaining: 0s Progress 8779 / 9694 Time remaining: 0s Progress 8780 / 9694 Time remaining: 0s Progress 8781 / 9694 Time remaining: 0s Progress 8782 / 9694 Time remaining: 0s Progress 8783 / 9694 Time remaining: 0s Progress 8784 / 9694 Time remaining: 0s Progress 8785 / 9694 Time remaining: 0s Progress 8786 / 9694 Time remaining: 0s Progress 8787 / 9694 Time remaining: 0s Progress 8788 / 9694 Time remaining: 0s Progress 8789 / 9694 Time remaining: 0s Progress 8790 / 9694 Time remaining: 0s Progress 8791 / 9694 Time remaining: 0s Progress 8792 / 9694 Time remaining: 0s Progress 8793 / 9694 Time remaining: 0s Progress 8794 / 9694 Time remaining: 0s Progress 8795 / 9694 Time remaining: 0s Progress 8796 / 9694 Time remaining: 0s Progress 8797 / 9694 Time remaining: 0s Progress 8798 / 9694 Time remaining: 0s Progress 8799 / 9694 Time remaining: 0s Progress 8800 / 9694 Time remaining: 0s Progress 8801 / 9694 Time remaining: 0s Progress 8802 / 9694 Time remaining: 0s Progress 8803 / 9694 Time remaining: 0s Progress 8804 / 9694 Time remaining: 0s Progress 8805 / 9694 Time remaining: 0s Progress 8806 / 9694 Time remaining: 0s Progress 8807 / 9694 Time remaining: 0s Progress 8808 / 9694 Time remaining: 0s Progress 8809 / 9694 Time remaining: 0s Progress 8810 / 9694 Time remaining: 0s Progress 8811 / 9694 Time remaining: 0s Progress 8812 / 9694 Time remaining: 0s Progress 8813 / 9694 Time remaining: 0s Progress 8814 / 9694 Time remaining: 0s Progress 8815 / 9694 Time remaining: 0s Progress 8816 / 9694 Time remaining: 0s Progress 8817 / 9694 Time remaining: 0s Progress 8818 / 9694 Time remaining: 0s Progress 8819 / 9694 Time remaining: 0s Progress 8820 / 9694 Time remaining: 0s Progress 8821 / 9694 Time remaining: 0s Progress 8822 / 9694 Time remaining: 0s Progress 8823 / 9694 Time remaining: 0s Progress 8824 / 9694 Time remaining: 0s Progress 8825 / 9694 Time remaining: 0s Progress 8826 / 9694 Time remaining: 0s Progress 8827 / 9694 Time remaining: 0s Progress 8828 / 9694 Time remaining: 0s Progress 8829 / 9694 Time remaining: 0s Progress 8830 / 9694 Time remaining: 0s Progress 8831 / 9694 Time remaining: 0s Progress 8832 / 9694 Time remaining: 0s Progress 8833 / 9694 Time remaining: 0s Progress 8834 / 9694 Time remaining: 0s Progress 8835 / 9694 Time remaining: 0s Progress 8836 / 9694 Time remaining: 0s Progress 8837 / 9694 Time remaining: 0s Progress 8838 / 9694 Time remaining: 0s Progress 8839 / 9694 Time remaining: 0s Progress 8840 / 9694 Time remaining: 0s Progress 8841 / 9694 Time remaining: 0s Progress 8842 / 9694 Time remaining: 0s Progress 8843 / 9694 Time remaining: 0s Progress 8844 / 9694 Time remaining: 0s Progress 8845 / 9694 Time remaining: 0s Progress 8846 / 9694 Time remaining: 0s Progress 8847 / 9694 Time remaining: 0s Progress 8848 / 9694 Time remaining: 0s Progress 8849 / 9694 Time remaining: 0s Progress 8850 / 9694 Time remaining: 0s Progress 8851 / 9694 Time remaining: 0s Progress 8852 / 9694 Time remaining: 0s Progress 8853 / 9694 Time remaining: 0s Progress 8854 / 9694 Time remaining: 0s Progress 8855 / 9694 Time remaining: 0s Progress 8856 / 9694 Time remaining: 0s Progress 8857 / 9694 Time remaining: 0s Progress 8858 / 9694 Time remaining: 0s Progress 8859 / 9694 Time remaining: 0s Progress 8860 / 9694 Time remaining: 0s Progress 8861 / 9694 Time remaining: 0s Progress 8862 / 9694 Time remaining: 0s Progress 8863 / 9694 Time remaining: 0s Progress 8864 / 9694 Time remaining: 0s Progress 8865 / 9694 Time remaining: 0s Progress 8866 / 9694 Time remaining: 0s Progress 8867 / 9694 Time remaining: 0s Progress 8868 / 9694 Time remaining: 0s Progress 8869 / 9694 Time remaining: 0s Progress 8870 / 9694 Time remaining: 0s Progress 8871 / 9694 Time remaining: 0s Progress 8872 / 9694 Time remaining: 0s Progress 8873 / 9694 Time remaining: 0s Progress 8874 / 9694 Time remaining: 0s Progress 8875 / 9694 Time remaining: 0s Progress 8876 / 9694 Time remaining: 0s Progress 8877 / 9694 Time remaining: 0s Progress 8878 / 9694 Time remaining: 0s Progress 8879 / 9694 Time remaining: 0s Progress 8880 / 9694 Time remaining: 0s Progress 8881 / 9694 Time remaining: 0s Progress 8882 / 9694 Time remaining: 0s Progress 8883 / 9694 Time remaining: 0s Progress 8884 / 9694 Time remaining: 0s Progress 8885 / 9694 Time remaining: 0s Progress 8886 / 9694 Time remaining: 0s Progress 8887 / 9694 Time remaining: 0s Progress 8888 / 9694 Time remaining: 0s Progress 8889 / 9694 Time remaining: 0s Progress 8890 / 9694 Time remaining: 0s Progress 8891 / 9694 Time remaining: 0s Progress 8892 / 9694 Time remaining: 0s Progress 8893 / 9694 Time remaining: 0s Progress 8894 / 9694 Time remaining: 0s Progress 8895 / 9694 Time remaining: 0s Progress 8896 / 9694 Time remaining: 0s Progress 8897 / 9694 Time remaining: 0s Progress 8898 / 9694 Time remaining: 0s Progress 8899 / 9694 Time remaining: 0s Progress 8900 / 9694 Time remaining: 0s Progress 8901 / 9694 Time remaining: 0s Progress 8902 / 9694 Time remaining: 0s Progress 8903 / 9694 Time remaining: 0s Progress 8904 / 9694 Time remaining: 0s Progress 8905 / 9694 Time remaining: 0s Progress 8906 / 9694 Time remaining: 0s Progress 8907 / 9694 Time remaining: 0s Progress 8908 / 9694 Time remaining: 0s Progress 8909 / 9694 Time remaining: 0s Progress 8910 / 9694 Time remaining: 0s Progress 8911 / 9694 Time remaining: 0s Progress 8912 / 9694 Time remaining: 0s Progress 8913 / 9694 Time remaining: 0s Progress 8914 / 9694 Time remaining: 0s Progress 8915 / 9694 Time remaining: 0s Progress 8916 / 9694 Time remaining: 0s Progress 8917 / 9694 Time remaining: 0s Progress 8918 / 9694 Time remaining: 0s Progress 8919 / 9694 Time remaining: 0s Progress 8920 / 9694 Time remaining: 0s Progress 8921 / 9694 Time remaining: 0s Progress 8922 / 9694 Time remaining: 0s Progress 8923 / 9694 Time remaining: 0s Progress 8924 / 9694 Time remaining: 0s Progress 8925 / 9694 Time remaining: 0s Progress 8926 / 9694 Time remaining: 0s Progress 8927 / 9694 Time remaining: 0s Progress 8928 / 9694 Time remaining: 0s Progress 8929 / 9694 Time remaining: 0s Progress 8930 / 9694 Time remaining: 0s Progress 8931 / 9694 Time remaining: 0s Progress 8932 / 9694 Time remaining: 0s Progress 8933 / 9694 Time remaining: 0s Progress 8934 / 9694 Time remaining: 0s Progress 8935 / 9694 Time remaining: 0s Progress 8936 / 9694 Time remaining: 0s Progress 8937 / 9694 Time remaining: 0s Progress 8938 / 9694 Time remaining: 0s Progress 8939 / 9694 Time remaining: 0s Progress 8940 / 9694 Time remaining: 0s Progress 8941 / 9694 Time remaining: 0s Progress 8942 / 9694 Time remaining: 0s Progress 8943 / 9694 Time remaining: 0s Progress 8944 / 9694 Time remaining: 0s Progress 8945 / 9694 Time remaining: 0s Progress 8946 / 9694 Time remaining: 0s Progress 8947 / 9694 Time remaining: 0s Progress 8948 / 9694 Time remaining: 0s Progress 8949 / 9694 Time remaining: 0s Progress 8950 / 9694 Time remaining: 0s Progress 8951 / 9694 Time remaining: 0s Progress 8952 / 9694 Time remaining: 0s Progress 8953 / 9694 Time remaining: 0s Progress 8954 / 9694 Time remaining: 0s Progress 8955 / 9694 Time remaining: 0s Progress 8956 / 9694 Time remaining: 0s Progress 8957 / 9694 Time remaining: 0s Progress 8958 / 9694 Time remaining: 0s Progress 8959 / 9694 Time remaining: 0s Progress 8960 / 9694 Time remaining: 0s Progress 8961 / 9694 Time remaining: 0s Progress 8962 / 9694 Time remaining: 0s Progress 8963 / 9694 Time remaining: 0s Progress 8964 / 9694 Time remaining: 0s Progress 8965 / 9694 Time remaining: 0s Progress 8966 / 9694 Time remaining: 0s Progress 8967 / 9694 Time remaining: 0s Progress 8968 / 9694 Time remaining: 0s Progress 8969 / 9694 Time remaining: 0s Progress 8970 / 9694 Time remaining: 0s Progress 8971 / 9694 Time remaining: 0s Progress 8972 / 9694 Time remaining: 0s Progress 8973 / 9694 Time remaining: 0s Progress 8974 / 9694 Time remaining: 0s Progress 8975 / 9694 Time remaining: 0s Progress 8976 / 9694 Time remaining: 0s Progress 8977 / 9694 Time remaining: 0s Progress 8978 / 9694 Time remaining: 0s Progress 8979 / 9694 Time remaining: 0s Progress 8980 / 9694 Time remaining: 0s Progress 8981 / 9694 Time remaining: 0s Progress 8982 / 9694 Time remaining: 0s Progress 8983 / 9694 Time remaining: 0s Progress 8984 / 9694 Time remaining: 0s Progress 8985 / 9694 Time remaining: 0s Progress 8986 / 9694 Time remaining: 0s Progress 8987 / 9694 Time remaining: 0s Progress 8988 / 9694 Time remaining: 0s Progress 8989 / 9694 Time remaining: 0s Progress 8990 / 9694 Time remaining: 0s Progress 8991 / 9694 Time remaining: 0s Progress 8992 / 9694 Time remaining: 0s Progress 8993 / 9694 Time remaining: 0s Progress 8994 / 9694 Time remaining: 0s Progress 8995 / 9694 Time remaining: 0s Progress 8996 / 9694 Time remaining: 0s Progress 8997 / 9694 Time remaining: 0s Progress 8998 / 9694 Time remaining: 0s Progress 8999 / 9694 Time remaining: 0s Progress 9000 / 9694 Time remaining: 0s Progress 9001 / 9694 Time remaining: 0s Progress 9002 / 9694 Time remaining: 0s Progress 9003 / 9694 Time remaining: 0s Progress 9004 / 9694 Time remaining: 0s Progress 9005 / 9694 Time remaining: 0s Progress 9006 / 9694 Time remaining: 0s Progress 9007 / 9694 Time remaining: 0s Progress 9008 / 9694 Time remaining: 0s Progress 9009 / 9694 Time remaining: 0s Progress 9010 / 9694 Time remaining: 0s Progress 9011 / 9694 Time remaining: 0s Progress 9012 / 9694 Time remaining: 0s Progress 9013 / 9694 Time remaining: 0s Progress 9014 / 9694 Time remaining: 0s Progress 9015 / 9694 Time remaining: 0s Progress 9016 / 9694 Time remaining: 0s Progress 9017 / 9694 Time remaining: 0s Progress 9018 / 9694 Time remaining: 0s Progress 9019 / 9694 Time remaining: 0s Progress 9020 / 9694 Time remaining: 0s Progress 9021 / 9694 Time remaining: 0s Progress 9022 / 9694 Time remaining: 0s Progress 9023 / 9694 Time remaining: 0s Progress 9024 / 9694 Time remaining: 0s Progress 9025 / 9694 Time remaining: 0s Progress 9026 / 9694 Time remaining: 0s Progress 9027 / 9694 Time remaining: 0s Progress 9028 / 9694 Time remaining: 0s Progress 9029 / 9694 Time remaining: 0s Progress 9030 / 9694 Time remaining: 0s Progress 9031 / 9694 Time remaining: 0s Progress 9032 / 9694 Time remaining: 0s Progress 9033 / 9694 Time remaining: 0s Progress 9034 / 9694 Time remaining: 0s Progress 9035 / 9694 Time remaining: 0s Progress 9036 / 9694 Time remaining: 0s Progress 9037 / 9694 Time remaining: 0s Progress 9038 / 9694 Time remaining: 0s Progress 9039 / 9694 Time remaining: 0s Progress 9040 / 9694 Time remaining: 0s Progress 9041 / 9694 Time remaining: 0s Progress 9042 / 9694 Time remaining: 0s Progress 9043 / 9694 Time remaining: 0s Progress 9044 / 9694 Time remaining: 0s Progress 9045 / 9694 Time remaining: 0s Progress 9046 / 9694 Time remaining: 0s Progress 9047 / 9694 Time remaining: 0s Progress 9048 / 9694 Time remaining: 0s Progress 9049 / 9694 Time remaining: 0s Progress 9050 / 9694 Time remaining: 0s Progress 9051 / 9694 Time remaining: 0s Progress 9052 / 9694 Time remaining: 0s Progress 9053 / 9694 Time remaining: 0s Progress 9054 / 9694 Time remaining: 0s Progress 9055 / 9694 Time remaining: 0s Progress 9056 / 9694 Time remaining: 0s Progress 9057 / 9694 Time remaining: 0s Progress 9058 / 9694 Time remaining: 0s Progress 9059 / 9694 Time remaining: 0s Progress 9060 / 9694 Time remaining: 0s Progress 9061 / 9694 Time remaining: 0s Progress 9062 / 9694 Time remaining: 0s Progress 9063 / 9694 Time remaining: 0s Progress 9064 / 9694 Time remaining: 0s Progress 9065 / 9694 Time remaining: 0s Progress 9066 / 9694 Time remaining: 0s Progress 9067 / 9694 Time remaining: 0s Progress 9068 / 9694 Time remaining: 0s Progress 9069 / 9694 Time remaining: 0s Progress 9070 / 9694 Time remaining: 0s Progress 9071 / 9694 Time remaining: 0s Progress 9072 / 9694 Time remaining: 0s Progress 9073 / 9694 Time remaining: 0s Progress 9074 / 9694 Time remaining: 0s Progress 9075 / 9694 Time remaining: 0s Progress 9076 / 9694 Time remaining: 0s Progress 9077 / 9694 Time remaining: 0s Progress 9078 / 9694 Time remaining: 0s Progress 9079 / 9694 Time remaining: 0s Progress 9080 / 9694 Time remaining: 0s Progress 9081 / 9694 Time remaining: 0s Progress 9082 / 9694 Time remaining: 0s Progress 9083 / 9694 Time remaining: 0s Progress 9084 / 9694 Time remaining: 0s Progress 9085 / 9694 Time remaining: 0s Progress 9086 / 9694 Time remaining: 0s Progress 9087 / 9694 Time remaining: 0s Progress 9088 / 9694 Time remaining: 0s Progress 9089 / 9694 Time remaining: 0s Progress 9090 / 9694 Time remaining: 0s Progress 9091 / 9694 Time remaining: 0s Progress 9092 / 9694 Time remaining: 0s Progress 9093 / 9694 Time remaining: 0s Progress 9094 / 9694 Time remaining: 0s Progress 9095 / 9694 Time remaining: 0s Progress 9096 / 9694 Time remaining: 0s Progress 9097 / 9694 Time remaining: 0s Progress 9098 / 9694 Time remaining: 0s Progress 9099 / 9694 Time remaining: 0s Progress 9100 / 9694 Time remaining: 0s Progress 9101 / 9694 Time remaining: 0s Progress 9102 / 9694 Time remaining: 0s Progress 9103 / 9694 Time remaining: 0s Progress 9104 / 9694 Time remaining: 0s Progress 9105 / 9694 Time remaining: 0s Progress 9106 / 9694 Time remaining: 0s Progress 9107 / 9694 Time remaining: 0s Progress 9108 / 9694 Time remaining: 0s Progress 9109 / 9694 Time remaining: 0s Progress 9110 / 9694 Time remaining: 0s Progress 9111 / 9694 Time remaining: 0s Progress 9112 / 9694 Time remaining: 0s Progress 9113 / 9694 Time remaining: 0s Progress 9114 / 9694 Time remaining: 0s Progress 9115 / 9694 Time remaining: 0s Progress 9116 / 9694 Time remaining: 0s Progress 9117 / 9694 Time remaining: 0s Progress 9118 / 9694 Time remaining: 0s Progress 9119 / 9694 Time remaining: 0s Progress 9120 / 9694 Time remaining: 0s Progress 9121 / 9694 Time remaining: 0s Progress 9122 / 9694 Time remaining: 0s Progress 9123 / 9694 Time remaining: 0s Progress 9124 / 9694 Time remaining: 0s Progress 9125 / 9694 Time remaining: 0s Progress 9126 / 9694 Time remaining: 0s Progress 9127 / 9694 Time remaining: 0s Progress 9128 / 9694 Time remaining: 0s Progress 9129 / 9694 Time remaining: 0s Progress 9130 / 9694 Time remaining: 0s Progress 9131 / 9694 Time remaining: 0s Progress 9132 / 9694 Time remaining: 0s Progress 9133 / 9694 Time remaining: 0s Progress 9134 / 9694 Time remaining: 0s Progress 9135 / 9694 Time remaining: 0s Progress 9136 / 9694 Time remaining: 0s Progress 9137 / 9694 Time remaining: 0s Progress 9138 / 9694 Time remaining: 0s Progress 9139 / 9694 Time remaining: 0s Progress 9140 / 9694 Time remaining: 0s Progress 9141 / 9694 Time remaining: 0s Progress 9142 / 9694 Time remaining: 0s Progress 9143 / 9694 Time remaining: 0s Progress 9144 / 9694 Time remaining: 0s Progress 9145 / 9694 Time remaining: 0s Progress 9146 / 9694 Time remaining: 0s Progress 9147 / 9694 Time remaining: 0s Progress 9148 / 9694 Time remaining: 0s Progress 9149 / 9694 Time remaining: 0s Progress 9150 / 9694 Time remaining: 0s Progress 9151 / 9694 Time remaining: 0s Progress 9152 / 9694 Time remaining: 0s Progress 9153 / 9694 Time remaining: 0s Progress 9154 / 9694 Time remaining: 0s Progress 9155 / 9694 Time remaining: 0s Progress 9156 / 9694 Time remaining: 0s Progress 9157 / 9694 Time remaining: 0s Progress 9158 / 9694 Time remaining: 0s Progress 9159 / 9694 Time remaining: 0s Progress 9160 / 9694 Time remaining: 0s Progress 9161 / 9694 Time remaining: 0s Progress 9162 / 9694 Time remaining: 0s Progress 9163 / 9694 Time remaining: 0s Progress 9164 / 9694 Time remaining: 0s Progress 9165 / 9694 Time remaining: 0s Progress 9166 / 9694 Time remaining: 0s Progress 9167 / 9694 Time remaining: 0s Progress 9168 / 9694 Time remaining: 0s Progress 9169 / 9694 Time remaining: 0s Progress 9170 / 9694 Time remaining: 0s Progress 9171 / 9694 Time remaining: 0s Progress 9172 / 9694 Time remaining: 0s Progress 9173 / 9694 Time remaining: 0s Progress 9174 / 9694 Time remaining: 0s Progress 9175 / 9694 Time remaining: 0s Progress 9176 / 9694 Time remaining: 0s Progress 9177 / 9694 Time remaining: 0s Progress 9178 / 9694 Time remaining: 0s Progress 9179 / 9694 Time remaining: 0s Progress 9180 / 9694 Time remaining: 0s Progress 9181 / 9694 Time remaining: 0s Progress 9182 / 9694 Time remaining: 0s Progress 9183 / 9694 Time remaining: 0s Progress 9184 / 9694 Time remaining: 0s Progress 9185 / 9694 Time remaining: 0s Progress 9186 / 9694 Time remaining: 0s Progress 9187 / 9694 Time remaining: 0s Progress 9188 / 9694 Time remaining: 0s Progress 9189 / 9694 Time remaining: 0s Progress 9190 / 9694 Time remaining: 0s Progress 9191 / 9694 Time remaining: 0s Progress 9192 / 9694 Time remaining: 0s Progress 9193 / 9694 Time remaining: 0s Progress 9194 / 9694 Time remaining: 0s Progress 9195 / 9694 Time remaining: 0s Progress 9196 / 9694 Time remaining: 0s Progress 9197 / 9694 Time remaining: 0s Progress 9198 / 9694 Time remaining: 0s Progress 9199 / 9694 Time remaining: 0s Progress 9200 / 9694 Time remaining: 0s Progress 9201 / 9694 Time remaining: 0s Progress 9202 / 9694 Time remaining: 0s Progress 9203 / 9694 Time remaining: 0s Progress 9204 / 9694 Time remaining: 0s Progress 9205 / 9694 Time remaining: 0s Progress 9206 / 9694 Time remaining: 0s Progress 9207 / 9694 Time remaining: 0s Progress 9208 / 9694 Time remaining: 0s Progress 9209 / 9694 Time remaining: 0s Progress 9210 / 9694 Time remaining: 0s Progress 9211 / 9694 Time remaining: 0s Progress 9212 / 9694 Time remaining: 0s Progress 9213 / 9694 Time remaining: 0s Progress 9214 / 9694 Time remaining: 0s Progress 9215 / 9694 Time remaining: 0s Progress 9216 / 9694 Time remaining: 0s Progress 9217 / 9694 Time remaining: 0s Progress 9218 / 9694 Time remaining: 0s Progress 9219 / 9694 Time remaining: 0s Progress 9220 / 9694 Time remaining: 0s Progress 9221 / 9694 Time remaining: 0s Progress 9222 / 9694 Time remaining: 0s Progress 9223 / 9694 Time remaining: 0s Progress 9224 / 9694 Time remaining: 0s Progress 9225 / 9694 Time remaining: 0s Progress 9226 / 9694 Time remaining: 0s Progress 9227 / 9694 Time remaining: 0s Progress 9228 / 9694 Time remaining: 0s Progress 9229 / 9694 Time remaining: 0s Progress 9230 / 9694 Time remaining: 0s Progress 9231 / 9694 Time remaining: 0s Progress 9232 / 9694 Time remaining: 0s Progress 9233 / 9694 Time remaining: 0s Progress 9234 / 9694 Time remaining: 0s Progress 9235 / 9694 Time remaining: 0s Progress 9236 / 9694 Time remaining: 0s Progress 9237 / 9694 Time remaining: 0s Progress 9238 / 9694 Time remaining: 0s Progress 9239 / 9694 Time remaining: 0s Progress 9240 / 9694 Time remaining: 0s Progress 9241 / 9694 Time remaining: 0s Progress 9242 / 9694 Time remaining: 0s Progress 9243 / 9694 Time remaining: 0s Progress 9244 / 9694 Time remaining: 0s Progress 9245 / 9694 Time remaining: 0s Progress 9246 / 9694 Time remaining: 0s Progress 9247 / 9694 Time remaining: 0s Progress 9248 / 9694 Time remaining: 0s Progress 9249 / 9694 Time remaining: 0s Progress 9250 / 9694 Time remaining: 0s Progress 9251 / 9694 Time remaining: 0s Progress 9252 / 9694 Time remaining: 0s Progress 9253 / 9694 Time remaining: 0s Progress 9254 / 9694 Time remaining: 0s Progress 9255 / 9694 Time remaining: 0s Progress 9256 / 9694 Time remaining: 0s Progress 9257 / 9694 Time remaining: 0s Progress 9258 / 9694 Time remaining: 0s Progress 9259 / 9694 Time remaining: 0s Progress 9260 / 9694 Time remaining: 0s Progress 9261 / 9694 Time remaining: 0s Progress 9262 / 9694 Time remaining: 0s Progress 9263 / 9694 Time remaining: 0s Progress 9264 / 9694 Time remaining: 0s Progress 9265 / 9694 Time remaining: 0s Progress 9266 / 9694 Time remaining: 0s Progress 9267 / 9694 Time remaining: 0s Progress 9268 / 9694 Time remaining: 0s Progress 9269 / 9694 Time remaining: 0s Progress 9270 / 9694 Time remaining: 0s Progress 9271 / 9694 Time remaining: 0s Progress 9272 / 9694 Time remaining: 0s Progress 9273 / 9694 Time remaining: 0s Progress 9274 / 9694 Time remaining: 0s Progress 9275 / 9694 Time remaining: 0s Progress 9276 / 9694 Time remaining: 0s Progress 9277 / 9694 Time remaining: 0s Progress 9278 / 9694 Time remaining: 0s Progress 9279 / 9694 Time remaining: 0s Progress 9280 / 9694 Time remaining: 0s Progress 9281 / 9694 Time remaining: 0s Progress 9282 / 9694 Time remaining: 0s Progress 9283 / 9694 Time remaining: 0s Progress 9284 / 9694 Time remaining: 0s Progress 9285 / 9694 Time remaining: 0s Progress 9286 / 9694 Time remaining: 0s Progress 9287 / 9694 Time remaining: 0s Progress 9288 / 9694 Time remaining: 0s Progress 9289 / 9694 Time remaining: 0s Progress 9290 / 9694 Time remaining: 0s Progress 9291 / 9694 Time remaining: 0s Progress 9292 / 9694 Time remaining: 0s Progress 9293 / 9694 Time remaining: 0s Progress 9294 / 9694 Time remaining: 0s Progress 9295 / 9694 Time remaining: 0s Progress 9296 / 9694 Time remaining: 0s Progress 9297 / 9694 Time remaining: 0s Progress 9298 / 9694 Time remaining: 0s Progress 9299 / 9694 Time remaining: 0s Progress 9300 / 9694 Time remaining: 0s Progress 9301 / 9694 Time remaining: 0s Progress 9302 / 9694 Time remaining: 0s Progress 9303 / 9694 Time remaining: 0s Progress 9304 / 9694 Time remaining: 0s Progress 9305 / 9694 Time remaining: 0s Progress 9306 / 9694 Time remaining: 0s Progress 9307 / 9694 Time remaining: 0s Progress 9308 / 9694 Time remaining: 0s Progress 9309 / 9694 Time remaining: 0s Progress 9310 / 9694 Time remaining: 0s Progress 9311 / 9694 Time remaining: 0s Progress 9312 / 9694 Time remaining: 0s Progress 9313 / 9694 Time remaining: 0s Progress 9314 / 9694 Time remaining: 0s Progress 9315 / 9694 Time remaining: 0s Progress 9316 / 9694 Time remaining: 0s Progress 9317 / 9694 Time remaining: 0s Progress 9318 / 9694 Time remaining: 0s Progress 9319 / 9694 Time remaining: 0s Progress 9320 / 9694 Time remaining: 0s Progress 9321 / 9694 Time remaining: 0s Progress 9322 / 9694 Time remaining: 0s Progress 9323 / 9694 Time remaining: 0s Progress 9324 / 9694 Time remaining: 0s Progress 9325 / 9694 Time remaining: 0s Progress 9326 / 9694 Time remaining: 0s Progress 9327 / 9694 Time remaining: 0s Progress 9328 / 9694 Time remaining: 0s Progress 9329 / 9694 Time remaining: 0s Progress 9330 / 9694 Time remaining: 0s Progress 9331 / 9694 Time remaining: 0s Progress 9332 / 9694 Time remaining: 0s Progress 9333 / 9694 Time remaining: 0s Progress 9334 / 9694 Time remaining: 0s Progress 9335 / 9694 Time remaining: 0s Progress 9336 / 9694 Time remaining: 0s Progress 9337 / 9694 Time remaining: 0s Progress 9338 / 9694 Time remaining: 0s Progress 9339 / 9694 Time remaining: 0s Progress 9340 / 9694 Time remaining: 0s Progress 9341 / 9694 Time remaining: 0s Progress 9342 / 9694 Time remaining: 0s Progress 9343 / 9694 Time remaining: 0s Progress 9344 / 9694 Time remaining: 0s Progress 9345 / 9694 Time remaining: 0s Progress 9346 / 9694 Time remaining: 0s Progress 9347 / 9694 Time remaining: 0s Progress 9348 / 9694 Time remaining: 0s Progress 9349 / 9694 Time remaining: 0s Progress 9350 / 9694 Time remaining: 0s Progress 9351 / 9694 Time remaining: 0s Progress 9352 / 9694 Time remaining: 0s Progress 9353 / 9694 Time remaining: 0s Progress 9354 / 9694 Time remaining: 0s Progress 9355 / 9694 Time remaining: 0s Progress 9356 / 9694 Time remaining: 0s Progress 9357 / 9694 Time remaining: 0s Progress 9358 / 9694 Time remaining: 0s Progress 9359 / 9694 Time remaining: 0s Progress 9360 / 9694 Time remaining: 0s Progress 9361 / 9694 Time remaining: 0s Progress 9362 / 9694 Time remaining: 0s Progress 9363 / 9694 Time remaining: 0s Progress 9364 / 9694 Time remaining: 0s Progress 9365 / 9694 Time remaining: 0s Progress 9366 / 9694 Time remaining: 0s Progress 9367 / 9694 Time remaining: 0s Progress 9368 / 9694 Time remaining: 0s Progress 9369 / 9694 Time remaining: 0s Progress 9370 / 9694 Time remaining: 0s Progress 9371 / 9694 Time remaining: 0s Progress 9372 / 9694 Time remaining: 0s Progress 9373 / 9694 Time remaining: 0s Progress 9374 / 9694 Time remaining: 0s Progress 9375 / 9694 Time remaining: 0s Progress 9376 / 9694 Time remaining: 0s Progress 9377 / 9694 Time remaining: 0s Progress 9378 / 9694 Time remaining: 0s Progress 9379 / 9694 Time remaining: 0s Progress 9380 / 9694 Time remaining: 0s Progress 9381 / 9694 Time remaining: 0s Progress 9382 / 9694 Time remaining: 0s Progress 9383 / 9694 Time remaining: 0s Progress 9384 / 9694 Time remaining: 0s Progress 9385 / 9694 Time remaining: 0s Progress 9386 / 9694 Time remaining: 0s Progress 9387 / 9694 Time remaining: 0s Progress 9388 / 9694 Time remaining: 0s Progress 9389 / 9694 Time remaining: 0s Progress 9390 / 9694 Time remaining: 0s Progress 9391 / 9694 Time remaining: 0s Progress 9392 / 9694 Time remaining: 0s Progress 9393 / 9694 Time remaining: 0s Progress 9394 / 9694 Time remaining: 0s Progress 9395 / 9694 Time remaining: 0s Progress 9396 / 9694 Time remaining: 0s Progress 9397 / 9694 Time remaining: 0s Progress 9398 / 9694 Time remaining: 0s Progress 9399 / 9694 Time remaining: 0s Progress 9400 / 9694 Time remaining: 0s Progress 9401 / 9694 Time remaining: 0s Progress 9402 / 9694 Time remaining: 0s Progress 9403 / 9694 Time remaining: 0s Progress 9404 / 9694 Time remaining: 0s Progress 9405 / 9694 Time remaining: 0s Progress 9406 / 9694 Time remaining: 0s Progress 9407 / 9694 Time remaining: 0s Progress 9408 / 9694 Time remaining: 0s Progress 9409 / 9694 Time remaining: 0s Progress 9410 / 9694 Time remaining: 0s Progress 9411 / 9694 Time remaining: 0s Progress 9412 / 9694 Time remaining: 0s Progress 9413 / 9694 Time remaining: 0s Progress 9414 / 9694 Time remaining: 0s Progress 9415 / 9694 Time remaining: 0s Progress 9416 / 9694 Time remaining: 0s Progress 9417 / 9694 Time remaining: 0s Progress 9418 / 9694 Time remaining: 0s Progress 9419 / 9694 Time remaining: 0s Progress 9420 / 9694 Time remaining: 0s Progress 9421 / 9694 Time remaining: 0s Progress 9422 / 9694 Time remaining: 0s Progress 9423 / 9694 Time remaining: 0s Progress 9424 / 9694 Time remaining: 0s Progress 9425 / 9694 Time remaining: 0s Progress 9426 / 9694 Time remaining: 0s Progress 9427 / 9694 Time remaining: 0s Progress 9428 / 9694 Time remaining: 0s Progress 9429 / 9694 Time remaining: 0s Progress 9430 / 9694 Time remaining: 0s Progress 9431 / 9694 Time remaining: 0s Progress 9432 / 9694 Time remaining: 0s Progress 9433 / 9694 Time remaining: 0s Progress 9434 / 9694 Time remaining: 0s Progress 9435 / 9694 Time remaining: 0s Progress 9436 / 9694 Time remaining: 0s Progress 9437 / 9694 Time remaining: 0s Progress 9438 / 9694 Time remaining: 0s Progress 9439 / 9694 Time remaining: 0s Progress 9440 / 9694 Time remaining: 0s Progress 9441 / 9694 Time remaining: 0s Progress 9442 / 9694 Time remaining: 0s Progress 9443 / 9694 Time remaining: 0s Progress 9444 / 9694 Time remaining: 0s Progress 9445 / 9694 Time remaining: 0s Progress 9446 / 9694 Time remaining: 0s Progress 9447 / 9694 Time remaining: 0s Progress 9448 / 9694 Time remaining: 0s Progress 9449 / 9694 Time remaining: 0s Progress 9450 / 9694 Time remaining: 0s Progress 9451 / 9694 Time remaining: 0s Progress 9452 / 9694 Time remaining: 0s Progress 9453 / 9694 Time remaining: 0s Progress 9454 / 9694 Time remaining: 0s Progress 9455 / 9694 Time remaining: 0s Progress 9456 / 9694 Time remaining: 0s Progress 9457 / 9694 Time remaining: 0s Progress 9458 / 9694 Time remaining: 0s Progress 9459 / 9694 Time remaining: 0s Progress 9460 / 9694 Time remaining: 0s Progress 9461 / 9694 Time remaining: 0s Progress 9462 / 9694 Time remaining: 0s Progress 9463 / 9694 Time remaining: 0s Progress 9464 / 9694 Time remaining: 0s Progress 9465 / 9694 Time remaining: 0s Progress 9466 / 9694 Time remaining: 0s Progress 9467 / 9694 Time remaining: 0s Progress 9468 / 9694 Time remaining: 0s Progress 9469 / 9694 Time remaining: 0s Progress 9470 / 9694 Time remaining: 0s Progress 9471 / 9694 Time remaining: 0s Progress 9472 / 9694 Time remaining: 0s Progress 9473 / 9694 Time remaining: 0s Progress 9474 / 9694 Time remaining: 0s Progress 9475 / 9694 Time remaining: 0s Progress 9476 / 9694 Time remaining: 0s Progress 9477 / 9694 Time remaining: 0s Progress 9478 / 9694 Time remaining: 0s Progress 9479 / 9694 Time remaining: 0s Progress 9480 / 9694 Time remaining: 0s Progress 9481 / 9694 Time remaining: 0s Progress 9482 / 9694 Time remaining: 0s Progress 9483 / 9694 Time remaining: 0s Progress 9484 / 9694 Time remaining: 0s Progress 9485 / 9694 Time remaining: 0s Progress 9486 / 9694 Time remaining: 0s Progress 9487 / 9694 Time remaining: 0s Progress 9488 / 9694 Time remaining: 0s Progress 9489 / 9694 Time remaining: 0s Progress 9490 / 9694 Time remaining: 0s Progress 9491 / 9694 Time remaining: 0s Progress 9492 / 9694 Time remaining: 0s Progress 9493 / 9694 Time remaining: 0s Progress 9494 / 9694 Time remaining: 0s Progress 9495 / 9694 Time remaining: 0s Progress 9496 / 9694 Time remaining: 0s Progress 9497 / 9694 Time remaining: 0s Progress 9498 / 9694 Time remaining: 0s Progress 9499 / 9694 Time remaining: 0s Progress 9500 / 9694 Time remaining: 0s Progress 9501 / 9694 Time remaining: 0s Progress 9502 / 9694 Time remaining: 0s Progress 9503 / 9694 Time remaining: 0s Progress 9504 / 9694 Time remaining: 0s Progress 9505 / 9694 Time remaining: 0s Progress 9506 / 9694 Time remaining: 0s Progress 9507 / 9694 Time remaining: 0s Progress 9508 / 9694 Time remaining: 0s Progress 9509 / 9694 Time remaining: 0s Progress 9510 / 9694 Time remaining: 0s Progress 9511 / 9694 Time remaining: 0s Progress 9512 / 9694 Time remaining: 0s Progress 9513 / 9694 Time remaining: 0s Progress 9514 / 9694 Time remaining: 0s Progress 9515 / 9694 Time remaining: 0s Progress 9516 / 9694 Time remaining: 0s Progress 9517 / 9694 Time remaining: 0s Progress 9518 / 9694 Time remaining: 0s Progress 9519 / 9694 Time remaining: 0s Progress 9520 / 9694 Time remaining: 0s Progress 9521 / 9694 Time remaining: 0s Progress 9522 / 9694 Time remaining: 0s Progress 9523 / 9694 Time remaining: 0s Progress 9524 / 9694 Time remaining: 0s Progress 9525 / 9694 Time remaining: 0s Progress 9526 / 9694 Time remaining: 0s Progress 9527 / 9694 Time remaining: 0s Progress 9528 / 9694 Time remaining: 0s Progress 9529 / 9694 Time remaining: 0s Progress 9530 / 9694 Time remaining: 0s Progress 9531 / 9694 Time remaining: 0s Progress 9532 / 9694 Time remaining: 0s Progress 9533 / 9694 Time remaining: 0s Progress 9534 / 9694 Time remaining: 0s Progress 9535 / 9694 Time remaining: 0s Progress 9536 / 9694 Time remaining: 0s Progress 9537 / 9694 Time remaining: 0s Progress 9538 / 9694 Time remaining: 0s Progress 9539 / 9694 Time remaining: 0s Progress 9540 / 9694 Time remaining: 0s Progress 9541 / 9694 Time remaining: 0s Progress 9542 / 9694 Time remaining: 0s Progress 9543 / 9694 Time remaining: 0s Progress 9544 / 9694 Time remaining: 0s Progress 9545 / 9694 Time remaining: 0s Progress 9546 / 9694 Time remaining: 0s Progress 9547 / 9694 Time remaining: 0s Progress 9548 / 9694 Time remaining: 0s Progress 9549 / 9694 Time remaining: 0s Progress 9550 / 9694 Time remaining: 0s Progress 9551 / 9694 Time remaining: 0s Progress 9552 / 9694 Time remaining: 0s Progress 9553 / 9694 Time remaining: 0s Progress 9554 / 9694 Time remaining: 0s Progress 9555 / 9694 Time remaining: 0s Progress 9556 / 9694 Time remaining: 0s Progress 9557 / 9694 Time remaining: 0s Progress 9558 / 9694 Time remaining: 0s Progress 9559 / 9694 Time remaining: 0s Progress 9560 / 9694 Time remaining: 0s Progress 9561 / 9694 Time remaining: 0s Progress 9562 / 9694 Time remaining: 0s Progress 9563 / 9694 Time remaining: 0s Progress 9564 / 9694 Time remaining: 0s Progress 9565 / 9694 Time remaining: 0s Progress 9566 / 9694 Time remaining: 0s Progress 9567 / 9694 Time remaining: 0s Progress 9568 / 9694 Time remaining: 0s Progress 9569 / 9694 Time remaining: 0s Progress 9570 / 9694 Time remaining: 0s Progress 9571 / 9694 Time remaining: 0s Progress 9572 / 9694 Time remaining: 0s Progress 9573 / 9694 Time remaining: 0s Progress 9574 / 9694 Time remaining: 0s Progress 9575 / 9694 Time remaining: 0s Progress 9576 / 9694 Time remaining: 0s Progress 9577 / 9694 Time remaining: 0s Progress 9578 / 9694 Time remaining: 0s Progress 9579 / 9694 Time remaining: 0s Progress 9580 / 9694 Time remaining: 0s Progress 9581 / 9694 Time remaining: 0s Progress 9582 / 9694 Time remaining: 0s Progress 9583 / 9694 Time remaining: 0s Progress 9584 / 9694 Time remaining: 0s Progress 9585 / 9694 Time remaining: 0s Progress 9586 / 9694 Time remaining: 0s Progress 9587 / 9694 Time remaining: 0s Progress 9588 / 9694 Time remaining: 0s Progress 9589 / 9694 Time remaining: 0s Progress 9590 / 9694 Time remaining: 0s Progress 9591 / 9694 Time remaining: 0s Progress 9592 / 9694 Time remaining: 0s Progress 9593 / 9694 Time remaining: 0s Progress 9594 / 9694 Time remaining: 0s Progress 9595 / 9694 Time remaining: 0s Progress 9596 / 9694 Time remaining: 0s Progress 9597 / 9694 Time remaining: 0s Progress 9598 / 9694 Time remaining: 0s Progress 9599 / 9694 Time remaining: 0s Progress 9600 / 9694 Time remaining: 0s Progress 9601 / 9694 Time remaining: 0s Progress 9602 / 9694 Time remaining: 0s Progress 9603 / 9694 Time remaining: 0s Progress 9604 / 9694 Time remaining: 0s Progress 9605 / 9694 Time remaining: 0s Progress 9606 / 9694 Time remaining: 0s Progress 9607 / 9694 Time remaining: 0s Progress 9608 / 9694 Time remaining: 0s Progress 9609 / 9694 Time remaining: 0s Progress 9610 / 9694 Time remaining: 0s Progress 9611 / 9694 Time remaining: 0s Progress 9612 / 9694 Time remaining: 0s Progress 9613 / 9694 Time remaining: 0s Progress 9614 / 9694 Time remaining: 0s Progress 9615 / 9694 Time remaining: 0s Progress 9616 / 9694 Time remaining: 0s Progress 9617 / 9694 Time remaining: 0s Progress 9618 / 9694 Time remaining: 0s Progress 9619 / 9694 Time remaining: 0s Progress 9620 / 9694 Time remaining: 0s Progress 9621 / 9694 Time remaining: 0s Progress 9622 / 9694 Time remaining: 0s Progress 9623 / 9694 Time remaining: 0s Progress 9624 / 9694 Time remaining: 0s Progress 9625 / 9694 Time remaining: 0s Progress 9626 / 9694 Time remaining: 0s Progress 9627 / 9694 Time remaining: 0s Progress 9628 / 9694 Time remaining: 0s Progress 9629 / 9694 Time remaining: 0s Progress 9630 / 9694 Time remaining: 0s Progress 9631 / 9694 Time remaining: 0s Progress 9632 / 9694 Time remaining: 0s Progress 9633 / 9694 Time remaining: 0s Progress 9634 / 9694 Time remaining: 0s Progress 9635 / 9694 Time remaining: 0s Progress 9636 / 9694 Time remaining: 0s Progress 9637 / 9694 Time remaining: 0s Progress 9638 / 9694 Time remaining: 0s Progress 9639 / 9694 Time remaining: 0s Progress 9640 / 9694 Time remaining: 0s Progress 9641 / 9694 Time remaining: 0s Progress 9642 / 9694 Time remaining: 0s Progress 9643 / 9694 Time remaining: 0s Progress 9644 / 9694 Time remaining: 0s Progress 9645 / 9694 Time remaining: 0s Progress 9646 / 9694 Time remaining: 0s Progress 9647 / 9694 Time remaining: 0s Progress 9648 / 9694 Time remaining: 0s Progress 9649 / 9694 Time remaining: 0s Progress 9650 / 9694 Time remaining: 0s Progress 9651 / 9694 Time remaining: 0s Progress 9652 / 9694 Time remaining: 0s Progress 9653 / 9694 Time remaining: 0s Progress 9654 / 9694 Time remaining: 0s Progress 9655 / 9694 Time remaining: 0s Progress 9656 / 9694 Time remaining: 0s Progress 9657 / 9694 Time remaining: 0s Progress 9658 / 9694 Time remaining: 0s Progress 9659 / 9694 Time remaining: 0s Progress 9660 / 9694 Time remaining: 0s Progress 9661 / 9694 Time remaining: 0s Progress 9662 / 9694 Time remaining: 0s Progress 9663 / 9694 Time remaining: 0s Progress 9664 / 9694 Time remaining: 0s Progress 9665 / 9694 Time remaining: 0s Progress 9666 / 9694 Time remaining: 0s Progress 9667 / 9694 Time remaining: 0s Progress 9668 / 9694 Time remaining: 0s Progress 9669 / 9694 Time remaining: 0s Progress 9670 / 9694 Time remaining: 0s Progress 9671 / 9694 Time remaining: 0s Progress 9672 / 9694 Time remaining: 0s Progress 9673 / 9694 Time remaining: 0s Progress 9674 / 9694 Time remaining: 0s Progress 9675 / 9694 Time remaining: 0s Progress 9676 / 9694 Time remaining: 0s Progress 9677 / 9694 Time remaining: 0s Progress 9678 / 9694 Time remaining: 0s Progress 9679 / 9694 Time remaining: 0s Progress 9680 / 9694 Time remaining: 0s Progress 9681 / 9694 Time remaining: 0s Progress 9682 / 9694 Time remaining: 0s Progress 9683 / 9694 Time remaining: 0s Progress 9684 / 9694 Time remaining: 0s Progress 9685 / 9694 Time remaining: 0s Progress 9686 / 9694 Time remaining: 0s Progress 9687 / 9694 Time remaining: 0s Progress 9688 / 9694 Time remaining: 0s Progress 9689 / 9694 Time remaining: 0s Progress 9690 / 9694 Time remaining: 0s Progress 9691 / 9694 Time remaining: 0s Progress 9692 / 9694 Time remaining: 0s Progress 9693 / 9694 Time remaining: 0s Progress 9694 / 9694 Time remaining: Added 9687 of 9694 gyroscope error terms (skipped 7 out-of-bounds measurements) + +Before Optimization +=================== +Normalized Residuals +---------------------------- +Reprojection error (cam0): mean 0.506342081976, median 0.434602238418, std: 0.341331757394 +Reprojection error (cam1): mean 0.509975734516, median 0.436638503778, std: 0.342444594089 +Gyroscope error (imu0): mean 28.6669576391, median 26.1750498063, std: 15.4726100018 +Accelerometer error (imu0): mean 9.51147595665, median 8.23642029117, std: 5.56788557255 + +Residuals +---------------------------- +Reprojection error (cam0) [px]: mean 0.506342081976, median 0.434602238418, std: 0.341331757394 +Reprojection error (cam1) [px]: mean 0.509975734516, median 0.436638503778, std: 0.342444594089 +Gyroscope error (imu0) [rad/s]: mean 0.0648659204564, median 0.059227376691, std: 0.0350105198558 +Accelerometer error (imu0) [m/s^2]: mean 0.37663523229, median 0.326145603873, std: 0.220477020133 + +Optimizing... +Using the block_cholesky linear system solver +Using the levenberg_marquardt trust region policy +Using the block_cholesky linear system solver +Using the levenberg_marquardt trust region policy +Initializing +Optimization problem initialized with 9737 design variables and 288904 error terms +The Jacobian matrix is 597180 x 43802 +[0.0]: J: 1.15576e+07 +[1]: J: 10631.3, dJ: 1.1547e+07, deltaX: 0.0893657, LM - lambda:10 mu:2 +[2]: J: 10246.5, dJ: 384.768, deltaX: 0.0335854, LM - lambda:3.33333 mu:2 +[3]: J: 10245.5, dJ: 1.02663, deltaX: 0.00299535, LM - lambda:1.11111 mu:2 +[4]: J: 10245.5, dJ: 0.000701007, deltaX: 7.76402e-05, LM - lambda:0.37037 mu:2 + +After Optimization (Results) +================== +Normalized Residuals +---------------------------- +Reprojection error (cam0): mean 0.0939591806842, median 0.0897653808334, std: 0.0471297656657 +Reprojection error (cam1): mean 0.0951201111853, median 0.090382870928, std: 0.0482771853494 +Gyroscope error (imu0): mean 0.492355871626, median 0.457753293123, std: 0.260809882769 +Accelerometer error (imu0): mean 0.581066153956, median 0.53486424318, std: 0.302719919025 + +Residuals +---------------------------- +Reprojection error (cam0) [px]: mean 0.0939591806842, median 0.0897653808334, std: 0.0471297656657 +Reprojection error (cam1) [px]: mean 0.0951201111853, median 0.090382870928, std: 0.0482771853494 +Gyroscope error (imu0) [rad/s]: mean 0.00111407416187, median 0.00103577746457, std: 0.000590145397461 +Accelerometer error (imu0) [m/s^2]: mean 0.0230090457957, median 0.0211795434685, std: 0.0119870972224 + +Transformation T_cam0_imu0 (imu0 to cam0, T_ci): +[[-0.99952504 0.02961534 -0.00852233 0.04727988] + [ 0.00750192 -0.03439736 -0.99938008 -0.04744323] + [-0.02989013 -0.99896935 0.03415885 -0.06819996] + [ 0. 0. 0. 1. ]] + +Transformation T_cam1_imu0 (imu0 to cam1, T_ci): +[[-0.99951105 0.03029912 -0.00772188 -0.05369743] + [ 0.00810408 0.01251164 -0.99988889 -0.04613174] + [-0.03019914 -0.99946257 -0.01275107 -0.07149261] + [ 0. 0. 0. 1. ]] + +IMU0: +---------------------------- + Model: calibrated + Update rate: 200.0 + Accelerometer: + Noise density: 0.0028 + Noise density (discrete): 0.0395979797464 + Random walk: 0.00086 + Gyroscope: + Noise density: 0.00016 + Noise density (discrete): 0.0022627416998 + Random walk: 2.2e-05 + T_i_b + [[ 1. 0. 0. 0.] + [ 0. 1. 0. 0.] + [ 0. 0. 1. 0.] + [ 0. 0. 0. 1.]] + time offset with respect to IMU0: 0.0 [s] + + Saving camera chain calibration to file: camchain-imucam-imucalib.yaml + + Saving imu calibration to file: imu-imucalib.yaml + Detailed results written to file: results-imucam-imucalib.txt +Generating result report... + Report written to report-imucam-imucalib.pdf + diff --git a/misc/tumvi_calib/pinhole-equi-512/results-imucam-imucalib.txt b/misc/tumvi_calib/pinhole-equi-512/results-imucam-imucalib.txt new file mode 100644 index 00000000..46fb2dc9 --- /dev/null +++ b/misc/tumvi_calib/pinhole-equi-512/results-imucam-imucalib.txt @@ -0,0 +1,121 @@ +Calibration results +=================== +Normalized Residuals +---------------------------- +Reprojection error (cam0): mean 0.0939591806842, median 0.0897653808334, std: 0.0471297656657 +Reprojection error (cam1): mean 0.0951201111853, median 0.090382870928, std: 0.0482771853494 +Gyroscope error (imu0): mean 0.492355871626, median 0.457753293123, std: 0.260809882769 +Accelerometer error (imu0): mean 0.581066153956, median 0.53486424318, std: 0.302719919025 + +Residuals +---------------------------- +Reprojection error (cam0) [px]: mean 0.0939591806842, median 0.0897653808334, std: 0.0471297656657 +Reprojection error (cam1) [px]: mean 0.0951201111853, median 0.090382870928, std: 0.0482771853494 +Gyroscope error (imu0) [rad/s]: mean 0.00111407416187, median 0.00103577746457, std: 0.000590145397461 +Accelerometer error (imu0) [m/s^2]: mean 0.0230090457957, median 0.0211795434685, std: 0.0119870972224 + +Transformation (cam0): +----------------------- +T_ci: (imu0 to cam0): +[[-0.99952504 0.02961534 -0.00852233 0.04727988] + [ 0.00750192 -0.03439736 -0.99938008 -0.04744323] + [-0.02989013 -0.99896935 0.03415885 -0.06819996] + [ 0. 0. 0. 1. ]] + +T_ic: (cam0 to imu0): +[[-0.99952504 0.00750192 -0.02989013 0.04557484] + [ 0.02961534 -0.03439736 -0.99896935 -0.0711618 ] + [-0.00852233 -0.99938008 0.03415885 -0.04468125] + [ 0. 0. 0. 1. ]] + +timeshift cam0 to imu0: [s] (t_imu = t_cam + shift) +0.0 + + +Transformation (cam1): +----------------------- +T_ci: (imu0 to cam1): +[[-0.99951105 0.03029912 -0.00772188 -0.05369743] + [ 0.00810408 0.01251164 -0.99988889 -0.04613174] + [-0.03019914 -0.99946257 -0.01275107 -0.07149261] + [ 0. 0. 0. 1. ]] + +T_ic: (cam1 to imu0): +[[-0.99951105 0.00810408 -0.03019914 -0.05545634] + [ 0.03029912 0.01251164 -0.99946257 -0.06925002] + [-0.00772188 -0.99988889 -0.01275107 -0.04745286] + [ 0. 0. 0. 1. ]] + +timeshift cam1 to imu0: [s] (t_imu = t_cam + shift) +0.0 + +Baselines: +---------- +Baseline (cam0 to cam1): +[[ 0.99999945 -0.00082336 -0.00065614 -0.1010611 ] + [ 0.00079169 0.99889946 -0.04689604 -0.00197646] + [ 0.00069403 0.04689549 0.99889956 -0.00117564] + [ 0. 0. 0. 1. ]] +baseline norm: 0.101087264328 [m] + + +Gravity vector in target coords: [m/s^2] +[ 0.03410895 -9.69438391 -1.47857369] + + +Calibration configuration +========================= + +cam0 +----- + Camera model: pinhole + Focal length: [190.97847715128717, 190.9733070521226] + Principal point: [254.93170605935475, 256.8974428996504] + Distortion model: equidistant + Distortion coefficients: [0.0034823894022493434, 0.0007150348452162257, -0.0020532361418706202, 0.00020293673591811182] + Type: aprilgrid + Tags: + Rows: 6 + Cols: 6 + Size: 0.088 [m] + Spacing 0.0264 [m] + + +cam1 +----- + Camera model: pinhole + Focal length: [190.44236969414825, 190.4344384721956] + Principal point: [252.59949716835982, 254.91723064636983] + Distortion model: equidistant + Distortion coefficients: [0.0034003170790442797, 0.001766278153469831, -0.00266312569781606, 0.0003299517423931039] + Type: aprilgrid + Tags: + Rows: 6 + Cols: 6 + Size: 0.088 [m] + Spacing 0.0264 [m] + + + +IMU configuration +================= + +IMU0: +---------------------------- + Model: calibrated + Update rate: 200.0 + Accelerometer: + Noise density: 0.0028 + Noise density (discrete): 0.0395979797464 + Random walk: 0.00086 + Gyroscope: + Noise density: 0.00016 + Noise density (discrete): 0.0022627416998 + Random walk: 2.2e-05 + T_i_b + [[ 1. 0. 0. 0.] + [ 0. 1. 0. 0.] + [ 0. 0. 1. 0.] + [ 0. 0. 0. 1.]] + time offset with respect to IMU0: 0.0 [s] + diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt new file mode 100644 index 00000000..2fa11822 --- /dev/null +++ b/node/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.5) +project(xivo) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) + +find_package(roscpp REQUIRED) +find_package(catkin REQUIRED COMPONENTS + dynamic_reconfigure + std_msgs + image_transport + message_generation + sensor_msgs + cv_bridge + tf + nav_msgs + roscpp + pcl_ros +) + +# Declare the message files to be built +catkin_package(CATKIN_DEPENDS + dynamic_reconfigure + std_msgs + message_runtime + image_transport + dynamic_reconfigure + sensor_msgs + tf + cv_bridge + nav_msgs + roscpp + CATKIN_DEPENDS + INCLUDE_DIRS + LIBRARIES +) + +include_directories( + ${CMAKE_SOURCE_DIR}/common + ${CMAKE_SOURCE_DIR}/src + ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/msg/cpp/ + ${catkin_INCLUDE_DIRS} +) + +link_directories( + ${CMAKE_SOURCE_DIR}/lib + /opt/ros/kinetic/lib/x86_64-linux-gnu +) + +add_executable(mynode main.cpp simple_node.cpp simple_node.h) +target_link_libraries(mynode + application + estimator + gflags::gflags + glog + jsoncpp + opencv_imgcodecs3 + opencv_highgui3 + opencv_core3 + ${catkin_LIBRARIES} + ${roscpp_LIBRARIES}) diff --git a/node/launch/sensors.launch b/node/launch/sensors.launch new file mode 100644 index 00000000..fd0ae246 --- /dev/null +++ b/node/launch/sensors.launch @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node/launch/tumvi.launch b/node/launch/tumvi.launch new file mode 100644 index 00000000..8ae6a75a --- /dev/null +++ b/node/launch/tumvi.launch @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/node/launch/tumvi.xml b/node/launch/tumvi.xml new file mode 100644 index 00000000..e0ad664a --- /dev/null +++ b/node/launch/tumvi.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node/launch/xivo.launch b/node/launch/xivo.launch new file mode 100644 index 00000000..f898959d --- /dev/null +++ b/node/launch/xivo.launch @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/node/launch/xivo.xml b/node/launch/xivo.xml new file mode 100644 index 00000000..c60a6195 --- /dev/null +++ b/node/launch/xivo.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node/main.cpp b/node/main.cpp new file mode 100644 index 00000000..d202ac28 --- /dev/null +++ b/node/main.cpp @@ -0,0 +1,25 @@ +// 3rdparty +#include "ros/ros.h" +#include "gflags/gflags.h" +#include "glog/logging.h" +// xivo +#include "simple_node.h" + +using namespace feh; + +int main(int argc, char ** argv) +{ + google::InitGoogleLogging(argv[0]); + gflags::ParseCommandLineFlags(&argc, &argv, true); + + ros::init(argc, argv, "xivo"); + + SimpleNode node; + + while(ros::ok()) { + // node.HandleQueue(); + if(ros::ok()) { + ros::spinOnce(); + } + } +} diff --git a/node/package.xml b/node/package.xml new file mode 100644 index 00000000..1a92b3af --- /dev/null +++ b/node/package.xml @@ -0,0 +1,37 @@ + + xivo + 0.0.1 + + Xiaohan's Inertial-aided Visual Odometry + + Xiaohan Fei + TBD + + feixh.github.io + Xiaohan Fei + + catkin + + message_generation + roscpp + std_msgs + sensor_msgs + nav_msgs + image_transport + dynamic_reconfigure + tf + cv_bridge + + message_runtime + roscpp + std_msgs + sensor_msgs + nav_msgs + image_transport + dynamic_reconfigure + tf + + cv_bridge + + + diff --git a/node/ros_setup.h b/node/ros_setup.h new file mode 100644 index 00000000..72aa6f45 --- /dev/null +++ b/node/ros_setup.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include diff --git a/node/simple_node.cpp b/node/simple_node.cpp new file mode 100644 index 00000000..eea153a1 --- /dev/null +++ b/node/simple_node.cpp @@ -0,0 +1,136 @@ +#include +#include "simple_node.h" +#include "glog/logging.h" +#include "opencv2/highgui/highgui.hpp" + +#include "utils.h" + +namespace feh +{ + +void ROSPublisherAdapter::Publish(ftype ts, const cv::Mat &disp) { + if (!disp.empty()) { + DLOG(INFO) << "Display image is ready"; + cv_bridge::CvImage cv_msg; + // cv_msg.header.stamp = msg->header.stamp; + cv_msg.header.frame_id = "image"; + cv_msg.encoding = disp.channels() > 1 ? "bgr8" : "mono8"; + cv_msg.image = disp; + sensor_msgs::Image ros_msg; + cv_msg.toImageMsg(ros_msg); + rospub_.publish(ros_msg); + cv_msg.image.release(); + } +} +SimpleNode::~SimpleNode() { + if (est_proc_) { + est_proc_->Wait(); + est_proc_.reset(); + } + if (adapter_) { + adapter_.reset(); + } + if (viewer_) { + viewer_->Wait(); + viewer_.reset(); + } +} + +SimpleNode::SimpleNode(): adapter_{nullptr}, viewer_{nullptr}, viz_{false} +{ + // parse node parameters + ros::NodeHandle nh_priv("~"); + + // get configuration path & create estimator process + std::string cfg_path; + int estimator_queue_size; + + nh_priv.param("config_path", cfg_path, cfg_path); + LOG(INFO) << "Found configuration @ " << cfg_path; + + // get image and imu topics + std::string imu_topic, image_topic; + nh_priv.param("imu_topic", imu_topic, imu_topic); + nh_priv.param("image_topic", image_topic, image_topic); + + // subscribe to topics + imu_sub_ = nh_.subscribe(imu_topic, 0, &SimpleNode::ImuMsgCallback, this); + LOG(INFO) << "Subscribed to IMU topic: " << imu_topic; + + image_sub_ = nh_.subscribe(image_topic, 0, &SimpleNode::ImageMsgCallback, this); + LOG(INFO) << "Subscribed to image topic: " << image_topic; + + // estimator process + nh_priv.param("estimator_queue_size", estimator_queue_size, estimator_queue_size); + LOG(INFO) << "Size of estimator process queue = " << estimator_queue_size; + + est_proc_ = std::unique_ptr( + new EstimatorProcess("Estimator", estimator_queue_size)); + est_proc_->Initialize(cfg_path); + + std::string viewer_type{"ros"}; + nh_priv.param("viewer_type", viewer_type, viewer_type); + if (viewer_type.empty()) { + LOG(WARNING) << "viewer type not set!"; + } else { + viz_ = true; + if (viewer_type == "ros") { + // publisher + viz_pub_ = nh_.advertise("TrackerView", 1); + adapter_ = std::unique_ptr( + new ROSPublisherAdapter(viz_pub_)); + // set publisher to estimator process + est_proc_->SetPublisher(adapter_.get()); + } else if (viewer_type == "pangolin") { + std::string viewer_cfg_path; + nh_priv.param("viewer_config_path", viewer_cfg_path, viewer_cfg_path); + auto viewer_cfg = LoadJson(viewer_cfg_path); + viewer_ = std::unique_ptr( + new ViewPublisher(viewer_cfg)); + // start the view-publisher thread + viewer_->Start(); + // set publisher to estimator process + est_proc_->SetPublisher(viewer_.get()); + } else { + LOG(FATAL) << "unknown viewer type; only support ros & pangolin (all lower case)"; + } + } + // start the estimator thread + est_proc_->Start(); +} + +void SimpleNode::ImuMsgCallback(sensor_msgs::ImuConstPtr msg) +{ + Vec3 gyro{msg->angular_velocity.x, msg->angular_velocity.y, msg->angular_velocity.z}; + Vec3 accel{msg->linear_acceleration.x, msg->linear_acceleration.y, msg->linear_acceleration.z}; + timestamp_t ts{msg->header.stamp.toNSec()}; + + est_proc_->Enqueue(std::move(std::make_unique(ts, gyro, accel, viz_))); +} + +void SimpleNode::ImageMsgCallback(sensor_msgs::ImageConstPtr msg) +{ + timestamp_t ts{msg->header.stamp.toNSec()}; + cv_bridge::CvImagePtr cv_ptr; + cv::Mat image; + if (msg->encoding == sensor_msgs::image_encodings::MONO8) { + cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::MONO8); + cv_ptr->image.copyTo(image); + } else if (msg->encoding == sensor_msgs::image_encodings::MONO16) { + cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::MONO16); + cv_ptr->image.convertTo(image, CV_8UC1, 1.0/256); + } else if (msg->encoding == sensor_msgs::image_encodings::RGB8) { + cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::RGB8); + cv::cvtColor(cv_ptr->image, image, CV_RGB2GRAY); + } else if (msg->encoding == sensor_msgs::image_encodings::BGR8) { + cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8); + cv::cvtColor(cv_ptr->image, image, CV_BGR2GRAY); + } else { + LOG(FATAL) << "unexpected image encoding"; + } + + est_proc_->Enqueue(std::move(std::make_unique(ts, image, viz_))); +} + +} // namespace feh + diff --git a/node/simple_node.h b/node/simple_node.h new file mode 100644 index 00000000..3cbcf2e4 --- /dev/null +++ b/node/simple_node.h @@ -0,0 +1,49 @@ +#pragma once +#include +#include + +#include "Eigen/Core" +#include "ros_setup.h" + +#include "estimator_process.h" +#include "publisher.h" + +namespace feh +{ + +// Size of the small buffer used for sorting messages based on timestamps. +constexpr int ros_msg_buf_size = 10; + +class ROSPublisherAdapter: public Publisher { +public: + ROSPublisherAdapter(ros::Publisher &rospub): Publisher{}, rospub_{rospub} + {} + virtual void Publish(ftype ts, const cv::Mat &disp); +private: + ros::Publisher &rospub_; +}; + +class SimpleNode +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + SimpleNode(); + ~SimpleNode(); + void ImuMsgCallback(sensor_msgs::ImuConstPtr msg); + void ImageMsgCallback(sensor_msgs::ImageConstPtr msg); +private: + std::unique_ptr est_proc_; + ros::NodeHandle nh_; + ros::Subscriber imu_sub_, image_sub_; + // std::priority_queue> queue_; + std::vector> buf_; + + bool viz_; // enable vizualization if true + // the following two (viz_pub and adapter) are used together + ros::Publisher viz_pub_; + std::unique_ptr adapter_; // to be shared with the estimator process + + std::unique_ptr viewer_; // pangolin-based view publisher +}; + +} diff --git a/print_stats.sh b/print_stats.sh new file mode 100755 index 00000000..390818d8 --- /dev/null +++ b/print_stats.sh @@ -0,0 +1,2 @@ +#!/bin/bash +ls src/*.cpp src/*.h common/*.cpp common/*.h node/*.cpp node/*.h | xargs wc -l diff --git a/pybind11/pyxivo.cpp b/pybind11/pyxivo.cpp new file mode 100644 index 00000000..3a0175d6 --- /dev/null +++ b/pybind11/pyxivo.cpp @@ -0,0 +1,94 @@ +#include "pybind11/eigen.h" +#include "pybind11/pybind11.h" + +#include "estimator.h" +#include "opencv2/highgui/highgui.hpp" +#include "utils.h" + +// for visualization +#include "viewer.h" +#include "visualize.h" + +namespace py = pybind11; +using namespace feh; + +class EstimatorWrapper { +public: + EstimatorWrapper(const std::string &cfg_path, + const std::string &viewer_cfg_path, + const std::string &name) { + + if (!glog_init_) { + google::InitGoogleLogging("pyxivo"); + glog_init_ = true; + } + + auto cfg = LoadJson(cfg_path); + estimator_ = std::unique_ptr(new Estimator{cfg}); + + if (!viewer_cfg_path.empty()) { + auto viewer_cfg = LoadJson(viewer_cfg_path); + viewer_ = std::unique_ptr(new Viewer{viewer_cfg, name}); + } + } + void InertialMeas(uint64_t ts, double wx, double wy, double wz, double ax, + double ay, double az) { + estimator_->InertialMeas(timestamp_t{ts}, {wx, wy, wz}, {ax, ay, az}); + + if (viewer_) { + viewer_->Update_gsb(estimator_->gsb()); + viewer_->Update_gsc(estimator_->gsc()); + } + } + + void VisualMeas(uint64_t ts, std::string &image_path) { + auto image = cv::imread(image_path); + + estimator_->VisualMeas(timestamp_t{ts}, image); + + if (viewer_) { + auto disp = Canvas::instance()->display(); + + if (!disp.empty()) { + LOG(INFO) << "Display image is ready"; + // cv::imshow("tracker", disp); + // if (cv::waitKey(cfg.get("wait_time", 5).asInt()) == 'q') break; + viewer_->Update(disp); + } + } + } + + Eigen::Matrix gsb() { return estimator_->gsb().matrix3x4(); } + + uint64_t now() const { return estimator_->ts().count(); } + + void Visualize() { + if (viewer_) + viewer_->Refresh(); + } + + void Release() { + viewer_.reset(); + estimator_.reset(); + } + +private: + std::unique_ptr estimator_; + std::unique_ptr viewer_; + static bool glog_init_; +}; + +bool EstimatorWrapper::glog_init_{false}; + +PYBIND11_MODULE(pyxivo, m) { + m.doc() = "python binding of XIVO (Xiaohan's Inertial-aided Visual Odometry)"; + py::class_(m, "Estimator") + .def(py::init()) + .def("InertialMeas", &EstimatorWrapper::InertialMeas) + .def("VisualMeas", &EstimatorWrapper::VisualMeas) + .def("gsb", &EstimatorWrapper::gsb) + .def("now", &EstimatorWrapper::now) + .def("Visualize", &EstimatorWrapper::Visualize) + .def("Release", &EstimatorWrapper::Release); +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..876c287a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +transforms3d +mayavi +numpy +glog + diff --git a/run_all.sh b/run_all.sh new file mode 100755 index 00000000..84a4a2ec --- /dev/null +++ b/run_all.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# TMPDIR=$(mktemp -d -p .) +TUMVIROOT="/local2/Data/tumvi/exported/euroc/512_16" + +#python scripts/quick_run.py -out_dir $TMPDIR -root $TUMVIROOT -seq room1 +#python scripts/quick_run.py -out_dir $TMPDIR -root $TUMVIROOT -seq room2 +#python scripts/quick_run.py -out_dir $TMPDIR -root $TUMVIROOT -seq room3 +#python scripts/quick_run.py -out_dir $TMPDIR -root $TUMVIROOT -seq room4 +#python scripts/quick_run.py -out_dir $TMPDIR -root $TUMVIROOT -seq room5 +#python scripts/quick_run.py -out_dir $TMPDIR -root $TUMVIROOT -seq room6 + +mkdir $CFG +python scripts/run_and_eval_pyxivo.py -out_dir $CFG -root $TUMVIROOT -seq room1 -cfg test_cfg/$CFG.json ${1} & +python scripts/run_and_eval_pyxivo.py -out_dir $CFG -root $TUMVIROOT -seq room2 -cfg test_cfg/$CFG.json ${1} & +python scripts/run_and_eval_pyxivo.py -out_dir $CFG -root $TUMVIROOT -seq room3 -cfg test_cfg/$CFG.json ${1} & +python scripts/run_and_eval_pyxivo.py -out_dir $CFG -root $TUMVIROOT -seq room4 -cfg test_cfg/$CFG.json ${1} & +python scripts/run_and_eval_pyxivo.py -out_dir $CFG -root $TUMVIROOT -seq room5 -cfg test_cfg/$CFG.json ${1} & +python scripts/run_and_eval_pyxivo.py -out_dir $CFG -root $TUMVIROOT -seq room6 -cfg test_cfg/$CFG.json ${1} & diff --git a/scripts/compareTraj.py b/scripts/compareTraj.py new file mode 100644 index 00000000..d900d4bc --- /dev/null +++ b/scripts/compareTraj.py @@ -0,0 +1,54 @@ +""" +Head-to-head comparison of MoCap ground truth and estimated state. +Usage: python compareTraj.py SEQUENCE_NAME YOUR_OUTPUT_FILE +If not working, change the path template +Author: Xiaohan Fei +""" +import numpy as np +import matplotlib.pyplot as plt +import sys + +# path_template = '/home/feixh/Data/tumvi/exported/euroc/512_16/dataset-{}_512_16/mav0/mocap0/data.csv' +path_template = '/local2/Data/tumvi/exported/euroc/512_16/dataset-{}_512_16/mav0/mocap0/data.csv' +# path_template = '/local/Data/tumvi/exported/euroc/512_16/dataset-{}_512_16/mav0/mocap0/data.csv' + +def loadMoCapData(seq): + if seq == '-': + return None, None + data = [] + with open(path_template.format(seq), 'r') as fid: + for l in fid.readlines()[1:]: + data.append([float(x) for x in l.strip().split(',')]) + data = np.asarray(data) + + ts = data[:, 0] + T = data[:, 1:4] + return ts, T + +def loadResults(path): + if path == '-': + return None, None + data = np.loadtxt(path) + ts = data[:, 0] + T = data[:, 1:4] + return ts, T + +if __name__ == '__main__': + mocap_ts, mocap_T = loadMoCapData(sys.argv[1]) + est_ts, est_T = loadResults(sys.argv[2]) + + valid = est_ts > 0 + est_ts = est_ts[valid] + est_T = est_T[valid, :] + + tag='xyz' + t0 = min(mocap_ts[0], est_ts[0]) + for i in range(3): + plt.subplot(311+i) + if mocap_ts is not None: + plt.plot((mocap_ts - t0) * 1e-9, mocap_T[:, i], 'b', label='MoCap') + if est_ts is not None: + plt.plot((est_ts - t0) * 1e-9, est_T[:, i], 'r', label='MSCKF') + plt.title('translation-' + tag[i]) + plt.legend() + plt.show() diff --git a/scripts/plot_state.py b/scripts/plot_state.py new file mode 100644 index 00000000..ce4ae741 --- /dev/null +++ b/scripts/plot_state.py @@ -0,0 +1,25 @@ +import numpy as np +import matplotlib.pyplot as plt + +if __name__ == '__main__': + state = np.loadtxt('state.txt') + estimate = np.loadtxt('estimate.txt') + meas = np.loadtxt('meas.txt') + plt.figure() + tags = ['X', 'Y', 'Z', 'Vx', 'Vy', 'Vz'] + for i in range(2): + for j in range(3): + idx = i * 3 + j + if idx < state.shape[1] and idx < estimate.shape[1]: + plt.subplot(231+idx) + plt.plot(state[:, idx], 'b*') + plt.hold(True) + plt.plot(estimate[:, idx], 'r.') + plt.title(tags[idx]) + + plt.figure() + for i in range(meas.shape[1]): + plt.subplot(101+meas.shape[1]*10+i) + plt.hold(True) + plt.plot(meas[:, i]) + plt.show() diff --git a/scripts/pyxivo.py b/scripts/pyxivo.py new file mode 100644 index 00000000..e398c689 --- /dev/null +++ b/scripts/pyxivo.py @@ -0,0 +1,114 @@ +import argparse +import os, glob + +import numpy as np +import glog +from transforms3d.quaternions import mat2quat + +import sys +sys.path.insert(0, 'lib') +import pyxivo + +TP_ROOT = '/home/feixh/Data/tumvi/exported/euroc/512_16' +KIF_ROOT = '/local2/Data/tumvi/exported/euroc/512_16' + +parser = argparse.ArgumentParser() +parser.add_argument( + '-root', default=KIF_ROOT, help='root directory of the tumvi dataset') +parser.add_argument( + '-cfg', default='cfg/estimator.json', help='path to the estimator configuration') +parser.add_argument( + '-seq', default='room6', help='short tag for the seuqence name') +parser.add_argument( + '-cam_id', default=0, type=int, help='specify which camera to use') +parser.add_argument( + '-out_dir', default='.', help='output directory to save results') +parser.add_argument( + '-use_viewer', default=False, action='store_true', + help='visualize trajectory and feature tracks if set') +args = parser.parse_args() + +if __name__ == '__main__': + if not os.path.exists(args.out_dir): + os.makedirs(args.out_dir) + + ######################################## + # LOAD DATA + ######################################## + img_dir = os.path.join(args.root, 'dataset-{}_512_16'.format(args.seq), + 'mav0', 'cam{}'.format(args.cam_id), 'data') + + imu_path = os.path.join(args.root, 'dataset-{}_512_16'.format(args.seq), + 'mav0', 'imu0', 'data.csv') + + data = [] + + for p in glob.glob(os.path.join(img_dir, '*.png')): + ts = int(os.path.basename(p)[:-4]) + data.append((ts, p)) + + with open(imu_path, 'r') as fid: + for l in fid.readlines(): + if l[0] != '#': + v = l.strip().split(',') + ts = int(v[0]) + w = [float(x) for x in v[1:4]] + t = [float(x) for x in v[4:]] + data.append((ts, (w, t))) + + data.sort(key=lambda tup: tup[0]) + + + ######################################## + # INITIALIZE ESTIMATOR + ######################################## + estimator = pyxivo.Estimator(args.cfg, 'cfg/viewer.json' if args.use_viewer else '', args.seq) + results = [] + for i, (ts, content) in enumerate(data): + # if i > 0 and i % 500 == 0: + # print('{:6}/{:6}'.format(i, len(data))) + if isinstance(content, tuple): + gyro, accel = content + estimator.InertialMeas(ts, gyro[0], gyro[1], gyro[2], accel[0], + accel[1], accel[2]) + else: + estimator.VisualMeas(ts, content) + estimator.Visualize() + + now = estimator.now() + gsb = np.array(estimator.gsb()) + Tsb = gsb[:, 3] + + # print gsb[:3, :3] + try: + q = mat2quat(gsb[:3, :3]) # [w, x, y, z] + # format compatible with tumvi rgbd benchmark scripts + results.append( + [now * 1e-9, Tsb[0], Tsb[1], Tsb[2], q[1], q[2], q[3], q[0]]) + except np.linalg.linalg.LinAlgError: + pass + + + np.savetxt( + os.path.join(args.out_dir, 'tumvi_{}'.format(args.seq)), + results, + fmt='%f %f %f %f %f %f %f %f') + + mocap_path = os.path.join(args.root, 'dataset-{}_512_16'.format(args.seq), + 'mav0', 'mocap0', 'data.csv') + + gt = [] + with open(mocap_path, 'r') as fid: + for l in fid.readlines(): + if l[0] != '#': + v = l.strip().split(',') + ts = int(v[0]) + t = [float(x) for x in v[1:4]] + q = [float(x) for x in v[4:]] # [w, x, y, z] + gt.append( + [ts * 1e-9, t[0], t[1], t[2], q[1], q[2], q[3], q[0]]) + + np.savetxt( + os.path.join(args.out_dir, 'tumvi_{}_gt'.format(args.seq)), + gt, + fmt='%f %f %f %f %f %f %f %f') diff --git a/scripts/run_and_eval_pyxivo.py b/scripts/run_and_eval_pyxivo.py new file mode 100644 index 00000000..fbeee617 --- /dev/null +++ b/scripts/run_and_eval_pyxivo.py @@ -0,0 +1,88 @@ +import numpy as np +import argparse +import os, sys +from shutil import copyfile + +TP_ROOT = '/home/feixh/Data/tumvi/exported/euroc/512_16' +KIF_ROOT = '/local2/Data/tumvi/exported/euroc/512_16' + +parser = argparse.ArgumentParser() +parser.add_argument( + '-root', default=KIF_ROOT, help='root directory of the tumvi dataset') +parser.add_argument( + '-cfg', default='cfg/estimator.json', help='path to the estimator configuration') +parser.add_argument( + '-seq', default='room6', help='short tag for the seuqence name') +parser.add_argument( + '-cam_id', default=0, type=int, help='specify which camera to use') +parser.add_argument( + '-out_dir', default='.', help='output directory to save results') +parser.add_argument( + '-use_viewer', default=False, action='store_true', help='visualize if set') +parser.add_argument( + '-stdout', default=False, action='store_true', help='write to stdout instead of a benchmark file if set') +args = parser.parse_args() + +if __name__ == '__main__': + + ######################################## + # BACKUP CONFIGURATION + ######################################## + if not os.path.exists(args.out_dir): + os.makedirs(args.out_dir) + copyfile(args.cfg, os.path.join(args.out_dir, os.path.basename(args.cfg))) + + ######################################## + # RUN THE FILTER + ######################################## + cmd = 'python scripts/pyxivo.py \ +-root {root:} \ +-cfg {cfg:} \ +-seq {seq:} \ +-cam_id {cam_id:} \ +-out_dir {out_dir:} \ +{use_viewer:}'.format( + root=args.root, cfg=args.cfg, seq=args.seq, cam_id=args.cam_id, out_dir=args.out_dir, + use_viewer='-use_viewer' if args.use_viewer else '') + print('*** COMMAND TO BE EXECUTED ***') + print(cmd) + os.system(cmd) + + result_file = os.path.join(args.out_dir, 'tumvi_{}'.format(args.seq)) + groundtruth_file = os.path.join(args.out_dir, 'tumvi_{}_gt'.format( + args.seq)) + benchmark_file = os.path.join(args.out_dir, 'tumvi_{}_bench'.format(args.seq)) + + os.system('echo {} >> {}'.format(args.seq, benchmark_file)) + + ######################################## + # COMPUTE ATE + ######################################## + cmd = 'python scripts/tum_rgbd_benchmark_tools/evaluate_ate.py \ +--max_difference 0.001 \ +--verbose \ +{groundtruth_file:} \ +{result_file:} {write_to:}'.format( + groundtruth_file=groundtruth_file, + result_file=result_file, + write_to='>> {}'.format(benchmark_file) if not args.stdout else '') + print('*** COMMAND TO BE EXECUTED ***') + print(cmd) + os.system(cmd) + + ######################################## + # COMPUTE RPE + ######################################## + cmd = 'python scripts/tum_rgbd_benchmark_tools/evaluate_rpe.py \ +--fixed_delta \ +--delta_unit s \ +--delta 1 \ +--verbose \ +{groundtruth_file:} \ +{result_file:} {write_to:}'.format( + groundtruth_file=groundtruth_file, + result_file=result_file, + write_to='>> {}'.format(benchmark_file) if not args.stdout else '') + print('*** COMMAND TO BE EXECUTED ***') + print(cmd) + os.system(cmd) diff --git a/scripts/run_and_eval_xivo.py b/scripts/run_and_eval_xivo.py new file mode 100644 index 00000000..66ce8389 --- /dev/null +++ b/scripts/run_and_eval_xivo.py @@ -0,0 +1,68 @@ +# quick script to run and evaluate vio on a given dataset +import argparse +import os, sys +from shutil import copyfile + +parser = argparse.ArgumentParser() +parser.add_argument('-log_dir', default='log', + help='directory to save logs') +parser.add_argument('-root', default='/home/feixh/Data/tumvi/exported/euroc/512_16', + help='root directory of the tumvi dataset') +parser.add_argument('-dataset', default='tumvi', + help='type of dataset, tumvi|euroc') +parser.add_argument('-seq', default='room6', + help='short tag for the seuqence name') +parser.add_argument('-cam_id', default=0, type=int, + help='specify which camera to use') +parser.add_argument('-resolution', default=0.001, type=float, + help='resolution to pair poses and compute RPE') +parser.add_argument('-out_dir', default='.', + help='directory to hold results') + +args = parser.parse_args() + +if __name__ == '__main__': + if not os.path.exists(args.log_dir): + os.makedirs(args.log_dir) + + result_file = os.path.join(args.out_dir, '{}_{}'.format(args.dataset, args.seq)) + benchmark_file = os.path.join(args.out_dir, 'benchmark') + copyfile('cfg/estimator.json', os.path.join(args.out_dir, 'estimator.json')) + + # run + cmd = 'GLOG_logtostderr=0 GLOG_log_dir={log_dir:} GLOG_v=0 \ +msckf/bin/st_vio \ +-cfg cfg/vio.json \ +-root {root:} \ +-dataset {dataset:} \ +-seq {seq:} \ +-cam_id {cam_id:} \ +-out {out:}'.format( + log_dir=args.log_dir, + root=args.root, + dataset=args.dataset, + seq=args.seq, + cam_id=args.cam_id, + out=result_file) + print('***Executing the following command***\n{}'.format(cmd)) + os.system(cmd) + + # evaluation + os.system('echo {} >> {}'.format(args.seq, benchmark_file)) + cmd = 'msckf/bin/eval \ +-root {root:} \ +-dataset {dataset:} \ +-seq {seq:} \ +-cam_id {cam_id:} \ +-result {result:} \ +-resolution {resolution:} >> {benchmark_file:}'.format( + log_dir=args.log_dir, + root=args.root, + dataset=args.dataset, + seq=args.seq, + cam_id=args.cam_id, + result=result_file, + resolution=args.resolution, + benchmark_file=benchmark_file) + print('***Executing the following command***\n{}'.format(cmd)) + os.system(cmd) diff --git a/scripts/scenenet_demo.py b/scripts/scenenet_demo.py new file mode 100644 index 00000000..835d9e76 --- /dev/null +++ b/scripts/scenenet_demo.py @@ -0,0 +1,116 @@ +import argparse +import os, glob +import pickle +import matplotlib.pyplot as plt + +import numpy as np +import glog +from transforms3d.quaternions import mat2quat +from transforms3d.axangles import mat2axangle +import cv2 + +import sys +sys.path.insert(0, 'lib') +import pyxivo + +TP_ROOT = '/home/feixh/Data/tumvi/exported/euroc/512_16' +KIF_ROOT = '/local2/Data/tumvi/exported/euroc/512_16' + +parser = argparse.ArgumentParser() +parser.add_argument( + '-data', default='xivo_data_0_223.pkl', help='data to play') +parser.add_argument( + '-use_viewer', default=False, action='store_true', + help='visualize trajectory and feature tracks if set') +args = parser.parse_args() + +def SO3log(R): + # print R + ax, a = mat2axangle(R) + return ax * a + +def compareStates(est, gt): + est = np.array(est) if est is not None else None + for i in range(3): + plt.subplot(2, 3, i+1) + plt.title('T' + chr(ord('x') + i)) + if est is not None: + plt.plot(est[:, 0], est[:, i+1], 'b', label='estimation') + if gt is not None: + plt.plot([tup[0] for tup in gt], + [tup[1][i, 3] for tup in gt], 'r', label='ground truth') + plt.legend(loc='upper left') + + for i in range(3): + plt.subplot(2, 3, i+4) + plt.title('W' + chr(ord('x') + i)) + if est is not None: + plt.plot(est[:, 0], est[:, i+4], 'b', label='estimation') + if gt is not None: + plt.plot([tup[0] for tup in gt], + [SO3log(tup[1][:3, :3])[i] for tup in gt], 'r', label='ground truth') + plt.legend(loc='upper left') + + plt.show() + +if __name__ == '__main__': + with open(args.data, 'rb') as fid: + data = pickle.load(fid) + data, mocap_data = data['image_data'] + data['imu_data'], data['mocap_data'] + data.sort(key=lambda tup: tup[0]) + + ######################################## + # INITIALIZE ESTIMATOR + ######################################## + estimator = pyxivo.Estimator('cfg/estimator_scenenet.json', + 'cfg/viewer_scenenet.json' if args.use_viewer else '', + 'Demo-SceneNet') + results = [] + results_w = [] + # create a temp folder to hold debug info + if not os.path.exists('tmp'): + os.makedirs('tmp') + for i, item in enumerate(data): + if i > 0 and i % 500 == 0: + print('{:6}/{:6}'.format(i, len(data))) + ts = int(item[0] * 1e9) + if len(item) == 3: + gyro, accel = item[1:] + estimator.InertialMeas(ts, + gyro[0], gyro[1], gyro[2], + accel[0], accel[1], accel[2]) + else: + image = item[1] + cv2.imwrite('tmp/{:04}.jpg'.format(i), image) # super hack: dump image and read ... + estimator.VisualMeas(ts, 'tmp/{:04}.jpg'.format(i)) + estimator.Visualize() + + gsb = np.array(estimator.gsb()) + Tsb = gsb[:, 3] + + q = mat2quat(gsb[:3, :3]) # [w, x, y, z] + # format compatible with tumvi rgbd benchmark scripts + results.append( + [ts * 1e-9, Tsb[0], Tsb[1], Tsb[2], q[1], q[2], q[3], q[0]]) + + w = SO3log(gsb[:3, :3]) + results_w.append( + [ts * 1e-9, Tsb[0], Tsb[1], Tsb[2], w[0], w[1], w[2]]) + + compareStates(results_w, mocap_data) + + np.savetxt( + os.path.join('scenenet_estimate'), + results, + fmt='%f %f %f %f %f %f %f %f') + + gt = [] + for ts, gwc in mocap_data: + T = gwc[:3, 3] + q = mat2quat(gwc[:3, :3]) + gt.append([ts, T[0], T[1], T[2], q[1], q[2], q[3], q[0]]) + + np.savetxt( + os.path.join('scenenet_gt'), + gt, + fmt='%f %f %f %f %f %f %f %f') diff --git a/scripts/tum_rgbd_benchmark_tools/associate.py b/scripts/tum_rgbd_benchmark_tools/associate.py new file mode 100644 index 00000000..554314a7 --- /dev/null +++ b/scripts/tum_rgbd_benchmark_tools/associate.py @@ -0,0 +1,128 @@ +#!/usr/bin/python +# Software License Agreement (BSD License) +# +# Copyright (c) 2013, Juergen Sturm, TUM +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of TUM nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Requirements: +# sudo apt-get install python-argparse + +""" +The Kinect provides the color and depth images in an un-synchronized way. This means that the set of time stamps from the color images do not intersect with those of the depth images. Therefore, we need some way of associating color images to depth images. + +For this purpose, you can use the ''associate.py'' script. It reads the time stamps from the rgb.txt file and the depth.txt file, and joins them by finding the best matches. +""" + +import argparse +import sys +import os +import numpy + + +def read_file_list(filename): + """ + Reads a trajectory from a text file. + + File format: + The file format is "stamp d1 d2 d3 ...", where stamp denotes the time stamp (to be matched) + and "d1 d2 d3.." is arbitary data (e.g., a 3D position and 3D orientation) associated to this timestamp. + + Input: + filename -- File name + + Output: + dict -- dictionary of (stamp,data) tuples + + """ + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + list = [[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"] + list = [(float(l[0]),l[1:]) for l in list if len(l)>1] + return dict(list) + +def associate(first_list, second_list,offset,max_difference): + """ + Associate two dictionaries of (stamp,data). As the time stamps never match exactly, we aim + to find the closest match for every input tuple. + + Input: + first_list -- first dictionary of (stamp,data) tuples + second_list -- second dictionary of (stamp,data) tuples + offset -- time offset between both dictionaries (e.g., to model the delay between the sensors) + max_difference -- search radius for candidate generation + + Output: + matches -- list of matched tuples ((stamp1,data1),(stamp2,data2)) + + """ + first_keys = first_list.keys() + second_keys = second_list.keys() + potential_matches = [(abs(a - (b + offset)), a, b) + for a in first_keys + for b in second_keys + if abs(a - (b + offset)) < max_difference] + potential_matches.sort() + matches = [] + for diff, a, b in potential_matches: + if a in first_keys and b in second_keys: + first_keys.remove(a) + second_keys.remove(b) + matches.append((a, b)) + + matches.sort() + return matches + +if __name__ == '__main__': + + # parse command line + parser = argparse.ArgumentParser(description=''' + This script takes two data files with timestamps and associates them + ''') + parser.add_argument('first_file', help='first text file (format: timestamp data)') + parser.add_argument('second_file', help='second text file (format: timestamp data)') + parser.add_argument('--first_only', help='only output associated lines from first file', action='store_true') + parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) + parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) + args = parser.parse_args() + + first_list = read_file_list(args.first_file) + second_list = read_file_list(args.second_file) + + matches = associate(first_list, second_list,float(args.offset),float(args.max_difference)) + + if args.first_only: + for a,b in matches: + print("%f %s"%(a," ".join(first_list[a]))) + else: + for a,b in matches: + print("%f %s %f %s"%(a," ".join(first_list[a]),b-float(args.offset)," ".join(second_list[b]))) + + diff --git a/scripts/tum_rgbd_benchmark_tools/evaluate_ate.py b/scripts/tum_rgbd_benchmark_tools/evaluate_ate.py new file mode 100644 index 00000000..683b598e --- /dev/null +++ b/scripts/tum_rgbd_benchmark_tools/evaluate_ate.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +# Software License Agreement (BSD License) +# +# Copyright (c) 2013, Juergen Sturm, TUM +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of TUM nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Requirements: +# sudo apt-get install python-argparse + +""" +This script computes the absolute trajectory error from the ground truth +trajectory and the estimated trajectory. +""" + +import sys +import numpy +import argparse +import associate + +def align(model,data): + """Align two trajectories using the method of Horn (closed-form). + + Input: + model -- first trajectory (3xn) + data -- second trajectory (3xn) + + Output: + rot -- rotation matrix (3x3) + trans -- translation vector (3x1) + trans_error -- translational error per point (1xn) + + """ + numpy.set_printoptions(precision=3,suppress=True) + model_zerocentered = model - model.mean(1) + data_zerocentered = data - data.mean(1) + + W = numpy.zeros( (3,3) ) + for column in range(model.shape[1]): + W += numpy.outer(model_zerocentered[:,column],data_zerocentered[:,column]) + U,d,Vh = numpy.linalg.linalg.svd(W.transpose()) + S = numpy.matrix(numpy.identity( 3 )) + if(numpy.linalg.det(U) * numpy.linalg.det(Vh)<0): + S[2,2] = -1 + rot = U*S*Vh + trans = data.mean(1) - rot * model.mean(1) + + model_aligned = rot * model + trans + alignment_error = model_aligned - data + + trans_error = numpy.sqrt(numpy.sum(numpy.multiply(alignment_error,alignment_error),0)).A[0] + + return rot,trans,trans_error + +def plot_traj(ax,stamps,traj,style,color,label): + """ + Plot a trajectory using matplotlib. + + Input: + ax -- the plot + stamps -- time stamps (1xn) + traj -- trajectory (3xn) + style -- line style + color -- line color + label -- plot legend + + """ + stamps.sort() + interval = numpy.median([s-t for s,t in zip(stamps[1:],stamps[:-1])]) + x = [] + y = [] + last = stamps[0] + for i in range(len(stamps)): + if stamps[i]-last < 2*interval: + x.append(traj[i][0]) + y.append(traj[i][1]) + elif len(x)>0: + ax.plot(x,y,style,color=color,label=label) + label="" + x=[] + y=[] + last= stamps[i] + if len(x)>0: + ax.plot(x,y,style,color=color,label=label) + + +if __name__=="__main__": + # parse command line + parser = argparse.ArgumentParser(description=''' + This script computes the absolute trajectory error from the ground truth trajectory and the estimated trajectory. + ''') + parser.add_argument('first_file', help='ground truth trajectory (format: timestamp tx ty tz qx qy qz qw)') + parser.add_argument('second_file', help='estimated trajectory (format: timestamp tx ty tz qx qy qz qw)') + parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) + parser.add_argument('--scale', help='scaling factor for the second trajectory (default: 1.0)',default=1.0) + parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) + parser.add_argument('--save', help='save aligned second trajectory to disk (format: stamp2 x2 y2 z2)') + parser.add_argument('--save_associations', help='save associated first and aligned second trajectory to disk (format: stamp1 x1 y1 z1 stamp2 x2 y2 z2)') + parser.add_argument('--plot', help='plot the first and the aligned second trajectory to an image (format: png)') + parser.add_argument('--verbose', help='print all evaluation data (otherwise, only the RMSE absolute translational error in meters after alignment will be printed)', action='store_true') + args = parser.parse_args() + + first_list = associate.read_file_list(args.first_file) + second_list = associate.read_file_list(args.second_file) + + matches = associate.associate(first_list, second_list,float(args.offset),float(args.max_difference)) + if len(matches)<2: + sys.exit("Couldn't find matching timestamp pairs between groundtruth and estimated trajectory! Did you choose the correct sequence?") + + + first_xyz = numpy.matrix([[float(value) for value in first_list[a][0:3]] for a,b in matches]).transpose() + second_xyz = numpy.matrix([[float(value)*float(args.scale) for value in second_list[b][0:3]] for a,b in matches]).transpose() + rot,trans,trans_error = align(second_xyz,first_xyz) + + second_xyz_aligned = rot * second_xyz + trans + + first_stamps = first_list.keys() + first_stamps.sort() + first_xyz_full = numpy.matrix([[float(value) for value in first_list[b][0:3]] for b in first_stamps]).transpose() + + second_stamps = second_list.keys() + second_stamps.sort() + second_xyz_full = numpy.matrix([[float(value)*float(args.scale) for value in second_list[b][0:3]] for b in second_stamps]).transpose() + second_xyz_full_aligned = rot * second_xyz_full + trans + + if args.verbose: + print "compared_pose_pairs %d pairs"%(len(trans_error)) + + print "absolute_translational_error.rmse %f m"%numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error)) + print "absolute_translational_error.mean %f m"%numpy.mean(trans_error) + print "absolute_translational_error.median %f m"%numpy.median(trans_error) + print "absolute_translational_error.std %f m"%numpy.std(trans_error) + print "absolute_translational_error.min %f m"%numpy.min(trans_error) + print "absolute_translational_error.max %f m"%numpy.max(trans_error) + else: + print "%f"%numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error)) + + if args.save_associations: + file = open(args.save_associations,"w") + file.write("\n".join(["%f %f %f %f %f %f %f %f"%(a,x1,y1,z1,b,x2,y2,z2) for (a,b),(x1,y1,z1),(x2,y2,z2) in zip(matches,first_xyz.transpose().A,second_xyz_aligned.transpose().A)])) + file.close() + + if args.save: + file = open(args.save,"w") + file.write("\n".join(["%f "%stamp+" ".join(["%f"%d for d in line]) for stamp,line in zip(second_stamps,second_xyz_full_aligned.transpose().A)])) + file.close() + + if args.plot: + import matplotlib + matplotlib.use('Agg') + import matplotlib.pyplot as plt + import matplotlib.pylab as pylab + from matplotlib.patches import Ellipse + fig = plt.figure() + ax = fig.add_subplot(111) + plot_traj(ax,first_stamps,first_xyz_full.transpose().A,'-',"black","ground truth") + plot_traj(ax,second_stamps,second_xyz_full_aligned.transpose().A,'-',"blue","estimated") + + label="difference" + for (a,b),(x1,y1,z1),(x2,y2,z2) in zip(matches,first_xyz.transpose().A,second_xyz_aligned.transpose().A): + ax.plot([x1,x2],[y1,y2],'-',color="red",label=label) + label="" + + ax.legend() + + ax.set_xlabel('x [m]') + ax.set_ylabel('y [m]') + plt.savefig(args.plot,dpi=90) + diff --git a/scripts/tum_rgbd_benchmark_tools/evaluate_rpe.py b/scripts/tum_rgbd_benchmark_tools/evaluate_rpe.py new file mode 100644 index 00000000..c8bd26c6 --- /dev/null +++ b/scripts/tum_rgbd_benchmark_tools/evaluate_rpe.py @@ -0,0 +1,380 @@ +#!/usr/bin/python +# Software License Agreement (BSD License) +# +# Copyright (c) 2013, Juergen Sturm, TUM +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of TUM nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +""" +This script computes the relative pose error from the ground truth trajectory +and the estimated trajectory. +""" + +import argparse +import random +import numpy +import sys + +_EPS = numpy.finfo(float).eps * 4.0 + +def transform44(l): + """ + Generate a 4x4 homogeneous transformation matrix from a 3D point and unit quaternion. + + Input: + l -- tuple consisting of (stamp,tx,ty,tz,qx,qy,qz,qw) where + (tx,ty,tz) is the 3D position and (qx,qy,qz,qw) is the unit quaternion. + + Output: + matrix -- 4x4 homogeneous transformation matrix + """ + t = l[1:4] + q = numpy.array(l[4:8], dtype=numpy.float64, copy=True) + nq = numpy.dot(q, q) + if nq < _EPS: + return numpy.array(( + ( 1.0, 0.0, 0.0, t[0]) + ( 0.0, 1.0, 0.0, t[1]) + ( 0.0, 0.0, 1.0, t[2]) + ( 0.0, 0.0, 0.0, 1.0) + ), dtype=numpy.float64) + q *= numpy.sqrt(2.0 / nq) + q = numpy.outer(q, q) + return numpy.array(( + (1.0-q[1, 1]-q[2, 2], q[0, 1]-q[2, 3], q[0, 2]+q[1, 3], t[0]), + ( q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2], q[1, 2]-q[0, 3], t[1]), + ( q[0, 2]-q[1, 3], q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1], t[2]), + ( 0.0, 0.0, 0.0, 1.0) + ), dtype=numpy.float64) + +def read_trajectory(filename, matrix=True): + """ + Read a trajectory from a text file. + + Input: + filename -- file to be read + matrix -- convert poses to 4x4 matrices + + Output: + dictionary of stamped 3D poses + """ + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + list = [[float(v.strip()) for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"] + list_ok = [] + for i,l in enumerate(list): + if l[4:8]==[0,0,0,0]: + continue + isnan = False + for v in l: + if numpy.isnan(v): + isnan = True + break + if isnan: + sys.stderr.write("Warning: line %d of file '%s' has NaNs, skipping line\n"%(i,filename)) + continue + list_ok.append(l) + if matrix : + traj = dict([(l[0],transform44(l[0:])) for l in list_ok]) + else: + traj = dict([(l[0],l[1:8]) for l in list_ok]) + return traj + +def find_closest_index(L,t): + """ + Find the index of the closest value in a list. + + Input: + L -- the list + t -- value to be found + + Output: + index of the closest element + """ + beginning = 0 + difference = abs(L[0] - t) + best = 0 + end = len(L) + while beginning < end: + middle = int((end+beginning)/2) + if abs(L[middle] - t) < difference: + difference = abs(L[middle] - t) + best = middle + if t == L[middle]: + return middle + elif L[middle] > t: + end = middle + else: + beginning = middle + 1 + return best + +def ominus(a,b): + """ + Compute the relative 3D transformation between a and b. + + Input: + a -- first pose (homogeneous 4x4 matrix) + b -- second pose (homogeneous 4x4 matrix) + + Output: + Relative 3D transformation from a to b. + """ + return numpy.dot(numpy.linalg.inv(a),b) + +def scale(a,scalar): + """ + Scale the translational components of a 4x4 homogeneous matrix by a scale factor. + """ + return numpy.array( + [[a[0,0], a[0,1], a[0,2], a[0,3]*scalar], + [a[1,0], a[1,1], a[1,2], a[1,3]*scalar], + [a[2,0], a[2,1], a[2,2], a[2,3]*scalar], + [a[3,0], a[3,1], a[3,2], a[3,3]]] + ) + +def compute_distance(transform): + """ + Compute the distance of the translational component of a 4x4 homogeneous matrix. + """ + return numpy.linalg.norm(transform[0:3,3]) + +def compute_angle(transform): + """ + Compute the rotation angle from a 4x4 homogeneous matrix. + """ + # an invitation to 3-d vision, p 27 + return numpy.arccos( min(1,max(-1, (numpy.trace(transform[0:3,0:3]) - 1)/2) )) + +def distances_along_trajectory(traj): + """ + Compute the translational distances along a trajectory. + """ + keys = traj.keys() + keys.sort() + motion = [ominus(traj[keys[i+1]],traj[keys[i]]) for i in range(len(keys)-1)] + distances = [0] + sum = 0 + for t in motion: + sum += compute_distance(t) + distances.append(sum) + return distances + +def rotations_along_trajectory(traj,scale): + """ + Compute the angular rotations along a trajectory. + """ + keys = traj.keys() + keys.sort() + motion = [ominus(traj[keys[i+1]],traj[keys[i]]) for i in range(len(keys)-1)] + distances = [0] + sum = 0 + for t in motion: + sum += compute_angle(t)*scale + distances.append(sum) + return distances + + +def evaluate_trajectory(traj_gt,traj_est,param_max_pairs=10000,param_fixed_delta=False,param_delta=1.00,param_delta_unit="s",param_offset=0.00,param_scale=1.00): + """ + Compute the relative pose error between two trajectories. + + Input: + traj_gt -- the first trajectory (ground truth) + traj_est -- the second trajectory (estimated trajectory) + param_max_pairs -- number of relative poses to be evaluated + param_fixed_delta -- false: evaluate over all possible pairs + true: only evaluate over pairs with a given distance (delta) + param_delta -- distance between the evaluated pairs + param_delta_unit -- unit for comparison: + "s": seconds + "m": meters + "rad": radians + "deg": degrees + "f": frames + param_offset -- time offset between two trajectories (to model the delay) + param_scale -- scale to be applied to the second trajectory + + Output: + list of compared poses and the resulting translation and rotation error + """ + stamps_gt = list(traj_gt.keys()) + stamps_est = list(traj_est.keys()) + stamps_gt.sort() + stamps_est.sort() + + stamps_est_return = [] + for t_est in stamps_est: + t_gt = stamps_gt[find_closest_index(stamps_gt,t_est + param_offset)] + t_est_return = stamps_est[find_closest_index(stamps_est,t_gt - param_offset)] + t_gt_return = stamps_gt[find_closest_index(stamps_gt,t_est_return + param_offset)] + if not t_est_return in stamps_est_return: + stamps_est_return.append(t_est_return) + if(len(stamps_est_return)<2): + raise Exception("Number of overlap in the timestamps is too small. Did you run the evaluation on the right files?") + + if param_delta_unit=="s": + index_est = list(traj_est.keys()) + index_est.sort() + elif param_delta_unit=="m": + index_est = distances_along_trajectory(traj_est) + elif param_delta_unit=="rad": + index_est = rotations_along_trajectory(traj_est,1) + elif param_delta_unit=="deg": + index_est = rotations_along_trajectory(traj_est,180/numpy.pi) + elif param_delta_unit=="f": + index_est = range(len(traj_est)) + else: + raise Exception("Unknown unit for delta: '%s'"%param_delta_unit) + + if not param_fixed_delta: + if(param_max_pairs==0 or len(traj_est)param_max_pairs): + pairs = random.sample(pairs,param_max_pairs) + + gt_interval = numpy.median([s-t for s,t in zip(stamps_gt[1:],stamps_gt[:-1])]) + gt_max_time_difference = 2*gt_interval + + result = [] + for i,j in pairs: + stamp_est_0 = stamps_est[i] + stamp_est_1 = stamps_est[j] + + stamp_gt_0 = stamps_gt[ find_closest_index(stamps_gt,stamp_est_0 + param_offset) ] + stamp_gt_1 = stamps_gt[ find_closest_index(stamps_gt,stamp_est_1 + param_offset) ] + + if(abs(stamp_gt_0 - (stamp_est_0 + param_offset)) > gt_max_time_difference or + abs(stamp_gt_1 - (stamp_est_1 + param_offset)) > gt_max_time_difference): + continue + + error44 = ominus( scale( + ominus( traj_est[stamp_est_1], traj_est[stamp_est_0] ),param_scale), + ominus( traj_gt[stamp_gt_1], traj_gt[stamp_gt_0] ) ) + + trans = compute_distance(error44) + rot = compute_angle(error44) + + result.append([stamp_est_0,stamp_est_1,stamp_gt_0,stamp_gt_1,trans,rot]) + + if len(result)<2: + raise Exception("Couldn't find matching timestamp pairs between groundtruth and estimated trajectory!") + + return result + +def percentile(seq,q): + """ + Return the q-percentile of a list + """ + seq_sorted = list(seq) + seq_sorted.sort() + return seq_sorted[int((len(seq_sorted)-1)*q)] + +if __name__ == '__main__': + random.seed(0) + + parser = argparse.ArgumentParser(description=''' + This script computes the relative pose error from the ground truth trajectory and the estimated trajectory. + ''') + parser.add_argument('groundtruth_file', help='ground-truth trajectory file (format: "timestamp tx ty tz qx qy qz qw")') + parser.add_argument('estimated_file', help='estimated trajectory file (format: "timestamp tx ty tz qx qy qz qw")') + parser.add_argument('--max_pairs', help='maximum number of pose comparisons (default: 10000, set to zero to disable downsampling)', default=10000) + parser.add_argument('--fixed_delta', help='only consider pose pairs that have a distance of delta delta_unit (e.g., for evaluating the drift per second/meter/radian)', action='store_true') + parser.add_argument('--delta', help='delta for evaluation (default: 1.0)',default=1.0) + parser.add_argument('--delta_unit', help='unit of delta (options: \'s\' for seconds, \'m\' for meters, \'rad\' for radians, \'f\' for frames; default: \'s\')',default='s') + parser.add_argument('--offset', help='time offset between ground-truth and estimated trajectory (default: 0.0)',default=0.0) + parser.add_argument('--scale', help='scaling factor for the estimated trajectory (default: 1.0)',default=1.0) + parser.add_argument('--save', help='text file to which the evaluation will be saved (format: stamp_est0 stamp_est1 stamp_gt0 stamp_gt1 trans_error rot_error)') + parser.add_argument('--plot', help='plot the result to a file (requires --fixed_delta, output format: png)') + parser.add_argument('--verbose', help='print all evaluation data (otherwise, only the mean translational error measured in meters will be printed)', action='store_true') + args = parser.parse_args() + + if args.plot and not args.fixed_delta: + sys.exit("The '--plot' option can only be used in combination with '--fixed_delta'") + + traj_gt = read_trajectory(args.groundtruth_file) + traj_est = read_trajectory(args.estimated_file) + + result = evaluate_trajectory(traj_gt, + traj_est, + int(args.max_pairs), + args.fixed_delta, + float(args.delta), + args.delta_unit, + float(args.offset), + float(args.scale)) + + stamps = numpy.array(result)[:,0] + trans_error = numpy.array(result)[:,4] + rot_error = numpy.array(result)[:,5] + + if args.save: + f = open(args.save,"w") + f.write("\n".join([" ".join(["%f"%v for v in line]) for line in result])) + f.close() + + if args.verbose: + print "compared_pose_pairs %d pairs"%(len(trans_error)) + + print "translational_error.rmse %f m"%numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error)) + print "translational_error.mean %f m"%numpy.mean(trans_error) + print "translational_error.median %f m"%numpy.median(trans_error) + print "translational_error.std %f m"%numpy.std(trans_error) + print "translational_error.min %f m"%numpy.min(trans_error) + print "translational_error.max %f m"%numpy.max(trans_error) + + print "rotational_error.rmse %f deg"%(numpy.sqrt(numpy.dot(rot_error,rot_error) / len(rot_error)) * 180.0 / numpy.pi) + print "rotational_error.mean %f deg"%(numpy.mean(rot_error) * 180.0 / numpy.pi) + print "rotational_error.median %f deg"%(numpy.median(rot_error) * 180.0 / numpy.pi) + print "rotational_error.std %f deg"%(numpy.std(rot_error) * 180.0 / numpy.pi) + print "rotational_error.min %f deg"%(numpy.min(rot_error) * 180.0 / numpy.pi) + print "rotational_error.max %f deg"%(numpy.max(rot_error) * 180.0 / numpy.pi) + else: + print numpy.mean(trans_error) + + if args.plot: + import matplotlib + matplotlib.use('Agg') + import matplotlib.pyplot as plt + import matplotlib.pylab as pylab + fig = plt.figure() + ax = fig.add_subplot(111) + ax.plot(stamps - stamps[0],trans_error,'-',color="blue") + #ax.plot([t for t,e in err_rot],[e for t,e in err_rot],'-',color="red") + ax.set_xlabel('time [s]') + ax.set_ylabel('translational error [m]') + plt.savefig(args.plot,dpi=300) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..fbebc563 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,115 @@ +cmake_minimum_required(VERSION 3.5) + +project(estimator) + +# # overwrite binary output directory +# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) +# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) + +# if set, use inverse-depth parametrization +# add_definitions(-DUSE_INVDEPTH) + +# if set, perform online temporal calibration +add_definitions(-DUSE_ONLINE_IMU_CALIB) +add_definitions(-DUSE_ONLINE_TEMPORAL_CALIB) +add_definitions(-DUSE_ONLINE_CAMERA_CALIB) + +# disable logging whose severity level is below the given integer +add_definitions(-DGOOGLE_STRIP_LOG=1) + +include_directories( + ${PROJECT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/common) + +link_directories( + ${CMAKE_SOURCE_DIR}/lib) + +set(deps + opencv_highgui + opencv_features2d + opencv_core + opencv_video + opencv_imgproc + opencv_imgcodecs + opencv_xfeatures2d + glog + pangolin + pthread + jsoncpp + GL + GLEW + common + ) + +add_library(application SHARED + estimator_process.cpp + tumvi.cpp + geometry.cpp + metrics.cpp + publisher.cpp + viewer.cpp) +target_link_libraries(application ${deps}) + +add_library(estimator SHARED + estimator.cpp + princedormand.cpp + rk4.cpp + # simulator.cpp + visualize.cpp + tracker.cpp + manager.cpp + update.cpp + graph.cpp + feature.cpp + group.cpp + core.cpp + helpers.cpp + options.cpp + param.cpp + mm.cpp + camera_manager.cpp + imu.cpp) +target_link_libraries(estimator ${deps}) # profiler) + +add_executable(vio app/vio.cpp) +target_link_libraries(vio estimator application gflags::gflags) + +add_executable(st_vio app/singlethread_vio.cpp) +target_link_libraries(st_vio estimator application gflags::gflags) + +################################################################################ +# TOOLING +################################################################################ +# add_executable(eval app/evaluate.cpp) +# target_link_libraries(eval estimator application gflags::gflags) + +# add_executable(simulation app/simulation.cpp ) +# target_link_libraries(simulation estimator) + + +################################################################################ +# TESTS +################################################################################ +# add_executable(test_givens test/test_givens.cpp ) +# target_link_libraries(test_givens estimator) +# +# add_executable(test_qr test/test_qr.cpp ) +# target_link_libraries(test_qr estimator) + +# add_executable(test_estimator test/test_estimator.cpp ) +# target_link_libraries(test_estimator estimator gtest gtest_main) +# +# add_executable(test_simulator test/test_simulator.cpp ) +# target_link_libraries(test_simulator estimator gtest gtest_main) + +# add_executable(test_tumvi test/test_tumvi.cpp ) +# target_link_libraries(test_tumvi estimator gtest gtest_main) + +# add_executable(test_viewer test/test_viewer.cpp) +# target_link_libraries(test_viewer estimator gtest gtest_main) + +# add_executable(test_tracker test/test_tracker.cpp ) +# target_link_libraries(test_tracker estimator gtest gtest_main) +# +# add_executable(test_matcher test/test_matcher.cpp ) +# target_link_libraries(test_matcher estimator gtest gtest_main) diff --git a/src/adjustable_cameras.h b/src/adjustable_cameras.h new file mode 100644 index 00000000..0fb99059 --- /dev/null +++ b/src/adjustable_cameras.h @@ -0,0 +1,163 @@ +#pragma once + +#include "alias.h" +#include "component.h" +#include "equidist.h" + +namespace feh { + +class A_RadialTangentialCamera + : public RadialTangentialCamera, + public Component< + A_RadialTangentialCamera, + Eigen::Matrix::DIM, 1>> { + +public: + using f_t = ftype; + using MyBase = RadialTangentialCamera; + static constexpr int DIM = MyBase::DIM; + + A_RadialTangentialCamera(int rows, int cols, f_t fx, f_t fy, f_t cx, f_t cy, + f_t p1, f_t p2, f_t k1, f_t k2, f_t k3, + int max_iter = 15) + : MyBase{rows, cols, fx, fy, cx, cy, p1, p2, k1, k2, k3, max_iter} {} + + void UpdateState(const Eigen::Matrix &dX) { + fx_ += dX(0); + fy_ += dX(1); + cx_ += dX(2); + cy_ += dX(3); + + p1_ += dX(4); + p2_ += dX(5); + + k1_ += dX(6); + k2_ += dX(7); + k3_ += dX(8); + } + +protected: + using MyBase::rows_; + using MyBase::cols_; + + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; + + using MyBase::p1_; + using MyBase::p2_; + + using MyBase::k1_; + using MyBase::k2_; + using MyBase::k3_; +}; + +class A_PinholeCamera + : public PinholeCamera, + public Component::DIM, 1>> { + +public: + using f_t = ftype; + using MyBase = PinholeCamera; + static constexpr int DIM = MyBase::DIM; + + A_PinholeCamera(int rows, int cols, f_t fx, f_t fy, f_t cx, f_t cy) + : PinholeCamera{rows, cols, fx, fy, cx, cy} {} + + void UpdateState(const Eigen::Matrix &dX) { + fx_ += dX(0); + fy_ += dX(1); + cx_ += dX(2); + cy_ += dX(3); + } + +protected: + using MyBase::rows_; + using MyBase::cols_; + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; +}; + +class A_ATANCamera + : public ATANCamera, + public Component::DIM, 1>> { + +public: + using f_t = ftype; + using MyBase = ATANCamera; + static constexpr int DIM = MyBase::DIM; + + A_ATANCamera(int rows, int cols, f_t fx, f_t fy, f_t cx, f_t cy, f_t w) + : ATANCamera{rows, cols, fx, fy, cx, cy, w} {} + + void UpdateState(const Eigen::Matrix &dX) { + fx_ += dX(0); + fy_ += dX(1); + cx_ += dX(2); + cy_ += dX(3); + w_ += dX(4); + invw_ = 1.0 / w_; + w2_ = 2.0 * std::tan(w_ * 0.5); + } + +protected: + using MyBase::rows_; + using MyBase::cols_; + + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; + + using MyBase::w_; + using MyBase::invw_; + using MyBase::w2_; +}; + +class A_EquidistantCamera + : public EquidistantCamera, + public Component::DIM, 1>> { + +public: + using f_t = ftype; + using MyBase = EquidistantCamera; + static constexpr int DIM = MyBase::DIM; + + A_EquidistantCamera(int rows, int cols, f_t fx, f_t fy, f_t cx, f_t cy, + f_t k0, f_t k1, f_t k2, f_t k3, int max_iter = 15) + : EquidistantCamera{rows, cols, fx, fy, cx, cy, k0, k1, k2, k3} {} + + void UpdateState(const Eigen::Matrix &dX) { + fx_ += dX(0); + fy_ += dX(1); + cx_ += dX(2); + cy_ += dX(3); + + k0_ += dX(4); + k1_ += dX(5); + k2_ += dX(6); + k3_ += dX(7); + } + +private: + using MyBase::rows_; + using MyBase::cols_; + + using MyBase::fx_; + using MyBase::fy_; + using MyBase::cx_; + using MyBase::cy_; + + using MyBase::k0_; + using MyBase::k1_; + using MyBase::k2_; + using MyBase::k3_; +}; + +} // namespace feh diff --git a/src/app/evaluate.cpp b/src/app/evaluate.cpp new file mode 100644 index 00000000..5648f8e7 --- /dev/null +++ b/src/app/evaluate.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "gflags/gflags.h" +#include "glog/logging.h" + +#include "alias.h" +#include "message_types.h" +#include "metrics.h" +#include "se3.h" +#include "tumvi.h" + +// flags +DEFINE_string(root, "/home/feixh/Data/tumvi/exported/euroc/512_16/", + "Root directory containing tumvi dataset folder."); +DEFINE_string(dataset, "tumvi", "euroc | tumvi"); +DEFINE_string(seq, "room1", "Sequence of TUM VI benchmark to play with."); +DEFINE_int32(cam_id, 0, "Camera id."); +DEFINE_string(result, "out_state", "Path to the result file."); + +// flags for evaluation +DEFINE_double(resolution, 0.001, + "Asynchronized timestemps within this bound, in seconds, are " + "paired and compared."); // do interpolation instead +DEFINE_double(RPE_interval, 1.0, + "Interval, in seconds, over which to compute RPE."); + +namespace feh { +std::vector LoadEstimatedState(const std::string &path) { + std::ifstream istream(path, std::ios::in); + int64_t ts; // timestamp + ftype x, y, z; // translation + ftype w0, w1, w2; // rotation in exponential coordinates + std::vector out; + while (istream >> ts >> x >> y >> z >> w0 >> w1 >> w2) { + auto R = SO3::exp({w0, w1, w2}); + auto T = Vec3{x, y, z}; + out.push_back({ts, SE3{R, T}}); + } + return out; +} +} + +using namespace feh; + +int main(int argc, char **argv) { + google::InitGoogleLogging(argv[0]); + gflags::ParseCommandLineFlags(&argc, &argv, true); + + std::string image_dir, imu_dir, mocap_dir; + std::tie(image_dir, imu_dir, mocap_dir) = + GetDirs(FLAGS_dataset, FLAGS_root, FLAGS_seq, FLAGS_cam_id); + std::unique_ptr loader(new TUMVILoader{image_dir, imu_dir}); + + auto traj_gt = loader->LoadGroundTruthState(mocap_dir); + LOG(INFO) << "Ground truth loaded"; + + std::vector traj_est = LoadEstimatedState(FLAGS_result); + + LOG(INFO) << "Estimated trajectory loaded"; + // Absolute Trajectory Error + ftype ate; + SE3 g_est_gt; + std::tie(ate, g_est_gt) = ComputeATE(traj_est, traj_gt, FLAGS_resolution); + LOG(INFO) << "ATE computed"; + + // Relative Position Error + ftype rpe_pos, rpe_rot; + std::tie(rpe_pos, rpe_rot) = + ComputeRPE(traj_est, traj_gt, FLAGS_RPE_interval, FLAGS_resolution); + LOG(INFO) << "RPE computed"; + + std::cout << absl::StreamFormat("ATE=%0.4f meters\n", ate); + std::cout << absl::StreamFormat( + "RPE @ %0.4f ms=[%0.4f meters, %0.4f degrees]\n", + 1000.0 * FLAGS_RPE_interval, rpe_pos, rpe_rot / M_PI * 180); + + // write aligned estimates to file. + std::string output_path = FLAGS_result + "_aligned"; + std::ofstream ostream{output_path, std::ios::out}; + if (!ostream.is_open()) + LOG(FATAL) << "failed to open output file @ " << output_path; + ; + for (auto msg : traj_est) { + auto aligned_g = g_est_gt.inv() * msg.g_; + ostream << absl::StrFormat("%ld", msg.ts_) << " " + << aligned_g.T().transpose() << " " + << aligned_g.R().log().transpose() << std::endl; + } + ostream.close(); + LOG(INFO) << "aligned trajectory saved" << std::endl; +} diff --git a/src/app/simulation.cpp b/src/app/simulation.cpp new file mode 100644 index 00000000..ba125502 --- /dev/null +++ b/src/app/simulation.cpp @@ -0,0 +1,131 @@ +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "glog/logging.h" +#include "opencv2/highgui/highgui.hpp" +#include "json/json.h" + +#include "core.h" +#include "estimator.h" +#include "simulator.h" + +using namespace feh; + +// \brief: Clone state from simulator to estimator for initialization in +// simulation. +void CloneState(std::shared_ptr est, std::shared_ptr sim, + bool add_noise = false) { + // clone nominal state + est->X_ = sim->X_; + // clone imu calibration + est->Cas_ = sim->Cas_; + est->Car_ = sim->Car_; + est->Cgs_ = sim->Cgs_; + est->Cgr_ = sim->Cgr_; + // clone gravity + est->g_ = sim->g_; + + // now add some noise to initial state + if (add_noise) { + auto n = sim->cfg_["init_noise_std"]; + est->X_.Rsb = + SO3::exp(est->X_.Rsb.log() + RandomVector<3>(0., n["W"].asDouble())); + est->X_.Tsb += RandomVector<3>(0., n["T"].asDouble()); + est->X_.Vsb += RandomVector<3>(0., n["V"].asDouble()); + est->X_.bg += RandomVector<3>(0., n["bg"].asDouble()); + est->X_.ba += RandomVector<3>(0., n["ba"].asDouble()); + est->X_.Rbc = + SO3::exp(est->X_.Rbc.log() + RandomVector<3>(0., n["Wbc"].asDouble())); + est->X_.Tbc += RandomVector<3>(0., n["Tbc"].asDouble()); + Vec3 Wg = est->X_.Rg.log(); + Wg.head<2>() += RandomVector<2>(0., n["Wg"].asDouble()); + Wg(2) = 0; + est->X_.Rg = SO3::exp(Wg); + } + + auto dX = est->X_ - sim->X_; + LOG(INFO) << "Estimator state initialized from simulator."; + LOG(INFO) << absl::StrFormat("||dT||=%0.2f, ||dR||=%0.2f\n", dX.Tsb.norm(), + dX.Rsb.log().norm()); +} + +//############################################################################ +int main(int argc, char *argv[]) { + google::InitGoogleLogging(argv[0]); + + std::string cfg_path; + if (argc < 2) { + cfg_path = "../cfg/simulation.json"; + LOG(INFO) << "Usage: ./simulate [CONFIGURATION]" << std::endl; + LOG(INFO) << "CONFIGURATION not specified; use default configuration @ " + << cfg_path << std::endl; + } else { + cfg_path = argv[1]; + } + + auto cfg = LoadJson(cfg_path); + + auto est = std::make_shared(cfg["estimator_cfg"].asString()); + auto sim = std::make_shared(cfg["simulator_cfg"].asString()); + // duplicate the initial state ... + // otherwise, this won't work since the initial gravity rotation is not right + // and we are not integrating gravity properly + CloneState(est, sim, cfg.get("add_noise_to_init_state", false).asBool()); + + msg::IMU imu_msg; + msg::Track track_msg; + + imu_msg.initialized_ = false; + track_msg.initialized_ = false; + + bool enable_update = cfg.get("enable_update", true).asBool(); + + cv::Mat disp; + ftype path_length(0); + int counter(0); + State last_X; + while (sim->GetMeas(imu_msg, track_msg)) { + if (imu_msg.initialized_) { + est->InertialMeas(imu_msg.ts_, imu_msg.gyro_, imu_msg.accel_); + if (!enable_update) { + // pretend vision module has initialized + est->vision_initialized_ = true; + est->curr_time_ = imu_msg.ts_; + } + } + + if (track_msg.initialized_) { + if (enable_update) { + est->ProcessTracks_EKF(track_msg.ts_, track_msg.features_); + } + disp = sim->VisualizeTracks(); + } + auto dX = est->X_ - sim->X_; + VLOG(0) << absl::StrFormat("||dT||=%0.6f, ||dR||=%0.6f\n", dX.Tsb.norm(), + dX.Rsb.log().norm()); + VLOG(0) << absl::StrFormat("||dTbc||=%0.6f, ||dRbc||=%0.6f\n", + dX.Tbc.norm(), dX.Rbc.log().norm()); + if (counter != 0) { + path_length += (sim->X_ - last_X).Tsb.norm(); + VLOG(0) << absl::StrFormat("T.drift=%0.2f%% of %0.2f meters\n", + dX.Tsb.norm() / path_length * 100, + path_length); + } + std::cout << path_length << " " << dX.Tsb.norm() << std::endl; + last_X = sim->X_; + ++counter; + + // reset messages + imu_msg.initialized_ = false; + track_msg.initialized_ = false; + + if (cfg.get("visualize", false).asBool()) { + cv::imshow("simulation", disp); + char ckey = cv::waitKey(5); + if (ckey == 'q') + break; + } + } +} diff --git a/src/app/singlethread_vio.cpp b/src/app/singlethread_vio.cpp new file mode 100644 index 00000000..f85eb20a --- /dev/null +++ b/src/app/singlethread_vio.cpp @@ -0,0 +1,108 @@ +// Single-thread VIO running on TUMVI dataset +// Author: Xiaohan Fei +#include "unistd.h" +#include + +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" +#include "gflags/gflags.h" +#include "glog/logging.h" +#include "opencv2/highgui/highgui.hpp" + +#include "estimator.h" +#include "estimator_process.h" +#include "metrics.h" +#include "tracker.h" +#include "tumvi.h" +#include "viewer.h" +#include "visualize.h" + +// flags +DEFINE_string(cfg, "cfg/vio.json", + "Configuration file for the VIO application."); +DEFINE_string(root, "/home/feixh/Data/tumvi/exported/euroc/512_16/", + "Root directory containing tumvi dataset folder."); +DEFINE_string(dataset, "tumvi", "euroc | tumvi"); +DEFINE_string(seq, "room1", "Sequence of TUM VI benchmark to play with."); +DEFINE_int32(cam_id, 0, "Camera id."); +DEFINE_string(out, "out_state", "Output file path."); + +using namespace feh; + +int main(int argc, char **argv) { + google::InitGoogleLogging(argv[0]); + gflags::ParseCommandLineFlags(&argc, &argv, true); + + auto cfg = LoadJson(FLAGS_cfg); + bool verbose = cfg.get("verbose", false).asBool(); + + std::string image_dir, imu_dir, mocap_dir; + std::tie(image_dir, imu_dir, mocap_dir) = + GetDirs(FLAGS_dataset, FLAGS_root, FLAGS_seq, FLAGS_cam_id); + + std::unique_ptr loader(new TUMVILoader{image_dir, imu_dir}); + + // create estimator + auto est = std::make_unique( + LoadJson(cfg["estimator_cfg"].asString())); + + // create viewer + std::unique_ptr viewer; + if (cfg.get("visualize", false).asBool()) { + viewer = std::make_unique( + LoadJson(cfg["viewer_cfg"].asString()), FLAGS_seq); + } + + // setup I/O for saving results + if (std::ofstream ostream{FLAGS_out, std::ios::out}) { + + std::vector traj_est; + + for (int i = 0; i < loader->size(); ++i) { + auto raw_msg = loader->Get(i); + + if (verbose && i % 1000 == 0) { + std::cout << i << "/" << loader->size() << std::endl; + } + + if (auto msg = dynamic_cast(raw_msg)) { + auto image = cv::imread(msg->image_path_); + est->VisualMeas(msg->ts_, image); + if (viewer) { + viewer->Update_gsb(est->gsb()); + viewer->Update_gsc(est->gsc()); + + cv::Mat disp = Canvas::instance()->display(); + + if (!disp.empty()) { + LOG(INFO) << "Display image is ready"; + viewer->Update(disp); + viewer->Refresh(); + } + } + } else if (auto msg = dynamic_cast(raw_msg)) { + est->InertialMeas(msg->ts_, msg->gyro_, msg->accel_); + // if (viewer) { + // viewer->Update_gsb(est->gsb()); + // viewer->Update_gsc(est->gsc()); + // } + } else { + throw std::runtime_error("Invalid entry type."); + } + + traj_est.emplace_back(est->ts(), est->gsb()); + ostream << absl::StrFormat("%ld", est->ts().count()) << " " + << est->gsb().translation().transpose() << " " + << est->gsb().rotation().log().transpose() << std::endl; + + // std::this_thread::sleep_for(std::chrono::milliseconds(3)); + + } + } else { + LOG(FATAL) << "failed to open output file @ " << FLAGS_out; + } + // while (viewer) { + // viewer->Refresh(); + // usleep(30); + // } +} diff --git a/src/app/vio.cpp b/src/app/vio.cpp new file mode 100644 index 00000000..dbcda512 --- /dev/null +++ b/src/app/vio.cpp @@ -0,0 +1,103 @@ +// Visual-Inertial Odometry application with threading. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#include "unistd.h" +#include + +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" +#include "gflags/gflags.h" +#include "glog/logging.h" +#include "opencv2/highgui/highgui.hpp" + +#include "estimator.h" +#include "estimator_process.h" +#include "metrics.h" +#include "tracker.h" +#include "tumvi.h" +#include "publisher.h" +#include "visualize.h" + +// flags +DEFINE_string(cfg, "cfg/vio.json", + "Configuration file for the VIO application."); +DEFINE_string(root, "/home/feixh/Data/tumvi/exported/euroc/512_16/", + "Root directory containing tumvi dataset folder."); +DEFINE_string(dataset, "tumvi", "euroc | tumvi"); +DEFINE_string(seq, "room1", "Sequence of TUM VI benchmark to play with."); +DEFINE_int32(cam_id, 0, "Camera id."); +DEFINE_string(out, "out_state", "Output file path."); + +using namespace feh; + +int main(int argc, char **argv) { + google::InitGoogleLogging(argv[0]); + gflags::ParseCommandLineFlags(&argc, &argv, true); + + auto cfg = LoadJson(FLAGS_cfg); + bool verbose = cfg.get("verbose", false).asBool(); + bool viz = cfg.get("visualize", false).asBool(); + + std::string image_dir, imu_dir, mocap_dir; + std::tie(image_dir, imu_dir, mocap_dir) = + GetDirs(FLAGS_dataset, FLAGS_root, FLAGS_seq, FLAGS_cam_id); + + TUMVILoader loader(image_dir, imu_dir); + + // create estimator + std::unique_ptr est_proc( + new EstimatorProcess{"Estimator", 1000}); + est_proc->Initialize(cfg["estimator_cfg"].asString()); + + // create view publisher + std::unique_ptr publisher; + if (viz) { + auto viewer_cfg = LoadJson(cfg["viewer_cfg"].asString()); + publisher = std::unique_ptr( + new ViewPublisher(viewer_cfg)); + est_proc->SetPublisher(publisher.get()); + publisher->Start(); + } + est_proc->Start(); + + for (int i = 0; i < loader.size(); ++i) { + if (verbose && i % 1000 == 0) { + std::cout << i << "/" << loader.size() << std::endl; + } + auto msg = loader.Get(i); + + if (typeid(*msg) == typeid(msg::Image)) { + + auto image_msg = dynamic_cast(msg); + auto image = cv::imread(image_msg->image_path_); + est_proc->Enqueue(std::move( + std::make_unique(image_msg->ts_, image, viz))); + + } else if (typeid(*msg) == typeid(msg::IMU)) { + + auto imu_msg = dynamic_cast(msg); + est_proc->Enqueue(std::move( + std::make_unique(imu_msg->ts_, imu_msg->gyro_, imu_msg->accel_, viz))); + + } else { + throw std::runtime_error("Invalid entry type."); + } + //////////////////////////////////////// + // EXAMPLE: SYNC AND READ OUT CURRENT ESTIMATES + //////////////////////////////////////// + if (verbose) { + est_proc->Wait(); + std::cout << absl::StrFormat("%ld", est_proc->ts().count()) << " " + << est_proc->gsb().translation().transpose() << std::endl; + } + } + est_proc->Wait(); + // sleep(5); + std::cout << "done" << std::endl; + est_proc.reset(); + std::cout << "estimator-process reset" << std::endl; + if (publisher) { + publisher->Wait(); + publisher.reset(); + std::cout << "publisher reset" << std::endl; + } +} diff --git a/src/camera_manager.cpp b/src/camera_manager.cpp new file mode 100644 index 00000000..0b8f27e6 --- /dev/null +++ b/src/camera_manager.cpp @@ -0,0 +1,56 @@ +#include "camera_manager.h" + +namespace feh { +std::unique_ptr CameraManager::instance_ = nullptr; + +CameraManager *CameraManager::Create(const Json::Value &cfg) { + if (!instance_) { + instance_ = std::unique_ptr(new CameraManager(cfg)); + } + return instance_.get(); +} + +CameraManager::CameraManager(const Json::Value &cfg) : model_{Unknown{}} { + + auto cam_model = cfg["model"].asString(); + int rows = cfg["rows"].asInt(); + int cols = cfg["cols"].asInt(); + ftype fx = cfg["fx"].asDouble(); + ftype fy = cfg["fy"].asDouble(); + ftype cx = cfg["cx"].asDouble(); + ftype cy = cfg["cy"].asDouble(); + + if (cam_model == "atan") { + fx = cols * fx; + fy = rows * fy; + cx = cols * cx; + cy = rows * cy; + ftype w = cfg["w"].asDouble(); + model_ = ATAN{rows, cols, fx, fy, cx, cy, w}; + dim_ = ATAN::DIM; + } else if (cam_model == "equidistant") { + auto k0123 = GetVectorFromJson(cfg, "k0123"); + int max_iter = cfg.get("max_iter", 15).asInt(); + + model_ = EquiDist{rows, cols, fx, fy, cx, cy, + k0123[0], k0123[1], k0123[2], k0123[3], max_iter}; + dim_ = EquiDist::DIM; + } else if (cam_model == "radtan") { + throw std::runtime_error("Radial-Tangential Model NOT implemented"); + } else if (cam_model == "pinhole") { + model_ = Pinhole{rows, cols, fx, fy, cx, cy}; + dim_ = Pinhole::DIM; + } else { + throw std::invalid_argument("invalid camera model"); + } + + rows_ = rows; + cols_ = cols; + fx_ = fx; + fy_ = fy; + cx_ = cx; + cy_ = cy; + fl_ = 0.5 * std::sqrt(fx * fx + fy * fy); +} + +} // namespace feh diff --git a/src/camera_manager.h b/src/camera_manager.h new file mode 100644 index 00000000..3abbf8fd --- /dev/null +++ b/src/camera_manager.h @@ -0,0 +1,137 @@ +#pragma once +#include +#include + +#include "atan.h" +#include "equidist.h" +#include "pinhole.h" +#include "radtan.h" + +#include "adjustable_cameras.h" +#include "alias.h" +#include "glog/logging.h" +#include "utils.h" +#include "json/json.h" + +namespace feh { + +template using UnknownCamera = T; + +class CameraManager { +public: + using Unknown = UnknownCamera; + using ATAN = A_ATANCamera; + using EquiDist = A_EquidistantCamera; + // using EquiDist = EquidistantCamera; + using RadTan = A_RadialTangentialCamera; + using Pinhole = A_PinholeCamera; + + static CameraManager *Create(const Json::Value &cfg); + static CameraManager *instance() { return instance_.get(); } + + // project a point from camera coordinatex xc to pixel coordinates xp. + // xc: a point in camera coordinates. + // jac: jacobian matrix dxp/dxc + // jacc: jacobian matrix of xp w.r.t. camera intrinsics + template + Eigen::Matrix Project( + const Eigen::MatrixBase &xc, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + if (std::holds_alternative(model_)) { + return std::get(model_).Project(xc, jac, jacc); + } else if (std::holds_alternative(model_)) { + return std::get(model_).Project(xc, jac, jacc); + } else if (std::holds_alternative(model_)) { + return std::get(model_).Project(xc, jac, jacc); + } else if (std::holds_alternative(model_)) { + return std::get(model_).Project(xc, jac, jacc); + } else { + LOG(FATAL) << "unknown camera model"; + } + } + + // unproject a point from pixel coordinatex xp to camera coordinates xc. + // xp: a point in pixel coordinates. + // jac: jacobian matrix dxc/dxp + // jacc: jacobian matrix of xc w.r.t. camera intrinsics + template + Eigen::Matrix UnProject( + const Eigen::MatrixBase &xp, + Eigen::Matrix *jac = nullptr, + Eigen::Matrix *jacc = nullptr) const { + if (jacc != nullptr) { + LOG(FATAL) << "jacobian w.r.t. camera intrinsics (jacc) NOT implemented"; + } + + if (std::holds_alternative(model_)) { + return std::get(model_).UnProject(xp, jac, jacc); + } else if (std::holds_alternative(model_)) { + return std::get(model_).UnProject(xp, jac, jacc); + } else if (std::holds_alternative(model_)) { + return std::get(model_).UnProject(xp, jac, jacc); + } else if (std::holds_alternative(model_)) { + return std::get(model_).UnProject(xp, jac, jacc); + } else { + LOG(FATAL) << "unknown camera model"; + } + } + + void Print(std::ostream &out) const { + if (std::holds_alternative(model_)) { + std::get(model_).Print(out); + } else if (std::holds_alternative(model_)) { + std::get(model_).Print(out); + } else if (std::holds_alternative(model_)) { + std::get(model_).Print(out); + } else if (std::holds_alternative(model_)) { + std::get(model_).Print(out); + } else { + LOG(FATAL) << "unknown camera model"; + } + } + + void UpdateState(const VecX &dX) { + if (std::holds_alternative(model_)) { + std::get(model_).UpdateState(dX.head()); + } else if (std::holds_alternative(model_)) { + std::get(model_).UpdateState(dX.head()); + } else if (std::holds_alternative(model_)) { + std::get(model_).UpdateState(dX.head()); + } else if (std::holds_alternative(model_)) { + std::get(model_).UpdateState(dX.head()); + } else { + LOG(FATAL) << "unknown camera model"; + } + // also update intrinsics for the camer manager ... + fx_ += dX(0); + fy_ += dX(1); + cx_ += dX(2); + cy_ += dX(3); + fl_ = std::sqrt(0.5 * (fx_ * fx_ + fy_ * fy_)); + } + + ftype GetFocalLength() const { return fl_; } + int rows() const { return rows_; } + int cols() const { return cols_; } + ftype fx() const { return fx_; } + ftype fy() const { return fy_; } + ftype cx() const { return cx_; } + ftype cy() const { return cy_; } + int dim() const { return dim_; } + +private: + CameraManager &operator=(const CameraManager &) = delete; + CameraManager(const CameraManager &) = delete; + + CameraManager(const Json::Value &cfg); + static std::unique_ptr instance_; + + int rows_, cols_; + ftype fx_, fy_, cx_, cy_; + ftype fl_; // focal length + std::variant model_; + int dim_; // number of intrinsic parameters +}; + +} // namespace feh diff --git a/src/core.cpp b/src/core.cpp new file mode 100644 index 00000000..788ffc00 --- /dev/null +++ b/src/core.cpp @@ -0,0 +1,26 @@ +#include "core.h" + +namespace feh { + +// utilities for nominal state +State operator-(const State &s1, const State &s2) { + return {s1.Rsb * s2.Rsb.inv(), s1.Tsb - s2.Tsb, s1.Vsb - s2.Vsb, + s1.bg - s2.bg, s1.ba - s2.ba, s1.Rbc * s2.Rbc.inv(), + s1.Tbc - s2.Tbc, s1.Rg * s2.Rg.inv()}; +} + +std::ostream &operator<<(std::ostream &os, const State &s) { + os << "\n=====\n"; + os << "Rsb=\n" << s.Rsb.matrix(); + os << "\nTsb=\n" << s.Tsb.transpose(); + os << "\nVsb=\n" << s.Vsb.transpose(); + os << "\nbg=\n" << s.bg.transpose(); + os << "\nba=\n" << s.ba.transpose(); + os << "\nRbc=\n" << s.Rbc.matrix(); + os << "\nTbc=\n" << s.Tbc.transpose(); + os << "\nRg=\n" << s.Rg.matrix(); + os << "\n=====\n"; + return os; +} + +} // namespace feh diff --git a/src/core.h b/src/core.h new file mode 100644 index 00000000..ba0e12dd --- /dev/null +++ b/src/core.h @@ -0,0 +1,170 @@ +// Core data structures +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include +#include +#include +#include +#include + +#include "alias.h" +#include "camera_manager.h" +#include "helpers.h" +#include "rodrigues.h" +#include "se3.h" +#include "utils.h" + +namespace feh { +//////////////////////////////////////// +// TYPES FOR TIME +//////////////////////////////////////// +using nanoseconds = std::chrono::nanoseconds; // uint64_t +using seconds = std::chrono::duration; // double +using timestamp_t = nanoseconds; + +//////////////////////////////////////// +// STATE DIMENSION +//////////////////////////////////////// +enum Index : int { + W = 0, // Wsb, rotation + Wsb = 0, + T = 3, // Tsb, translation + Tsb = 3, + V = 6, // vsb, velocity + Vsb = 6, + bg = 9, // omega bias + ba = 12, // alpha bias + Wbc = 15, // alignment rotation + Tbc = 18, // alignment translation + Wg = 21, // gravity +#ifdef USE_ONLINE_TEMPORAL_CALIB + td = 24, // temporal offset +#endif + +#ifdef USE_ONLINE_IMU_CALIB + +#ifdef USE_ONLINE_TEMPORAL_CALIB + Cg = 25, // gyro calibration, 9 numbers +#else + Cg = 24, // gyro calibration, 9 numbers +#endif + Ca = Cg + 9, // accel calibration, 6 numbers + End = Ca + 6, + +#else + +#ifdef USE_ONLINE_TEMPORAL_CALIB + End = td + 1, +#else + End = Wg + 3 +#endif + +#endif + +}; + +constexpr int kMotionSize = Index::End; + +constexpr int kCameraBegin = kMotionSize; + +#ifdef USE_ONLINE_CAMERA_CALIB +constexpr int kMaxCameraIntrinsics = + 9; // maximal possible number of intrinsic parameters +#else +constexpr int kMaxCameraIntrinsics = + 0; // maximal possible number of intrinsic parameters +#endif + +constexpr int kGroupSize = 6; +constexpr int kFeatureSize = 3; + +constexpr int kMaxGroup = 30; +constexpr int kMaxFeature = 30; + +constexpr int kGroupBegin = kCameraBegin + kMaxCameraIntrinsics; +constexpr int kFeatureBegin = kGroupBegin + kGroupSize * kMaxGroup; +constexpr int kFullSize = kFeatureBegin + kFeatureSize * kMaxFeature; +//////////////////////////////////////// +// STATE +//////////////////////////////////////// +struct State { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + // nominal state + SO3 Rsb; // body to spatial rotation + Vec3 Tsb, Vsb; // body to spatial translation and velocity + Vec3 bg, ba; // gyro and accl bias + + SO3 Rbc; + Vec3 Tbc; + SO3 Rg; + + ftype td; + + using Tangent = Eigen::Matrix; + State &operator+=(const Tangent &dX) { + Rsb *= SO3::exp(dX.segment<3>(Index::Wsb)); + Tsb += dX.segment<3>(Index::Tsb); + Vsb += dX.segment<3>(Index::Vsb); + bg += dX.segment<3>(Index::bg); + ba += dX.segment<3>(Index::ba); + Rbc *= SO3::exp(dX.segment<3>(Index::Wbc)); + Tbc += dX.segment<3>(Index::Tbc); + // Rg *= SO3::exp(Vec3{dX(Index::Wg), dX(Index::Wg + 1), 0.0}); + Rg *= SO3::exp(dX.segment<3>(Index::Wg)); +// std::cout << "Wg=" << dX.segment<3>(Index::Wg).transpose() << std::endl; +#ifdef USE_ONLINE_TEMPORAL_CALIB + td += dX(Index::td); +#endif + return *this; + } +}; + +State operator-(const State &s1, const State &s2); +std::ostream &operator<<(std::ostream &out, const State &s); +//////////////////////////////////////// +// STATUS +//////////////////////////////////////// +enum class TrackStatus : int { + CREATED = 0, // feature just been detected + TRACKED = 1, // feature being tracked well + REJECTED = 2, // rejected by the tracker + DROPPED = 3 // out of view? +}; +enum class FeatureStatus : int { + CREATED = 0, + INITIALIZING = 1, + READY = 2, + INSTATE = 3, + REJECTED_BY_FILTER = 4, + REJECTED_BY_TRACKER = 5, + DROPPED = 6, + // GAUGE = 7 // chosen to fix gauge freedom +}; + +enum class GroupStatus : int { + CREATED = 0, // newly created + INSTATE = 1, // instate + FLOATING = 2, // floating + GAUGE = 3 // chosen to fix gauge freedom +}; + +class Feature; +using FeaturePtr = Feature *; +class Group; +using GroupPtr = Group *; +class Tracker; +using TrackerPtr = Tracker *; +using Camera = CameraManager; +using CameraPtr = Camera *; +using Config = Json::Value; +class MemoryManager; +using MemoryManagerPtr = MemoryManager *; +class Estimator; +//////////////////////////////////////// +// CUSTOM EXCEPTION +//////////////////////////////////////// +struct NotImplemented : public std::exception { + virtual char const *what() noexcept { return "NOT implemented"; } +}; + +} // namespace feh diff --git a/src/estimator.cpp b/src/estimator.cpp new file mode 100644 index 00000000..8e7bcbba --- /dev/null +++ b/src/estimator.cpp @@ -0,0 +1,977 @@ +#include +#include +#include +#include + +#include "Eigen/QR" +#include "absl/strings/str_format.h" +#include "glog/logging.h" + +#include "estimator.h" +#include "feature.h" +#include "geometry.h" +#include "group.h" +#include "jac.h" +#include "mm.h" +#include "param.h" +#include "tracker.h" + +namespace feh { + +static bool cmp(const std::unique_ptr &m1, + const std::unique_ptr &m2) { + return m1->ts() > m2->ts(); +} + +namespace internal { +void Inertial::Execute(Estimator *est) { + est->InertialMeasInternal(ts_, gyro_, accel_); +} + +void Visual::Execute(Estimator *est) { est->VisualMeasInternal(ts_, img_); } +} // namespace internal + +Estimator::~Estimator() { + if (worker_) { + worker_->join(); + delete worker_; + } +} + +Estimator::Estimator(const Json::Value &cfg) + : cfg_{cfg}, gauge_group_{-1}, worker_{nullptr}, timer_{"estimator"} { + // ///////////////////////////// + // Component flags + // ///////////////////////////// + simulation_ = cfg_.get("simulation", false).asBool(); + use_canvas_ = cfg_.get("use_canvas", true).asBool(); + print_timing_ = cfg_.get("print_timing", false).asBool(); + integration_method_ = + cfg_.get("integration_method", "unspecified").asString(); + + // OOS update options + use_OOS_ = cfg_.get("use_OOS", false).asBool(); + use_compression_ = cfg_.get("use_compression", false).asBool(); + compression_trigger_ratio_ = + cfg_.get("compression_trigger_ratio", 1.5).asDouble(); + + // one point ransac parameters + use_1pt_RANSAC_ = cfg_.get("use_1pt_RANSAC", false).asBool(); + ransac_thresh_ = cfg_.get("1pt_RANSAC_thresh", 5).asDouble(); + ransac_prob_ = cfg_.get("1pt_RANSAC_prob", 0.95).asDouble(); + ransac_Chi2_ = cfg_.get("1pt_RANSAC_Chi2", 5.89).asDouble(); + + // depth optimization options + use_depth_opt_ = cfg_.get("use_depth_opt", false).asBool(); + refinement_options_.two_view = + cfg_["depth_opt"].get("two_view", false).asBool(); + refinement_options_.max_iters = cfg_["depth_opt"].get("max_iters", 5).asInt(); + refinement_options_.eps = cfg_["depth_opt"].get("eps", 1e-4).asDouble(); + refinement_options_.damping = + cfg_["depth_opt"].get("damping", 1e-3).asDouble(); + refinement_options_.max_res_norm = + cfg_["depth_opt"].get("max_res_norm", 2.0).asDouble(); + + // depth-initialization subfilter options + ftype tri_std = cfg_["subfilter"].get("visual_meas_std", 3.5).asDouble(); + subfilter_options_.Rtri = tri_std * tri_std; + subfilter_options_.MH_thresh = + cfg_["subfilter"].get("MH_thresh", 5.991).asDouble(); + subfilter_options_.ready_steps = + cfg_["subfilter"].get("ready_steps", 5).asInt(); + + triangulate_pre_subfilter_ = + cfg_.get("triangulate_pre_subfilter", false).asBool(); + triangulate_options_.method = cfg_["triangulation"].get("method", 1).asInt(); + triangulate_options_.zmin = + cfg_["triangulation"].get("zmin", 0.05).asDouble(); + triangulate_options_.zmax = cfg_["triangulation"].get("zmax", 5.0).asDouble(); + + // load imu calibration + auto imu_calib = cfg_["imu_calib"]; + // load accel axis misalignment first as a 3x3 matrix + Mat3 Ca = + GetMatrixFromJson(imu_calib, "Car", JsonMatLayout::RowMajor); + // then overwrite the diagonal with scaling + Ca.diagonal() = GetVectorFromJson(imu_calib, "Cas"); + // load gyro axis misalignment first as 3x3 matrix + Mat3 Cg = + GetMatrixFromJson(imu_calib, "Cgr", JsonMatLayout::RowMajor); + // hen overwrite the diagonal with scaling + Cg.diagonal() = GetVectorFromJson(imu_calib, "Cgs"); + // now update the IMU component + imu_ = IMU{Ca, Cg}; + LOG(INFO) << "Imu calibration loaded"; + + // load camera parameters + auto cam_cfg = cfg_["camera_cfg"].isString() + ? LoadJson(cfg_["camera_cfg"].asString()) + : cfg_["camera_cfg"]; + Camera::Create(cam_cfg); + LOG(INFO) << "Camera created"; + + g_ = GetMatrixFromJson(cfg_, "gravity"); + LOG(INFO) << "gravity loaded:" << g_.transpose(); + + // ///////////////////////////// + // Initialize motion state + // ///////////////////////////// + auto X = cfg_["X"]; + try { + X_.Rsb = SO3::exp(GetVectorFromJson(X, "W")); + } catch (const Json::LogicError &e) { + X_.Rsb = + SO3(GetMatrixFromJson(X, "W", JsonMatLayout::RowMajor)); + } + X_.Tsb = GetVectorFromJson(X, "T"); + X_.Vsb = GetVectorFromJson(X, "V"); + X_.bg = GetVectorFromJson(X, "bg"); + X_.ba = GetVectorFromJson(X, "ba"); + try { + X_.Rbc = SO3::exp(GetVectorFromJson(X, "Wbc")); + } catch (const Json::LogicError &e) { + X_.Rbc = + SO3(GetMatrixFromJson(X, "Wbc", JsonMatLayout::RowMajor)); + } + X_.Tbc = GetVectorFromJson(X, "Tbc"); + Vec3 Wg; + // Wg.head<2>() = GetVectorFromJson(X, "Wg"); + Wg = GetVectorFromJson(X, "Wg"); + X_.Rg = SO3::exp(Wg); +// temporal offset +#ifdef USE_ONLINE_TEMPORAL_CALIB + X_.td = X["td"].asDouble(); +#endif + + // initialize error state + err_.resize(kFullSize); + err_.setZero(); + // make all group & feature slots available + std::fill(gsel_.begin(), gsel_.end(), false); + std::fill(fsel_.begin(), fsel_.end(), false); + LOG(INFO) << "Initial state loaded"; + LOG(INFO) << X_; + + auto P = cfg_["P"]; + P_.setIdentity(kFullSize, kFullSize); + P_.block<3, 3>(Index::W, Index::W) *= P["W"].asDouble(); + P_.block<3, 3>(Index::T, Index::T) *= P["T"].asDouble(); + P_.block<3, 3>(Index::V, Index::V) *= P["V"].asDouble(); + P_.block<3, 3>(Index::bg, Index::bg) *= P["bg"].asDouble(); + P_.block<3, 3>(Index::ba, Index::ba) *= P["ba"].asDouble(); + P_.block<3, 3>(Index::Wbc, Index::Wbc) *= P["Wbc"].asDouble(); + P_.block<3, 3>(Index::Tbc, Index::Tbc) *= P["Tbc"].asDouble(); + P_.block<3, 3>(Index::Wg, Index::Wg) *= P["Wg"].asDouble(); +#ifdef USE_ONLINE_TEMPORAL_CALIB + P_(Index::td, Index::td) *= P["td"].asDouble(); +#endif + +#ifdef USE_ONLINE_IMU_CALIB + // online IMU calibration + P_.block<9, 9>(Index::Cg, Index::Cg) *= P["Cg"].asDouble(); + P_.block<6, 6>(Index::Ca, Index::Ca) *= P["Ca"].asDouble(); +#endif +// online camera intrinsics calibration +// initialize covariance for camera intrinsics +#ifdef USE_ONLINE_CAMERA_CALIB + int dim = Camera::instance()->dim(); + P_.block(kCameraBegin, kCameraBegin, 4, 4) *= P["FC"].asDouble(); + P_.block(kCameraBegin + 4, kCameraBegin + 4, dim - 4, dim - 4) *= + P["distortion"].asDouble(); + P_.block(kCameraBegin + dim, kCameraBegin + dim, kMaxCameraIntrinsics - dim, + kMaxCameraIntrinsics - dim) *= 0; +#endif + // standard deviation -> covariance + P_.block(0, 0) *= + P_.block(0, 0); + LOG(INFO) << "Initial covariance loaded"; + + // allocate spaces for Jacobians + F_.resize(kMotionSize, kMotionSize); + F_.setIdentity(); + G_.resize(kMotionSize, 12); + G_.setZero(); + + auto Qmodel = cfg_["Qmodel"]; + Qmodel_.setIdentity(kMotionSize, kMotionSize); + Qmodel_.block<3, 3>(Index::W, Index::W) *= Qmodel["W"].asDouble(); + Qmodel_.block<3, 3>(Index::T, Index::T) *= Qmodel["T"].asDouble(); + Qmodel_.block<3, 3>(Index::V, Index::V) *= Qmodel["V"].asDouble(); + Qmodel_.block<3, 3>(Index::bg, Index::bg) *= Qmodel["bg"].asDouble(); + Qmodel_.block<3, 3>(Index::ba, Index::ba) *= Qmodel["ba"].asDouble(); + Qmodel_.block<3, 3>(Index::Wbc, Index::Wbc) *= Qmodel["Wbc"].asDouble(); + Qmodel_.block<3, 3>(Index::Tbc, Index::Tbc) *= Qmodel["Tbc"].asDouble(); + Qmodel_.block<3, 3>(Index::Wg, Index::Wg) *= Qmodel["Wg"].asDouble(); + Qmodel_.block(0, 0) *= + Qmodel_.block(0, 0); + LOG(INFO) << "Covariance of process noises loaded"; + + // ///////////////////////////// + // Initialize measurement noise + // ///////////////////////////// + auto Qimu = cfg_["Qimu"]; + Qimu_.setIdentity(12, 12); + Qimu_.block<3, 3>(0, 0) *= Qimu["gyro"].asDouble(); + Qimu_.block<3, 3>(3, 3) *= Qimu["accel"].asDouble(); + Qimu_.block<3, 3>(6, 6) *= Qimu["gyro_bias"].asDouble(); + Qimu_.block<3, 3>(9, 9) *= Qimu["accel_bias"].asDouble(); + Qimu_ *= Qimu_; + LOG(INFO) << "Covariance of IMU measurement noise loaded"; + + // initialize memory manager + MemoryManager::Create(cfg_["memory"].get("max_features", 256).asInt(), + cfg_["memory"].get("max_groups", 128).asInt()); + LOG(INFO) << "Memory management unit created"; + + // FIXME: better to make the usage consistent + // i.e., replace cfg_ with the parameter server totally + // initialize paramter server + ParameterServer::Create(cfg_); + LOG(INFO) << "Parameter server created"; + + // initialize tracker + auto tracker_cfg = cfg_["tracker_cfg"].isString() + ? LoadJson(cfg_["tracker_cfg"].asString()) + : cfg_["tracker_cfg"]; + Tracker::Create(tracker_cfg); + LOG(INFO) << "Tracker created"; + + R_ = cfg_["visual_meas_std"].asDouble(); + R_ *= R_; + + Roos_ = cfg["oos_meas_std"].asDouble(); + Roos_ *= Roos_; + + LOG(INFO) << "R=" << R_ << " ;Roos=" << Roos_; + + // ///////////////////////////// + // Load initial std on feature state + // ///////////////////////////// + init_z_ = cfg_["initial_z"].asDouble(); + init_std_x_ = cfg_["initial_std_x"].asDouble(); + init_std_y_ = cfg_["initial_std_y"].asDouble(); + init_std_x_ /= Camera::instance()->GetFocalLength(); + init_std_y_ /= Camera::instance()->GetFocalLength(); + init_std_z_ = cfg_["initial_std_z"].asDouble(); + LOG(INFO) << "Initial covariance for features loaded"; + + // ///////////////////////////// + // Outlier rejection options + // ///////////////////////////// + use_MH_gating_ = cfg_.get("use_MH_gating", true).asBool(); + min_required_inliers_ = cfg_.get("min_inliers", 5).asInt(); + MH_thresh_ = cfg_.get("MH_thresh", 5.991).asDouble(); + MH_thresh_multipler_ = cfg_.get("MH_adjust_factor", 1.1).asDouble(); + // FIXME (xfei): used in HuberOnInnovation, but kinda overlaps with MH gating + outlier_thresh_ = cfg_.get("outlier_thresh", 1.1).asDouble(); + + // reset initialization status + gravity_init_counter_ = cfg_.get("gravity_init_counter", 20).asInt(); + gravity_initialized_ = false; + vision_initialized_ = false; + // reset measurement counter + imu_counter_ = 0; + vision_counter_ = 0; + // reset various timestamps + last_imu_time_ = timestamp_t::zero(); + curr_imu_time_ = timestamp_t::zero(); + + last_vision_time_ = timestamp_t::zero(); + curr_vision_time_ = timestamp_t::zero(); + + last_time_ = timestamp_t::zero(); + curr_time_ = timestamp_t::zero(); + + // random number generator + rng_ = std::unique_ptr( + new std::default_random_engine); + + async_run_ = cfg_.get("async_run", false).asBool(); + if (async_run_) { + Run(); + } +} + +void Estimator::Run() { + worker_ = new std::thread([this]() { + for (;;) { + std::unique_ptr msg; + { + std::scoped_lock lck(buf_.mtx); + if (buf_.initialized && buf_.size() > InternalBuffer::MAX_SIZE) { + msg = std::move(buf_.front()); + std::pop_heap(buf_.begin(), buf_.end(), cmp); + buf_.pop_back(); + } + } + if (msg != nullptr) { + // std::cout << "executing\n"; + msg->Execute(this); + } + } + }); +} + +bool Estimator::Finished() { + CHECK(async_run_); + std::scoped_lock lck(buf_.mtx); + return buf_.empty(); +} + +bool Estimator::InitializeGravity() { + VLOG(0) << "attempt to initialize gravity"; + if (!simulation_) { + if (gravity_init_buf_.size() < gravity_init_counter_) { + return false; + } + VLOG(0) << "initializing gravity"; + + // got enough stationary samples, estimate gravity + Vec3 mean_accel = std::accumulate(gravity_init_buf_.begin(), + gravity_init_buf_.end(), Vec3{0, 0, 0}); + mean_accel /= gravity_init_buf_.size(); + + Vec3 accel_calib = imu_.Ca() * (mean_accel - X_.ba); + + // FromTwoVectors(a, b): returns R such that b=R*a + // we need R * accel + Rg * g_ == 0 + // And R = Identity + // so accel = Rg * (-g_) + Eigen::AngleAxis AAg( + Eigen::Quaternion::FromTwoVectors(-g_, accel_calib)); + Vec3 Wg(AAg.axis() * AAg.angle()); + // Wg(2) = 0; + auto Rg = SO3::exp(Wg); + X_.Rg = Rg; + + LOG(INFO) << "===== Wg initialization ====="; + LOG(INFO) << "stationary accel samples=" << gravity_init_buf_.size(); + LOG(INFO) << "accel " << accel_calib.transpose(); + LOG(INFO) << "Wg=" << Wg.transpose(); + LOG(INFO) << "g=" << g_.transpose(); + LOG(INFO) << "The norm below should be small"; + LOG(INFO) << "|Rsb*a+Rg*g|=" << (X_.Rsb * accel_calib + X_.Rg * g_).norm(); + } + return true; +} + +void Estimator::InertialMeasInternal(const timestamp_t &ts, const Vec3 &gyro, + const Vec3 &accel) { + if (!GoodTimestamp(ts)) + return; + + ++imu_counter_; + + // initialize imu -- basically gravity + if (!gravity_initialized_) { + gravity_init_buf_.emplace_back(accel); + + if (InitializeGravity()) { + // lock 4DoF gauge freedom + for (int i = 0; i < 3; ++i) { + P_(Index::T + i, Index::T + i) = eps; + } + P_(Index::W + 0, Index::W + 0) = eps; + P_(Index::W + 1, Index::W + 1) = eps; + P_(Index::W + 2, Index::W + 2) = eps; + + curr_imu_time_ = last_time_ = ts; + + curr_accel_ = last_accel_ = accel; + curr_gyro_ = last_gyro_ = gyro; + + gravity_initialized_ = true; + gravity_init_buf_.clear(); + LOG(INFO) << "IMU initialized"; + } + } else { + // process inertials only after vision module initialized + if (vision_initialized_) { + last_time_ = curr_time_; + curr_time_ = ts; + + curr_accel_ = accel; + curr_gyro_ = gyro; + + last_imu_time_ = curr_imu_time_; + curr_imu_time_ = ts; + Propagate(false); + } + } +} + +void Estimator::Propagate(bool visual_meas) { + CHECK(gravity_initialized_) + << "state progagation with un-initialized imu module"; + + timer_.Tick("propagation"); + + ftype dt; + Vec3 accel0, gyro0; // initial condition for integration + + dt = std::chrono::duration(curr_time_ - last_time_).count(); + if (dt == 0) { + LOG(WARNING) << "measurement timestamps coincide?"; + return; + } + + if (!visual_meas) { + // this is an imu meas + slope_accel_ = (curr_accel_ - last_accel_) / dt; + slope_gyro_ = (curr_gyro_ - last_gyro_) / dt; + + accel0 = last_accel_; + gyro0 = last_gyro_; + + last_accel_ = curr_accel_; + last_gyro_ = curr_gyro_; + } else { + // this is a visual meas + accel0 = last_accel_; + gyro0 = last_gyro_; + + last_accel_ = accel0 + slope_accel_ * dt; + last_gyro_ = gyro0 + slope_gyro_ * dt; + } + // std::cout << slope_accel_.transpose() << std::endl; + + if (dt > 0.030) { + LOG(WARNING) << "dt=" << dt << " > 30 ms"; + } + if (integration_method_ == "PrinceDormand") { + PrinceDormand(gyro0, accel0, dt); + } else if (integration_method_ == "Fehlberg") { + Fehlberg(gyro0, accel0, dt); + } else if (integration_method_ == "RK4") { + RK4(gyro0, accel0, dt); + } else { + LOG(FATAL) << "Unknown integration method"; + } + timer_.Tock("propagation"); +} + +void Estimator::Fehlberg(const Vec3 &gyro0, const Vec3 &accel0, ftype dt) { + throw NotImplemented(); +} + +void Estimator::ComposeMotion(State &X, const Vec3 &V, + const Eigen::Matrix &gyro_accel, + ftype dt) { + Vec3 gyro = gyro_accel.head<3>(); + Vec3 accel = gyro_accel.tail<3>(); + + Vec3 gyro_calib = imu_.Ca() * gyro - X.bg; + Vec3 accel_calib = imu_.Cg() * accel - X.ba; + + // integrate the nominal state + X.Tsb += V * dt; //+ 0.5 * a * dt * dt; + X.Vsb += (X.Rsb * accel_calib + X.Rg * g_) * dt; + X.Rsb *= SO3::exp(gyro_calib * dt); +} + +void Estimator::ComputeMotionJacobianAt( + const State &X, const Eigen::Matrix &gyro_accel) { + + Vec3 gyro = gyro_accel.head<3>(); + Vec3 accel = gyro_accel.tail<3>(); + + Vec3 gyro_calib = imu_.Cg() * gyro - X.bg; // \hat\omega in the doc + Vec3 accel_calib = imu_.Ca() * accel - X.ba; // \hat\alpha in the doc + + // jacobian w.r.t. error state + Mat3 R = X.Rsb.matrix(); + + Eigen::Matrix dW_dCg; + for (int i = 0; i < 3; ++i) { + // NOTE: use the raw measurement (gyro) here. NOT the calibrated one + // (gyro_calib)!!! + dW_dCg.block<1, 3>(i, 3 * i) = gyro; + } + + Eigen::Matrix dV_dRCa = dAB_dA(Mat3{}, accel); + Eigen::Matrix dRCa_dCafm = dAB_dB(R, Mat3{}); // fm: full matrix + Eigen::Matrix dCafm_dCa = + dA_dAu(Mat3{}); // full matrix w.r.t. upper triangle + Eigen::Matrix dV_dCa = dV_dRCa * dRCa_dCafm * dCafm_dCa; + + Mat3 dW_dW = -hat(gyro_calib); + Mat3 dW_dbg = -Mat3::Identity(); + + Mat3 dT_dV = Mat3::Identity(); + + Mat3 dV_dW = -R * hat(accel_calib); + Mat3 dV_dba = -R; + Mat3 tmp = -R * hat(g_); // 3x3 + // Mat32 dV_dWg = tmp.block<3, 3>(0, 0); // 3x2 + // + Mat3 dV_dWg = -R * hat(g_); + // Mat2 dWg_dWg = Mat2::Identity(); + + F_.setZero(); // wipe out the delta added to F in the previous step + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + // W + F_.coeffRef(Index::W + i, Index::W + j) += dW_dW(i, j); + F_.coeffRef(Index::W + i, Index::bg + j) += dW_dbg(i, j); + + // T + F_.coeffRef(Index::T + i, Index::V + j) += dT_dV(i, j); + + // V + F_.coeffRef(Index::V + i, Index::W + j) += dV_dW(i, j); + F_.coeffRef(Index::V + i, Index::ba + j) += dV_dba(i, j); + // if (j < 2) + F_.coeffRef(Index::V + i, Index::Wg + j) += dV_dWg(i, j); + } +#ifdef USE_ONLINE_IMU_CALIB + for (int j = 0; j < 9; ++j) { + F_.coeffRef(Index::W + i, Index::Cg + j) += dW_dCg(i, j); + } + for (int j = 0; j < 6; ++j) { + F_.coeffRef(Index::V + i, Index::Ca + j) += dV_dCa(i, j); + } +#endif + } + + Mat3 dW_dng = -Mat3::Identity(); + Mat3 dV_dna = -R; + Mat3 dbg_dnbg = Mat3::Identity(); + Mat3 dba_dnba = Mat3::Identity(); + + // jacobian w.r.t. noise + G_.setZero(); + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + G_.coeffRef(Index::W + i, j) += dW_dng(i, j); + G_.coeffRef(Index::V + i, 3 + j) += dV_dna(i, j); + G_.coeffRef(Index::bg + i, 6 + j) += dbg_dnbg(i, j); + G_.coeffRef(Index::ba + i, 9 + j) += dba_dnba(i, j); + } + } +} + +bool Estimator::GoodTimestamp(const timestamp_t &now) { + auto now_ms = std::chrono::duration_cast(now); + auto curr_ms = + std::chrono::duration_cast(curr_time_); + if (now_ms < curr_ms) { + LOG(WARNING) << absl::StrFormat("now=%ld ms < curr=%ld ms", now_ms.count(), + curr_ms.count()); + return false; + } else { + return true; + } +} + +void Estimator::UpdateSystemClock(const timestamp_t &now) { + if (!vision_initialized_) { + if (gravity_initialized_) { + // only initialize vision module after gravity initialized + curr_time_ = now; + last_vision_time_ = curr_vision_time_; + curr_vision_time_ = now; + + vision_initialized_ = true; + LOG(INFO) << "vision initialized"; + } + } else { + last_time_ = curr_time_; + curr_time_ = now; + + last_vision_time_ = curr_vision_time_; + curr_vision_time_ = now; + } +} + +void Estimator::RemoveGroupFromState(GroupPtr g) { + CHECK(g->instate()) << "free a group not instate"; + CHECK(g->sind() != -1) << "invalid state index"; + + VLOG(0) << "removing group #" << g->id(); + // change the covariance and error state + int index = g->sind(); + CHECK(gsel_[index]) << "Group not in state?!"; + + gsel_[index] = false; + g->SetSind(-1); + g->SetStatus(GroupStatus::FLOATING); + + int offset = kGroupBegin + 6 * index; + int size = err_.rows(); + + err_.segment<6>(offset).setZero(); + P_.block(offset, 0, 6, size).setZero(); + P_.block(0, offset, size, 6).setZero(); +} + +void Estimator::RemoveFeatureFromState(FeaturePtr f) { + + CHECK((f->instate() && (f->track_status() == TrackStatus::REJECTED || + f->track_status() == TrackStatus::DROPPED)) || + f->status() == FeatureStatus::REJECTED_BY_FILTER); + CHECK(f->sind() != -1) << "invalid state index"; + + VLOG(0) << "removing feature #" << f->id(); + int index = f->sind(); + CHECK(fsel_[index]) << "Feature not in state?!"; + + fsel_[index] = false; + f->SetSind(-1); + + int offset = kFeatureBegin + 3 * index; + int size = err_.rows(); + + err_.segment<3>(offset).setZero(); + P_.block(offset, 0, 3, size).setZero(); + P_.block(0, offset, size, 3).setZero(); +} + +void Estimator::AddGroupToState(GroupPtr g) { + CHECK(!g->instate()) << "group already in state"; + CHECK(g->sind() == -1) << "group slot already allocated"; + + // change the covariance and error state + int index; + // find empty slot + for (index = 0; index < gsel_.size() && gsel_[index]; ++index) + ; + if (index < gsel_.size()) { + gsel_[index] = true; + g->SetSind(index); + g->SetStatus(GroupStatus::INSTATE); + int offset = kGroupBegin + 6 * index; + + // with gsb=(Rsb, Tsb) as the augmented state + // augmentation is much simpler + err_.segment<3>(offset) = err_.segment<3>(Index::Wsb); + err_.segment<3>(offset + 3) = err_.segment<3>(Index::Tsb); + + P_.block(offset, 0, 3, err_.size()) = + P_.block(Index::Wsb, 0, 3, err_.size()); + P_.block(0, offset, err_.size(), 3) = + P_.block(0, Index::Wsb, err_.size(), 3); + + P_.block(offset + 3, 0, 3, err_.size()) = + P_.block(Index::Tsb, 0, 3, err_.size()); + P_.block(0, offset + 3, err_.size(), 3) = + P_.block(0, Index::Tsb, err_.size(), 3); + + VLOG(0) << absl::StrFormat("group #%d inserted @ %d/%d", g->id(), index, + kMaxGroup); + } else { + throw std::runtime_error("Failed to find slot in state for group."); + } +} + +void Estimator::AddFeatureToState(FeaturePtr f) { + CHECK(!f->instate()) << "feature already in state"; + CHECK(f->sind() == -1) << "feature slot already allocated"; + + // change the covariance and error state + int index; + // find empty slot + for (index = 0; index < fsel_.size() && fsel_[index]; ++index) + ; + if (index < fsel_.size()) { + fsel_[index] = true; + f->SetStatus(FeatureStatus::INSTATE); + f->SetSind(index); + int offset = kFeatureBegin + 3 * index; + + // Error-state equation + err_.segment<3>(offset).setZero(); + + // TODO: might need to play with the covariance + // copy local covariance obtained during initialization to state covariance + P_.block(offset, 0, 3, err_.size()).setZero(); + P_.block(0, offset, err_.size(), 3).setZero(); + // P_.block<3, 3>(offset, offset) = + // f->P() * cfg_.get("feature_P0_damping", 100).asDouble(); // damping + P_.block<3, 3>(offset, offset) = f->P(); + ftype damping = cfg_.get("feature_P0_damping", 10).asDouble(); + P_.block<2, 1>(offset, offset + 2) *= damping; + P_.block<1, 2>(offset + 2, offset) *= damping; + P_(offset + 2, offset + 2) *= (damping * damping); + + VLOG(0) << absl::StrFormat("feature #%d inserted @ %d/%d", f->id(), index, + kMaxFeature); + } else { + throw std::runtime_error("Failed to find slot in state for feature."); + } +} + +void Estimator::PrintErrorStateNorm() { + VLOG(0) << absl::StrFormat( + "|Wsb|=%0.8f, |Tsb|=%0.8f, |Vsb|=%0.8f, " + "|bg|=%0.8f, |ba|=%0.8f, |Wbc|=%0.8f, |Tbc|=%0.8f, |Wg|=%0.8f\n", + err_.segment<3>(Index::Wsb).norm(), err_.segment<3>(Index::Tsb).norm(), + err_.segment<3>(Index::Vsb).norm(), err_.segment<3>(Index::bg).norm(), + err_.segment<3>(Index::ba).norm(), err_.segment<3>(Index::Wbc).norm(), + err_.segment<3>(Index::Tbc).norm(), err_.segment<3>(Index::Wg).norm()); + for (auto g : instate_groups_) { + CHECK(gsel_[g->sind()]) << "instate group not actually instate"; + VLOG(0) << absl::StrFormat( + "g#%d |W|=%0.8f, |T|=%0.8f\n", g->id(), + err_.segment<3>(kGroupBegin + 6 * g->sind()).norm(), + err_.segment<3>(kGroupBegin + 6 * g->sind() + 3).norm()); + } + for (auto f : instate_features_) { + CHECK(fsel_[f->sind()]) << "instate feature not yet instate"; + VLOG(0) << absl::StrFormat( + "f#%d |X|=%0.8f\n", f->id(), + err_.segment<3>(kFeatureBegin + 3 * f->sind()).norm()); + } +} + +void Estimator::AbsorbError(const VecX &err) { + // motion state + this->UpdateState(err.head()); + +#ifdef USE_ONLINE_IMU_CALIB + // update IMU state + Eigen::Matrix dCaCg; + dCaCg << err.segment<6>(Index::Ca), err.segment<9>(Index::Cg); + imu_.UpdateState(dCaCg); +#endif + +#ifdef USE_ONLINE_CAMERA_CALIB + // update camera instrinsics + Camera::instance()->UpdateState( + err.segment(kCameraBegin)); +#endif + // Camera::instance()->Print(std::cout); + // std::cout << "Ca=\n" << imu_.Ca() << std::endl; + // std::cout << "Cg=\n" << imu_.Cg() << std::endl; + // std::cout << "td=" << err(Index::td) << std::endl; + + // augmented state + for (auto g : instate_groups_) { + CHECK(g->sind() != -1); + int offset = kGroupBegin + 6 * g->sind(); + g->UpdateState(err.segment<6>(offset)); + + // if (g->id() == gauge_group_) { + // std::cout << "gauge group:" << err.segment<6>(offset).transpose() << + // std::endl; + // } + } + for (auto f : instate_features_) { + CHECK(f->sind() != -1); + int offset = kFeatureBegin + 3 * f->sind(); + f->UpdateState(err.segment<3>(offset)); + } +} + +void Estimator::AbsorbError() { + AbsorbError(err_); + err_.setZero(); +} + +void Estimator::MaintainBuffer() { + if (!buf_.initialized) { + if (buf_.size() >= InternalBuffer::MAX_SIZE) { + std::make_heap(buf_.begin(), buf_.end(), cmp); + buf_.initialized = true; + } + } else { + std::push_heap(buf_.begin(), buf_.end(), cmp); + } + + if (!async_run_) { + // execute here + if (buf_.initialized && buf_.size() > InternalBuffer::MAX_SIZE) { + buf_.front()->Execute(this); + std::pop_heap(buf_.begin(), buf_.end(), cmp); + buf_.pop_back(); + } + } +} + +void Estimator::VisualMeas(const timestamp_t &ts_raw, const cv::Mat &img) { + timestamp_t ts{ts_raw}; +#ifdef USE_ONLINE_TEMPORAL_CALIB + if (X_.td >= 0) { + ts += timestamp_t(uint64_t(X_.td * 1e9)); // seconds -> nanoseconds + } else { + ts -= timestamp_t(uint64_t(-X_.td * 1e9)); // seconds -> nanoseconds + } +#endif + { + std::scoped_lock lck(buf_.mtx); + buf_.push_back(std::make_unique(ts, img)); + // std::cout << "visual pushed\n"; + MaintainBuffer(); + // std::cout << "buffer.size=" << buf_.size() << std::endl; + } +} + +void Estimator::InertialMeas(const timestamp_t &ts, const Vec3 &gyro, + const Vec3 &accel) { + { + std::scoped_lock lck(buf_.mtx); + buf_.push_back(std::make_unique(ts, gyro, accel)); + // std::cout << "inertial pushed\n"; + MaintainBuffer(); + } +} + +void Estimator::VisualMeasInternal(const timestamp_t &ts, const cv::Mat &img) { + if (!GoodTimestamp(ts)) + return; + + if (simulation_) { + throw std::invalid_argument( + "function VisualMeas cannot be called in simulation"); + } + + ++vision_counter_; + timer_.Tick("visual-meas"); + UpdateSystemClock(ts); + if (vision_initialized_) { + // propagate state upto current timestamp + Propagate(true); + if (use_canvas_) { + Canvas::instance()->Update(img); + } + // measurement prediction for feature tracking + auto tracker = Tracker::instance(); + Predict(tracker->features_); + // track features + timer_.Tick("track"); + tracker->Update(img); + timer_.Tock("track"); + // process features + timer_.Tick("process-tracks"); + ProcessTracks(ts, tracker->features_); + timer_.Tock("process-tracks"); + + if (gauge_group_ == -1) { + SwitchRefGroup(); + } + } + timer_.Tock("visual-meas"); +} + +void Estimator::Predict(std::list &features) { + for (auto f : features) { + f->Predict(gsb(), gbc()); + } +} + +void Estimator::UpdateJosephForm() { + + S_.setZero(H_.rows(), H_.cols()); + S_ = H_ * P_ * H_.transpose(); + + for (int i = 0; i < diagR_.size(); ++i) { + S_(i, i) += diagR_(i); + } + + K_.setZero(err_.size(), H_.rows()); + K_.transpose() = S_.llt().solve(H_ * P_); + err_ = K_ * inn_; + I_KH_.setZero(P_.rows(), P_.cols()); + I_KH_ = -K_ * H_; + for (int i = 0; i < err_.size(); ++i) { + I_KH_(i, i) += 1; + } + P_ = I_KH_ * P_ * I_KH_.transpose(); + + int kr = K_.rows(); + int kc = K_.cols(); + for (int i = 0; i < kc; ++i) { + K_.block(0, i, kr, 1) *= sqrt(diagR_(i)); + } + + P_ = P_ + K_ * K_.transpose(); +} + +std::tuple Estimator::HuberOnInnovation(const Vec2 &inn, + ftype Rviz) { + + ftype robust_Rviz{Rviz}; // robustified measurement variance + bool outlier{false}; // consider this measurement as an outlier? + + if (ftype ratio{inn.squaredNorm() / (2 * Rviz) / outlier_thresh_}; + ratio > 1.0) { + ratio = sqrt(ratio); + robust_Rviz *= ratio; + outlier = true; + // outlier_counter += ratio; + } else { + // outlier_counter = 0 + } + return std::make_tuple(robust_Rviz, outlier); +} + +std::vector +Estimator::DiscardGroups(const std::vector &discards) { + std::vector nullref_features; + for (auto g : discards) { + // transfer ownership of the remaining features whose reference is this one + auto failed = graph_.TransferFeatureOwnership(g, gbc()); + nullref_features.insert(nullref_features.end(), failed.begin(), + failed.end()); + + if (g->id() == gauge_group_) { + // just lost the gauge group + gauge_group_ = -1; + } + + graph_.RemoveGroup(g); + if (g->instate()) { + RemoveGroupFromState(g); + } + Group::Delete(g); + } + MakePtrVectorUnique(nullref_features); + return nullref_features; +} + +void Estimator::DiscardFeatures(const std::vector &discards) { + graph_.RemoveFeatures(discards); + for (auto f : discards) { + if (f->instate()) { + RemoveFeatureFromState(f); + } + Feature::Delete(f); + } +} + +void Estimator::SwitchRefGroup() { + auto candidates = + graph_.GetGroupsIf([](GroupPtr g) -> bool { return g->instate(); }); + if (!candidates.empty()) { + // FIXME: in addition to the variance, also take account of the number of + // instate features + // associated with the group -- for an efficient implementation, use a + // decorator to get the + // "number of instate features" attribute first + auto git = + std::min_element(candidates.begin(), candidates.end(), + [this](const GroupPtr g1, const GroupPtr g2) -> bool { + int offset1 = kGroupBegin + 6 * g1->sind(); + int offset2 = kGroupBegin + 6 * g2->sind(); + ftype cov1{0}, cov2{0}; + for (int i = 0; i < 6; ++i) { + cov1 += P_(offset1 + i, offset1 + i); + cov2 += P_(offset2 + i, offset2 + i); + } + return cov1 < cov2; + }); + + // reset new gauge group + GroupPtr g{*git}; + gauge_group_ = g->id(); + VLOG(0) << "gauge group #" << gauge_group_ << " selected"; + // std::cout << "gauge group #" << gauge_group_ << " selected"; + + // now fix covariance of the new gauge group + int offset = kGroupBegin + 6 * g->sind(); + P_.block(offset, 0, 6, err_.size()).setZero(); + P_.block(0, offset, err_.size(), 6).setZero(); + } +} + +} // feh diff --git a/src/estimator.h b/src/estimator.h new file mode 100644 index 00000000..824df862 --- /dev/null +++ b/src/estimator.h @@ -0,0 +1,245 @@ +// Inertial-aided Visual Odometry estimator. +// Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Eigen/Sparse" +#include "opencv2/core/core.hpp" +#include "json/json.h" + +#include "component.h" +#include "core.h" +#include "graph.h" +#include "imu.h" +#include "tracker.h" +#include "visualize.h" + +namespace feh { + +namespace internal { +class Message { +public: + Message(const timestamp_t &ts) : ts_{ts} {} + const timestamp_t &ts() const { return ts_; } + virtual ~Message() = default; + virtual void Execute(Estimator *) {} + +protected: + timestamp_t ts_; +}; + +class Visual : public Message { +public: + Visual(const timestamp_t &ts, const cv::Mat &img) : Message{ts}, img_{img} {} + void Execute(Estimator *est); + +private: + cv::Mat img_; +}; + +class Inertial : public Message { +public: + Inertial(const timestamp_t &ts, const Vec3 &gyro, const Vec3 &accel) + : Message{ts}, gyro_{gyro}, accel_{accel} {} + void Execute(Estimator *est); + +private: + Vec3 gyro_, accel_; +}; + +} // namespace internal + +class Estimator : public Component { +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + Estimator(const Json::Value &cfg); + ~Estimator(); + + void Run(); + // process inertial measurements + void InertialMeas(const timestamp_t &ts, const Vec3 &gyro, const Vec3 &accel); + void InertialMeasInternal(const timestamp_t &ts, const Vec3 &gyro, + const Vec3 &accel); + // perform tracking/matching to generate tracks + void VisualMeas(const timestamp_t &ts, const cv::Mat &img); + void VisualMeasInternal(const timestamp_t &ts, const cv::Mat &img); + + // accessors + SE3 gbc() const { return SE3{X_.Rbc, X_.Tbc}; } + SE3 gsb() const { return SE3{X_.Rsb, X_.Tsb}; } + SE3 gsc() const { return gsb() * gbc(); } + State X() const { return X_; } + const timestamp_t &ts() const { return curr_time_; } + bool Finished(); + +private: + void UpdateState(const State::Tangent &dX) { X_ += dX; } + + // initialize gravity with initial stationary samples + bool InitializeGravity(); + // propagate state + void Propagate(bool visual_meas); + // kalman filter update -- joseph form + void UpdateJosephForm(); + // measurement prediction + void Predict(std::list &features); + // compute the motion jacobian F and G at the given linearization point + void ComputeMotionJacobianAt(const State &X, + const Eigen::Matrix &gyro_accel); + // only need velocity as the slope for integration + void ComposeMotion(State &X, const Vec3 &V, + const Eigen::Matrix &gyro_accel, ftype dt); + // perform Fehlberg numerical integration + void Fehlberg(const Vec3 &gyro0, const Vec3 &accel0, ftype dt); + // perform Prince-Dormand numerical integration + void PrinceDormand(const Vec3 &gyro0, const Vec3 &accel0, ftype dt); + // return max(slope), i.e., max(V, max(gyro), max(accel)) + ftype PrinceDormandStep(const Vec3 &gyro0, const Vec3 &accel0, ftype dt); + // perform vanilla RK4 without step control + void RK4(const Vec3 &gyro0, const Vec3 &accel0, ftype dt); + // perform one-step in RK4 integration (4 inner steps) + void RK4Step(const Vec3 &gyro0, const Vec3 &accel0, ftype dt); + + void ProcessTracks(const timestamp_t &ts, std::list &features); + void Update(); + // one point RANSAC on individually compatible matches + std::vector + OnePointRANSAC(const std::vector &ic_matches); + std::tuple HuberOnInnovation(const Vec2 &inn, ftype Rviz); + + void UpdateSystemClock(const timestamp_t &now); + bool GoodTimestamp(const timestamp_t &now); + + // same as above, but the group list will be untouched + void RemoveGroupFromState(GroupPtr g); + void AddGroupToState(GroupPtr g); + std::vector DiscardGroups(const std::vector &discards); + void DiscardFeatures(const std::vector &discards); + void SwitchRefGroup(); + + // same as above, but the feature list will be untouched + void RemoveFeatureFromState(FeaturePtr f); + void AddFeatureToState(FeaturePtr f); + + void AbsorbError(const VecX &err); // absorb error state into nominal state + void AbsorbError(); // absorb error state into nominal state + // helpers + void PrintErrorStateNorm(); + void PrintErrorState(); + void PrintNominalState(); + +private: + std::vector instate_features_; // in-state features + std::vector oos_features_; // out-of-state features + std::vector instate_groups_; // in-state groups + Graph graph_; + int gauge_group_; // index of the selected gauge group, -1 for none + +private: + Config cfg_; // this is just a reference of the global parameter server + bool simulation_; // estimator used in simulation or not + bool use_canvas_; // visualization or not + bool print_timing_; // show timing info + std::string integration_method_; // motion integration numerical scheme + bool use_1pt_RANSAC_; // one point ransac + ftype ransac_thresh_, ransac_prob_, ransac_Chi2_; + bool use_OOS_; // Out-Of-State measurement update + bool use_compression_; // measurement compression + ftype compression_trigger_ratio_; // use measurement compression, if the ratio + // of columns/rows of measurement matrix is + // above this level + bool use_depth_opt_; // use depth optimization or not + RefinementOptions refinement_options_; // depth refinement options + SubfilterOptions subfilter_options_; // depth-subfilter options + bool triangulate_pre_subfilter_; // depth triangulation before depth subfilter + TriangulateOptions triangulate_options_; + + State X_; + VecX err_; // error state + std::array gsel_; // group selector + std::array fsel_; // feature selector + // imu component + IMU imu_; + // gravity + Vec3 g_; + + // measurement noise + ftype init_z_, init_std_x_, init_std_y_, init_std_z_; + + // jacobians + Eigen::SparseMatrix F_, G_; + // covariances + MatX P_; + MatX Qmodel_; // kMotionSize x kMotionSize + MatX Qimu_; // 12 x 12 + + // for update + MatX S_; + MatX K_; // kalman gain + MatX H_; // measurement Jacobian + MatX I_KH_; // I-KH + VecX inn_; // innovation stack + VecX diagR_; // diagonal of measurement covariance + ftype Roos_; // oos measurement covariance in pixels + ftype R_; // covariance of visual measurement noise, in pixels + ftype Rtri_; // measurement covariance, depth sub-filter + ftype outlier_thresh_; // outlier threshold -- multipler of the measurement + // variance + + // MH (Mahalanobis) gating parameters + bool use_MH_gating_; + ftype MH_thresh_; // MH threshold + int min_required_inliers_; // minimal inliers needed to perform update + ftype MH_thresh_multipler_; // if not enough inliers, repeatedly multiple the + // MH_thresh by this amount + + // time + timestamp_t last_imu_time_, curr_imu_time_; // time when the imu meas arrives + timestamp_t last_vision_time_, + curr_vision_time_; // time when visual meas arrives + timestamp_t curr_time_; // current system time + timestamp_t last_time_; // last measurement time, either imu or visual + + Vec3 curr_accel_, curr_gyro_; // current gyro and accel measurement + Vec3 last_accel_, last_gyro_; // accel & gyro measurement at last_time + Vec3 slope_accel_, slope_gyro_; + + bool gravity_initialized_, vision_initialized_; + int imu_counter_, vision_counter_; + + // helplers + int gravity_init_counter_; + std::vector gravity_init_buf_; // buffer of accel measurements for + // gravity initialization + // measurements buffer + struct InternalBuffer + : public std::vector> { + static constexpr int MAX_SIZE = 5; + InternalBuffer() : initialized{false} {} + std::mutex mtx; + bool initialized; + } buf_; + bool async_run_; // if true, run in a separate thread + void MaintainBuffer(); + + own worker_; + + Timer timer_; + std::unique_ptr rng_; +}; + +} // feh diff --git a/src/estimator_process.cpp b/src/estimator_process.cpp new file mode 100644 index 00000000..af38bb42 --- /dev/null +++ b/src/estimator_process.cpp @@ -0,0 +1,59 @@ +// 3rdparty +#include "opencv2/highgui/highgui.hpp" +// feh +#include "absl/strings/str_format.h" +#include "estimator_process.h" +#include "tracker.h" +#include "visualize.h" + +namespace feh { + +bool operator<(const std::unique_ptr &m1, + const std::unique_ptr &m2) { + return m1->ts() < m2->ts(); +} + +void EstimatorProcess::Initialize(const std::string &config_path) { + // TODO (xfei): error handling? + auto est_cfg = LoadJson(config_path); + estimator_ = std::unique_ptr(new Estimator{est_cfg}); +} + +/* +void EstimatorProcess::Wait() { + auto msg = new Block(); + Enqueue(msg); + while (!msg->ready_) { + usleep(1); + } +} +*/ + +bool EstimatorProcess::Handle(EstimatorMessage *message) { + if (Process::Handle(message)) + return true; + + message->Execute(estimator_.get()); + + if (auto msg = dynamic_cast(message)) { + // FIXME: instead of drawing on the canvas in the estimator + // the estimator can pass state and feature tracks to the publisher + // and let the publisher draw stuff. + // However, the publisher should live in its own thread, otherwise, + // the drawing is still performed in the current (estimator_process) thread, + // and will not make it more efficient. + if (msg->viz() && publisher_ != nullptr) { + publisher_->Publish(msg->ts(), Canvas::instance()->display()); + } + return true; + } else if (auto msg = dynamic_cast(message)) { + + if (msg->viz() && publisher_ != nullptr) { + publisher_->Publish(msg->ts(), estimator_->gsb(), estimator_->gbc()); + } + return true; + } + return false; +} + +} // namespace feh diff --git a/src/estimator_process.h b/src/estimator_process.h new file mode 100644 index 00000000..042d39b1 --- /dev/null +++ b/src/estimator_process.h @@ -0,0 +1,97 @@ +#pragma once +// stl +#include +#include +#include +// feh +#include "alias.h" +#include "estimator.h" +#include "message_types.h" +#include "process.h" + +namespace feh { + +class Publisher { +public: + virtual ~Publisher(){}; + virtual void Publish(const timestamp_t &ts, const cv::Mat &image) {} + virtual void Publish(const timestamp_t &ts, const SE3 &gsb, const SE3 &gbc) {} +}; + +class EstimatorMessage { +public: + EstimatorMessage(const timestamp_t &ts, bool viz = false) + : ts_{ts}, viz_{viz} {} + + timestamp_t ts() const { return ts_; } + bool viz() const { return viz_; } + + virtual void Execute(Estimator *) = 0; + virtual ~EstimatorMessage() {} + +protected: + timestamp_t ts_; + bool viz_; // if set, visualize the filtering result +}; + +bool operator<(const std::unique_ptr &m1, + const std::unique_ptr &m2); + +class VisualMeas : public EstimatorMessage { +public: + VisualMeas(const timestamp_t &ts, cv::Mat image, bool viz = false) + : EstimatorMessage{ts, viz}, image_{image} {} + + void Execute(Estimator *est) override { est->VisualMeas(ts_, image_); } + +private: + cv::Mat image_; +}; + +class InertialMeas : public EstimatorMessage { +public: + InertialMeas(const timestamp_t &ts, const Vec3 &gyro, const Vec3 &accel, + bool viz = false) + : EstimatorMessage{ts, viz}, gyro_{gyro}, accel_{accel} {} + + void Execute(Estimator *est) override { + est->InertialMeas(ts_, gyro_, accel_); + } + +private: + Vec3 gyro_, accel_; +}; + +class EstimatorProcess : public Process { +public: + EstimatorProcess(const std::string &name, uint32_t size = 1000) + : Process{size}, name_{name}, estimator_{nullptr}, publisher_{nullptr} { + LOG(INFO) << "Process " << name_ << " created!"; + } + void Initialize(const std::string &config_path); + void SetPublisher(Publisher *publisher) { publisher_ = publisher; } + + //////////////////////////////////////// + // used for synchronized communication + // call wait first, and then call the available accessors + //////////////////////////////////////// + cv::Mat display() { return Canvas::instance()->display(); } + // only call the following accessors when the process is properly synced + SE3 gsb() const { return estimator_->gsb(); } + SE3 gbc() const { return estimator_->gbc(); } + SE3 gsc() const { return estimator_->gsc(); } + State state() const { return estimator_->X(); } + const timestamp_t &ts() const { return estimator_->ts(); } + //////////////////////////////////////// + +private: + virtual bool Handle(EstimatorMessage *message) override; + +private: + std::string name_; + std::unique_ptr estimator_; // owned + // results publisher for asynchronized communication + Publisher *publisher_; // non-owned +}; // EstimatorProcess + +} // namespace feh diff --git a/src/feature.cpp b/src/feature.cpp new file mode 100644 index 00000000..66a25e1c --- /dev/null +++ b/src/feature.cpp @@ -0,0 +1,469 @@ +#include + +#include "estimator.h" +#include "feature.h" +#include "group.h" +#include "helpers.h" +#include "mm.h" +#include "param.h" + +#include "Eigen/QR" +#include "absl/strings/str_format.h" +#include "glog/logging.h" + +namespace feh { + +// Feature +int Feature::counter_ = 0; +JacobianCache Feature::cache_ = {}; + +//////////////////////////////////////// +// FACTORY METHODS +//////////////////////////////////////// +FeaturePtr Feature::Create(ftype x, ftype y) { + auto f = MemoryManager::instance()->GetFeature(); + CHECK(f); + f->Reset(x, y); + return f; +} + +void Feature::Delete(FeaturePtr f) { + MemoryManager::instance()->ReturnFeature(f); +} + +void Feature::Reset(ftype x, ftype y) { + id_ = counter_++; + sind_ = -1; + init_counter_ = 0; + lifetime_ = 0; + status_ = FeatureStatus::CREATED; + ref_ = nullptr; + Track::Reset(x, y); + x_ << x, y, 2.0; + pred_ << -1, -1; + J_.setZero(); + inn_ << 0, 0; + outlier_counter_ = 0; + + sim_.Xs << -1, -1, -1; + sim_.xp << -1, -1; + sim_.xc << -1, -1; + sim_.z = -1; + sim_.lifetime = -1; +} + +//////////////////////////////////////// +// SOME ACCESSORS +//////////////////////////////////////// +Vec3 Feature::Xc(Mat3 *J) const { +#ifdef USE_INVDEPTH + return unproject_invz(x_, J); +#else + return unproject_logz(x_, J); +#endif +} + +Vec3 Feature::Xs(const SE3 &gbc, Mat3 *J) const { + // Rsb * (Rbc*Xc + Tbc) + Tsb + CHECK(ref_) << "feature #" << id_ << " null ref"; + SE3 gsc = ref_->gsb() * gbc; + Vec3 Ps = gsc * Xc(J); // J = dXc_dx, where x is the local parametrization + if (J) { + *J = gsc.R().matrix() * (*J); + } + return Ps; +} + +ftype Feature::z() const { +#ifdef USE_INVDEPTH + // FIXME: ensure depth is positive + return 1.0 / x_(2); +#else + // in log-depth parametrization, positivity is guaranteed + return exp(x_(2)); +#endif +} + +bool Feature::instate() const { return status_ == FeatureStatus::INSTATE; } + +ftype Feature::score() const { + CHECK(!instate()) + << "score function should only be called for feature not-instate yet"; + // TODO: come up with better scoring + // confidence (negative uncertainty) in depth as score + // return -P_(0, 0) * P_(1, 1) * P_(2, 2); + return -P_(2, 2); +} + +void Feature::Initialize(ftype z0, const Vec3 &std_xyz) { + x_.head<2>() = Camera::instance()->UnProject(back()); +#ifdef USE_INVDEPTH + x_(2) = 1.0 / z0; +#else + x_(2) = log(z0); +#endif + + // ftype rho = 1.0 / z0; + // ftype rho_max = std::max(1.0 / (z0 - std_xyz(2)), 0.10); // 0.10 is + // inverse of max possible depth + // ftype rho_min = 1.0 / (z0 + std_xyz(2)); + // ftype std_rho = std::max(fabs(rho - rho_min), fabs(rho - rho_max)); + + P_ << std_xyz(0), 0, 0, 0, std_xyz(1), 0, 0, 0, std_xyz(2); + P_ *= P_; + status_ = FeatureStatus::INITIALIZING; +} + +void Feature::SetRef(GroupPtr ref) { + CHECK(ref_ == nullptr) << "reference already set!"; + // be very careful when reset references + VLOG(0) << "ref group# " << ref->id() << " -> feature #" << id_; + ref_ = ref; +} + +void Feature::ResetRef(GroupPtr nref) { + + std::string str; + if (nref == nullptr) { + str = "nullptr"; + } else { + str = "#" + std::to_string(nref->id()); + } + + VLOG(0) << "feature #" << id_ << " reset ref from #" << ref_->id() << " to " + << str; + + ref_ = nref; +} + +void Feature::SubfilterUpdate(const SE3 &gsb, const SE3 &gbc, + const SubfilterOptions &options) { + + CHECK(track_status() == TrackStatus::TRACKED); + CHECK(status_ == FeatureStatus::INITIALIZING || + status_ == FeatureStatus::READY); + + init_counter_++; + // depth sub-filter update + Mat3 dXc_dx; + Vec3 Xc = this->Xc(&dXc_dx); + SE3 gtot = (gsb * gbc).inv() * ref()->gsb() * gbc; // g(curr cam <- ref cam) + Vec3 Xcn = gtot * Xc; // predicted Xc + Mat3 dXcn_dXc = gtot.rotation(); + Mat23 dxcn_dXcn; + Vec2 xcn = project(Xcn, &dxcn_dXcn); + + Mat2 dxp_dxcn; + Vec2 xp = Camera::instance()->Project(xcn, &dxp_dxcn); + + Mat23 H = dxp_dxcn * dxcn_dXcn * dXcn_dXc * dXc_dx; + Vec2 inn = this->xp() - xp; + + Mat2 S = H * P_ * H.transpose(); + ftype Rtri = options.Rtri; + S(0, 0) += Rtri; + S(1, 1) += Rtri; + + ftype ratio{inn.dot(S.llt().solve(inn)) / options.MH_thresh}; + + if (ratio > 1) { + S(0, 0) += Rtri * (ratio - 1); + S(1, 1) += Rtri * (ratio - 1); + outlier_counter_ += sqrt(ratio); + } else { + outlier_counter_ = 0; + } + + Mat32 K = P_ * H.transpose() * S.inverse(); // kalman gain + + x_ += K * inn; + Mat3 I_KH = Mat3::Identity() - K * H; + P_ = I_KH * P_ * I_KH.transpose() + K * Rtri * K.transpose(); + + if (init_counter_ > options.ready_steps) { + SetStatus(FeatureStatus::READY); + } else { + SetStatus(FeatureStatus::INITIALIZING); + } +} + +bool Feature::RefineDepth(const SE3 &gbc, + const std::vector &observations, + const RefinementOptions &options) { + + std::vector views; + if (options.two_view) { + auto[first, last] = + std::minmax_element(std::begin(observations), std::end(observations), + [](const Observation &o1, const Observation &o2) { + return o1.g->id() < o1.g->id(); + }); + views = {*first, *last}; + } else { + views = observations; + } + + Mat3 FtF; + Vec3 Ftr; // F.transpose() * residual + ftype res_norm0{0}; // norm of residual corresponding to optimal state + + for (int iter = 0; iter < options.max_iters; ++iter) { + Mat3 dXs_dx; + Vec3 Xs = this->Xs(gbc, &dXs_dx); // ref_->gsb() * gbc * this->Xc(); + + FtF.setZero(); + Ftr.setZero(); + ftype res_norm{0}; + + for (const auto &obs : views) { + // skip reference group + if (obs.g->id() == ref_->id()) + continue; + + SE3 g_cn_s = (obs.g->gsb() * gbc).inv(); // spatial -> camera new + Vec3 Xcn = g_cn_s * Xs; + // Mat3 dXc_dXs = gcs.rotation(); + Mat3 dXcn_dx = g_cn_s.R().matrix() * dXs_dx; + + Mat23 dxcn_dXcn; + Vec2 xcn = project(Xcn, &dxcn_dXcn); + + Mat2 dxp_dxcn; + Vec2 xp = Camera::instance()->Project(xcn, &dxp_dxcn); + + Mat23 dxp_dx = dxp_dxcn * dxcn_dXcn * dXcn_dx; + // std::cout << dxp_dx << std::endl; + + FtF += dxp_dx.transpose() * dxp_dx; + Vec2 res = obs.xp - xp; + Ftr += dxp_dx.transpose() * res; + + res_norm += res.norm(); + } + + if (iter > 0 && res_norm > res_norm0) { + // current state not good, revert + RestoreState(); + break; + } + + VLOG_IF(0, iter > 0) << absl::StrFormat("iter=%d; |res|:%0.4f->%0.4f", iter, + res_norm0, res_norm); + + Vec3 delta = FtF.ldlt().solve(Ftr); + BackupState(); + x_ += delta; + res_norm0 = res_norm; + + // not much to progress + if (delta.lpNorm() < options.eps) { + break; + } + } + + if (auto res_norm_per_obs{res_norm0 / observations.size()}; + res_norm_per_obs > options.max_res_norm) { + VLOG(0) << absl::StrFormat("feature #%d; status=%d; |res|=%f\n", id_, + as_integer(status_), res_norm_per_obs); + return false; + } else { + return true; + } +} + +void Feature::ComputeJacobian(const Mat3 &Rsb, const Vec3 &Tsb, const Mat3 &Rbc, + const Vec3 &Tbc, const Vec3 &gyro, const Mat3 &Cg, + const Vec3 &bg, const Vec3 &Vsb, ftype td) { + + Mat3 Rsb_t = Rsb.transpose(); + Mat3 Rbc_t = Rbc.transpose(); + + Mat3 Rr = ref_->Rsb(); + Vec3 Tr = ref_->Tsb(); + + cache_.Xc = Xc(&cache_.dXc_dx); + + // Xc(ref) to Xs + cache_.Xs = Rr * Rbc * cache_.Xc + Rr * Tbc + Tr; + // cache_.dXs_dXc = Rr * Rbc; + cache_.dXs_dx = Rr * Rbc * cache_.dXc_dx; + cache_.dXs_dTbc = Rr; + cache_.dXs_dWbc = -Rr * hat(cache_.Xc); + cache_.dXs_dTr = Mat3::Identity(); + cache_.dXs_dWr = -hat(Rbc * cache_.Xc + Tbc); + + // Xs back to Xc(new) + cache_.Xcn = Rbc_t * Rsb_t * (cache_.Xs - Tsb) - Rbc_t * Tbc; + cache_.dXcn_dWbc = hat(Rsb_t * (cache_.Xs - Tsb) - Tbc); + cache_.dXcn_dWsb = Rbc_t * hat(cache_.Xs - Tsb); + cache_.dXcn_dXs = Rbc_t * Rsb_t; // dXcn_d... = dXcn_dXs * dXs_d... + cache_.dXcn_dTsb = -cache_.dXcn_dXs; + cache_.dXcn_dTbc = -Rbc_t; + +#ifdef USE_ONLINE_TEMPORAL_CALIB + Vec3 gyro_calib = Cg * gyro - bg; + cache_.dXcn_dtd = + -Rbc_t * (hat(gyro_calib) * Rsb_t * cache_.Xs + Rsb_t * Vsb); + + // since imu.Cg is used here, also need to compute jacobian block w.r.t. Cg + auto dXcn_dW = + dAB_dB(Rbc_t * hat(Rsb_t * cache_.Xs) * td, Vec3{}); // W=Cg * Wm +#ifdef USE_ONLINE_IMU_CALIB + Eigen::Matrix dW_dCg; + for (int i = 0; i < 3; ++i) { + dW_dCg.block<1, 3>(i, 3 * i) = gyro; + } + cache_.dXcn_dCg = dXcn_dW * dW_dCg; +#endif + cache_.dXcn_dbg = dXcn_dW; +#endif + + // Rbc and Tbc are used twice, so add extra terms + cache_.dXcn_dWbc += cache_.dXcn_dXs * cache_.dXs_dWbc; + cache_.dXcn_dTbc += cache_.dXcn_dXs * cache_.dXs_dTbc; + + cache_.dXcn_dx = cache_.dXcn_dXs * cache_.dXs_dx; + cache_.dXcn_dWr = cache_.dXcn_dXs * cache_.dXs_dWr; + cache_.dXcn_dTr = cache_.dXcn_dXs * cache_.dXs_dTr; + + // xc(new) + cache_.xcn = project(cache_.Xcn, &cache_.dxcn_dXcn); + +#ifdef USE_ONLINE_CAMERA_CALIB + Eigen::Matrix jacc; + cache_.xp = Camera::instance()->Project(cache_.xcn, &cache_.dxp_dxcn, &jacc); +#endif + + cache_.dxp_dXcn = cache_.dxp_dxcn * cache_.dxcn_dXcn; + + // set jacobians + J_.setZero(); + J_.block<2, 3>(0, Index::Wsb) = cache_.dxp_dXcn * cache_.dXcn_dWsb; + J_.block<2, 3>(0, Index::Tsb) = cache_.dxp_dXcn * cache_.dXcn_dTsb; + J_.block<2, 3>(0, Index::Wbc) = cache_.dxp_dXcn * cache_.dXcn_dWbc; + J_.block<2, 3>(0, Index::Tbc) = cache_.dxp_dXcn * cache_.dXcn_dTbc; +#ifdef USE_ONLINE_TEMPORAL_CALIB + J_.block<2, 1>(0, Index::td) = cache_.dxp_dXcn * cache_.dXcn_dtd; +#ifdef USE_ONLINE_IMU_CALIB + J_.block<2, 9>(0, Index::Cg) = cache_.dxp_dXcn * cache_.dXcn_dCg; +#endif + J_.block<2, 3>(0, Index::bg) = cache_.dxp_dXcn * cache_.dXcn_dbg; +#endif + CHECK(ref_->sind() != -1); + CHECK(sind() != -1); + int goff = kGroupBegin + 6 * ref_->sind(); + int foff = kFeatureBegin + 3 * sind(); + + J_.block<2, 3>(0, goff) = cache_.dxp_dXcn * cache_.dXcn_dWr; + J_.block<2, 3>(0, goff + 3) = cache_.dxp_dXcn * cache_.dXcn_dTr; + J_.block<2, 3>(0, foff) = cache_.dxp_dXcn * cache_.dXcn_dx; + +#ifdef USE_ONLINE_CAMERA_CALIB + // fill-in jacobian w.r.t. camera intrinsics + int dim{Camera::instance()->dim()}; + J_.block(0, kCameraBegin, 2, dim) = jacc.block(0, 0, 2, dim); +#endif + + // innovation + cache_.inn = back() - cache_.xp; + inn_ = cache_.inn; +} + +int Feature::ComputeOOSJacobian(const std::vector &vobs, + const Mat3 &Rbc, const Vec3 &Tbc) { + + int num_contraints = + std::count_if(vobs.begin(), vobs.end(), + [](const Observation &obs) { return obs.g->instate(); }); + + if (num_contraints > 1) { + // A constraint should involve at least 2 poses + cache_.Xs = this->Xs(SE3{SO3{Rbc}, Tbc}); + oos_jac_counter_ = 0; + for (auto obs : vobs) { + if (obs.g->instate()) { + ComputeOOSJacobianInternal(obs, Rbc, Tbc); + } + } + + // perform givens elimination + oos_jac_counter_ = Givens(oos_.inn, oos_.Hx, oos_.Hf, 2 * oos_jac_counter_); + // std::cout << "feature #" << id_ << " got " << oos_jac_counter_ << " oos + // jac blocks\n"; + } else { + oos_jac_counter_ = 0; + } + + return oos_jac_counter_; +} + +void Feature::ComputeOOSJacobianInternal(const Observation &obs, + const Mat3 &Rbc, const Vec3 &Tbc) { + + auto g = obs.g; + CHECK(g->sind() != -1); + + int goff = kGroupBegin + 6 * obs.g->sind(); + Mat3 Rsb = g->Rsb(); + Mat3 Rsb_t = Rsb.transpose(); + Vec3 Tsb = g->Tsb(); + Mat3 Rbc_t = Rbc.transpose(); + + cache_.Xcn = Rbc_t * Rsb_t * (cache_.Xs - Tsb) - Rbc_t * Tbc; + cache_.dXcn_dXs = Rbc_t * Rsb_t; + cache_.dXcn_dTsb = -cache_.dXcn_dXs; + cache_.dXcn_dWsb = Rbc_t * hat(cache_.Xs - Tsb); + cache_.dXcn_dTbc = -Rbc_t; + cache_.dXcn_dWbc = hat(Rsb_t * (cache_.Xs - Tsb) - Tbc); + + cache_.xcn = project(cache_.Xcn, &cache_.dxcn_dXcn); + + cache_.xp = Camera::instance()->Project(cache_.xcn, &cache_.dxp_dxcn); + + cache_.dxp_dXcn = cache_.dxp_dxcn * cache_.dxcn_dXcn; + + oos_.inn.segment<2>(2 * oos_jac_counter_) = obs.xp - cache_.xp; + + oos_.Hf.block<2, 3>(2 * oos_jac_counter_, 0) = + cache_.dxp_dXcn * cache_.dXcn_dXs; + + oos_.Hx.block<2, kFullSize>(2 * oos_jac_counter_, 0).setZero(); + oos_.Hx.block<2, 3>(2 * oos_jac_counter_, goff) = + cache_.dxp_dXcn * cache_.dXcn_dWsb; + oos_.Hx.block<2, 3>(2 * oos_jac_counter_, goff + 3) = + cache_.dxp_dXcn * cache_.dXcn_dTsb; + oos_.Hx.block<2, 3>(2 * oos_jac_counter_, Index::Wbc) = + cache_.dxp_dXcn * cache_.dXcn_dWbc; + oos_.Hx.block<2, 3>(2 * oos_jac_counter_, Index::Tbc) = + cache_.dxp_dXcn * cache_.dXcn_dTbc; + ++oos_jac_counter_; +} + +void Feature::FillJacobian(MatX &H, Vec2 &inn) { + H = J_; + inn = inn_; +} + +void Feature::Triangulate(const SE3 &gsb, const SE3 &gbc, + const TriangulateOptions &options) { + CHECK(size() == 2); + Vec2 xc1 = CameraManager::instance()->UnProject(front()); + Vec2 xc2 = CameraManager::instance()->UnProject(back()); + SE3 g12 = (ref_->gsb() * gbc).inv() * (gsb * gbc); + Vec3 Xc1 = options.method == 1 ? Triangulate1(g12, xc1, xc2) + : Triangulate2(g12, xc1, xc2); + + if (auto z = Xc1(2); z < options.zmin || z > options.zmax) { + // triangulated depth is not great + // stick to the constant depth + } else { + x_.head<2>() = Xc1.head<2>() / z; +#ifdef USE_INVDEPTH + x_(2) = 1.0 / z; +#else + x_(2) = log(z); +#endif + } +} + +} // feh diff --git a/src/feature.h b/src/feature.h new file mode 100644 index 00000000..d0a69e9d --- /dev/null +++ b/src/feature.h @@ -0,0 +1,199 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +#include "component.h" +#include "core.h" +#include "jac.h" +#include "options.h" +#include "project.h" + +namespace feh { + +struct Observation { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + GroupPtr g; + Vec2 xp; +}; + +using Obs = Observation; + +class Track : public std::vector> { +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + Track() : status_(TrackStatus::CREATED) {} + Track(ftype x, ftype y) { Reset(x, y); } + + void Reset(ftype x, ftype y) { + clear(); + status_ = TrackStatus::CREATED; + push_back(Vec2(x, y)); + } + + TrackStatus status() const { return status_; } + void SetStatus(TrackStatus status) { status_ = status; } + void SetDescriptor(const cv::Mat &descriptor) { descriptor_ = descriptor; } + void SetKeypoint(const cv::KeyPoint &keypoint) { keypoint_ = keypoint; } + const cv::KeyPoint &keypoint() const { return keypoint_; } + cv::KeyPoint &keypoint() { return keypoint_; } + const cv::Mat &descriptor() const { return descriptor_; } + cv::Mat &descriptor() { return descriptor_; } + +protected: + TrackStatus status_; + + // initial keypoint to store extra info, e.g., octave, orientation, etc. + cv::KeyPoint keypoint_; + // last descriptor + cv::Mat descriptor_; +}; + +struct XYlogZ { + using Tangent = Vec3; +}; + +class Feature : public Component, public Track { + friend class MemoryManager; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + static FeaturePtr Create(ftype x, ftype y); + static void Delete(FeaturePtr f); + + void UpdateTrack(ftype x, ftype y) { emplace_back(x, y); } + void UpdateTrack(const Vec2 &pt) { UpdateTrack(pt(0), pt(1)); } + + // quick predictor of instate status + bool instate() const; + // score of the potential goodness of being an instate feature + // The higher, the better. + ftype score() const; + ftype outlier_counter() const { return outlier_counter_; } + // get depth + ftype z() const; + const Vec3 &x() const { return x_; } + const Mat3 &P() const { return P_; } + Vec3 &x() { return x_; } + Mat3 &P() { return P_; } + void BackupState() { x0_ = x_; } + void RestoreState() { x_ = x0_; } + // get 3D coordinates in reference camera frame + Vec3 Xc(Mat3 *dXc_dx = nullptr) const; + // get 3D coordinates in spatial frame, cam2body alignment is required + Vec3 Xs(const SE3 &gbc, Mat3 *dXs_dx = nullptr) const; + + // return (2M-3) as the dimension of the measurement + void ComputeJacobian(const Mat3 &Rsb, const Vec3 &Tsb, const Mat3 &Rbc, + const Vec3 &Tbc, const Vec3 &gyro, const Mat3 &Cg, + const Vec3 &bg, const Vec3 &Vsb, ftype td); + + int oos_inn_size() const { return oos_jac_counter_; } + + int ComputeOOSJacobian(const std::vector &obs, const Mat3 &Rbc, + const Vec3 &Tbc); + // FIXME: make the following private + void ComputeOOSJacobianInternal(const Obs &obs, const Mat3 &Rbc, + const Vec3 &Tbc); + void FillJacobian(MatX &H, Vec2 &inn); + const Eigen::Matrix &J() const { return J_; } + const Vec2 &inn() const { return inn_; } + + const Vec2 &xp() const { return back(); } + const Vec2 &pred() const { return pred_; } + const Vec2 &Predict(const SE3 &gsb, const SE3 &gbc) { + Vec3 Xc = (gsb * gbc).inv() * this->Xs(gbc); + pred_ = Camera::instance()->Project(project(Xc)); + return pred_; + } + void ResetPred() { pred_ << -1, -1; } + + //////////////////////////////////////// + // OOS Jacobians accessors + //////////////////////////////////////// + VecX ro() const { return oos_.inn.head(oos_jac_counter_); } + MatX Ho() const { return oos_.Hx.topRows(oos_jac_counter_); } + + void Initialize(ftype z0, const Vec3 &std_xyz); + + FeatureStatus status() const { return status_; } + void SetStatus(FeatureStatus status) { status_ = status; } + + void SetTrackStatus(TrackStatus status) { Track::SetStatus(status); } + TrackStatus track_status() const { return Track::status(); } + + int id() const { return id_; } + int sind() const { return sind_; } + void SetSind(int ind) { sind_ = ind; } + + int lifetime() const { return lifetime_; } + int IncrementLifetime() { lifetime_++; } + int ResetLifetime() { lifetime_ = 0; } + + GroupPtr ref() const { return ref_; } + void SetRef(GroupPtr ref); + void ResetRef(GroupPtr nref); + + // subfilter used for depth initialization + void SubfilterUpdate(const SE3 &gsb, const SE3 &gbc, + const SubfilterOptions &options); + bool RefineDepth(const SE3 &gbc, const std::vector &obs, + const RefinementOptions &options); + // triangulate the 3D point from the reference and another view + void Triangulate(const SE3 &gsb, const SE3 &gbc, + const TriangulateOptions &options); + + void SetState(const Vec3 &x) { x_ = x; } + void UpdateState(const Vec3 &dx) { x_ += dx; } + +private: + Feature(const Feature &) = delete; + // default constructor used memory manager's pre-allocation + Feature() = default; + // Feature(ftype x, ftype y) { + // Reset(x, y); + // LOG(INFO) << "feature #" << id_ << " created"; + // } + void Reset(ftype x, ftype y); + +private: + static int counter_; + int id_; + int sind_; // state index + FeatureStatus status_; + GroupPtr ref_; // reference group: where the feature is first observed + int lifetime_; + + Vec3 x_, x0_; // state: (x, y, inv_z) + Mat3 P_; // covariance + Vec2 pred_; // predicted pixel coordinates + + Eigen::Matrix J_; + Vec2 inn_; + Mat23 Hx_; + + // outlier rejection + int init_counter_; + bool inlier_; + ftype outlier_counter_; + + static JacobianCache cache_; // in-state measurement jacobian cache + OOSJacobian oos_; // out-of-state measurement jacobian cache + int oos_jac_counter_; // valid OOS jacobian blocks + +public: + // simulation + struct { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + Vec3 Xs; + Vec2 xp, xc; + ftype z; + int lifetime; + } sim_; +}; + +} // namespace feh diff --git a/src/geometry.cpp b/src/geometry.cpp new file mode 100644 index 00000000..8944d439 --- /dev/null +++ b/src/geometry.cpp @@ -0,0 +1,160 @@ +#include + +#include "Eigen/OrderingMethods" +#include "Eigen/SparseCore" +#include "Eigen/SparseQR" +#include "glog/logging.h" + +#include "geometry.h" + +namespace feh { + +// Reference: +// Frank C. Park, Bryan J. Martin +// Robot Sensor Calibration: Solving AX = XB on the Euclidan Group +SO3 HandEyeCalibration(const std::vector &A, const std::vector &B) { + int n = A.size(); + + Eigen::SparseMatrix M(3 * n, 9); + using ordering = Eigen::COLAMDOrdering; + Eigen::SparseQR, ordering> solver; + VecX y(3 * n); + // solve Mx = y + for (int i = 0; i < n; ++i) { + auto a = A[i].log(); + a /= a.norm(); + auto b = B[i].log(); + b /= b.norm(); + // solve Rb = a + // Let R = [r1.T\\r2.T\\r3.T] + // x = stack(r1, r2, r3), 9x1 vector + int offset = i * 3; + y.segment<3>(offset) = a; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + M.coeffRef(offset + row, 3 * row + col) = b(col); + } + } + } + // solve Mx = y + solver.compute(M); + auto xstack = solver.solve(y); + Mat3 X; + for (int i = 0; i < 3; ++i) { + X.row(i) = xstack.segment<3>(i * 3).transpose(); + } + auto R = SO3::project(X); + + // compute residuals + ftype res(0); + for (int i = 0; i < n; ++i) { + // AR=RB + Vec3 r = SO3::log(A[i] * R * (R * B[i]).inv()); + res += r.norm(); + } + res = (res / n) / M_PI * 180; + LOG(INFO) << "residual=" << res << " degrees" << std::endl; + + return R; +} + +SE3 HandEyeCalibration(const std::vector &A, const std::vector &B) { + throw std::runtime_error("Not implemented."); +} + +SE3 TrajectoryAlignment(const std::vector &Y, + const std::vector &X) { + if (Y.size() != X.size()) + LOG(FATAL) << "Input trajectories have different length."; + LOG(INFO) << "effective data points on trajectory=" << Y.size(); + // Compute difference vector between two consecutive time steps dX and dY + // and find the rotational alignment R first such that dY = R dX. + // Then find translation T such that Y = RX + T + // Finally, on-manifold optimization for refinement. + std::vector dX, dY; + for (int i = 0; i + 1 < X.size(); ++i) { + auto dx = X[i + 1] - X[i]; + auto dy = Y[i + 1] - Y[i]; + if (dx.norm() > 0 && dy.norm() > 0) { + dX.push_back(dx / dx.norm()); + dY.push_back(dy / dy.norm()); + } + } + + Eigen::SparseMatrix M(3 * dX.size(), 9); + using ordering = Eigen::COLAMDOrdering; + Eigen::SparseQR, ordering> solver; + + LOG(INFO) << "building coefficient matrix M for M x = y"; + VecX rhs(3 * dY.size()); + // solve Mx = y + for (int i = 0; i < dX.size(); ++i) { + // solve Rb = a + // Let R = [r1.T\\r2.T\\r3.T] + // x = stack(r1, r2, r3), 9x1 vector + int offset = i * 3; + rhs.segment<3>(offset) = dY[i]; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + M.coeffRef(offset + row, 3 * row + col) = dX[i][col]; + } + } + } + + LOG(INFO) << "solving M x = y"; + // solve Mx = rhs + solver.compute(M); + auto xstack = solver.solve(rhs); + Mat3 Xmat; + for (int i = 0; i < 3; ++i) { + Xmat.row(i) = xstack.segment<3>(i * 3).transpose(); + } + auto R = SO3::project(Xmat); + + LOG(INFO) << "computing T"; + // compute translation + Vec3 T{0, 0, 0}; + for (int i = 0; i < X.size(); ++i) { + T += Y[i] - R * X[i]; + } + T /= X.size(); + + // on-manifold optimization + // Y = R(I+hat(dW)) X + T+dT = (R X + T) + R hat(dW) X + dT + // residual = Y - (R X + T) = f(dW, dT) = -R hat(X) dW + dT + // [-R hat(X) | I3x3] [dW' dT']' = residual + // Vec3 dW, dT; + rhs.resize(X.size() * 3); + M.resize(X.size() * 3, 6); + M.setZero(); + for (int iter = 0; iter < 5; ++iter) { + for (int i = 0; i < X.size(); ++i) { + int offset = i * 3; + rhs.segment<3>(offset) = Y[i] - (R * X[i] + T); + auto block = -R.matrix() * hat(X[i]); + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + M.coeffRef(offset + row, col) = block(row, col); + if (row == col) + M.coeffRef(offset + row, 3 + col) = 1.0; + } + } + } + auto Mt = M.transpose(); + auto MtM = Mt * M; + solver.compute(MtM); + auto dWdT = solver.solve(Mt * rhs); + R *= SO3::exp(dWdT.head<3>()); + T += dWdT.tail<3>(); + // std::cout << "iter=" << iter << " ;dWdT=" << dWdT.transpose() << + // std::endl; + } + + // output pose + SE3 g{R, T}; + LOG(INFO) << "trajectory alignment=\n" << g.matrix3x4(); + + return g; +} + +} // namespace feh diff --git a/src/geometry.h b/src/geometry.h new file mode 100644 index 00000000..4fa5d492 --- /dev/null +++ b/src/geometry.h @@ -0,0 +1,23 @@ +// Geometry utilities. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include "alias.h" +#include + +namespace feh { + +// Solve the hand-eye calibration problem: AX=XB +// where A, B and X \in SO(3); A & B are known, X is to solve +SO3 HandEyeCalibration(const std::vector &A, const std::vector &B); +SE3 HandEyeCalibration(const std::vector &A, const std::vector &B); + +// Find the rigid-body-transformation to align two trajectories, i.e., find +// spatial alignment. +// Temporal alignment is assumed. +// Args: +// Y, X: translational part of the trajectory +// Returns: +// G \in SE3 such that Y = G X +SE3 TrajectoryAlignment(const std::vector &Y, const std::vector &X); + +} // namespace feh diff --git a/src/graph.cpp b/src/graph.cpp new file mode 100644 index 00000000..2540eed4 --- /dev/null +++ b/src/graph.cpp @@ -0,0 +1,319 @@ +#include "graph.h" +#include "estimator.h" +#include "feature.h" +#include "group.h" + +namespace feh { + +void FeatureAdj::Add(const Observation &obs) { insert({obs.g->id(), obs.xp}); } +void FeatureAdj::Remove(int id) { erase(id); } +void GroupAdj::Add(int id) { insert(id); } +void GroupAdj::Remove(int id) { erase(id); } + +bool Graph::HasGroup(GroupPtr g) const { return HasGroup(g->id()); } + +bool Graph::HasGroup(int gid) const { + return groups_.count(gid) && group_adj_.count(gid); +} + +bool Graph::HasFeature(FeaturePtr f) const { return HasFeature(f->id()); } + +bool Graph::HasFeature(int fid) const { + return features_.count(fid) && feature_adj_.count(fid); +} + +FeaturePtr Graph::GetFeature(int fid) const { return features_.at(fid); } + +GroupPtr Graph::GetGroup(int gid) const { return groups_.at(gid); } + +const FeatureAdj &Graph::GetFeatureAdj(FeaturePtr f) const { + return feature_adj_.at(f->id()); +} + +const GroupAdj &Graph::GetGroupAdj(GroupPtr g) const { + return group_adj_.at(g->id()); +} + +void Graph::RemoveFeature(const FeaturePtr f) { + CHECK(HasFeature(f)) << "feature #" << f->id() << " not exists"; + + int fid = f->id(); + features_.erase(fid); + for (const auto &obs : feature_adj_.at(fid)) { + group_adj_.at(obs.first).Remove(fid); + } + feature_adj_.erase(fid); + + LOG(INFO) << "feature #" << fid << " removed"; +} + +void Graph::RemoveFeatures(const std::vector &features) { + for (auto f : features) { + RemoveFeature(f); + } +} + +void Graph::RemoveGroup(const GroupPtr g) { + CHECK(HasGroup(g)) << "group #" << g->id() << " not exists"; + + int gid = g->id(); + groups_.erase(gid); + for (auto fid : group_adj_.at(gid)) { + auto f = features_.at(fid); + // need to transfer ownership of the feature first + if (f->ref() == g) { + LOG(FATAL) << "removing group #" << gid << " but feature #" << fid + << " refers to it"; + } + feature_adj_.at(fid).Remove(gid); + } + group_adj_.erase(gid); + LOG(INFO) << "group #" << gid << " removed"; +} + +void Graph::RemoveGroups(const std::vector &groups) { + for (auto g : groups) { + RemoveGroup(g); + } +} + +void Graph::AddFeature(FeaturePtr f) { + int fid = f->id(); + CHECK(!features_.count(fid)) << "feature #" << fid << " arealdy exists"; + features_[fid] = f; + feature_adj_[fid] = {}; + LOG(INFO) << "feature #" << fid << " added to graph"; +} + +void Graph::AddGroup(GroupPtr g) { + int gid = g->id(); + CHECK(!groups_.count(gid)) << "group #" << gid << " already exists"; + groups_[gid] = g; + group_adj_[gid] = {}; + LOG(INFO) << "group #" << gid << " added to graph"; +} + +void Graph::AddGroupToFeature(GroupPtr g, FeaturePtr f) { + + int gid = g->id(); + int fid = f->id(); + + CHECK(HasFeature(f)) << "feature #" << fid << " not exists"; + CHECK(HasGroup(g)) << "group #" << gid << " not exists"; + + feature_adj_.at(fid).Add({g, f->xp()}); + LOG(INFO) << "group #" << gid << " added to feature #" << fid; +} + +void Graph::AddFeatureToGroup(FeaturePtr f, GroupPtr g) { + + int fid = f->id(); + int gid = g->id(); + + CHECK(HasFeature(f)) << "feature #" << fid << " not exists"; + CHECK(HasGroup(g)) << "group #" << gid << " not exists"; + + group_adj_[gid].Add(fid); + LOG(INFO) << "feature #" << fid << " added to group #" << gid; +} + +std::vector +Graph::GetFeaturesIf(std::function pred) const { + std::vector out; + for (auto p : features_) { + if (pred(p.second)) { + out.push_back(p.second); + } + } + return out; +} + +std::vector Graph::GetFeatures() const { + std::vector out; + out.reserve(features_.size()); + for (auto p : features_) { + out.push_back(p.second); + } + return out; +} + +std::vector Graph::GetGroups() const { + std::vector out; + out.reserve(groups_.size()); + for (auto p : groups_) { + out.push_back(p.second); + } + return out; +} + +std::vector Graph::GetFeaturesOf(GroupPtr g) const { + std::vector out; + for (int fid : group_adj_.at(g->id())) { + out.push_back(features_.at(fid)); + } + return out; +} + +std::vector +Graph::GetGroupsIf(std::function pred) const { + std::vector out; + for (auto p : groups_) { + if (pred(p.second)) { + out.push_back(p.second); + } + } + return out; +} + +std::vector Graph::GetGroupsOf(FeaturePtr f) const { + std::vector out; + for (const auto &obs : feature_adj_.at(f->id())) { + out.push_back(groups_.at(obs.first)); + } +} + +std::vector Graph::GetObservationsOf(FeaturePtr f) const { + std::vector out; + for (const auto &obs : feature_adj_.at(f->id())) { + out.push_back({groups_.at(obs.first), obs.second}); + } + return out; +} + +void Graph::SanityCheck() { + for (auto p : features_) { + int fid = p.first; + auto f = p.second; + CHECK(feature_adj_.count(fid)); + for (auto obs : feature_adj_.at(fid)) { + CHECK(groups_.count(obs.first)); + } + CHECK(f->ref()); + CHECK(groups_.count(f->ref()->id())); + } + + for (auto p : groups_) { + int gid = p.first; + auto g = p.second; + CHECK(group_adj_.count(gid)); + for (auto fid : group_adj_.at(gid)) { + CHECK(features_.count(fid)); + } + } + LOG(INFO) << "#graph.features=" << features_.size() + << " ;#graph.groups=" << groups_.size(); +} + +std::vector Graph::TransferFeatureOwnership(GroupPtr g, + const SE3 &gbc) { + + CHECK(HasGroup(g)); + + std::vector failed; + int gid = g->id(); + + for (int fid : group_adj_.at(gid)) { + CHECK(HasFeature(fid)); + + auto f = features_.at(fid); + if (f->ref() == g) { + // transfer ownership + auto nref = FindNewOwner(f); + if (nref) { + // now transfer + SE3 g_cn_s = + (nref->gsb() * gbc) + .inv(); // spatial (s) to camera of the new reference (cn) + Mat3 dXs_dx; + Vec3 Xcn = g_cn_s * f->Xs(gbc, &dXs_dx); + // Mat3 dXcn_dXs = gcb.R() * gbs.R(); + Mat3 dXcn_dx = g_cn_s.R().matrix() * dXs_dx; + Mat3 dxn_dXcn; +#ifdef USE_INVDEPTH + Vec3 xn = project_invz(Xcn, &dxn_dXcn); +#else + if (Xcn(2) < 0) { + f->ResetRef(nullptr); + failed.push_back(f); + LOG(WARNING) << "negative depth; mark feature #" << fid + << " as failed"; + continue; + } + Vec3 xn = project_logz(Xcn, &dxn_dXcn); +#endif + f->x() = xn; + + Mat3 J; + J = dxn_dXcn * dXcn_dx; + + f->P() = + J * f->P() * J.transpose() * 1.5; // inflate covariance a little bit + + f->ResetRef(nref); + + LOG(INFO) << "feature #" << fid << " transfered from group #" << gid + << " to group #" << nref->id(); + } else { + f->ResetRef(nullptr); + failed.push_back(f); + LOG(WARNING) << "failed to find new owner for feature #" << fid; + } + } + } + return failed; +} + +GroupPtr Graph::FindNewOwner(FeaturePtr f) { + int fid = f->id(); + CHECK(features_.count(fid)); + CHECK(feature_adj_.count(fid)); + auto old_gid = f->ref()->id(); + for (const auto &obs : feature_adj_.at(fid)) { + int gid = obs.first; + if (gid != old_gid) { + // TODO: can have fancy measure on which group should be the best to be + // the new owner + // For now, just pick the first one met. + return groups_.at(gid); + } + } + return nullptr; +} + +void Graph::CleanIsolatedGroups() { + std::vector islands; + ; + for (auto p : groups_) { + if (group_adj_.at(p.first).empty()) { + islands.push_back(p.second); + } + } + LOG(INFO) << "removing " << islands.size() << " isolated groups" << std::endl; + RemoveGroups(islands); + for (auto g : islands) { + Group::Delete(g); + } +} + +void Graph::CleanIsolatedFeatures() { + std::vector islands; + ; + for (auto p : features_) { + if (feature_adj_.at(p.first).empty()) { + islands.push_back(p.second); + } + } + LOG(INFO) << "removing " << islands.size() << " isolated features" + << std::endl; + RemoveFeatures(islands); + for (auto f : islands) { + Feature::Delete(f); + } +} + +void Graph::CleanIsolatedNodes() { + CleanIsolatedFeatures(); + CleanIsolatedGroups(); +} + +} // namespace feh diff --git a/src/graph.h b/src/graph.h new file mode 100644 index 00000000..8e312ea1 --- /dev/null +++ b/src/graph.h @@ -0,0 +1,79 @@ +// The feature-group graph. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include +#include +#include +#include + +#include "core.h" +#include "feature.h" + +namespace feh { + +struct FeatureAdj : public std::unordered_map { + void Add(const Observation &obs); + void Remove(int id); +}; + +struct GroupAdj : public std::unordered_set { + void Add(int id); + void Remove(int id); +}; + +class Graph { +public: + void RemoveFeature(const FeaturePtr f); + void RemoveFeatures(const std::vector &); + + void RemoveGroup(const GroupPtr g); + void RemoveGroups(const std::vector &); + + void AddFeature(FeaturePtr f); + void AddGroup(GroupPtr g); + + void AddGroupToFeature(GroupPtr g, FeaturePtr f); + void AddFeatureToGroup(FeaturePtr f, GroupPtr g); + + bool HasGroup(GroupPtr g) const; + bool HasGroup(int gid) const; + bool HasFeature(FeaturePtr f) const; + bool HasFeature(int fid) const; + FeaturePtr GetFeature(int fid) const; + GroupPtr GetGroup(int gid) const; + + std::vector + GetFeaturesIf(std::function pred) const; + std::vector GetFeatures() const; + std::vector GetGroupsIf(std::function pred) const; + std::vector GetGroups() const; + + std::vector GetFeaturesOf(GroupPtr g) const; + std::vector GetGroupsOf(FeaturePtr f) const; + + std::vector GetObservationsOf(FeaturePtr f) const; + + const FeatureAdj &GetFeatureAdj(FeaturePtr f) const; + const GroupAdj &GetGroupAdj(GroupPtr g) const; + + // transfer ownership of features owned by g, i.e., with g as reference + // return those for which a new owner cannot be found + // gsc is the camera to spatial frame transformation + std::vector TransferFeatureOwnership(GroupPtr g, const SE3 &gbc); + GroupPtr FindNewOwner(FeaturePtr f); + + void SanityCheck(); + void CleanIsolatedGroups(); + void CleanIsolatedFeatures(); + void CleanIsolatedNodes(); + +private: + // 2 types of nodes: feature and group + std::unordered_map features_; + std::unordered_map groups_; + // adjacent list + std::unordered_map feature_adj_; + std::unordered_map group_adj_; +}; + +} // namespace feh diff --git a/src/group.cpp b/src/group.cpp new file mode 100644 index 00000000..013df935 --- /dev/null +++ b/src/group.cpp @@ -0,0 +1,34 @@ +#include "group.h" +#include "mm.h" + +namespace feh { + +int Group::counter_ = 0; + +//////////////////////////////////////// +// FACTORY METHODS +//////////////////////////////////////// +GroupPtr Group::Create(const SO3 &Rsb, const Vec3 &Tsb) { + auto g = MemoryManager::instance()->GetGroup(); + CHECK(g); + g->Reset(Rsb, Tsb); + return g; +} + +void Group::Delete(GroupPtr g) { MemoryManager::instance()->ReturnGroup(g); } + +void Group::Reset(const SO3 &Rsb, const Vec3 &Tsb) { + id_ = counter_++; + lifetime_ = 0; + sind_ = -1; + status_ = GroupStatus::CREATED; + X_.Rsb = Rsb; + X_.Tsb = Tsb; + VLOG(0) << "group #" << id_ << " created"; +} + +bool Group::instate() const { + return status_ == GroupStatus::INSTATE || status_ == GroupStatus::GAUGE; +} + +} // namespace feh diff --git a/src/group.h b/src/group.h new file mode 100644 index 00000000..ae3420ec --- /dev/null +++ b/src/group.h @@ -0,0 +1,80 @@ +// Group structure. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include +#include +#include +#include +#include + +#include "component.h" +#include "core.h" + +namespace feh { + +struct SO3xR3 { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + SO3 Rsb; + Vec3 Tsb; + + using Tangent = Vec6; + SO3xR3 &operator+=(const Tangent &dX) { + Rsb *= SO3::exp(dX.head<3>()); + Tsb += dX.tail<3>(); + return *this; + } +}; + +class Group : public Component { + friend class MemoryManager; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + static GroupPtr Create(const SO3 &Rsb, const Vec3 &Tsb); + static void Delete(GroupPtr g); + + // id & index related accessors + int id() const { return id_; } + int sind() const { return sind_; } + void SetSind(int ind) { sind_ = ind; } + int lifetime() const { return lifetime_; } + int IncrementLifetime() { lifetime_++; } + int ResetLifetime() { lifetime_ = 0; } + + void BackupState() { X0_ = X_; } + void RestoreState() { X_ = X0_; } + + // status accessors + bool instate() const; + GroupStatus status() const { return status_; } + void SetStatus(GroupStatus status) { status_ = status; } + + // local state accessors + SE3 gsb() const { return SE3{X_.Rsb, X_.Tsb}; } + const SO3 &Rsb() const { return X_.Rsb; } + const Vec3 &Tsb() const { return X_.Tsb; } + void SetState(const SE3 &gsb) { SetState(gsb.R(), gsb.T()); } + void SetState(const SO3 &Rsb, const Vec3 &Tsb) { + X_.Rsb = Rsb; + X_.Tsb = Tsb; + } + void UpdateState(const Vec6 &dX) { X_ += dX; } + +private: + Group(const Group &) = delete; + // default constructor used in memory manager's pre-allocation + Group() = default; + void Reset(const SO3 &Rsb, const Vec3 &Tsb); + +private: + static int counter_; + int id_; + int sind_; // state index + GroupStatus status_; + int lifetime_; + + // nominal state + SO3xR3 X_, X0_; +}; + +} // namespace feh diff --git a/src/helpers.cpp b/src/helpers.cpp new file mode 100644 index 00000000..7798d5bb --- /dev/null +++ b/src/helpers.cpp @@ -0,0 +1,152 @@ +#include "helpers.h" + +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "glog/logging.h" + +namespace feh { + +// Reference: +// http://www.math.usm.edu/lambers/mat610/sum10/lecture9.pdf +void SlowGivens(const MatX &Hf, MatX &Hx) { + // FIXME: use Givens rotation + Eigen::FullPivLU lu(Hf.transpose()); + MatX A = lu.kernel(); // Hf.T * A = 0 -> A.T * Hf = 0 + // Hf: 2nx3, Hf.T: 3x2n, A: 2nx?, At: ?x2n + // MatX At = A.transpose(); + Hx = A.transpose() * Hx; +} + +// Matrix computation. Golub & Loan. +// page 240, Algorithm 5.1.3 +static Mat2 givens(ftype a, ftype b) { + Mat2 G; + ftype c, s, t; + if (fabs(b) < eps) { + c = 1; + s = 0; + } else { + if (fabs(b) > fabs(a)) { + t = -a / b; + s = 1 / sqrt(1 + t * t); + c = s * t; + } else { + t = -b / a; + c = 1 / sqrt(1 + t * t); + s = c * t; + } + } + G << c, s, -s, c; + return G; +} + +int Givens(VecX &x, MatX &Hx, MatX &Hf, int effective_rows) { + CHECK((effective_rows == -1 && (x.rows() ^ 1)) || + ((effective_rows <= x.rows()) && effective_rows ^ 1)); + + CHECK(x.rows() == Hx.rows()); + CHECK(x.rows() == Hf.rows()); + + int rows = (effective_rows == -1 ? Hf.rows() : effective_rows); + int cols = Hf.cols(); + + Mat2 Gt; + for (int c = 0; c < cols; ++c) { + for (int r = rows - 2; r >= c; --r) { + Gt.transpose() = givens(Hf(r, c), Hf(r + 1, c)); + Hf.block(r, 0, 2, cols) = Gt * Hf.block(r, 0, 2, cols); + Hx.block(r, 0, 2, cols) = Gt * Hx.block(r, 0, 2, cols); + + x.segment<2>(r) = Gt * x.segment<2>(r); + } + } + // now strip the first #cols rows + for (int r = 0; r < rows - cols; ++r) { + x(r) = x(r + cols); + Hx.row(r) = Hx.row(r + cols); + Hf.row(r) = Hf.row(r + cols); + } + return rows - cols; +} + +int QR(VecX &x, MatX &Hx, int effective_rows) { + CHECK(x.rows() == Hx.rows()); + + int rows = (effective_rows == -1 ? Hx.rows() : effective_rows); + int cols = Hx.cols(); + + CHECK(rows > cols); + + Mat2 Gt; + for (int c = 0; c < cols; ++c) { + for (int r = rows - 2; r >= c; --r) { + Gt.transpose() = givens(Hx(r, c), Hx(r + 1, c)); + Hx.block(r, 0, 2, cols) = Gt * Hx.block(r, 0, 2, cols); + x.segment<2>(r) = Gt * x.segment<2>(r); + } + } + // in contrast to the Givens function used to eliminate measurement jacobian + // Hf of feature, + // here we want to keep the parts which are not eliminated -- which are the + // first #rows + // of both residual vector x and measurement jacobian Hx + // return the number of rows, and let the caller to decide what to do with the + // matrices. + return rows; +} + +Vec3 Triangulate1(const SE3 &g12, const Vec2 &xc1, const Vec2 &xc2) { + Vec3 t12{g12.T()}; + Mat3 R12{g12.R()}; + Mat34 P1; + P1.block<3, 3>(0, 0).setIdentity(); + Mat34 P2; + P2.block<3, 3>(0, 0) = R12.transpose(); + P2.block<3, 1>(0, 3) = -R12.transpose() * t12; + Vec3 f1{xc1(0), xc1(1), 1.0}; + f1.normalize(); + Vec3 f2{xc2(0), xc2(1), 1.0}; + f2.normalize(); + + Mat4 A; + A.row(0) = f1(0) * P1.row(2) - f1(2) * P1.row(0); + A.row(1) = f1(1) * P1.row(2) - f1(2) * P1.row(1); + A.row(2) = f2(0) * P2.row(2) - f2(2) * P2.row(0); + A.row(3) = f2(1) * P2.row(2) - f2(2) * P2.row(1); + + Eigen::JacobiSVD svd(A, Eigen::ComputeFullV); + auto V = svd.matrixV(); + Vec3 x; + x << V(0, 3), V(1, 3), V(2, 3); + x /= V(3, 3); + return x; +} + +Vec3 Triangulate2(const SE3 &g12, const Vec2 &xc1, const Vec2 &xc2) { + Vec3 t12{g12.T()}; + Mat3 R12{g12.R()}; + + Vec3 f1{xc1(0), xc1(1), 1.0}; + f1.normalize(); + Vec3 f2{xc2(0), xc2(1), 1.0}; + f2.normalize(); + + Vec3 f2_unrotated{R12 * f2}; + Vec2 b; + b << t12.dot(f1), t12.dot(f2_unrotated); + Mat2 A; + A(0, 0) = f1.dot(f1); + A(1, 0) = f1.dot(f2_unrotated); + A(0, 1) = -A(1, 0); + A(1, 1) = -f2_unrotated.dot(f2_unrotated); + Vec2 lambda = A.inverse() * b; + Vec3 xm = lambda(0) * f1; + Vec3 xn = t12 + lambda(1) * f2_unrotated; + Vec3 x = (xm + xn) / 2.0; // in frame 1 + return x; +} + +} // namespace feh diff --git a/src/helpers.h b/src/helpers.h new file mode 100644 index 00000000..7ee7e0a5 --- /dev/null +++ b/src/helpers.h @@ -0,0 +1,45 @@ +// Help functions. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include +#include + +#include "alias.h" + +namespace feh { + +// Project matrix Hx onto the left nullspace of Hf via Givens rotations. +// i.e., A' * Hf = 0 and we compute Hx <- A' * Hx +// This can be achieved first concatenate Hf and Hx as [Hf | Hx] +// And then eliminate the left most block Hf via Givens rotation. +void SlowGivens(const MatX &Hf, MatX &Hx); + +// zero-out measurement jacobian matrix H by applying Givens rotations +// same rotations will also be used to transform residual vector r. +// Effective_rows is the number of rows actually used. Since r, n, Hx, and Hf +// might be over-sized. +int Givens(VecX &r, MatX &Hx, MatX &Hf, int effective_rows = -1); + +// QR-based measurement compression. +// Args: +// r: residual vector +// Hx: measurement jacobian +// Returns: size of the upper triangular matrix Th +int QR(VecX &r, MatX &Hx, int effective_rows = -1); + +template void MakePtrVectorUnique(std::vector &v) { + std::sort(v.begin(), v.end()); + v.erase(std::unique(v.begin(), v.end()), v.end()); +} + +// triangulation method1 +// g12: 2->1 +// xc1: camera coordinates in frame 1 +// xc2: camera coordiantes in frame 2 +Vec3 Triangulate1(const SE3 &g12, const Vec2 &xc1, const Vec2 &xc2); + +// triangulation method2 +// interface same as triangulation method1 above +Vec3 Triangulate2(const SE3 &g12, const Vec2 &xc1, const Vec2 &xc2); + +} // namespace feh diff --git a/src/imu.cpp b/src/imu.cpp new file mode 100644 index 00000000..b8ea70ae --- /dev/null +++ b/src/imu.cpp @@ -0,0 +1,27 @@ +#include "glog/logging.h" + +#include "imu.h" + +namespace feh { + +IMUState &IMUState::operator+=(const Tangent &dX) { + int idx{0}; + // accel scaling + for (int i = 0; i < 3; ++i) { + for (int j = i; j < 3; ++j) { + Ca(i, j) += dX(idx++); + } + } + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + Cg(i, j) += dX(idx++); + } + } + CHECK(idx == 15); +} + +IMU::IMU(const Mat3 &Ca, const Mat3 &Cg) : X_{Ca, Cg} { + CHECK(Ca(1, 0) == 0 && Ca(2, 0) == 0 && Ca(2, 1) == 0); +} + +} // namespace feh diff --git a/src/imu.h b/src/imu.h new file mode 100644 index 00000000..f9469f39 --- /dev/null +++ b/src/imu.h @@ -0,0 +1,42 @@ +// IMU class whose intrinsics can be (optionally) estimated. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once + +#include "Eigen/Core" + +#include "alias.h" +#include "component.h" + +namespace feh { + +struct IMUState { +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + Mat3 Ca; // accel scaling (diagonal) and misalignment (upper triangle) + Mat3 Cg; // gyro scaling (diagonal) and misalignment (upper & lower triangle) + + using Tangent = Eigen::Matrix; + IMUState &operator+=(const Tangent &dX); + +private: + // make the constructor prive, so ... + IMUState() : Ca{Mat3::Identity()}, Cg{Mat3::Identity()} {} + IMUState(const Mat3 &Ca_in, const Mat3 &Cg_in) : Ca{Ca_in}, Cg{Cg_in} {} + // only its friend IMU can create the IMUState + friend class IMU; +}; + +class IMU : public Component { +public: + IMU() = default; + IMU(const Mat3 &Ca, const Mat3 &Cg); + + void UpdateState(const IMUState::Tangent &dX) { X_ += dX; } + const Mat3 &Ca() const { return X_.Ca; } + const Mat3 &Cg() const { return X_.Cg; } + +private: + IMUState X_; +}; + +} // namespace feh diff --git a/src/jac.h b/src/jac.h new file mode 100644 index 00000000..a0b7ddc4 --- /dev/null +++ b/src/jac.h @@ -0,0 +1,54 @@ +// Jacobian management and cache. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include "Eigen/Dense" +#include "core.h" +#include + +namespace feh { + +struct OOSJacobian { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + OOSJacobian() { + Hx.resize(2 * kMaxGroup, kFullSize); + Hf.resize(2 * kMaxGroup, 3); + inn.resize(2 * kMaxGroup); + } + MatX Hx; // ... w.r.t. state + MatX Hf; + VecX inn; // n is std of measurement noise +}; + +using OOSJacobianPtr = OOSJacobian *; + +struct JacobianCache { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + Vec3 Xc; // 3D point in camera frame of the reference group + Mat3 dXc_dx; // 3D point in reference camera frame w.r.t. local state + + Vec3 Xs; // 3D point in spatial frame + Mat3 dXs_dXc; // 3D point in spatial frame w.r.t. Xc + Mat3 dXs_dTr, dXs_dWr; // w.r.t. body2spatial pose of the reference group + Mat3 dXs_dTbc, dXs_dWbc; // w.r.t. cam2body alignment + Mat3 dXs_dx; + + Vec3 Xcn; // 3D point in camera frame of the "new" (current) group + Mat3 dXcn_dXs; // Xc in "new" (current) camera frame w.r.t. Xs + Mat3 dXcn_dTr, dXcn_dWr; // w.r.t. body2spatial pose of the reference group + Mat3 dXcn_dTsb, dXcn_dWsb; // w.r.t. body2spatial pose + Mat3 dXcn_dTbc, dXcn_dWbc; // w.r.t. cam2body alignment + Mat3 dXcn_dx; + Vec3 dXcn_dtd; // w.r.t. temporal offset + Eigen::Matrix dXcn_dCg; // w.r.t. gyroscope intrinsics + Mat3 dXcn_dbg; + + Vec2 xcn; // camera coordinates in the "new" group + Mat23 dxcn_dXcn; // w.r.t. 3D point in camera frame + + Vec2 xp; // pixel coordinates + Mat23 dxp_dXcn; + Mat2 dxp_dxcn; // w.r.t. new camera coordinates + Vec2 inn; // innovation +}; + +} // namespace feh diff --git a/src/manager.cpp b/src/manager.cpp new file mode 100644 index 00000000..bbe8468f --- /dev/null +++ b/src/manager.cpp @@ -0,0 +1,362 @@ +#include +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "glog/logging.h" + +#include "estimator.h" +#include "feature.h" +#include "geometry.h" +#include "group.h" +#include "tracker.h" + +namespace feh { + +void Estimator::ProcessTracks(const timestamp_t &ts, + std::list &tracks) { + if (simulation_) { + UpdateSystemClock(ts); + // propagate state upto current timestamp + Propagate(true); + } + instate_features_.clear(); + oos_features_.clear(); + instate_groups_.clear(); + + // increment lifetime of all features and groups + for (auto f : graph_.GetFeatures()) { + f->IncrementLifetime(); + } + for (auto g : graph_.GetGroups()) { + g->IncrementLifetime(); + } + + // which lost at least one feature and might be a floating group + std::unordered_set affected_groups; + + // process instate but failed-to-be-tracked features + std::vector new_features; + ; + for (auto it = tracks.begin(); it != tracks.end();) { + auto f = *it; + + if (use_canvas_) { + Canvas::instance()->Draw(f); + } + + if (f->track_status() == TrackStatus::CREATED) { + // just created, must not included in the graph yet + new_features.push_back(f); + it = tracks.erase(it); + } else if ((f->instate() && f->track_status() == TrackStatus::DROPPED) || + f->track_status() == TrackStatus::REJECTED) { + graph_.RemoveFeature(f); + if (f->instate()) { + RemoveFeatureFromState(f); + affected_groups.insert(f->ref()); + } + Feature::Delete(f); + it = tracks.erase(it); + } else if (!f->instate() && f->track_status() == TrackStatus::DROPPED) { + if (use_OOS_) { + // use OOS features for update + f->SetStatus(FeatureStatus::DROPPED); + oos_features_.push_back(f); + } else { + // just remove + graph_.RemoveFeature(f); + Feature::Delete(f); + } + it = tracks.erase(it); + } else { + CHECK(f->track_status() == TrackStatus::TRACKED); + if (f->instate()) { + // instate feature being tracked -- use in measurement update later on + ++it; + } else { + CHECK(!f->instate()); + + // perform triangulation before + if (triangulate_pre_subfilter_ && f->size() == 2) { + // got a second view, triangulate! + f->Triangulate(gsb(), gbc(), triangulate_options_); + } + + // out-of-state feature, run depth subfilter to improve depth ... + f->SubfilterUpdate(gsb(), gbc(), subfilter_options_); + // std::cout << "outlier score=" << f->outlier_counter() << std::endl; + if (f->outlier_counter() > 10) { + graph_.RemoveFeature(f); + Feature::Delete(f); + it = tracks.erase(it); + } else { + ++it; + } + } + } + } + + // remaining in tracks: just created (not in graph yet) and being tracked well + // (may or may not be in graph, for those in graph, may or may not in state) + instate_features_ = graph_.GetFeaturesIf([](FeaturePtr f) -> bool { + return f->status() == FeatureStatus::INSTATE; + }); + + if (instate_features_.size() < kMaxFeature) { + + // choose the instate-candidate criterion + auto criterion = + vision_counter_ < 5 ? Criteria::Candidate : Criteria::CandidateStrict; + auto candidates = graph_.GetFeaturesIf(criterion); + + MakePtrVectorUnique(candidates); + std::sort(candidates.begin(), candidates.end(), + Criteria::CandidateComparison); + + std::vector bad_features; + for (auto it = candidates.begin(); + it != candidates.end() && instate_features_.size() < kMaxFeature;) { + + auto f = *it; + + if (use_depth_opt_) { + auto obs = graph_.GetObservationsOf(f); + if (obs.size() > 1) { + if (f->RefineDepth(gbc(), obs, refinement_options_)) { + ++it; + } else { + bad_features.push_back(f); + it = candidates.erase(it); + continue; + } + } else { + // FIXME: if not observation, should also skip + ++it; + } + } + + instate_features_.push_back(f); + AddFeatureToState(f); // insert f to state vector and covariance + if (!f->ref()->instate()) { + CHECK(graph_.HasGroup(f->ref())); + CHECK(graph_.GetGroupAdj(f->ref()).count(f->id())); + CHECK(graph_.GetFeatureAdj(f).count(f->ref()->id())); + // need to add reference group to state if it's not yet instate + AddGroupToState(f->ref()); + } + } + DiscardFeatures(bad_features); + } + + // Perform depth refinement before using oos features + if (!oos_features_.empty() && use_depth_opt_) { + std::vector bad_features; + for (auto it = oos_features_.begin(); it != oos_features_.end();) { + auto f = *it; + auto obs = graph_.GetObservationsOf(f); + if (obs.size() > 1 && f->RefineDepth(gbc(), obs, refinement_options_)) { + ++it; + } else { + // remove those failed to be optimized in depth refinement + bad_features.push_back(f); + it = oos_features_.erase(it); + } + } + DiscardFeatures(bad_features); + } + + // Once we have enough instate features, perform state update + if (!instate_features_.empty() || !oos_features_.empty()) { + MakePtrVectorUnique(oos_features_); + MakePtrVectorUnique(instate_features_); + + instate_groups_ = + graph_.GetGroupsIf([](GroupPtr g) { return g->instate(); }); + Update(); + } + + // remove oos features + for (auto f : oos_features_) { + CHECK(!f->instate()); + graph_.RemoveFeature(f); + Feature::Delete(f); + } + + // Post-update feature management + // For instate features rejected by the filter, + // 1) remove the fetaure from features_ and free state & covariance + // 2) detach the feature from the reference group + // 3) remove the group if it lost all the instate features + + auto rejected_features = graph_.GetFeaturesIf([](FeaturePtr f) -> bool { + return f->status() == FeatureStatus::REJECTED_BY_FILTER; + }); + // std::cout << "#rejected=" << rejected_features.size() << std::endl; + if (use_canvas_) { + for (auto f : rejected_features) { + Canvas::instance()->Draw(f); + } + } + // LOG(INFO) << "#rejected features=" << rejected_features.size(); + for (auto f : rejected_features) { + CHECK(f->ref() != nullptr); + affected_groups.insert(f->ref()); + } + graph_.RemoveFeatures(rejected_features); + for (auto f : rejected_features) { + RemoveFeatureFromState(f); + Feature::Delete(f); + } + + // different strategies to discard groups w & w/o OOS update + std::vector discards; + if (!use_OOS_) { + // If OOS update is NOT used, we need to + // remove floating groups (with no instate features) and + // floating features (not instate and reference group is floating) + for (auto g : affected_groups) { + const auto &adj_f = graph_.GetFeaturesOf(g); + if (std::none_of(adj_f.begin(), adj_f.end(), [g](FeaturePtr f) { + return f->ref() == g && f->instate(); + })) { + discards.push_back(g); + } + } + + } else { + // if not enough slots, remove old instate groups and recycle some spaces + std::vector groups = + graph_.GetGroupsIf([](GroupPtr g) { return g->instate(); }); + if (groups.size() == kMaxGroup) { + int oos_discard_step = cfg_.get("oos_discard_step", 3).asInt(); + // sort such that oldest groups are at the front of the vector + std::sort(groups.begin(), groups.end(), + [](GroupPtr g1, GroupPtr g2) { return g1->id() < g2->id(); }); + // NOTE: start with 1 is NOT a mistake, since the oldest (index 0) one + // should be kept + // (0), 1, 2, (3), 4, 5 ... + // bracketed indices are those to keep + for (int i = 1; i < groups.size(); ++i) { + if (i % oos_discard_step != 0) { + // if the group does not have instate features referring back to + // itself, + auto g = groups[i]; + auto adj_f = graph_.GetFeaturesOf(g); + if (std::none_of(adj_f.begin(), adj_f.end(), [g](FeaturePtr f) { + return f->instate() && f->ref() == g; + })) { + discards.push_back(g); + } + } + } + } // instate group size == kMaxGroup + } // use_OOS + + // for the to-be-discarded groups, transfer ownership of features owned by + // them + std::vector nullref_features = DiscardGroups(discards); + DiscardFeatures(nullref_features); + + // initialize those newly detected featuers + // create a new group and associate newly detected features to the new group + GroupPtr g = Group::Create(X_.Rsb, X_.Tsb); + graph_.AddGroup(g); + if (use_OOS_) { + // In OOS mode, always try to add groups to state. + AddGroupToState(g); + } + + tracks.clear(); // clear to prepare for re-assemble the feature list + for (auto f : new_features) { + // distinguish two cases: + // 1) feature is truely just created + // 2) feature just lost its reference + CHECK(f->track_status() == TrackStatus::CREATED && + f->status() == FeatureStatus::CREATED); + CHECK(f->ref() == nullptr); + f->SetRef(g); + f->Initialize(init_z_, {init_std_x_, init_std_y_, init_std_z_}); + + graph_.AddFeature(f); + graph_.AddFeatureToGroup(f, g); + graph_.AddGroupToFeature(g, f); + + // put back the detected feature + tracks.push_back(f); + } + + auto tracked_features = graph_.GetFeaturesIf([](FeaturePtr f) -> bool { + return f->track_status() == TrackStatus::TRACKED; + }); + for (auto f : tracked_features) { + CHECK(f->ref() != nullptr); + + // attach the new group to all the features being tracked + graph_.AddFeatureToGroup(f, g); + graph_.AddGroupToFeature(g, f); + + // put back the tracked feature + tracks.push_back(f); + } + + // adapt initial depth to average depth of features currently visible + auto depth_features = graph_.GetFeaturesIf([this](FeaturePtr f) -> bool { + return f->status() == FeatureStatus::INSTATE || + (f->status() == FeatureStatus::READY && f->lifetime() > 5); + }); + if (!depth_features.empty()) { + std::vector depth(depth_features.size()); + std::transform(depth_features.begin(), depth_features.end(), depth.begin(), + [](FeaturePtr f) { return f->z(); }); + ftype median_depth = depth[depth.size() >> 1]; + init_z_ = 0.01 * init_z_ + 0.99 * median_depth; + // init_z_ = median_depth; + VLOG(0) << "Adaptive initial depth=" << init_z_; + } + + if (!use_OOS_) { + // remove non-reference groups + auto all_groups = graph_.GetGroups(); + int max_group_lifetime = cfg_.get("max_group_lifetime", 1).asInt(); + for (auto g : all_groups) { + if (g->lifetime() > max_group_lifetime) { + const auto &adj = graph_.GetGroupAdj(g); + if (std::none_of(adj.begin(), adj.end(), [this, g](int fid) { + return graph_.GetFeature(fid)->ref() == g; + })) { + // for groups which have no reference features, they cannot be instate + // anyway + CHECK(!g->instate()); + + graph_.RemoveGroup(g); + Group::Delete(g); + } + } + } + } + + // std::cout << "#groups=" << graph_.GetGroups().size() << std::endl; + // check & clean graph + // graph_.SanityCheck(); + // // remove isolated groups + // auto empty_groups = graph_.GetGroupsIf([this](GroupPtr g)->bool { + // return graph_.GetGroupAdj(g).empty(); }); + // LOG(INFO) << "#empty groups=" << empty_groups.size(); + // graph_.RemoveGroups(empty_groups); + // for (auto g : empty_groups) { + // CHECK(!g->instate()); + // Group::Delete(g); + // } + + if (use_canvas_) { + Canvas::instance()->OverlayStateInfo(X_); + } + + if (print_timing_) { + std::cout << timer_; + } +} + +} // namespace feh diff --git a/src/message_types.h b/src/message_types.h new file mode 100644 index 00000000..533e8dac --- /dev/null +++ b/src/message_types.h @@ -0,0 +1,57 @@ +// Message types for interfacing the estimator with data acquisition module. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once + +#include +#include + +#include "core.h" + +namespace feh { + +namespace msg { + +struct Message { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + Message(const timestamp_t &ts) : ts_{ts} {} + virtual ~Message() {} + + timestamp_t ts_; +}; + +struct Image : public Message { + Image(const timestamp_t &ts, const std::string &image_path) + : Message{ts}, image_path_{image_path} {} + + std::string image_path_; +}; + +struct IMU : public Message { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + IMU(const timestamp_t &ts, const Vec3 &gyro, const Vec3 &accel) + : Message{ts}, gyro_{gyro}, accel_{accel} {} + + // friend std::ostream& operator<<(std::ostream& os, const IMU &msg); + + Vec3 gyro_, accel_; +}; + +struct Track : public Message { + Track(const timestamp_t &ts, std::list &&features) + : Message{ts}, features_{features} {} + + std::list features_; +}; + +struct Pose : public Message { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + Pose(const timestamp_t &ts, const SE3 &g) : Message{ts}, g_{g} {} + + SE3 g_; +}; + +} // namespace msg + +} // namespace feh diff --git a/src/metrics.cpp b/src/metrics.cpp new file mode 100644 index 00000000..bda6fbe8 --- /dev/null +++ b/src/metrics.cpp @@ -0,0 +1,132 @@ +#include "glog/logging.h" + +#include "geometry.h" +#include "metrics.h" + +namespace feh { + +static std::tuple +AbsoluteTrajectoryError(const std::vector &Y, + const std::vector &X) { + auto gYX = TrajectoryAlignment(Y, X); + + LOG(INFO) << "computing ATE"; + ftype res{0}; + for (int i = 0; i < X.size(); ++i) { + // AR=RB + Vec3 r = Y[i] - gYX * X[i]; + res += r.squaredNorm(); + } + res = sqrt(res / X.size()); + LOG(INFO) << "ATE=" << res << " meters" << std::endl; + return std::make_tuple(res, gYX); +} + +std::tuple ComputeATE(const std::vector &est, + const std::vector >, ftype res) { + using std::chrono::abs; + + auto it_est = est.begin(); + auto it_gt = gt.begin(); + timestamp_t bound(uint64_t{res * 1e9}); // seconds -> nanoseconds + + std::vector X, Y; + while (it_est < est.end() && next(it_gt) < gt.end()) { + if (it_est->ts_ >= it_gt->ts_ && it_est->ts_ < next(it_gt)->ts_) { + // make sure the timestamps are close enough + if (abs(it_est->ts_ - it_gt->ts_) < bound) { + Y.push_back(it_est->g_.translation()); + X.push_back(it_gt->g_.translation()); + } + // proceed + it_est++; + it_gt++; + } else if (it_est->ts_ < it_gt->ts_) { + ++it_est; + } else { + ++it_gt; + } + } + auto packet = X.empty() ? std::make_tuple(ftype(-1), SE3{}) + : AbsoluteTrajectoryError(Y, X); + return packet; +} + +std::tuple ComputeRPE(const std::vector &est, + const std::vector >, ftype dt, + ftype res) { + using std::chrono::abs; + + auto it_est = est.begin(); + auto it_gt = gt.begin(); + + // positional and rotational RPE + ftype rpe_pos{0}, rpe_rot{0}; + int counter{0}; + while (it_est < est.end() && next(it_gt) < gt.end()) { + if (it_est->ts_ >= it_gt->ts_ && it_est->ts_ < next(it_gt)->ts_) { + auto gY = (it_est++)->g_; + auto gX = (it_gt++)->g_; + // pair these poses with poses dt seconds apart in time + SE3 gY2, gX2; + bool found{false}; + // seconds -> nanoseconds + timestamp_t desire = it_est->ts_ + timestamp_t{uint64_t(dt * 1e9)}; + timestamp_t bound{uint64_t(res * 1e9)}; + + std::vector::const_iterator it; + for (it = it_est; it < est.end(); ++it) { + if (it->ts_ > desire - bound && it->ts_ < desire + bound) { + if (abs(it->ts_ - desire) < bound) { + gY2 = it->g_; + bound = abs(it->ts_ - desire); + } + found = true; + } else if (it->ts_ > desire + bound) { + break; + } + } + if (!found) + continue; + + found = false; + desire = it_gt->ts_ + timestamp_t{uint64_t(dt * 1e9)}; + bound = timestamp_t{uint64_t(res * 1e9)}; + + for (it = it_gt; it < gt.end(); ++it) { + if (it->ts_ > desire - bound && it->ts_ < desire + bound) { + if (abs(it->ts_ - desire) < bound) { + gX2 = it->g_; + bound = abs(it->ts_ - desire); + } + found = true; + } else if (it->ts_ > desire + bound) { + break; + } + } + if (!found) + continue; + + auto dgX = gX.inv() * gX2; + auto dgY = gY.inv() * gY2; + rpe_pos += (dgX.inv() * dgY).translation().squaredNorm(); + rpe_rot += (dgX.inv() * dgY).so3().log().squaredNorm(); + ++counter; + } else if (it_est->ts_ < it_gt->ts_) { + ++it_est; + } else { + ++it_gt; + } + } + LOG(INFO) << "Effective pairs in computing RPE=" << counter; + if (counter) { + rpe_pos = sqrt(rpe_pos / counter); + rpe_rot = sqrt(rpe_rot / counter); + } else { + rpe_pos = -1; + rpe_rot = -1; + } + return std::make_tuple(rpe_pos, rpe_rot); +} + +} // namespace feh diff --git a/src/metrics.h b/src/metrics.h new file mode 100644 index 00000000..1f4491a5 --- /dev/null +++ b/src/metrics.h @@ -0,0 +1,37 @@ +// Evaluation metrics, namely, ATE and RTE for trajectory evaluation. +// And surface error for reconstruction/object alignment, etc. +// Reference: +// David Schubert, Thore Goll, Nikolaus Demmel, Vladyslav Usenko, Jorg Stuckler +// and Daniel Cremers +// The TUM VI Benchmark for Evaluating Visual-Inertial Odometry +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include +#include +#include + +#include "message_types.h" + +namespace feh { + +// Compute Absolute Trajectory Error given estimated trajectory and ground truth +// Args: +// est, gt: Estimated (Groundtruth) trajectories +// resolution: if estimate exactly at t+dt cannot be found, return the closest +// one within +/- resolution seconds +// Returns: ATE +std::tuple ComputeATE(const std::vector &est, + const std::vector >, + ftype res = 0.005); +// Compute Relative Pose Error given estimated trajectory and ground truth +// Args: +// est, gt: Estimated (Groundtruth) trajectories +// dt: time interval to compute error +// resolution: if estimate exactly at t+dt cannot be found, return the closest +// one within +/- resolution seconds +// Returns: RPE +std::tuple ComputeRPE(const std::vector &est, + const std::vector >, + ftype dt = 1.0, ftype res = 0.005); + +} // namespace feh diff --git a/src/mm.cpp b/src/mm.cpp new file mode 100644 index 00000000..21e22eff --- /dev/null +++ b/src/mm.cpp @@ -0,0 +1,80 @@ +#include "mm.h" +#include "feature.h" +#include "feature.h" +#include "group.h" + +#include "absl/strings/str_format.h" +#include "glog/logging.h" + +namespace feh { + +std::unique_ptr MemoryManager::instance_ = nullptr; + +MemoryManagerPtr MemoryManager::Create(int max_features, int max_groups) { + if (!instance_) { + instance_ = std::unique_ptr( + new MemoryManager(max_features, max_groups)); + LOG(INFO) << absl::StrFormat( + "MemoryManager instance created with %d features and %d groups", + max_features, max_groups); + } else { + LOG(WARNING) << "MemoryManager instance already created!"; + } + return instance_.get(); +} + +MemoryManager::MemoryManager(int max_features, int max_groups) { + for (int i = 0; i < max_features; ++i) { + FeaturePtr addr = new Feature(); + fslots_[addr] = false; + } + for (int i = 0; i < max_groups; ++i) { + GroupPtr addr = new Group(); + gslots_[addr] = false; + } +} + +MemoryManager::~MemoryManager() { + for (auto p : fslots_) { + delete p.first; + } + for (auto p : gslots_) { + delete p.first; + } + // for (auto j : oos_jacs_) { + // delete j; + // } +} + +MemoryManagerPtr MemoryManager::instance() { + if (!instance_) { + throw std::runtime_error("MemoryManager instance not created yet"); + } + return instance_.get(); +} + +FeaturePtr MemoryManager::GetFeature() { + for (auto &p : fslots_) { + if (!p.second) { + p.second = true; + return p.first; + } + } + return nullptr; +} + +void MemoryManager::ReturnFeature(FeaturePtr f) { fslots_.at(f) = false; } + +GroupPtr MemoryManager::GetGroup() { + for (auto &p : gslots_) { + if (!p.second) { + p.second = true; + return p.first; + } + } + return nullptr; +} + +void MemoryManager::ReturnGroup(GroupPtr g) { gslots_.at(g) = false; } + +} // namespace feh diff --git a/src/mm.h b/src/mm.h new file mode 100644 index 00000000..91a49460 --- /dev/null +++ b/src/mm.h @@ -0,0 +1,36 @@ +// Memory management for feature and groups. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include +#include + +#include "core.h" +#include "jac.h" + +namespace feh { + +class MemoryManager { +public: + ~MemoryManager(); + + static MemoryManagerPtr Create(int max_features, int max_groups); + static MemoryManagerPtr instance(); + + FeaturePtr GetFeature(); + void ReturnFeature(FeaturePtr); + GroupPtr GetGroup(); + void ReturnGroup(GroupPtr); + +private: + MemoryManager() = delete; + MemoryManager(const MemoryManager &) = delete; + MemoryManager &operator=(const MemoryManager &) = delete; + + MemoryManager(int max_features = 512, int max_groups = 128); + + static std::unique_ptr instance_; + std::unordered_map fslots_; // false = not used + std::unordered_map gslots_; +}; + +} // namespace feh diff --git a/src/options.cpp b/src/options.cpp new file mode 100644 index 00000000..a69ffe0a --- /dev/null +++ b/src/options.cpp @@ -0,0 +1,25 @@ +#include "options.h" +#include "feature.h" + +namespace feh { + +bool Criteria::Candidate(FeaturePtr f) { + ftype max_outlier_counter{0.01}; // FIXME (xfei): make a parameter + return (f->status() == FeatureStatus::READY || + f->status() == FeatureStatus::INITIALIZING) && + (f->outlier_counter() < max_outlier_counter); +} + +bool Criteria::CandidateStrict(FeaturePtr f) { + ftype max_outlier_counter{0.01}; // FIXME (xfei): make a parameter + return f->status() == FeatureStatus::READY && + (f->outlier_counter() < max_outlier_counter); +} + +bool Criteria::CandidateComparison(FeaturePtr f1, FeaturePtr f2) { + int s1 = as_integer(f1->status()); + int s2 = as_integer(f2->status()); + return (s1 > s2) || (s1 == s2 && f1->score() > f2->score()); +} + +} // namespace feh diff --git a/src/options.h b/src/options.h new file mode 100644 index 00000000..3c2598cf --- /dev/null +++ b/src/options.h @@ -0,0 +1,45 @@ +// options objects for various depth-related algorithms +#pragma once +#include "core.h" + +namespace feh { +// depth refinement options +struct RefinementOptions { + RefinementOptions() + : two_view{false}, max_iters{5}, eps{1e-5}, damping{1e-3}, + max_res_norm{5.0} {} + + bool two_view; + int max_iters; // maximal iterations to perform + ftype eps; // epsilon tolerance to stop optimization + ftype damping; // optional damping factor + ftype max_res_norm; // maximal per observation residual norm +}; + +// depth subfilter options +struct SubfilterOptions { + SubfilterOptions() : Rtri{3.5}, MH_thresh{5.991}, ready_steps{5} {} + + ftype Rtri; // measurement covariance for triangulation + ftype MH_thresh; // Mahalanobis gating threshold in depth-subfilter + int ready_steps; // feature initialized with this amount of attempts is turned + // to ready status +}; + +// options for depth triangulation +struct TriangulateOptions { + TriangulateOptions() : method{1}, zmin{0.05}, zmax{5.0} {} + + int method; + ftype zmin, zmax; +}; + +struct Criteria { + // how good is the feature to be an instate candidate + static bool Candidate(FeaturePtr f); + static bool CandidateStrict(FeaturePtr f); + // return true if f1 is considered a better candidate than f2 + static bool CandidateComparison(FeaturePtr f1, FeaturePtr f2); +}; + +} // namespace feh diff --git a/src/param.cpp b/src/param.cpp new file mode 100644 index 00000000..90fb910e --- /dev/null +++ b/src/param.cpp @@ -0,0 +1,20 @@ +#include "param.h" +#include "glog/logging.h" + +namespace feh { + +std::unique_ptr ParameterServer::instance_ = nullptr; + +ParameterServerPtr ParameterServer::Create(const Json::Value &value) { + if (instance_) { + LOG(WARNING) << "parameter server already created!"; + } else { + instance_ = std::unique_ptr(new ParameterServer(value)); + } + return instance_.get(); +} + +ParameterServer::ParameterServer(const Json::Value &value) + : Json::Value{value} {} + +} // namespace feh diff --git a/src/param.h b/src/param.h new file mode 100644 index 00000000..27685668 --- /dev/null +++ b/src/param.h @@ -0,0 +1,26 @@ +// A wrapper of JsonCpp's Value class +// using as a globally accessible parameter server. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include "json/json.h" +#include + +namespace feh { + +class ParameterServer; +using ParameterServerPtr = ParameterServer *; +class ParameterServer : public Json::Value { +public: + static ParameterServerPtr Create(const Json::Value &value); + static ParameterServerPtr instance() { return instance_.get(); } + +private: + ParameterServer() = delete; + ParameterServer(const ParameterServer &) = delete; + ParameterServer &operator=(const ParameterServer &) = delete; + ParameterServer(const Json::Value &value); + + static std::unique_ptr instance_; +}; + +} // namespace feh diff --git a/src/princedormand.cpp b/src/princedormand.cpp new file mode 100644 index 00000000..243c8826 --- /dev/null +++ b/src/princedormand.cpp @@ -0,0 +1,223 @@ +// Prince-Dormand numerical integration +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#include "estimator.h" + +namespace feh { + +void Estimator::PrinceDormand(const Vec3 &gyro0, const Vec3 &accel0, ftype dt) { + // reference 1: + // http://www.mymathlib.com/c_source/diffeq/embedded_runge_kutta/embedded_prince_dormand_v3_4_5.c + // reference 2: + // http://depa.fquim.unam.mx/amyd/archivero/DormandPrince_19856.pdf + static bool pd_initialized{false}, control_stepsize{false}; + static ftype tolerance, min_scale_factor, max_scale_factor, h, h0; + static int attempts; + + if (!pd_initialized) { + auto pd_cfg = cfg_["PrinceDormand"]; + control_stepsize = pd_cfg.get("control_stepsize", false).asBool(); + tolerance = pd_cfg.get("tolerance", 1e-3).asDouble(); + attempts = pd_cfg.get("attempts", 12).asInt(); + min_scale_factor = pd_cfg.get("min_scale_factor", 0.125).asDouble(); + max_scale_factor = pd_cfg.get("max_scale_factor", 4.0).asDouble(); + h = pd_cfg.get("stepsize", 0.002).asDouble(); + h0 = h; + pd_initialized = true; + } + + if (control_stepsize) { + + ftype total_step = 0.0, scale = 1.0; + + if (h < 1e-6) { + h = h0; + } + + h = std::min(h, dt); + + while (total_step < dt) { + ftype err = PrinceDormandStep(gyro0 + slope_gyro_ * total_step, + accel0 + slope_accel_ * total_step, h); + total_step += h; + if (err == 0.0) { + scale = max_scale_factor; + } else { + scale = 0.8 * sqrt(sqrt(tolerance * h / err)); + scale = std::min(std::max(scale, min_scale_factor), + max_scale_factor); // clipping + } + std::cout << "err=" << err << " ;h=" << h << " ;s=" << scale << std::endl; + + h *= scale; + if (total_step < dt) { + if (total_step + h > dt) { + h = dt - total_step; + } else if (total_step + h + 0.5 * h > dt) { + h = 0.5 * h; + } + } + } + } else { + // constant h0 + if (h0 < 0) { + PrinceDormandStep(gyro0, accel0, dt); + } else { + ftype total_step = 0; + + Vec3 gyro{gyro0}, accel{accel0}; + while (total_step < dt) { + ftype h = h0; // this shadows the static variable h + if (total_step + h > dt) { + h = dt - total_step; + } else if (total_step + h + 0.5 * h > dt) { + // half step trick + h = 0.5 * h; + } + PrinceDormandStep(gyro, accel, h); + gyro += slope_gyro_ * h; + accel += slope_accel_ * h; + total_step += h; + } + } + } +} + +ftype Estimator::PrinceDormandStep(const Vec3 &gyro0, const Vec3 &accel0, + ftype dt) { + static const ftype r_9 = 1.0 / 9.0; + static const ftype r_2_9 = 2.0 / 9.0; + static const ftype r_12 = 1.0 / 12.0; + static const ftype r_324 = 1.0 / 324.0; + static const ftype r_330 = 1.0 / 330.0; + static const ftype r_28 = 1.0 / 28.0; + static const ftype r_400 = 1.0 / 400.0; + + static State X0; + static Vec3 K1, K2, K3, K4, K5, K6, K7; + static MatX FK1, FK2, FK3, FK4, FK5, FK6, FK7; + static MatX PK1, PK2, PK3, PK4, PK5, PK6, PK7; + + ftype step; + Eigen::Matrix slope; + slope << slope_gyro_, slope_accel_; + Eigen::Matrix gyro_accel0, gyro_accel; + gyro_accel0 << gyro0, accel0; + + X0 = X_; + K1 = X0.Vsb; + ComputeMotionJacobianAt(X0, gyro_accel0); + FK1 = F_; + MatX P0 = P_.block(0, 0); + PK1 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + step = r_2_9 * dt; + gyro_accel = gyro_accel0 + slope * step; + ComposeMotion(X0, r_2_9 * (K1), gyro_accel, step); + ComputeMotionJacobianAt(X0, gyro_accel); + K2 = X0.Vsb; + FK2 = F_ + F_ * r_2_9 * (FK1)*dt; + P0 = P_.block(0, 0) + r_2_9 * (PK1)*dt; + PK2 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + step = 3.0 * r_9 * dt; + gyro_accel = gyro_accel0 + slope * step; + ComposeMotion(X0, r_12 * (K1 + 3.0 * K2), gyro_accel, step); + ComputeMotionJacobianAt(X0, gyro_accel); + K3 = X0.Vsb; + FK3 = F_ + F_ * r_12 * (FK1 + 3.0 * FK2) * dt; + P0 = P_.block(0, 0) + r_12 * (PK1 + 3.0 * PK2) * dt; + PK3 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + step = 5.0 * r_9 * dt; + gyro_accel = gyro_accel0 + slope * step; + ComposeMotion(X0, r_324 * (55.0 * K1 - 75.0 * K2 + 200.0 * K3), gyro_accel, + step); + ComputeMotionJacobianAt(X0, gyro_accel); + K4 = X0.Vsb; + FK4 = F_ + F_ * r_324 * (55.0 * FK1 - 75.0 * FK2 + 200.0 * FK3) * dt; + P0 = P_.block(0, 0) + + r_324 * (55.0 * PK1 - 75.0 * PK2 + 200.0 * PK3) * dt; + PK4 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + step = 6.0 * r_9 * dt; + gyro_accel = gyro_accel0 + slope * step; + ComposeMotion(X0, r_330 * (83.0 * K1 - 195.0 * K2 + 305.0 * K3 + 27.0 * K4), + gyro_accel, step); + ComputeMotionJacobianAt(X0, gyro_accel); + K5 = X0.Vsb; + FK5 = F_ + + F_ * r_330 * (83.0 * FK1 - 195.0 * FK2 + 305.0 * FK3 + 27.0 * FK4) * dt; + P0 = P_.block(0, 0) + + r_330 * (83.0 * PK1 - 195.0 * PK2 + 305.0 * PK3 + 27.0 * PK4) * dt; + PK5 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + step = dt; + gyro_accel = gyro_accel0 + slope * step; + ComposeMotion( + X0, r_28 * (-19.0 * K1 + 63.0 * K2 + 4.0 * K3 - 108.0 * K4 + 88.0 * K5), + gyro_accel, step); + ComputeMotionJacobianAt(X0, gyro_accel); + K6 = X0.Vsb; + FK6 = F_ + + F_ * r_28 * + (-19.0 * FK1 + 63.0 * FK2 + 4.0 * FK3 - 108.0 * FK4 + 88.0 * FK5) * + dt; + P0 = P_.block(0, 0) + + r_28 * + (-19.0 * PK1 + 63.0 * PK2 + 4.0 * PK3 - 108.0 * PK4 + 88.0 * PK5) * + dt; + PK6 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + step = dt; + gyro_accel = gyro_accel0 + slope * step; + ComposeMotion(X0, r_400 * (38.0 * K1 + 240.0 * K3 - 243.0 * K4 + 330.0 * K5 + + 35.0 * K6), + gyro_accel, step); + ComputeMotionJacobianAt(X0, gyro_accel); + K7 = X0.Vsb; + FK7 = F_ + + F_ * r_400 * (38.0 * FK1 + 240.0 * FK3 - 243.0 * FK4 + 330.0 * FK5 + + 35.0 * FK6) * + dt; + P0 = P_.block(0, 0) + + r_400 * + (38.0 * PK1 + 240.0 * PK3 - 243.0 * PK4 + 330.0 * PK5 + 35.0 * PK6) * + dt; + PK7 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + static MatX K, FK, PK; + K = 0.0862 * K1 + 0.6660 * K3 - 0.7857 * K4 + 0.9570 * K5 + 0.0965 * K6 - + 0.0200 * K7; + FK = 0.0862 * FK1 + 0.6660 * FK3 - 0.7857 * FK4 + 0.9570 * FK5 + + 0.0965 * FK6 - 0.0200 * FK7; + PK = 0.0862 * PK1 + 0.6660 * PK3 - 0.7857 * PK4 + 0.9570 * PK5 + + 0.0965 * PK6 - 0.0200 * PK7; + + // apply the aggregated difference to state + gyro_accel = gyro_accel0 + slope * dt; + ComposeMotion(X_, K, gyro_accel, dt); + + F_.setIdentity(); + F_ = F_ + FK * dt; + + P_.block(0, 0) = + P_.block(0, 0) + PK * dt; + // update the correlation between motion and structure state + P_.block(0, kMotionSize) = + F_ * P_.block(0, kMotionSize); + P_.block(kMotionSize, 0) = + P_.block(kMotionSize, 0) * + F_.transpose(); + + static MatX diffK; + diffK = 0.0002 * (44.0 * K1 - 330.0 * K3 + 891.0 * K4 - 660.0 * K5 - + 45.0 * K6 + 100.0 * K7); + return std::max(fabs(diffK.minCoeff()), fabs(diffK.maxCoeff())); +} +} diff --git a/src/project.h b/src/project.h new file mode 100644 index 00000000..65de8f21 --- /dev/null +++ b/src/project.h @@ -0,0 +1,95 @@ +// Project and Unproject functions. +// +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once + +#include "Eigen/Core" + +namespace feh { +// perspective projection +// Xc=[x, y, z] +// returns xc=[x/z, y/z] +template +Eigen::Matrix +project(const Eigen::MatrixBase &Xc, + Eigen::Matrix *dxc_dXc = nullptr) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + + Eigen::Matrix xc; + xc << Xc.template head<2>() / Xc(2); + if (dxc_dXc) { + *dxc_dXc << 1 / Xc(2), 0, -Xc(0) / (Xc(2) * Xc(2)), 0, 1 / Xc(2), + -Xc(1) / (Xc(2) * Xc(2)); + } + return xc; +} + +// perspective projection with inverse depth appended +// Xc=[x, y, z] +// returns xc=[x/z, y/z, 1/z] +template +Eigen::Matrix +project_invz(const Eigen::MatrixBase &Xc, + Eigen::Matrix *dxc_dXc = nullptr) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + + Eigen::Matrix xc; + xc << Xc(0) / Xc(2), Xc(1) / Xc(2), 1.0 / Xc(2); + if (dxc_dXc) { + *dxc_dXc << 1 / Xc(2), 0, -Xc(0) / (Xc(2) * Xc(2)), 0, 1 / Xc(2), + -Xc(1) / (Xc(2) * Xc(2)), 0, 0, -1 / (Xc(2) * Xc(2)); + } + return xc; +} + +// un-projection with inverse depth appended +// Input: xc=[x, y, rho] where rho = 1/z +// returns Xc=[x/rho, y/rho, 1/rho] +// Note: this is exactly the same function form of project_invz. +template +Eigen::Matrix unproject_invz( + const Eigen::MatrixBase &xc, + Eigen::Matrix *dXc_dxc = nullptr) { + return project_invz(xc, dXc_dxc); +} + +// perspective projection with log depth appended +// Xc=[x, y, z] +// returns xc=[x/z, y/z, log(z)] +template +Eigen::Matrix +project_logz(const Eigen::MatrixBase &Xc, + Eigen::Matrix *dxc_dXc = nullptr) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + + Eigen::Matrix xc; + xc << Xc(0) / Xc(2), Xc(1) / Xc(2), log(Xc(2)); + if (dxc_dXc) { + *dxc_dXc << 1 / Xc(2), 0, -Xc(0) / (Xc(2) * Xc(2)), 0, 1 / Xc(2), + -Xc(1) / (Xc(2) * Xc(2)), 0, 0, 1 / Xc(2); + } + return xc; +} + +// un-projection with log depth appended +// xc=[x, y, rho=log(z)] +// returns xc=[x*exp(rho), y*exp(rho), exp(rho)] +template +Eigen::Matrix unproject_logz( + const Eigen::MatrixBase &xc, + Eigen::Matrix *dXc_dxc = nullptr) { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 1); + + using f_t = typename Derived::Scalar; + f_t z = exp(xc(2)); + + Eigen::Matrix Xc; + Xc << xc(0) * z, xc(1) * z, z; + + if (dXc_dxc) { + *dXc_dxc << z, 0, xc(0) * z, 0, z, xc(1) * z, 0, 0, z; + } + return Xc; +} + +} // namespace feh diff --git a/src/publisher.cpp b/src/publisher.cpp new file mode 100644 index 00000000..30106513 --- /dev/null +++ b/src/publisher.cpp @@ -0,0 +1,34 @@ +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#include "publisher.h" + +namespace feh { + +void ViewPublisher::Publish(const timestamp_t &ts, const cv::Mat &image) { + Enqueue(std::move(std::make_unique(ts, image))); +} + +void ViewPublisher::Publish(const timestamp_t &ts, const SE3 &gsb, + const SE3 &gbc) { + Enqueue(std::move(std::make_unique(ts, gsb, gbc))); +} + +/* +void ViewPublisher::Spin(int seconds) { + int refresh_rate = 30; // milliseconds + // if seconds < 0, spin forever + for (int i = 0; i < seconds * 1000 / refresh_rate; i += (seconds < 0 ? 0 : 1)) +{ + Refresh(); + usleep(refresh_rate); + } +} +*/ + +bool ViewPublisher::Handle(ViewMessage *message) { + if (Process::Handle(message)) + return true; + message->Execute(&viewer_); + return true; +} + +} // namespace feh diff --git a/src/publisher.h b/src/publisher.h new file mode 100644 index 00000000..d49b7a80 --- /dev/null +++ b/src/publisher.h @@ -0,0 +1,62 @@ +// A wrapper of the viewer class to support threading. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include "estimator_process.h" +#include "viewer.h" + +namespace feh { + +class ViewMessage { +public: + ViewMessage(const timestamp_t &ts) : ts_{ts} {} + virtual void Execute(Viewer *) = 0; + virtual ~ViewMessage() = default; + +protected: + timestamp_t ts_; +}; + +class ViewDisplayMessage : public ViewMessage { +public: + ViewDisplayMessage(const timestamp_t &ts, const cv::Mat &image) + : ViewMessage{ts}, image_{image.clone()} {} + void Execute(Viewer *viewer) override { + if (!image_.empty()) { + viewer->Update(image_); + viewer->Refresh(); + } + } + +private: + cv::Mat image_; +}; + +class ViewPoseMessage : public ViewMessage { +public: + ViewPoseMessage(const timestamp_t &ts, const SE3 &gsb, const SE3 &gbc) + : ViewMessage{ts}, gsb_{gsb}, gbc_{gbc} {} + + void Execute(Viewer *viewer) override { + viewer->Update_gsb(gsb_); + viewer->Update_gsc(gsb_ * gbc_); + } + +private: + SE3 gsb_, gbc_; +}; + +class ViewPublisher : public Publisher, public Process { +public: + ViewPublisher(const Json::Value &cfg, const std::string &name = "", + uint32_t size = 1000) + : Process{size}, viewer_{cfg, name} {} + virtual void Publish(const timestamp_t &ts, const cv::Mat &image) override; + virtual void Publish(const timestamp_t &ts, const SE3 &gsb, + const SE3 &gbc) override; + // void Spin(int seconds=0); + +private: + virtual bool Handle(ViewMessage *message) override; + Viewer viewer_; +}; +} // namespace feh diff --git a/src/rk4.cpp b/src/rk4.cpp new file mode 100644 index 00000000..eed7f13f --- /dev/null +++ b/src/rk4.cpp @@ -0,0 +1,105 @@ +#include "estimator.h" + +namespace feh { + +void Estimator::RK4(const Vec3 &gyro0, const Vec3 &accel0, ftype dt) { + static bool rk4_initialized{false}; + static ftype stepsize{-1}; + if (!rk4_initialized) { + stepsize = cfg_["RK4"].get("stepsize", 0.002).asDouble(); + rk4_initialized = true; + } + + if (stepsize < 0) { + RK4Step(gyro0, accel0, dt); + } else { + ftype total_step = 0; + + Vec3 gyro{gyro0}, accel{accel0}; + while (total_step < dt) { + ftype h = stepsize; + if (total_step + h > dt) { + h = dt - total_step; + } else if (total_step + h + 0.5 * h > dt) { + // half step trick + h = 0.5 * h; + } + RK4Step(gyro, accel, h); + gyro += slope_gyro_ * h; + accel += slope_accel_ * h; + total_step += h; + } + } +} + +void Estimator::RK4Step(const Vec3 &gyro0, const Vec3 &accel0, ftype dt) { + ftype halfstep = 0.5 * dt; + + static State X0; + static Vec3 K1, K2, K3, K4; + static MatX FK1, FK2, FK3, FK4; + static MatX PK1, PK2, PK3, PK4; + + Eigen::Matrix slope; + slope << slope_gyro_, slope_accel_; + Eigen::Matrix gyro_accel, gyro_accel0; + gyro_accel0 << gyro0, accel0; + + X0 = X_; + // uncomment the following to use non-standard RK4? + // ComposeMotion(X0, X0.Vsb, gyro_accel0, dt); + K1 = X0.Vsb; + ComputeMotionJacobianAt(X0, gyro_accel0); + FK1 = F_; + MatX P0 = P_.block(0, 0); + PK1 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + gyro_accel = gyro_accel0 + halfstep * slope; + ComposeMotion(X0, 0.5 * K1, gyro_accel, halfstep); + K2 = X0.Vsb; + ComputeMotionJacobianAt(X0, gyro_accel); + FK2 = F_ + F_ * FK1 * halfstep; + P0 = P_.block(0, 0) + halfstep * PK1; + PK2 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + gyro_accel = gyro_accel0 + halfstep * slope; + ComposeMotion(X0, 0.5 * K2, gyro_accel, halfstep); + K3 = X0.Vsb; + ComputeMotionJacobianAt(X0, gyro_accel); + FK3 = F_ + F_ * FK2 * halfstep; + P0 = P_.block(0, 0) + halfstep * PK2; + PK3 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + X0 = X_; + gyro_accel = gyro_accel0 + halfstep * slope; + ComposeMotion(X0, K3, gyro_accel, dt); + K4 = X0.Vsb; + ComputeMotionJacobianAt(X0, gyro_accel); + FK4 = F_ + F_ * FK3 * dt; + P0 = P_.block(0, 0) + dt * PK3; + PK4 = F_ * P0 + P0 * F_.transpose() + G_ * Qimu_ * G_.transpose(); + + auto Ktot{(K1 + 2.0 * (K2 + K3) + K4) / 6.0}; + auto FK{(FK1 + 2.0 * (FK2 + FK3) + FK4) / 6.0}; + auto PK{(PK1 + 2.0 * (PK2 + PK3) + PK4) / 6.0}; + + // apply the aggregated difference to state + gyro_accel = gyro_accel0 + dt * slope; + ComposeMotion(X_, Ktot, gyro_accel, dt); + + F_.setIdentity(); + F_ = F_ + FK * dt; + + P_.block(0, 0) = + P_.block(0, 0) + PK * dt; + // update the correlation between motion and structure state + P_.block(0, kMotionSize) = + F_ * P_.block(0, kMotionSize); + P_.block(kMotionSize, 0) = + P_.block(kMotionSize, 0) * + F_.transpose(); +} + +} // namespace feh diff --git a/src/simulator.cpp b/src/simulator.cpp new file mode 100644 index 00000000..d2d41982 --- /dev/null +++ b/src/simulator.cpp @@ -0,0 +1,398 @@ + +#include +#include +#include +#include +#include + +#include "glog/logging.h" +#include "opencv2/imgproc/imgproc.hpp" + +#include "simulator.h" +#include "visualize.h" + +namespace feh { + +Simulator::Simulator(const std::string &cfg_path) { + LOG(INFO) << "Initializing simulator... " << std::endl; + cfg_ = LoadJson(cfg_path); + total_time_ = cfg_["total_time"].asDouble(); // seconds + imu_hz_ = cfg_["imu_hz"].asDouble(); + cam_hz_ = cfg_["camera_hz"].asDouble(); + total_count_ = static_cast(ceil(imu_hz_ * total_time_)); + counter_ = 0; + curr_sim_time_ = 0; + frame_counter_ = 0; + motion_type_ = 0; // easiest motion type + init_period_ = cfg_["init_static_period"].asDouble(); + + num_pts_to_track_ = cfg_["num_pts_to_track"].asUInt(); + min_num_pts_to_track_ = + cfg_["min_num_pts_to_track"].asUInt(); // when number of tracks is below + // this threshold, add more tracks + + // Measurement Noises + gyro_noise_std_ = cfg_["gyro_noise_std"].asDouble(); + accel_noise_std_ = cfg_["accel_noise_std"].asDouble(); + tracking_noise_std_ = cfg_["tracking_noise_std"].asDouble(); + max_track_lifetime_ = cfg_["max_track_lifetime"].asInt(); + + // camera sampling rate + cam_sample_rate_ = imu_hz_ / cam_hz_; + + // State generation noises + // model_noise_da_ = 0.005; // for motion_type ? + // model_noise_dw_ = 0.005; + + // initialize camera model + auto cam_cfg = cfg_["camera_cfg"].isString() + ? LoadJson(cfg_["camera_cfg"].asString()) + : cfg_["camera_cfg"]; + cam_ = new Camera(cam_cfg); + LOG(INFO) << "camera initialized" << std::endl; + + mask_ = cv::Mat(cam_->rows(), cam_->cols(), CV_8UC1); + z_near_ = cfg_.get("z_nar", 0.05).asDouble(); + z_far_ = cfg_.get("z_far", 10.0).asDouble(); + + z_dist_ = std::uniform_real_distribution(z_near_, z_far_); + x_dist_ = std::uniform_real_distribution(0, cam_->cols()); + y_dist_ = std::uniform_real_distribution(0, cam_->rows()); + + drop_prob_ = cfg_["track_drop_probability"].asDouble(); + mask_size_ = cfg_["mask_size"].asDouble() / 2.0; + motion_type_ = cfg_["motion_type"].asInt(); + delay_camera_time_ = cfg_["delay_camera_time"].asDouble(); + + // measurement noise distributions + if (!cfg_["fixed_seed"].asBool()) { + long seed = std::chrono::system_clock::now().time_since_epoch().count(); + LOG(INFO) << "\nseed=" << seed << std::endl; + gen_ = std::shared_ptr(new std::knuth_b(seed)); + } else { + long seed = cfg_["seed"].asInt64(); + LOG(INFO) << "\nuse saved seed=" << seed << std::endl; + gen_ = std::shared_ptr(new std::knuth_b(seed)); + } + + // Construct simulated trajectories + translations_.clear(); + velocities_.clear(); + accelerations_.clear(); + GenerateTrajectory(); + + // Initialize simulated state + auto X = cfg_["X"]; + X_.Rsb = SO3::exp(GetVectorFromJson(X, "W")); + X_.Tsb = GetVectorFromJson(X, "T"); + X_.Vsb = GetVectorFromJson(X, "V"); + X_.bg = GetVectorFromJson(X, "bg"); + X_.ba = GetVectorFromJson(X, "ba"); + X_.Rbc = SO3::exp(GetVectorFromJson(X, "Wbc")); + X_.Tbc = GetVectorFromJson(X, "Tbc"); + Vec3 Wg; + Wg.head<2>() = GetVectorFromJson(X, "Wg"); + X_.Rg = SO3::exp(Wg); + + // Initialize grav Vector WARNING: Make sure filter has the same one + g_ << 0, 0, -9.8; + // Initialize imu calibration + Cas_.setIdentity(); + Car_.setIdentity(); + Cgs_.setIdentity(); + Cgr_.setIdentity(); + LOG(INFO) << "Simulator initialized"; +} + +bool Simulator::GetMeas(msg::IMU &imu_msg, msg::Track &track_msg) { + ftype dt = 1.0 / imu_hz_; + imu_msg.ts_ = curr_sim_time_; + + // both accel and gyro below are measured in spatial frame + Vec3 accel = accelerations_[counter_]; + Vec3 gyro = rotational_velocities_[counter_]; + SO3 Rsb = X_.Rsb; + + // fix the the gravity mis-alignment (not really used here, since Rg=I) + // and transfer to body frame + SO3 Rg; + accel = Rsb.inv() * (accel - X_.Rg * g_); // in body frame + + accel += X_.ba; + imu_msg.accel_ = accel; + gyro += X_.bg; + imu_msg.gyro_ = gyro; + + // Propagate the true state + Vec3 gyro_calib = Cgr_ * Cgs_ * (gyro - X_.bg); + Vec3 accel_calib = Car_ * Cas_ * (accel - X_.ba); + X_.Rsb = Rsb * SO3::exp(gyro_calib * dt); + X_.Tsb += X_.Vsb * dt; + X_.Vsb += (Rsb * accel_calib + X_.Rg * g_) * dt; + + // Add measurement noise + imu_msg.accel_ += RandomVector<3>(0, accel_noise_std_, gen_); + imu_msg.gyro_ += RandomVector<3>(0, gyro_noise_std_, gen_); + imu_msg.initialized_ = true; + + // Generate visual measurement + if (counter_ % cam_sample_rate_ == 0) { + // Pull out the measurement for pose + + const auto &Rsb = X_.Rsb; + const auto &Rbc = X_.Rbc; + + const auto &Tsb = X_.Tsb; + const auto &Vsb = X_.Vsb; + const auto &Tbc = X_.Tbc; + + // camera to spatial frame transformation + SO3 Rsc = Rsb * Rbc; + Vec3 Tsc = Rsb * Tbc + Tsb; + + SO3 Rcs = Rsc.inv(); + Vec3 Tcs = -(Rcs * Tsc); + + // generate random points in camera frame (always in the front of the + // camera) + // and bring them to the spatial frame + + // remove invalid tracks + auto it = std::remove_if(pts_.begin(), pts_.end(), [](FeaturePtr f) { + return f->status_ == FeatureStatus::REJECTED_BY_TRACKER || + f->status_ == FeatureStatus::REJECTED_BY_FILTER || + f->status_ == FeatureStatus::DROPPED; + }); + pts_.erase(it, pts_.end()); + + // clear mask + mask_.setTo(cv::Scalar(1)); + std::vector pts(pts_.begin(), pts_.end()); + std::sort(pts.begin(), pts.end(), [](FeaturePtr f1, FeaturePtr f2) -> bool { + return f1->score_ > f2->score_; + }); + pts_.resize(pts.size()); + std::copy(pts.begin(), pts.end(), pts_.begin()); + + // "track" the features + uint32_t valid_tracks = 0; + int total_drop = 0; + for (auto f : pts_) { + Vec3 Xs = f->sim_.Xs; + Vec3 Xc = Rcs * Xs + Tcs; + if (Xc(2) <= z_near_ || Xc(2) > z_far_) { + f->track_.status_ = TrackStatus::REJECTED; + continue; + } + Vec2 xc = Xc.head<2>() / Xc(2); + + Vec2 xp = cam_->Project(xc); + xp += RandomVector<2>(0.0, tracking_noise_std_, gen_); + bool track_ok(true); + + if (OutOfView(xp, *cam_)) { + f->track_.status_ = TrackStatus::DROPPED; + track_ok = false; + ++total_drop; + } else { + if (std::uniform_real_distribution(0, 1)(*gen_) < drop_prob_) { + f->track_.status_ = TrackStatus::DROPPED; + track_ok = false; + ++total_drop; + } else if (f->track_.size() > f->sim_.lifetime) { + // drop tracks exceeding max lifetime with high probability + f->track_.status_ = TrackStatus::DROPPED; + track_ok = false; + ++total_drop; + } + } + + if (track_ok) { + if (!mask_.at(int(xp(1)), int(xp(0)))) { + f->track_.status_ = TrackStatus::REJECTED; + track_ok = false; + } else { + auto x(xp(0)), y(xp(1)); + cv::rectangle(mask_, cv::Point2d(x - mask_size_, y - mask_size_), + cv::Point2d(x + mask_size_, y + mask_size_), + cv::Scalar(0), -1); + } + + ++valid_tracks; + f->UpdateTrack(xp); + f->track_.status_ = TrackStatus::TRACKED; + } + } + VLOG(0) << "Total drop=" << total_drop << std::endl; + // only add more tracks when number of valid tracks is below a threshold + for (; valid_tracks < min_num_pts_to_track_; ++valid_tracks) { + ftype z = z_dist_(*gen_); + Vec2 xp(x_dist_(*gen_), y_dist_(*gen_)); + while (OutOfView(xp, *cam_) || !mask_.at((int)xp[1], (int)xp[0])) { + xp << x_dist_(*gen_), y_dist_(*gen_); + } + // mask out the occupied region + auto x(xp(0)), y(xp(1)); + cv::rectangle(mask_, cv::Point2d(x - mask_size_, y - mask_size_), + cv::Point2d(x + mask_size_, y + mask_size_), cv::Scalar(0), + -1); + Vec2 xc = cam_->UnProject(xp); + auto xp_meas = xp + RandomVector<2>(0.0, tracking_noise_std_, gen_); + + FeaturePtr f = std::make_shared(xp_meas(0), xp_meas(1)); + Vec3 Xs = Rsc * Vec3{xc(0) * z, xc(1) * z, z} + Tsc; + // set ground truth + f->sim_.Xs = Xs; + f->sim_.xp = xp; + f->sim_.xc = xc; + f->sim_.z = z; + f->sim_.lifetime = + std::uniform_int_distribution(2, max_track_lifetime_)(*gen_); + + // simulate score of a feature detector + f->score_ = std::uniform_real_distribution(0, 1)(*gen_); + + pts_.emplace_back(f); + } + + track_msg.features_.resize(pts_.size()); + std::copy(pts_.begin(), pts_.end(), track_msg.features_.begin()); + track_msg.initialized_ = true; + track_msg.ts_ = imu_msg.ts_; + + LOG(INFO) << "simulated features: " << pts_.size(); + + // debug + int mean_track_lifetime = + std::accumulate(pts_.begin(), pts_.end(), 0, [](int x, FeaturePtr f) { + return x + f->track_.size(); + }); + mean_track_lifetime /= pts_.size(); + LOG(INFO) << "mean track life=" << mean_track_lifetime; + } + + ++counter_; + curr_sim_time_ += dt; + return counter_ < total_count_; +} + +SO3 fixor(const Vec3 &A, const Vec3 &B) { + Vec3 x(1, 0, 0); + Vec3 y = A - B; + Vec3 z = y / y.norm(); + + y = z.cross(x); + y /= y.norm(); + // now y is a unit vector perpendicular to x-z plane + x = y.cross(z); + x /= x.norm(); + // now x is a unit vector perpendicular to y-z plane + + // overall, direction of z is fixed to (B->A) + // and the other directions are constructed properly + Mat3 R; + R.setZero(); + R.block<3, 1>(0, 0) = x; + R.block<3, 1>(0, 1) = y; + R.block<3, 1>(0, 2) = z; + return SO3{R}; +} + +void Simulator::GenerateTrajectory() { + LOG(INFO) << "Generating simulated trajectory type " << motion_type_ + << std::endl; + ftype delta_t = 1.0 / imu_hz_; // TODO: make clock for sim work with differing + // rates of imu and cam + ftype time = 0; + + // parameters controling the synthetic data + Vec3 rate, mult; + + // random frequencies and multipliers + rate = RandomVector<3>(0., 1., gen_); + mult = RandomVector<3>(0., 1., gen_); + + // saved set + rate << 15, 30, 15; + rate /= 180.0; + mult << 2, 3, 4; + Vec3 init_slope(mult / (init_period_ * init_period_)); + + // generate the trajectory + for (int i = 0; i < total_count_ + 2; ++i) { + ftype u = time * time / (init_period_ + time); + // ftype u = time * std::sqrt(time) / (10 + time); + // ftype u = time; + Vec3 radius(mult); + if (time < init_period_) { + radius -= init_slope * (time - init_period_) * (time - init_period_); + } + if (motion_type_ == 0) { + translations_.emplace_back(radius[0] * std::cos((M_PI * rate[0] * u)) * + std::sin((M_PI * rate[0]) * u), + radius[1] * std::cos((M_PI * rate[1] * u)) * + std::cos((M_PI * rate[1]) * u), + radius[2] * std::sin((M_PI * rate[2]) * u)); + } else if (motion_type_ == 1) { + translations_.emplace_back(radius[0] * std::sin((M_PI * rate[0]) * u), + radius[1] * std::sin((M_PI * rate[1]) * u), + radius[2] * std::cos((M_PI * rate[2]) * u)); + } else if (motion_type_ == 2) { + // most challenging + translations_.emplace_back(radius[0] * std::sin((M_PI * rate[0]) * u), + radius[1] * std::sin((M_PI * rate[1]) * u), + radius[2] * + (1 - std::cos((M_PI * rate[2]) * u))); + } else if (motion_type_ == 3) { + translations_.emplace_back(5 * std::cos(M_PI * rate[0] * u), + 5 * std::sin(M_PI * rate[1] * u), 0); + } else if (motion_type_ == 4) { + // stationary + translations_.emplace_back(0, 0, 0); + } else { + LOG(FATAL) << "only motion type 0, 1, 2, 3 are supported"; + } + time += delta_t; + } + LOG(INFO) << "translation generated"; + + // differentiate + for (int i = 1; i < total_count_ + 2; ++i) + velocities_.emplace_back((translations_[i] - translations_[i - 1]) / + delta_t); + LOG(INFO) << "velocity generated"; + + for (int i = 1; i < total_count_ + 1; ++i) + accelerations_.emplace_back((velocities_[i] - velocities_[i - 1]) / + delta_t); + accelerations_.push_back(accelerations_[total_count_ - 1]); + LOG(INFO) << "acceleration generated"; + + Vec3 look_at; // point to look at + // look_at = RandomVector<3>(1, 2, gen_); + look_at = Vec3(0, 0, 5); + + // get rotational velocities + for (int i = 1; i < total_count_ + 2; ++i) { + SO3 Ra, Rb; + if (motion_type_ <= 2) { + Rb = fixor(translations_[i], look_at); + Ra = fixor(translations_[i - 1], look_at); + } else if (motion_type_ == 3) { + Rb = fixor(translations_[i], translations_[i] + Vec3(0, 0, 1.0)); + Ra = fixor(translations_[i - 1], translations_[i - 1] + Vec3(0, 0, 1.0)); + } else if (motion_type_ == 4) { + // do nothing + } + auto rot_vel = SO3::log(Ra.inv() * Rb) / delta_t; + rotational_velocities_.push_back(rot_vel); + } + LOG(INFO) << "orientation generated" << std::endl; +} + +cv::Mat Simulator::VisualizeTracks() { + cv::Mat disp(cam_->rows(), cam_->cols(), CV_8UC3); + disp.setTo(cv::Scalar(0, 0, 0)); + return feh::VisualizeTracks(disp, pts_); +} +} diff --git a/src/simulator.h b/src/simulator.h new file mode 100644 index 00000000..e60eb0aa --- /dev/null +++ b/src/simulator.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include +#include + +#include "core.h" +#include "estimator.h" +#include "feature.h" + +#undef SIMULATE_VISUAL_MEAS + +namespace feh { + +struct Simulator { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + Simulator(const std::string &cfg_path); + + /// \brief get and pass measurements to motion integtration of simulator + /// \param imu_dat: imu measurement with Gaussian noise + bool GetMeas(msg::IMU &imu_msg, msg::Track &track_msg); + /// \brief internal simulation generation functions + void GenerateTrajectory(); + cv::Mat VisualizeTracks(); + + Json::Value cfg_; + + //////////////////////////////////////////////////////////////////////////////// + // Clone the following to initialize estimator in simulation + //////////////////////////////////////////////////////////////////////////////// + State X_; + Eigen::Matrix err_; // error state + Mat3 Cas_, Car_; + Mat3 Cgs_, Cgr_; + Vec3 g_; + //////////////////////////////////////////////////////////////////////////////// + + std::list pts_; + Camera *cam_; + + cv::Mat mask_; + uint32_t num_pts_to_track_; + uint32_t min_num_pts_to_track_; // when number of tracks is below this + // threshold, add more tracks + ftype z_near_, z_far_; // near and far plane + std::uniform_real_distribution x_dist_, y_dist_, z_dist_; + + ftype drop_prob_; + ftype mask_size_; + int motion_type_; + ftype init_period_; + + // sampling rates and duration + int64_t total_time_, curr_sim_time_; // seconds + ftype imu_hz_, cam_hz_; + int counter_, total_count_, cam_sample_rate_; + int frame_counter_; + + ftype delay_camera_time_; + + // generation noises + ftype accel_noise_std_, gyro_noise_std_; + ftype tracking_noise_std_; + int max_track_lifetime_; + + ftype model_noise_da_, model_noise_dw_; + + // trajectory generation + std::vector translations_; + std::vector velocities_; + std::vector accelerations_; + std::vector rotational_velocities_; + + // measurement noise generators + std::shared_ptr gen_; +}; + +using SimulatorPtr = std::shared_ptr; + +} // feh diff --git a/src/test/test_estimator.cpp b/src/test/test_estimator.cpp new file mode 100644 index 00000000..8deb0b9d --- /dev/null +++ b/src/test/test_estimator.cpp @@ -0,0 +1,34 @@ +#include +#include "gtest/gtest.h" +#include "estimator.h" + +using namespace feh; + +class EstimatorTest: public ::testing::Test { +protected: + EstimatorTest() : est_(){ + est_ = std::make_shared(std::string{"../cfg/estimator.json"}); + } + std::shared_ptr est_; +}; + +TEST_F(EstimatorTest, Init) { + std::cout << est_->X_.Rsb.matrix() << std::endl; +} + +TEST_F(EstimatorTest, Inertial) { + for (int i = 0; i < 100; ++i) { + Vec3 static_acc = 0.1 * RandomVector<3>(); + static_acc += Vec3{0.0, 0.0, 9.8}; + ftype ts = i*0.01; + est_->InertialMeas(ts, static_acc, Vec3::Random()); + if (est_->gravity_initialized_) { + // std::cout << err_.segment<3>(Index::T).transpose() << std::endl; + ASSERT_EQ(est_->err_.head().norm(), 0) << "With no correction, error state should be zero"; + est_->vision_initialized_ = true; + est_->curr_time_ = ts*1.5; + } + + } +} + diff --git a/src/test/test_geometry.cpp b/src/test/test_geometry.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/test/test_givens.cpp b/src/test/test_givens.cpp new file mode 100644 index 00000000..bd1fac58 --- /dev/null +++ b/src/test/test_givens.cpp @@ -0,0 +1,26 @@ +#include +#include "helpers.h" + +using namespace feh; + +int main() { + int M = 4; + VecX r; + MatX Hf, Hx; + r = MatX::Random(2 * M, 1); + Hf = MatX::Random(2 * M, 3); + + Hx = MatX::Random(2 * M, 5); + + std::cout << r.transpose() << std::endl; + Givens(r, Hx, Hf); + std::cout << "===== After givens =====\n"; + std::cout << "r=\n"; + std::cout << r.transpose() << std::endl; + std::cout << "Hf=\n"; + std::cout << Hf << std::endl; + + std::cout << "Hx=\n"; + std::cout << Hx << std::endl; + +} diff --git a/src/test/test_matcher.cpp b/src/test/test_matcher.cpp new file mode 100644 index 00000000..6a61ccd7 --- /dev/null +++ b/src/test/test_matcher.cpp @@ -0,0 +1,48 @@ +#include "gtest/gtest.h" + +#include "opencv2/highgui/highgui.hpp" + +#include "visualize.h" +#include "matcher.h" +#include "tumvi.h" + +using namespace feh; + +static std::string dataroot = "/home/feixh/Data/tumvi/exported/euroc/512_16/"; + +class MatcherTest: public ::testing::Test { +}; + +TEST_F(MatcherTest, Init) +{ + Matcher matcher("../cfg/tracker.json"); +} + +TEST_F(MatcherTest, Detect) +{ + Matcher matcher("../cfg/tracker.json"); + + std::string dataset = dataroot + "/dataset-corridor1_512_16/mav0/"; + TUMVILoader loader(dataset+"/cam0/", dataset+"/imu0/"); + for (int i = 0; i < loader.size(); ++i) { + auto entry = loader.Get(i); + if (entry.type_ == msg::Generic::IMAGE) { + std::cout << entry.image_path_ << std::endl; + auto image = cv::imread(entry.image_path_); + cv::imshow("image", image); + + // overwrite + matcher.initialized_ = false; + matcher.features_.clear(); + + matcher.Update(image); + + auto disp = matcher.VisualizeTracks(); + cv::imshow("detect", disp); + + char ckey = cv::waitKey(0); + if (ckey == 'q') break; + } + } +} + diff --git a/src/test/test_qr.cpp b/src/test/test_qr.cpp new file mode 100644 index 00000000..25d92f0b --- /dev/null +++ b/src/test/test_qr.cpp @@ -0,0 +1,22 @@ +#include +#include "helpers.h" + +using namespace feh; + +int main() { + int N = 4; // state size + int M = 8; // measurement size + VecX r; + MatX Hf, Hx; + r = MatX::Random(M, 1); + Hx = MatX::Random(M, N); + + std::cout << "r=\n" << r.transpose() << std::endl; + std::cout << "Hx=\n" << Hx << std::endl; + int rows = QR(r, Hx); + std::cout << "===== After givens =====\n"; + std::cout << "r=\n"; + std::cout << r.head(rows).transpose() << std::endl; + std::cout << "TH=\n"; + std::cout << Hx.topRows(rows) << std::endl; +} diff --git a/src/test/test_simulator.cpp b/src/test/test_simulator.cpp new file mode 100644 index 00000000..7c8adaac --- /dev/null +++ b/src/test/test_simulator.cpp @@ -0,0 +1,33 @@ +#include +#include "gtest/gtest.h" +#include "simulator.h" + +using namespace feh; + +class SimulatorTest: public ::testing::Test { +protected: + SimulatorTest() : sim_(){ + sim_ = std::make_shared("../cfg/simulator.json"); + } + SimulatorPtr sim_; +}; + +TEST_F(SimulatorTest, Init) { + std::cout << sim_->X_.Rsb.matrix() << std::endl; +} + +// TEST_F(SimulatorTest, Traj) { +// for (auto p : sim_->translations_) { +// std::cout << p.transpose() << std::endl; +// } +// } + +TEST_F(SimulatorTest, Meas) { + msg::IMU imu_msg; + msg::Track track_msg; + while (sim_->GetMeas(imu_msg, track_msg)) { + std::cout << sim_->X_.Tsb.transpose() << std::endl; + } +} + + diff --git a/src/test/test_tracker.cpp b/src/test/test_tracker.cpp new file mode 100644 index 00000000..3e3b5f52 --- /dev/null +++ b/src/test/test_tracker.cpp @@ -0,0 +1,40 @@ +#include "gtest/gtest.h" + +#include "opencv2/highgui/highgui.hpp" + +#include "tracker.h" +#include "tumvi.h" + +using namespace feh; + +static std::string dataroot = "/home/feixh/Data/tumvi/exported/euroc/512_16/"; + +class TrackerTest: public ::testing::Test { +}; + +TEST_F(TrackerTest, Init) +{ + Tracker tracker(std::string{"../cfg/tracker.json"}); +} + +TEST_F(TrackerTest, Track) +{ + Tracker tracker(std::string{"../cfg/tracker.json"}); + + std::string dataset = dataroot + "/dataset-corridor1_512_16/mav0/"; + TUMVILoader loader(dataset+"/cam0/", dataset+"/imu0/"); + for (int i = 0; i < loader.size(); ++i) { + auto entry = loader.Get(i); + if (entry.type_ == msg::Generic::IMAGE) { + std::cout << entry.image_path_ << std::endl; + auto image = cv::imread(entry.image_path_); + cv::imshow("image", image); + + tracker.Update(image); + auto disp = tracker.VisualizeTracks(); + cv::imshow("track", disp); + char ckey = cv::waitKey(0); + if (ckey == 'q') break; + } + } +} diff --git a/src/test/test_tumvi.cpp b/src/test/test_tumvi.cpp new file mode 100644 index 00000000..e6487ebd --- /dev/null +++ b/src/test/test_tumvi.cpp @@ -0,0 +1,49 @@ +#include "tumvi.h" +#include "gtest/gtest.h" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/core/core.hpp" + +using namespace feh; + +static std::string tumvi_root = "/local2/Data/tumvi/exported/euroc/512_16/"; +static std::string euroc_root = "/local2/Data/EuRoC/ASL_format/"; + +class LoaderTest: public ::testing::Test { +}; + +TEST_F(LoaderTest, Init) +{ + std::string dataset = tumvi_root + "/dataset-room1_512_16/mav0/"; + TUMVILoader loader(dataset+"/cam0/", dataset+"/imu0/"); + ASSERT_GT(loader.size(), 0) << "Wrong dataset path?"; + std::cout << "#entries=" << loader.size() << std::endl; + for (int i = 0; i < loader.size(); ++i) { + auto entry = loader.Get(i); + std::cout << entry; + if (entry.type_ == msg::Generic::IMAGE) { + auto image = cv::imread(entry.image_path_); + cv::imshow("TUMVI", image); + char ckey = cv::waitKey(5); + if (ckey == 'q') break; + } + } + +} + +TEST_F(LoaderTest, EuRoC) +{ + std::string dataset = euroc_root + "/MH_01_easy/mav0/"; + EuRoCLoader loader(dataset+"/cam0/", dataset+"/imu0/"); + ASSERT_GT(loader.size(), 0) << "Wrong dataset path?"; + std::cout << "#entries=" << loader.size() << std::endl; + for (int i = 0; i < loader.size(); ++i) { + auto entry = loader.Get(i); + std::cout << entry; + if (entry.type_ == msg::Generic::IMAGE) { + auto image = cv::imread(entry.image_path_); + cv::imshow("EuRoC", image); + char ckey = cv::waitKey(5); + if (ckey == 'q') break; + } + } +} diff --git a/src/test/test_viewer.cpp b/src/test/test_viewer.cpp new file mode 100644 index 00000000..981c23bc --- /dev/null +++ b/src/test/test_viewer.cpp @@ -0,0 +1,34 @@ +#include "tumvi.h" +#include "viewer.h" +#include "gtest/gtest.h" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/core/core.hpp" + +using namespace feh; + +static std::string tumvi_root = "/local2/Data/tumvi/exported/euroc/512_16/"; + +class LoaderTest: public ::testing::Test { +}; + +TEST_F(LoaderTest, Init) +{ + std::string dataset = tumvi_root + "/dataset-room1_512_16/mav0/"; + TUMVILoader loader(dataset+"/cam0/", dataset+"/imu0/"); + ASSERT_GT(loader.size(), 0) << "Wrong dataset path?"; + std::cout << "#entries=" << loader.size() << std::endl; + Viewer viewer; + viewer.Initialize("cfg/viewer.json"); + + for (int i = 0; i < loader.size(); ++i) { + auto entry = loader.Get(i); + std::cout << entry; + if (entry.type_ == msg::Generic::IMAGE) { + auto image = cv::imread(entry.image_path_); + viewer.Update(image); + viewer.Refresh(); + } + } + +} + diff --git a/src/tracker.cpp b/src/tracker.cpp new file mode 100644 index 00000000..773214ec --- /dev/null +++ b/src/tracker.cpp @@ -0,0 +1,323 @@ +#include + +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" +#include "glog/logging.h" +#include "opencv2/video/video.hpp" +#include "opencv2/xfeatures2d.hpp" + +#include "feature.h" +#include "tracker.h" +#include "visualize.h" + +// FIXME: move to config + +namespace feh { + +std::unique_ptr Tracker::instance_ = nullptr; + +TrackerPtr Tracker::Create(const Json::Value &cfg) { + if (instance_ == nullptr) { + instance_ = std::unique_ptr(new Tracker(cfg)); + } else { + LOG(WARNING) << "tracker already created"; + } + return instance_.get(); +} + +Tracker::Tracker(const Json::Value &cfg) : cfg_{cfg} { + initialized_ = false; + mask_size_ = cfg_.get("mask_size", 15).asInt(); + margin_ = cfg_.get("margin", 16).asInt(); + num_features_min_ = cfg_.get("num_features_min", 120).asInt(); + num_features_max_ = cfg_.get("num_features_max", 150).asInt(); + max_pixel_displacement_ = cfg_.get("max_pixel_displacement", 64).asInt(); + + auto klt_cfg = cfg_["KLT"]; + win_size_ = klt_cfg.get("win_size", 15).asInt(); + max_level_ = klt_cfg.get("max_level", 4).asInt(); + max_iter_ = klt_cfg.get("max_iter", 15).asInt(); + eps_ = klt_cfg.get("eps", 0.01).asDouble(); + + // TODO (xfei): hardcoded detector type + std::string detector_type = cfg_.get("detector", "FAST").asString(); + LOG(INFO) << "detector type=" << detector_type; + auto detector_cfg = cfg_[detector_type]; + + if (detector_type == "FAST") { + detector_ = cv::FastFeatureDetector::create( + detector_cfg.get("threshold", 5).asInt(), + detector_cfg.get("nonmaxSuppression", true).asBool()); + } else if (detector_type == "BRISK") { + detector_ = + cv::BRISK::create(detector_cfg.get("thresh", 5).asInt(), + detector_cfg.get("octaves", 3).asInt(), + detector_cfg.get("patternScale", 1.0).asFloat()); + } else if (detector_type == "ORB") { + detector_ = cv::ORB::create(detector_cfg.get("nfeatures", 500).asInt(), + detector_cfg.get("scaleFactor", 1.2).asFloat(), + detector_cfg.get("nlevels", 4).asInt(), + detector_cfg.get("edgeThreshold", 31).asInt(), + detector_cfg.get("firstLevel", 0).asInt(), + detector_cfg.get("WTA_K", 2).asInt(), + detector_cfg.get("patchSize", 31).asInt(), + detector_cfg.get("fastThreshold", 20).asInt()); + } else if (detector_type == "AGAST") { + detector_ = cv::AgastFeatureDetector::create( + detector_cfg.get("threshold", 10).asInt(), + detector_cfg.get("nonmaxSuppression", true).asBool()); + } else if (detector_type == "GFTT") { + detector_ = cv::GFTTDetector::create( + detector_cfg.get("maxCorners", 1000).asInt(), + detector_cfg.get("qualityLevel", true).asDouble(), + detector_cfg.get("minDistance", 1.0).asDouble(), + detector_cfg.get("blockSize", 3).asInt(), + detector_cfg.get("useHarrisDetector", false).asBool(), + detector_cfg.get("k", 0.04).asDouble()); + } else { + throw std::invalid_argument("unrecognized detector type"); + } + LOG(INFO) << "detector created"; + + descriptor_distance_thresh_ = + cfg_.get("descriptor_distance_thresh", -1).asInt(); + extract_descriptor_ = cfg_.get("extract_descriptor", false).asBool() || + descriptor_distance_thresh_ > -1; + LOG(INFO) << "descriptor extraction " << extract_descriptor_ ? "ENABLED" + : "DISABLED"; + + if (extract_descriptor_) { + if (detector_type == "FAST" || detector_type == "AGAST" || + detector_type == "GFTT") { + LOG(WARNING) + << "detectors NOT able to extract descriptors; default to BRIEF"; + + auto default_descriptor = + cfg_.get("default_descriptor", "BRIEF").asString(); + auto desc_cfg = cfg_[default_descriptor]; + + if (default_descriptor == "BRIEF") { + extractor_ = cv::xfeatures2d::BriefDescriptorExtractor::create( + desc_cfg.get("bytes", 64).asInt(), + desc_cfg.get("use_orientation", false).asBool()); + } else if (default_descriptor == "FREAK") { + extractor_ = cv::xfeatures2d::FREAK::create( + desc_cfg.get("orientationNormalized", true).asBool(), + desc_cfg.get("scaleNormalized", true).asBool(), + desc_cfg.get("patternScale", 22.0).asDouble(), + desc_cfg.get("nOctaves", 4).asInt()); + } else { + throw std::invalid_argument("unrecognized descriptor type"); + } + + } else { + // detector is also the extractor + extractor_ = detector_; + } + } +} + +void Tracker::Detect(const cv::Mat &img, int num_to_add) { + std::vector kps; + detector_->detect(img, kps, mask_); + // sort + std::sort(kps.begin(), kps.end(), + [](const cv::KeyPoint &kp1, const cv::KeyPoint &kp2) { + return kp1.response > kp2.response; + }); + + cv::Mat descriptors; + if (extract_descriptor_) { + descriptors.reserveBuffer(kps.size() * 256); + extractor_->compute(img, kps, descriptors); + } + + // now every keypoint is equipped with a descriptor + + // collect keypoints + for (int i = 0; i < kps.size(); ++i) { + const cv::KeyPoint &kp = kps[i]; + if (MaskValid(mask_, kp.pt.x, kp.pt.y)) { + FeaturePtr f = Feature::Create(kp.pt.x, kp.pt.y); + features_.push_back(f); + + if (extract_descriptor_) { + f->SetDescriptor(descriptors.row(i)); + } + f->SetKeypoint(kp); + + // mask out + MaskOut(mask_, kp.pt.x, kp.pt.y, mask_size_); + --num_to_add; + } + if (num_to_add <= 0 || kp.response < 5) + break; + } +} + +void Tracker::Update(const cv::Mat &image) { + img_ = image.clone(); + if (cfg_.get("normalize", false).asBool()) { + cv::normalize(image, img_, 0, 255, cv::NORM_MINMAX); + } + + if (!initialized_) { + rows_ = img_.rows; + cols_ = img_.cols; + mask_ = cv::Mat(rows_, cols_, CV_8UC1); + mask_.setTo(0); + + // build image pyramid + cv::buildOpticalFlowPyramid(img_, pyramid_, cv::Size(win_size_, win_size_), + max_level_); + // setup the mask + ResetMask(mask_( + cv::Rect(margin_, margin_, cols_ - 2 * margin_, rows_ - 2 * margin_))); + // detect an initial set of features + Detect(img_, num_features_max_); + initialized_ = true; + // std::cout << "tracker initialized"; + return; + } + // reset mask + ResetMask(mask_( + cv::Rect(margin_, margin_, cols_ - 2 * margin_, rows_ - 2 * margin_))); + // std::cout << "reset mask\n"; + + // build new pyramid + std::vector pyramid; + cv::buildOpticalFlowPyramid(img_, pyramid, cv::Size(win_size_, win_size_), + max_level_); + + // prepare for optical flow + cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, + max_iter_, eps_); + + std::vector pts0, pts1; + std::vector status; + std::vector err; + + pts0.reserve(features_.size()); + pts1.reserve(pts0.size()); + + for (auto f : features_) { + const Vec2 &pt(f->xp()); + pts0.emplace_back(pt[0], pt[1]); + + // fill in predicted locations + auto pred = f->pred(); + if (pred(0) != -1 && pred(1) != -1) { + pts1.emplace_back(pred(0), pred(1)); + f->ResetPred(); // reset + } else { + pts1.emplace_back(pt[0], pt[1]); + } + } + + if (pts0.size() == 0) { + initialized_ = false; + return; + } + // cv::calcOpticalFlowPyrLK(pyramid_, pyramid, pts0, pts1, status, err, + // cv::Size(win_size_, win_size_), max_level_, + // criteria, + // cv::OPTFLOW_USE_INITIAL_FLOW | + // cv::OPTFLOW_LK_GET_MIN_EIGENVALS, + // 1e-4); + cv::calcOpticalFlowPyrLK(pyramid_, pyramid, pts0, pts1, status, err, + cv::Size(win_size_, win_size_), max_level_, criteria, + cv::OPTFLOW_USE_INITIAL_FLOW); + + std::vector kps; + cv::Mat descriptors; + if (extract_descriptor_) { + std::vector vf{features_.begin(), features_.end()}; + kps.reserve(vf.size()); + descriptors.reserveBuffer(vf.size() * 256); + for (int i = 0; i < vf.size(); ++i) { + auto f = vf[i]; + cv::KeyPoint kp = + f->keypoint(); // preserve all the properties of the initial keypoint + kp.pt.x = pts1[i].x; // with updated pixel location + kp.pt.y = pts1[i].y; + kp.class_id = i; + kps.push_back(kp); + } + extractor_->compute(img_, kps, descriptors); + + for (int i = 0; i < kps.size(); ++i) { + auto f = vf[kps[i].class_id]; + if (descriptor_distance_thresh_ != -1) { + int dist = + cv::norm(f->descriptor(), descriptors.row(i), cv::NORM_HAMMING); + if (dist > descriptor_distance_thresh_) { + status[i] = 0; // enforce to be dropped + } + } + // FIXME: so if the distance test fails, we probably do not want to update + // the descriptor + // set new descriptor + f->SetDescriptor(descriptors.row(i)); + } + } + + // iterate through features and mark bad ones + int num_valid_features = 0; + int i = 0; + + for (auto it = features_.begin(); it != features_.end(); ++it, ++i) { + FeaturePtr f(*it); + + Vec2 last_pos(f->xp()); + if (status[i]) { + if (MaskValid(mask_, pts1[i].x, pts1[i].y) && + (last_pos - Vec2{pts1[i].x, pts1[i].y}).norm() < + max_pixel_displacement_) { + // FIXME: SUPER HACK drop features to enforce update + // update track status + f->SetTrackStatus(TrackStatus::TRACKED); + f->UpdateTrack(pts1[i].x, pts1[i].y); + // MaskOut(mask_, last_pos(0), last_pos(1), mask_size_); + MaskOut(mask_, pts1[i].x, pts1[i].y, mask_size_); + ++num_valid_features; + } else { + // failed to extract descriptors or invalid mask + f->SetTrackStatus(TrackStatus::DROPPED); + // MaskOut(mask_, last_pos(0), last_pos(1), mask_size_); + } + } else { + // failed to track, reject + f->SetTrackStatus(TrackStatus::DROPPED); + // MaskOut(mask_, last_pos(0), last_pos(1), mask_size_); + } + } + + // detect a new set of features + if (num_valid_features < num_features_min_) { + Detect(img_, num_features_max_ - num_valid_features); + // TODO: rescue dropped featuers by matching them to newly detected ones + } + // swap buffers ... + std::swap(pyramid, pyramid_); +} + +//////////////////////////////////////// +// helpers +//////////////////////////////////////// +void ResetMask(cv::Mat mask) { mask.setTo(255); } + +void MaskOut(cv::Mat mask, ftype x, ftype y, int mask_size) { + static int half_size = (mask_size >> 1); + cv::rectangle(mask, cv::Point2d(x - half_size, y - half_size), + cv::Point2d(x + half_size, y + half_size), cv::Scalar(0), -1); +} + +bool MaskValid(const cv::Mat &mask, ftype x, ftype y) { + int col = static_cast(x); + int row = static_cast(y); + if (col < 0 || col >= mask.cols || row < 0 || row >= mask.rows) + return false; + return static_cast(mask.at(row, col)); +} + +} // namespace feh diff --git a/src/tracker.h b/src/tracker.h new file mode 100644 index 00000000..bb8b4165 --- /dev/null +++ b/src/tracker.h @@ -0,0 +1,74 @@ +// The feature tracking module; +// Multi-scale Lucas-Kanade tracker from OpenCV. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once + +#include +#include + +#include "opencv2/core/core.hpp" +#include "opencv2/features2d/features2d.hpp" +#include "json/json.h" + +#include "core.h" + +namespace feh { + +class Tracker { +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + static TrackerPtr Create(const Json::Value &cfg); + static TrackerPtr instance() { return instance_.get(); } + + void Update(const cv::Mat &img); + +public: + std::list features_; + +private: + Tracker(const Tracker &other) = delete; + Tracker &operator=(const Tracker &other) = delete; + + Tracker(const Json::Value &cfg); + static std::unique_ptr instance_; + + // variables + bool initialized_; + Json::Value cfg_; + int descriptor_distance_thresh_; // use this to verify feature tracking + int max_pixel_displacement_; // pixels shifted larger than this amount are + // dropped + + cv::Mat img_; + std::vector pyramid_; + int rows_, cols_; + + // for the geneirc feature2d interface, see the following openc document: + // https://docs.opencv.org/3.4/d0/d13/classcv_1_1Feature2D.html + cv::Ptr detector_, extractor_; + bool extract_descriptor_; + + cv::Mat mask_; + int mask_size_; + int margin_; + + // optical flow params + int win_size_; + int max_level_; + int max_iter_; + ftype eps_; + + // fast params + int num_features_min_; + int num_features_max_; + +private: + void Detect(const cv::Mat &img, int num_to_add); +}; + +// helpers +void ResetMask(cv::Mat mask); +void MaskOut(cv::Mat mask, ftype x, ftype y, int mask_size = 15); +bool MaskValid(const cv::Mat &mask, ftype x, ftype y); + +} // namespace feh diff --git a/src/tumvi.cpp b/src/tumvi.cpp new file mode 100644 index 00000000..7ad4d74a --- /dev/null +++ b/src/tumvi.cpp @@ -0,0 +1,121 @@ +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "absl/strings/str_split.h" +#include "glog/logging.h" + +#include "message_types.h" +#include "tumvi.h" + +namespace feh { + +TUMVILoader::TUMVILoader(const std::string &image_dir, + const std::string &imu_dir) { + + // load image data entries + std::string image_data = image_dir + "/data.csv"; + if (std::ifstream is{image_data}) { + std::string line; + std::getline(is, line); // get rid of the header + while (is >> line) { + if (line.front() != '#') { + std::vector content = absl::StrSplit(line, ','); + auto ts{timestamp_t(std::stoll(content[0]))}; + std::string image_path = image_dir + "/data/" + content[1]; + entries_.emplace_back(std::make_unique(ts, image_path)); + } + } + } else { + LOG(FATAL) << "failed to open image csv @ " << image_data; + } + + // load imu data + std::string imu_data = imu_dir + "/data.csv"; + if (std::ifstream is{imu_data}) { + std::string line; + std::getline(is, line); // get rid of the header + while (is >> line) { + if (line.front() != '#') { + std::vector content = absl::StrSplit(line, ','); + auto ts{timestamp_t(std::stoll(content[0]))}; + Vec3 gyro; + Vec3 accel; + for (int i = 0; i < 3; ++i) + gyro(i) = std::stod(content[i + 1]); + for (int i = 0; i < 3; ++i) + accel(i) = std::stod(content[i + 4]); + entries_.emplace_back(std::make_unique(ts, gyro, accel)); + } + } + } else { + LOG(FATAL) << "failed to open data.csv @ " << imu_data; + } + + // ascend timestamps + std::sort(entries_.begin(), entries_.end(), + [](const auto &e1, const auto &e2) { return e1->ts_ < e2->ts_; }); +} + +std::vector +TUMVILoader::LoadGroundTruthState(const std::string &state_dir) { + std::string state_data = state_dir + "/data.csv"; + if (std::ifstream is{state_data}) { + std::string line; + std::getline(is, line); // get rid of the header + while (is >> line) { + if (line.front() != '#') { + std::vector content = absl::StrSplit(line, ','); + auto ts{timestamp_t(std::stoull(content[0]))}; + // pose frame -> world frame + Vec3 T; + Vec4 Q; // qw, qx, qy, qz + // FIXME: load the full state -- for now only load translation and + // quaternion + for (int i = 0; i < 3; ++i) + T(i) = std::stod(content[i + 1]); + for (int i = 0; i < 4; ++i) + Q(i) = std::stod(content[i + 4]); + Eigen::Quaternion q(Q(0), Q(1), Q(2), Q(3)); + SE3 gsb{SO3{q.normalized().toRotationMatrix()}, T}; + + poses_.emplace_back(ts, gsb); + } + } + LOG(INFO) << absl::StreamFormat("%d ground truth poses in total loaded", + poses_.size()); + } else { + LOG(FATAL) << "failed to load ground-truth state csv @ " << state_data; + } + + return poses_; +} + +std::tuple +GetDirs(const std::string dataset, const std::string root, + const std::string seq, int cam_id) { + std::string dataset_type{dataset}; + std::transform(dataset.begin(), dataset.end(), dataset_type.begin(), tolower); + + if (dataset_type == "tumvi") { + std::string image_dir = + absl::StrFormat("%s/dataset-%s_512_16/mav0/cam%d/", root, seq, cam_id); + std::string imu_dir = + absl::StrFormat("%s/dataset-%s_512_16/mav0/imu0/", root, seq); + std::string mocap_dir = + absl::StrFormat("%s/dataset-%s_512_16/mav0/mocap0/", root, seq); + return std::make_tuple(image_dir, imu_dir, mocap_dir); + } else if (dataset_type == "euroc") { + std::string image_dir = + absl::StrFormat("%s/%s/mav0/cam%d/", root, seq, cam_id); + std::string imu_dir = absl::StrFormat("%s/%s/mav0/imu0/", root, seq); + std::string mocap_dir = + absl::StrFormat("%s/%s/mav0/state_groundtruth_estimate0/", root, seq); + return std::make_tuple(image_dir, imu_dir, mocap_dir); + } else { + LOG(FATAL) << "Unrecognized dataset type, expecting [euroc|tumvi]"; + } +} + +} // namespace feh diff --git a/src/tumvi.h b/src/tumvi.h new file mode 100644 index 00000000..384c3e2d --- /dev/null +++ b/src/tumvi.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include +#include + +#include "core.h" +#include "message_types.h" + +namespace feh { + +class TUMVILoader { +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + TUMVILoader(const std::string &image_dir, const std::string &imu_dir); + std::vector LoadGroundTruthState(const std::string &state_dir); + + msg::Message *Get(int i) const { return entries_[i].get(); }; + int size() const { return entries_.size(); } + +private: + std::vector> entries_; + std::vector poses_; +}; + +using EuRoCLoader = TUMVILoader; + +// Get image, imu and groundtruth directories for TUMVI and EuRoC dataset +std::tuple +GetDirs(const std::string dataset, const std::string root, + const std::string seq, int cam_id); + +} // namespace feh diff --git a/src/update.cpp b/src/update.cpp new file mode 100644 index 00000000..3d63c474 --- /dev/null +++ b/src/update.cpp @@ -0,0 +1,337 @@ +#include +#include +#include +#include + +#include "absl/strings/str_format.h" +#include "glog/logging.h" + +#include "estimator.h" +#include "feature.h" +#include "geometry.h" +#include "group.h" +#include "tracker.h" + +namespace feh { + +void Estimator::Update() { + if (instate_features_.empty() && oos_features_.empty()) + return; + + timer_.Tick("update"); + std::vector inliers; // individually compatible matches + std::vector dist, + inlier_dist; // MH distance of features & inlier features + + timer_.Tick("jacobian"); + for (auto f : instate_features_) { + f->ComputeJacobian(X_.Rsb, X_.Tsb, X_.Rbc, X_.Tbc, last_gyro_, imu_.Cg(), + X_.bg, X_.Vsb, X_.td); + auto J = f->J(); + auto res = f->inn(); + + // Mahalanobis gating + Mat2 S = J * P_ * J.transpose(); + S(0, 0) += R_; + S(1, 1) += R_; + ftype mh_dist = res.dot(S.llt().solve(res)); + dist.push_back(mh_dist); + } + timer_.Tock("jacobian"); + + timer_.Tick("MH-gating"); + + if (use_MH_gating_ && instate_features_.size() > min_required_inliers_) { + + ftype mh_thresh = MH_thresh_; + while (inliers.size() < min_required_inliers_) { + // reset states + for (auto f : instate_features_) { + f->SetStatus(FeatureStatus::INSTATE); + } + inliers.clear(); + // mark inliers + for (int i = 0; i < instate_features_.size(); ++i) { + auto f = instate_features_[i]; + if (dist[i] < mh_thresh) { + inliers.push_back(f); + } else { + f->SetStatus(FeatureStatus::REJECTED_BY_FILTER); + } + } + // relax the threshold + mh_thresh *= MH_thresh_multipler_; + } + } else { + inliers.resize(instate_features_.size()); + std::copy(instate_features_.begin(), instate_features_.end(), + inliers.begin()); + } + timer_.Tock("MH-gating"); + + if (use_1pt_RANSAC_) { + inliers = OnePointRANSAC(inliers); + } + + std::vector active_oos_features; + int total_oos_jac_size{0}; + if (use_OOS_) { + // std::vector oos_jacs; // jacobians w.r.t. feature + // parametrization + for (auto f : oos_features_) { + auto vobs = graph_.GetObservationsOf(f); + int oos_jac_size = f->ComputeOOSJacobian(vobs, X_.Rbc, X_.Tbc); + if (oos_jac_size > 0) { + total_oos_jac_size += oos_jac_size; + active_oos_features.push_back(f); + } + } + if (total_oos_jac_size > 0) { + LOG(INFO) << "#total_oos_jac=" << total_oos_jac_size << std::endl; + } + } + + if (inliers.empty() && (!use_OOS_ || !total_oos_jac_size)) { + return; + } + + int total_size = 2 * inliers.size() + total_oos_jac_size; + H_.resize(total_size, err_.size()); + inn_.resize(total_size); + diagR_.resize(total_size); + + for (int i = 0; i < inliers.size(); ++i) { + H_.block(2 * i, 0, 2, err_.size()) = inliers[i]->J(); + inn_.segment<2>(2 * i) = inliers[i]->inn(); + + // if (outlier_thresh_ > 1.0) { + // auto [robust_R, is_outlier] = HuberOnInnovation(inliers[i]->inn(), R_); + // diagR_.segment<2>(2 * i) << robust_R, robust_R; + // } else { + // diagR_.segment<2>(2 * i) << R_, R_; + // } + diagR_.segment<2>(2 * i) << R_, R_; + } + + if (total_oos_jac_size) { + int oos_offset = 2 * inliers.size(); + + for (auto f : active_oos_features) { + int size = f->oos_inn_size(); + H_.block(oos_offset, 0, size, err_.size()) = f->Ho(); + inn_.segment(oos_offset, size) = f->ro(); + for (int i = 0; i < size; ++i) { + // FIXME (xfei): how to perform huber on innovation for OOS features? + diagR_(oos_offset + i) = Roos_; + } + oos_offset += size; + } + } + + if (use_OOS_) { + if (use_compression_ && + H_.rows() > H_.cols() * compression_trigger_ratio_) { + // prform measurement compression + int rows = QR(inn_, H_); + inn_ = inn_.head(rows); + H_ = H_.topRows(rows); + diagR_ = diagR_.head(rows); // FIXME: this does not seem right + } + } + + timer_.Tick("actual-update"); + UpdateJosephForm(); + timer_.Tock("actual-update"); + + // absorb error + AbsorbError(); + timer_.Tock("update"); + + LOG(INFO) << "Error state absorbed"; + + if (print_timing_) { + std::cout << timer_; + } +} + +std::vector +Estimator::OnePointRANSAC(const std::vector &mh_inliers) { + if (mh_inliers.empty()) + return mh_inliers; + // Reference: + // https://www.doc.ic.ac.uk/~ajd/Publications/civera_etal_jfr2010.pdf + int n_hyp = 1000; + std::vector selected(mh_inliers.size(), false); + int selected_counter = 0; + std::uniform_int_distribution distribution(0, mh_inliers.size() - 1); + + // find those involved in update step + std::unordered_set active_features; + std::unordered_set active_groups; + for (auto f : mh_inliers) { + active_features.insert(f); + } + for (auto f : mh_inliers) { + active_groups.insert(f->ref()); + } + + // backup states + State X0 = X_; + for (auto g : active_groups) { + g->BackupState(); + } + for (auto f : active_features) { + f->BackupState(); + } + + // tmp vars + MatX K(err_.size(), 2); + Mat2 S; + + std::vector max_inliers, inliers; + for (int i = 0; i < n_hyp && selected_counter < selected.size(); ++i) { + int k = distribution(*rng_); + while (selected[k]) { + k = distribution(*rng_); + } + selected[k] = true; + ++selected_counter; + // state-only update with the selected measurement k + // + // std::cout << "H_.rows=" << H_.rows() << ";;; H_.cols=" << H_.cols() << + // std::endl; + // std::cout << "index=" << mh_inliers[k].first << std::endl; + + auto J = mh_inliers[k]->J(); + auto inn = mh_inliers[k]->inn(); + + S = J * P_ * J.transpose(); + S(0, 0) += R_; + S(1, 1) += R_; + + K.transpose() = S.llt().solve(J * P_); + + err_ = K * inn; + AbsorbError(); + err_.setZero(); // redudant (done in AbsorbError already) but for + // readibility + + inliers.clear(); + for (auto f : mh_inliers) { + auto res = f->xp() - f->Predict(gsb(), gbc()); + + // std::cout << "xp=" << f->xp().transpose() << std::endl; + // std::cout << "pred=" << f->pred().transpose() << std::endl; + // std::cout << "res=" << res.transpose() << std::endl; + + if (res.norm() < ransac_thresh_) { + inliers.push_back(f); + } + } + if (inliers.size() > max_inliers.size()) { + max_inliers = inliers; + ftype eps = 1 - max_inliers.size() / float(mh_inliers.size()); + n_hyp = int(log(1 - ransac_prob_) / log(eps + 1e-5)) + 1; + } + + X_ = X0; + for (auto f : active_features) { + f->RestoreState(); + } + for (auto g : active_groups) { + g->RestoreState(); + } + } + auto str = absl::StrFormat("#hyp tested=%d: li_inliers/mh_inliers=%d/%d", + n_hyp, max_inliers.size(), mh_inliers.size()); + + LOG(INFO) << str; + + // back up state and covariance again + MatX P0 = P_; + for (auto g : active_groups) { + g->BackupState(); + } + for (auto f : active_features) { + f->BackupState(); + } + + if (!max_inliers.empty()) { + // low innovation update + H_.resize(2 * max_inliers.size(), err_.size()); + H_.setZero(); + inn_.resize(2 * max_inliers.size()); + inn_.setZero(); + selected.resize(mh_inliers.size(), false); + for (int i = 0; i < max_inliers.size(); ++i) { + selected[i] = true; + H_.block(2 * i, 0, 2, err_.size()) = max_inliers[i]->J(); + inn_.segment<2>(2 * i) = max_inliers[i]->inn(); + } + UpdateJosephForm(); + AbsorbError(); + } + + if (max_inliers.size() < mh_inliers.size()) { + // rescue high-innovation measurements + std::vector hi_inliers; // high-innovation inlier set + for (int i = 0; i < mh_inliers.size(); ++i) { + if (!selected[i]) { + // potentially a high-innovation inlier + auto f = mh_inliers[i]; + + f->ComputeJacobian(X_.Rsb, X_.Tsb, X_.Rbc, X_.Tbc, last_gyro_, + imu_.Cg(), X_.bg, X_.Vsb, X_.td); + auto J = f->J(); + auto res = f->inn(); + + Mat2 S = J * P_ * J.transpose(); + S(0, 0) += R_; + S(1, 1) += R_; + if (res.dot(S.llt().solve(res)) < ransac_Chi2_) { + hi_inliers.push_back(f); + } else { + f->SetStatus(FeatureStatus::REJECTED_BY_FILTER); + } + } + } + if (!hi_inliers.empty()) { + // H_.resize(2 * hi_inliers.size(), err_.size()); + // H_.setZero(); + // inn_.resize(2 * hi_inliers.size()); + // inn_.setZero(); + // for (int i = 0; i < hi_inliers.size(); ++i) { + // H_.block(i * 2, 0, 2, err_.size()) = hi_inliers[i]->J(); + // inn_.segment<2>(i * 2) = hi_inliers[i]->inn(); + // } + // UpdateJosephForm(); + // AbsorbError(); + // + // // instead of using high-innovation inliers directly + // // return them and perform one update + max_inliers.insert(max_inliers.end(), hi_inliers.begin(), + hi_inliers.end()); + LOG(INFO) << "rescued " << hi_inliers.size() << " high-innovation inliers" + << std::endl; + } + } + + // restore state + X_ = X0; + P_ = P0; + for (auto f : active_features) { + f->RestoreState(); + } + for (auto g : active_groups) { + g->RestoreState(); + } + err_.setZero(); + // need to re-compute jacobians + for (auto f : max_inliers) { + f->ComputeJacobian(X_.Rsb, X_.Tsb, X_.Rbc, X_.Tbc, last_gyro_, imu_.Cg(), + X_.bg, X_.Vsb, X_.td); + } + return max_inliers; +} + +} // namespace feh diff --git a/src/viewer.cpp b/src/viewer.cpp new file mode 100644 index 00000000..1cd16174 --- /dev/null +++ b/src/viewer.cpp @@ -0,0 +1,164 @@ +// Pangolin backed 2D and 3D viewer. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#include "glog/logging.h" +#include "opencv2/imgproc/imgproc.hpp" +#include "json/json.h" + +#include "core.h" +#include "estimator.h" +#include "viewer.h" + +namespace feh { + +const static Vec3f kYellow{1., 1., 0}; +const static Vec3f kGreen{0, 1., 0}; +const static Vec3f kCyan{0, 1., 1.}; + +Viewer::~Viewer() { + if (camera_state_) { + delete camera_state_; + } + if (image_state_) { + delete image_state_; + } + if (texture_) { + delete texture_; + } +} + +Viewer::Viewer(const Json::Value &cfg, const std::string &name) + : window_name_{name.empty() ? "XIVO Display" : name}, + camera_state_{nullptr}, image_state_{nullptr}, texture_{nullptr}, + cfg_{cfg} { + + pangolin::CreateWindowAndBind(window_name_, cfg_["window"]["width"].asInt(), + cfg_["window"]["height"].asInt()); + + // aspect ratio setup + auto viewport = cfg_["viewport"]; + height_ = viewport["height"].asInt(); + width_ = viewport["width"].asInt(); + fx_ = viewport["fx"].asDouble(); + fy_ = viewport["fy"].asDouble(); + cx_ = viewport["cx"].asDouble(); + cy_ = viewport["cy"].asDouble(); + znear_ = viewport["znear"].asDouble(); + zfar_ = viewport["zfar"].asDouble(); + + K_ << fx_, 0, cx_, 0, fy_, cy_, 0, 0, 1; + Kinv_ = K_.inverse(); + + camera_state_ = new pangolin::OpenGlRenderState(); + + camera_state_->SetProjectionMatrix(pangolin::ProjectionMatrixRDF_TopLeft( + width_, height_, fx_, fy_, cx_, cy_, znear_, zfar_)); + + camera_state_->SetModelViewMatrix(pangolin::ModelViewLookAtRDF( + 0.5f, 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.f, 0.0f, 1.0f)); + + float aspect = width_ / (float)height_; + pangolin::View &camera_view = pangolin::Display("cam").SetAspect(aspect); + + camera_view.SetHandler(new pangolin::Handler3D(*camera_state_)); + + image_state_ = new pangolin::OpenGlRenderState( + pangolin::ProjectionMatrix(width_, height_, fx_, fy_, cx_, cy_, znear_, + zfar_), + pangolin::ModelViewLookAt(-1, 1, -1, 0, 0, 0, pangolin::AxisY)); + + pangolin::View &image_view = pangolin::Display("image").SetAspect(aspect); + + image_view.SetHandler(new pangolin::Handler3D(*image_state_)); + + // background setup + bg_color_[0] = cfg_["bg_color"]["r"].asFloat(); + bg_color_[1] = cfg_["bg_color"]["g"].asFloat(); + bg_color_[2] = cfg_["bg_color"]["b"].asFloat(); + bg_color_[3] = cfg_["bg_color"]["a"].asFloat(); + + pangolin::DisplayBase() + .SetBounds(0, 1, 0, 1) + .SetLayout(pangolin::LayoutEqual) + .AddDisplay(camera_view) + .AddDisplay(image_view); + + // NOTE: have to unset the current context from the main thread + // otherwise segfault + // Reference: + // https://github.com/stevenlovegrove/Pangolin/blob/master/examples/HelloPangolinThreads/main.cpp + pangolin::GetBoundWindow()->RemoveCurrent(); +} + +void Viewer::Update(const cv::Mat &image) { + if (image.empty()) + return; + image_ = image.clone(); + cv::cvtColor(image_, image_, CV_RGB2BGR); + cv::flip(image_, image_, 0); + + int rows(image_.rows); + int cols(image_.cols); + // bind to context + pangolin::BindToContext(window_name_); + if (!texture_) { + texture_ = new pangolin::GlTexture(cols, rows, GL_RGB, false, 0, GL_RGB, + GL_UNSIGNED_BYTE); + } + texture_->Upload((uint8_t *)image_.data, GL_RGB, GL_UNSIGNED_BYTE); + // unset context + pangolin::GetBoundWindow()->RemoveCurrent(); +} + +void Viewer::Update_gsb(const SE3 &gsb) { + gsb_ = gsb; + trace_.push_back(gsb_.translation()); +} + +void Viewer::Update_gbc(const SE3 &gbc) { gbc_ = gbc; } + +void Viewer::Update_gsc(const SE3 &gsc) { gsc_ = gsc; } + +void Viewer::Refresh() { + // bind to context + pangolin::BindToContext(window_name_); + + pangolin::View &camera_view = pangolin::Display("cam"); + camera_view.Activate(*camera_state_); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(bg_color_[0], bg_color_[1], bg_color_[2], bg_color_[3]); + + // DrawGrid(half_grid_size_); + glColor3f(0.25f, 0.25f, 0.25f); + pangolin::glDraw_z0(0.2, cfg_.get("grid_size", 20).asInt()); + + // draw axis for body frame + pangolin::glDrawAxis(gsb_.matrix(), 0.2); + + // draw trace + glColor3f(kYellow(0), kYellow(1), kYellow(2)); + + if (cfg_.get("draw_trace_as_dots", false).asBool()) { + pangolin::glDrawVertices(trace_, GL_POINTS); // as points + } else { + pangolin::glDrawVertices(trace_, GL_LINE_STRIP); // as line strips + } + + // draw frustrum for camera frame + glColor3f(kGreen(0), kGreen(1), kGreen(2)); + pangolin::glDrawFrustum(Kinv_, width_, height_, gsc_.matrix4x4(), 0.2); + + // tracker view + if (texture_) { + pangolin::View &image_view = pangolin::Display("image"); + camera_view.Activate(*image_state_); + + image_view.Activate(); + glColor3f(1.0, 1.0, 1.0); + texture_->RenderToViewport(); + } + pangolin::FinishFrame(); + // unbind context + pangolin::GetBoundWindow()->RemoveCurrent(); +} + +} // namespace feh diff --git a/src/viewer.h b/src/viewer.h new file mode 100644 index 00000000..f4766bb1 --- /dev/null +++ b/src/viewer.h @@ -0,0 +1,50 @@ +// Viewer for VIO. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once + +#include +#include + +#include "opencv2/core/core.hpp" +#include "pangolin/pangolin.h" + +#include "core.h" + +namespace feh { + +using XYZRGB = std::array; + +class Viewer { +public: + Viewer(const Json::Value &cfg, const std::string &name = ""); + ~Viewer(); + + void Update_gsb(const SE3 &gsb); + void Update_gbc(const SE3 &gbc); + void Update_gsc(const SE3 &gsc); + void Update(const cv::Mat &img); + void Refresh(); + +private: + std::string window_name_; + pangolin::OpenGlRenderState *camera_state_; + pangolin::OpenGlRenderState *image_state_; + pangolin::GlTexture *texture_; + Json::Value cfg_; + + // viewport attributes + int height_, width_; + Mat3 K_, Kinv_; + ftype fx_, fy_, cx_, cy_; + ftype znear_, zfar_; + + cv::Mat image_; + + SE3 Rg_, gsb_, gbc_, gsc_; + std::vector trace_; // body frame trajectory + + float bg_color_[4]; // background color (rgba) + static int counter_; +}; + +} // feh diff --git a/src/visualize.cpp b/src/visualize.cpp new file mode 100644 index 00000000..8e8f8e07 --- /dev/null +++ b/src/visualize.cpp @@ -0,0 +1,119 @@ +#include "absl/strings/str_format.h" +#include "opencv2/imgproc/imgproc.hpp" + +#include "feature.h" +#include "visualize.h" + +namespace feh { + +std::unique_ptr Canvas::instance_ = nullptr; + +// BGR +static cv::Scalar kColorPink(203, 192, 255); +static cv::Scalar kColorCyan(255, 192, 203); +static cv::Scalar kColorRed(0, 0, 255); +static cv::Scalar kColorGreen(0, 255, 0); +static cv::Scalar kColorYellow(0, 255, 255); +static cv::Scalar kColorBlue(255, 0, 0); +static cv::Scalar kColorLakeBlue(219, 152, 52); + +CanvasPtr Canvas::instance() { + if (instance_ == nullptr) { + instance_ = std::unique_ptr(new Canvas()); + } + return instance_.get(); +} + +void Canvas::Update(const cv::Mat &img) { + if (img.empty()) { + return; + } + if (img.channels() == 1) { + cv::cvtColor(img, disp_, CV_GRAY2RGB); + } else { + img.copyTo(disp_); + } +} + +void Canvas::Draw(const FeaturePtr f) { + if (disp_.empty()) { + return; + } + + auto pos(f->xp()); + cv::Scalar color; + if (f->track_status() == TrackStatus::TRACKED) { + Vec2 last_pos(f->front()); + for (auto pos : *f) { + if (pos != f->xp()) { + last_pos = pos; + } else + break; + } + + // draw the trace + cv::line(disp_, cv::Point2d(pos[0], pos[1]), + cv::Point2d(last_pos[0], last_pos[1]), kColorYellow, 1); + + if (f->instate()) { + cv::drawMarker(disp_, cv::Point2d(pos[0], pos[1]), kColorGreen, + cv::MARKER_CROSS, 10, 2); + } else { + cv::circle(disp_, cv::Point2d(pos[0], pos[1]), 2, kColorRed, -1); + } + } else if (f->track_status() == TrackStatus::REJECTED || + f->track_status() == TrackStatus::DROPPED) { + +#define DEBUG_VIEW +#ifdef DEBUG_VIEW + cv::drawMarker(disp_, cv::Point2d(pos[0], pos[1]), kColorPink, + cv::MARKER_TRIANGLE_UP, 20, 5); +#endif + + } else if (f->track_status() == TrackStatus::CREATED) { + // cv::circle(disp_, cv::Point2d(pos[0], pos[1]), 3, kColorYellow, -1); + } else { + // LOG(WARNING) << "Feature status NOT recognized."; + } + +// overwrite rejected features +#ifdef DEBUG_VIEW + // if (f->status() == FeatureStatus::REJECTED_BY_TRACKER) { + // cv::drawMarker(disp_, cv::Point2d(pos[0], pos[1]), kColorPink, + // cv::MARKER_TRIANGLE_UP, 20, 5); + // } else + + if (f->status() == FeatureStatus::REJECTED_BY_FILTER) { + cv::drawMarker(disp_, cv::Point2d(pos[0], pos[1]), kColorCyan, + cv::MARKER_DIAMOND, 20, 5); + } +#endif +} + +void Canvas::OverlayStateInfo(const State &X, int vspace, int hspace, + int thickness, double font_scale) { + if (disp_.empty()) { + return; + } + + cv::putText(disp_, absl::StrFormat("Tsb=[%0.4f, %0.4f, %0.4f]", X.Tsb(0), + X.Tsb(1), X.Tsb(2)), + cv::Point(hspace, vspace * 1), CV_FONT_HERSHEY_PLAIN, font_scale, + kColorLakeBlue, thickness); + + cv::putText(disp_, absl::StrFormat("Vsb=[%0.4f, %0.4f, %0.4f]", X.Vsb(0), + X.Vsb(1), X.Vsb(2)), + cv::Point(hspace, vspace * 2), CV_FONT_HERSHEY_PLAIN, font_scale, + kColorLakeBlue, thickness); + + cv::putText(disp_, absl::StrFormat("bg=[%0.4f, %0.4f, %0.4f]", X.bg(0), + X.bg(1), X.bg(2)), + cv::Point(hspace, vspace * 3), CV_FONT_HERSHEY_PLAIN, font_scale, + kColorLakeBlue, thickness); + + cv::putText(disp_, absl::StrFormat("ba=[%0.4f, %0.4f, %0.4f]", X.ba(0), + X.ba(1), X.ba(2)), + cv::Point(hspace, vspace * 4), CV_FONT_HERSHEY_PLAIN, font_scale, + kColorLakeBlue, thickness); +} +} diff --git a/src/visualize.h b/src/visualize.h new file mode 100644 index 00000000..a8850d22 --- /dev/null +++ b/src/visualize.h @@ -0,0 +1,34 @@ +// Visualization utilities. +// Author: Xiaohan Fei (feixh@cs.ucla.edu) +#pragma once +#include + +#include "opencv2/core/core.hpp" + +#include "core.h" + +namespace feh { + +class Canvas; +using CanvasPtr = Canvas *; + +class Canvas { +public: + static CanvasPtr instance(); + + static void Delete(); + void Update(const cv::Mat &img); + void Draw(const FeaturePtr f); + void OverlayStateInfo(const State &X, int vspace = 12, int hspace = 12, + int thickness = 1, double font_scale = 0.9); + const cv::Mat &display() const { return disp_; } + +private: + Canvas(const Canvas &) = delete; + Canvas &operator=(const Canvas &) = delete; + Canvas() = default; + static std::unique_ptr instance_; + + cv::Mat disp_; +}; +} diff --git a/thirdparty/Pangolin/.clang-format b/thirdparty/Pangolin/.clang-format new file mode 100644 index 00000000..9d159247 --- /dev/null +++ b/thirdparty/Pangolin/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: false diff --git a/thirdparty/Pangolin/.gitignore b/thirdparty/Pangolin/.gitignore new file mode 100644 index 00000000..ca028872 --- /dev/null +++ b/thirdparty/Pangolin/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +CMakeLists.txt.user +build* diff --git a/thirdparty/Pangolin/.gitmodules b/thirdparty/Pangolin/.gitmodules new file mode 100644 index 00000000..7676f394 --- /dev/null +++ b/thirdparty/Pangolin/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/pybind11"] + path = external/pybind11 + url = https://github.com/pybind/pybind11.git diff --git a/thirdparty/Pangolin/.travis.yml b/thirdparty/Pangolin/.travis.yml new file mode 100644 index 00000000..b087f37f --- /dev/null +++ b/thirdparty/Pangolin/.travis.yml @@ -0,0 +1,30 @@ +sudo: required +dist: xenial + +before_install: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libeigen3-dev libglew-dev libc++-dev libwayland-dev libxkbcommon-dev libegl1-mesa-dev; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pyenv versions && pyenv global system 3.7; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install eigen glew ; fi + +language: cpp + +matrix: + include: + - os: linux + compiler: gcc + env: PARALLEL_BUILD="-- -j 8" + - os: linux + compiler: clang + env: PARALLEL_BUILD="-- -j 8" + - os: osx + env: PARALLEL_BUILD="-- -j 8" + - os: windows + env: PARALLEL_BUILD="--parallel 8" + +script: + - mkdir build + - cd build + - cmake -D CMAKE_BUILD_TYPE=Release .. + - cmake --build . $PARALLEL_BUILD diff --git a/thirdparty/Pangolin/CMakeLists.txt b/thirdparty/Pangolin/CMakeLists.txt new file mode 100644 index 00000000..66badcca --- /dev/null +++ b/thirdparty/Pangolin/CMakeLists.txt @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 2.8.12) +project("Pangolin") +set(PANGOLIN_VERSION_MAJOR 0) +set(PANGOLIN_VERSION_MINOR 5) +set(PANGOLIN_VERSION ${PANGOLIN_VERSION_MAJOR}.${PANGOLIN_VERSION_MINOR}) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/") + +# Platform configuration vars +include(SetPlatformVars) + +SET(CPACK_GENERATOR "DEB") + +SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Steven Lovegrove") +SET(CPACK_PACKAGE_VERSION_MAJOR ${PANGOLIN_VERSION_MAJOR}) +SET(CPACK_PACKAGE_VERSION_MINOR ${PANGOLIN_VERSION_MINOR}) +SET(CPACK_PACKAGE_VERSION_PATCH "0") +include(CPack) + +option( BUILD_TESTS "Build Tests" ON ) +option( BUILD_TOOLS "Build Examples" ON ) +option( BUILD_EXAMPLES "Build Tools" ON ) + +set (CMAKE_CXX_STANDARD 14) + +if(_WIN_) + option( BUILD_SHARED_LIBS "Build Shared Library" OFF) + option( BUILD_EXTERN_GLEW "Automatically download, build and compile GLEW" ON) + option( BUILD_EXTERN_LIBPNG "Automatically download, build and compile libpng" ON) + option( BUILD_EXTERN_LIBJPEG "Automatically download, build and compile libjpeg" ON) + option( MSVC_USE_STATIC_CRT "Use static C Runtime with MSVC, /MT instead of /MD" ON) + + # Make sure there are no erroneous C Runtime flags + list(APPEND FLAG_VARS + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO + ) + if(MSVC_USE_STATIC_CRT) + foreach(FLAG_VAR ${FLAG_VARS}) + string(REGEX REPLACE "/MD" "/MT" NEW_FLAGS "${${FLAG_VAR}}") + set(${FLAG_VAR} "${NEW_FLAGS}" CACHE STRING "" FORCE) + endforeach() + else() + foreach(FLAG_VAR ${FLAG_VARS}) + string(REGEX REPLACE "/MT" "/MD" NEW_FLAGS "${${FLAG_VAR}}") + set(${FLAG_VAR} "${NEW_FLAGS}" CACHE STRING "" FORCE) + endforeach() + endif() +else() + option( BUILD_SHARED_LIBS "Build Shared Library" ON) +endif() + +if(NOT MSVC) + set( CMAKE_CXX_FLAGS "-Wall -Wextra ${CMAKE_CXX_FLAGS}" ) +endif() + +if(ANDROID) + set(ANDROID_PACKAGE_NAME "com.github.stevenlovegrove.pangolin") + include(AndroidUtils) +endif() + +if(ANDROID OR IOS) + set(HAVE_GLES 1) + option(BUILD_FOR_GLES_2 "Build for OpenGL ES 2 instead of ES 1" ON ) + if(BUILD_FOR_GLES_2) + set(HAVE_GLES_2 1) + endif() +endif() + +if(_OSX_) + set(CMAKE_MACOSX_RPATH ON) +endif() + +# Overide with cmake -DCMAKE_BUILD_TYPE=Debug {dir} +if( NOT CMAKE_BUILD_TYPE AND NOT _WIN_ ) + message("Build type not set (defaults to release)") + message("-DCMAKE_BUILD_TYPE=Debug for debug") + set( CMAKE_BUILD_TYPE Release ) +endif() + +string(TOLOWER ${PROJECT_NAME} LIBRARY_NAME) + +# make an uninstall target +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY +) + +add_custom_target(pangolin_uninstall + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + +add_subdirectory("external") +add_subdirectory("src") + +if(BUILD_TESTS) + set(Pangolin_DIR ${Pangolin_BINARY_DIR}/src) + add_subdirectory("test") +endif() + +if(BUILD_TOOLS) + set(Pangolin_DIR ${Pangolin_BINARY_DIR}/src) + add_subdirectory(tools) +endif() + +if(BUILD_EXAMPLES) + set(Pangolin_DIR ${Pangolin_BINARY_DIR}/src) + add_subdirectory(examples) +endif() diff --git a/thirdparty/Pangolin/CMakeModules/AndroidUtils.cmake b/thirdparty/Pangolin/CMakeModules/AndroidUtils.cmake new file mode 100644 index 00000000..cfb13dc2 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/AndroidUtils.cmake @@ -0,0 +1,245 @@ +if(NOT ANDROID_PACKAGE_NAME) + set(ANDROID_PACKAGE_NAME "com.github.stevenlovegrove.pangolin") +endif() + +if(NOT ANDROID_DEFERRED_ENTRY_SO) + set(ANDROID_DEFERRED_ENTRY_SO "libpangolin.so") +endif() + +# Configure build environment to automatically generate APK's instead of executables. +if(ANDROID AND NOT TARGET apk) + # virtual targets which we'll add apks and push actions to. + add_custom_target( apk ) + add_custom_target( push ) + add_custom_target( run ) + + # Reset output directories to be in binary folder (rather than source) + set(LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_CURRENT_BINARY_DIR}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}) + + macro( create_android_manifest_xml filename prog_name package_name activity_name) + file( WRITE ${filename} +" + + + + + + + + + + + + + + + + + + + + + + + + + + +" ) + endmacro() + + macro( create_bootstrap_library prog_name package_name) + set(bootstrap_cpp "${CMAKE_CURRENT_BINARY_DIR}/${prog_name}_start.cpp" ) + file( WRITE ${bootstrap_cpp} +"#include +#include +#include +#include +#include +#include + +#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, \"AndroidUtils.cmake\", __VA_ARGS__)) +#define LIB_PATH \"/data/data/${package_name}.${prog_name}/lib/\" + +void * load_lib(const char * l) { + void * handle = dlopen(l, RTLD_NOW | RTLD_GLOBAL); + if (!handle) LOGE( \"dlopen('%s'): %s\", l, strerror(errno) ); + return handle; +} + +void ANativeActivity_onCreate(ANativeActivity * app, void * ud, size_t udsize) { + #include \"${prog_name}_shared_load.h\" + + // Look for standard entrypoint in user lib + void (*stdentrypoint)(ANativeActivity*, void*, size_t); + *(void **) (&stdentrypoint) = dlsym(load_lib( LIB_PATH \"lib${prog_name}.so\"), \"ANativeActivity_onCreate\"); + if (stdentrypoint) { + (*stdentrypoint)(app, ud, udsize); + }else{ + // Look for deferred load entry point + void (*exdentrypoint)(ANativeActivity*, void*, size_t, const char*); + *(void **) (&exdentrypoint) = dlsym(load_lib( LIB_PATH \"lib${prog_name}.so\"), \"DeferredNativeActivity_onCreate\"); + if (!exdentrypoint) { + // Look in specific shared lib + *(void **) (&exdentrypoint) = dlsym(load_lib( LIB_PATH \"${ANDROID_DEFERRED_ENTRY_SO}\"), \"DeferredNativeActivity_onCreate\"); + } + if(exdentrypoint) { + (*exdentrypoint)(app, ud, udsize, LIB_PATH \"lib${prog_name}.so\" ); + }else{ + LOGE( \"Unable to find compatible entry point\" ); + } + } +}" ) + add_library( "${prog_name}_start" SHARED ${bootstrap_cpp} ) + target_link_libraries( "${prog_name}_start" android log ) + add_dependencies( ${prog_name} "${prog_name}_start" ) + endmacro() + + macro( android_update android_project_name) + # Find which android platforms are available. + execute_process( + COMMAND android list targets -c + OUTPUT_VARIABLE android_target_list + ) + + # Pick first platform from this list. + string(REGEX MATCH "^[^\n]+" android_target "${android_target_list}" ) + message(STATUS "Android Target: ${android_target}") + + if( NOT "${android_target}" STREQUAL "" ) + # Generate ant build scripts for making APK + execute_process( + COMMAND android update project --name ${android_project_name} --path . --target ${android_target} --subprojects + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + else() + message( FATAL_ERROR "No Android SDK platforms found. Please install an Android platform SDK. On Linux, run 'android'." ) + endif() + endmacro() + + # Override add_executable to build android .so instead! + macro( add_executable prog_name) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libs/${ANDROID_NDK_ABI_NAME}) + add_library( ${prog_name} SHARED ${ARGN} ) + + # Add required link libs for android + target_link_libraries(${prog_name} log android ) + + # Create manifest required for APK + create_android_manifest_xml( + "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" "${prog_name}" + "${ANDROID_PACKAGE_NAME}" "${prog_name}" + ) + + # Create library that will launch this program and load shared libs + create_bootstrap_library( ${prog_name} ${ANDROID_PACKAGE_NAME} ) + + # Generate ant build system for APK + android_update( ${prog_name} ) + + # Target to invoke ant build system for APK + set( APK_FILE "${CMAKE_CURRENT_BINARY_DIR}/bin/${prog_name}-debug.apk" ) + add_custom_command( + OUTPUT ${APK_FILE} + COMMAND ant debug + DEPENDS ${prog_name} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + # Target to install on device + add_custom_target( ${prog_name}-apk + DEPENDS ${APK_FILE} + ) + add_dependencies(apk ${prog_name}-apk) + + # Target to install on device + add_custom_target( ${prog_name}-push + COMMAND adb install -r ${APK_FILE} + DEPENDS ${APK_FILE} + ) + add_dependencies(push ${prog_name}-push) + + # install and run on device + add_custom_target( ${prog_name}-run + COMMAND adb shell am start -n ${ANDROID_PACKAGE_NAME}.${prog_name}/android.app.NativeActivity + DEPENDS ${prog_name}-push + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + add_dependencies(run ${prog_name}-run) + + # Flag to package dependent libs + set_property(TARGET ${prog_name} APPEND PROPERTY MAKE_APK 1 ) + + # Clear shared library loading header + file( WRITE "${CMAKE_CURRENT_BINARY_DIR}/${prog_name}_shared_load.h" "") + endmacro() + + macro( package_with_target prog_name lib_path ) + # Mark lib_path as dependent of prog_name + set_property(TARGET ${prog_name} APPEND PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE ${lib_path} ) + + # If prog_name is to be packaged, add file copy command to package .so's. + get_target_property( package_dependent_libs ${prog_name} MAKE_APK ) + if( package_dependent_libs ) + get_filename_component(target_filename ${lib_path} NAME) + file( APPEND ${depend_file} "load_lib(LIB_PATH \"${target_filename}\" );\n") + add_custom_command(TARGET ${prog_name} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${lib_path} "${CMAKE_CURRENT_BINARY_DIR}/libs/${ANDROID_NDK_ABI_NAME}/" + ) + endif() + endmacro() + + macro( add_to_depend_libs prog_name depend_file lib_name ) + # Recursively Process dependents of lib_name + get_target_property(TARGET_LIBS ${lib_name} IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE) + if(NOT TARGET_LIBS) + get_target_property(TARGET_LIBS ${lib_name} IMPORTED_LINK_INTERFACE_LIBRARIES_NOCONFIG) + endif() + if(NOT TARGET_LIBS) + get_target_property(TARGET_LIBS ${lib_name} IMPORTED_LINK_INTERFACE_LIBRARIES_DEBUG) + endif() + + foreach(SUBLIB ${TARGET_LIBS}) + if(SUBLIB) + add_to_depend_libs( ${prog_name} ${depend_file} ${SUBLIB} ) + endif() + endforeach() + + # Check if lib itself is an external shared library + if("${lib_name}" MATCHES "\\.so$") + package_with_target( ${prog_name} ${lib_name} ) + endif() + + # Check if lib itself is an internal shared library + get_target_property(TARGET_LIB ${lib_name} LOCATION) + if("${TARGET_LIB}" MATCHES "\\.so$") + package_with_target( ${prog_name} ${TARGET_LIB} ) + endif() + endmacro() + + macro( target_link_libraries prog_name) + # _target_link_libraries corresponds to original + _target_link_libraries( ${prog_name} ${ARGN} ) + + # Recursively process dependencies + set(depend_file "${CMAKE_CURRENT_BINARY_DIR}/${prog_name}_shared_load.h" ) + foreach( LIB ${ARGN} ) + add_to_depend_libs( ${prog_name} ${depend_file} ${LIB} ) + endforeach() + endmacro() + +endif() diff --git a/thirdparty/Pangolin/CMakeModules/CreateMethodCallFile.cmake b/thirdparty/Pangolin/CMakeModules/CreateMethodCallFile.cmake new file mode 100644 index 00000000..c1ae95bd --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/CreateMethodCallFile.cmake @@ -0,0 +1,11 @@ +macro( CreateMethodCallFile filename namespace function symbols) + file(WRITE ${filename} "// CMake generated file. Do Not Edit.\n\n#pragma once\n\nnamespace ${namespace} {\n\n") + foreach( symbol ${symbols} ) + file(APPEND ${filename} "void ${symbol}();\n") + endforeach() + file(APPEND ${filename} "\ninline bool ${function}()\n{\n") + foreach( symbol ${symbols} ) + file(APPEND ${filename} " ${symbol}();\n") + endforeach() + file(APPEND ${filename} " return true;\n}\n\n} // ${namespace}\n") +endmacro() diff --git a/thirdparty/Pangolin/CMakeModules/EmbedBinaryFiles.cmake b/thirdparty/Pangolin/CMakeModules/EmbedBinaryFiles.cmake new file mode 100644 index 00000000..a579e27a --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/EmbedBinaryFiles.cmake @@ -0,0 +1,32 @@ +# Creates C resources file from files in given directory +# Based on http://stackoverflow.com/a/27206982 +function(embed_binary_files file_glob output) + # Collect input files + file(GLOB bins ${file_glob}) + # Stop when output file is newer than all binary files + set(output_newer_than_bins 1) + foreach(bin ${bins}) + if(bin IS_NEWER_THAN output) + set(output_newer_than_bins 0) + break() + endif() + endforeach() + if(output_newer_than_bins) + return() + endif() + # Create empty output file + file(WRITE ${output} "") + # Iterate through input files + foreach(bin ${bins}) + # Get short filename + string(REGEX MATCH "([^/]+)$" filename ${bin}) + # Replace filename spaces & extension separator for C compatibility + string(REGEX REPLACE "\\.| " "_" filename ${filename}) + # Read hex data from file + file(READ ${bin} filedata HEX) + # Convert hex data for C compatibility + string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) + # Append data to output file + file(APPEND ${output} "extern const unsigned char ${filename}[] = {${filedata}};\nextern const unsigned ${filename}_size = sizeof(${filename});\n") + endforeach() +endfunction() diff --git a/thirdparty/Pangolin/CMakeModules/FindDC1394.cmake b/thirdparty/Pangolin/CMakeModules/FindDC1394.cmake new file mode 100644 index 00000000..1dbce01a --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindDC1394.cmake @@ -0,0 +1,32 @@ +# Try to find the dc1394 v2 lib and include files +# +# DC1394_INCLUDE_DIR +# DC1394_LIBRARIES +# DC1394_FOUND + +FIND_PATH( DC1394_INCLUDE_DIR dc1394/control.h + /usr/include + /usr/local/include +) + +FIND_LIBRARY( DC1394_LIBRARY dc1394 + /usr/lib64 + /usr/lib + /usr/local/lib +) + +IF(DC1394_INCLUDE_DIR AND DC1394_LIBRARY) + SET( DC1394_FOUND TRUE ) + SET( DC1394_LIBRARIES ${DC1394_LIBRARY} ) +ENDIF(DC1394_INCLUDE_DIR AND DC1394_LIBRARY) + +IF(DC1394_FOUND) + IF(NOT DC1394_FIND_QUIETLY) + MESSAGE(STATUS "Found DC1394: ${DC1394_LIBRARY}") + ENDIF(NOT DC1394_FIND_QUIETLY) +ELSE(DC1394_FOUND) + IF(DC1394_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find libdc1394") + ENDIF(DC1394_FIND_REQUIRED) +ENDIF(DC1394_FOUND) + diff --git a/thirdparty/Pangolin/CMakeModules/FindDepthSense.cmake b/thirdparty/Pangolin/CMakeModules/FindDepthSense.cmake new file mode 100644 index 00000000..83dfb23d --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindDepthSense.cmake @@ -0,0 +1,43 @@ +# Try to find the DepthSense SDK For SoftKinetic Cameras +# +# DepthSense_INCLUDE_DIRS +# DepthSense_LIBRARIES +# DepthSense_FOUND + +FIND_PATH( DepthSense_INCLUDE_DIR DepthSense.hxx + PATHS + "${PROGRAM_FILES}/SoftKinetic/DepthSenseSDK/include" + "${PROGRAM_FILES}/Meta/DepthSenseSDK/include" + /usr/include + /usr/local/include + /opt/local/include + /opt/softkinetic/DepthSenseSDK/include +) + +FIND_LIBRARY( DepthSense_LIBRARY DepthSense + PATHS + "${PROGRAM_FILES}/SoftKinetic/DepthSenseSDK/lib" + "${PROGRAM_FILES}/Meta/DepthSenseSDK/lib" + /usr/lib64 + /usr/lib + /usr/local/lib + /opt/local/lib + /opt/softkinetic/DepthSenseSDK/lib +) + +IF(DepthSense_INCLUDE_DIR AND DepthSense_LIBRARY) + SET( DepthSense_FOUND TRUE ) + SET( DepthSense_LIBRARIES ${DepthSense_LIBRARY} ) + SET( DepthSense_INCLUDE_DIRS ${DepthSense_INCLUDE_DIR} ) +ENDIF() + +IF(DepthSense_FOUND) + IF(NOT DepthSense_FIND_QUIETLY) + MESSAGE(STATUS "Found DepthSense: ${DepthSense_LIBRARY}") + ENDIF() +ELSE() + IF(DepthSense_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find DepthSense") + ENDIF() +ENDIF() + diff --git a/thirdparty/Pangolin/CMakeModules/FindEigen.cmake b/thirdparty/Pangolin/CMakeModules/FindEigen.cmake new file mode 100644 index 00000000..1df56fd4 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindEigen.cmake @@ -0,0 +1,83 @@ +# - Try to find Eigen lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen 3.1.2) +# to require version 3.1.2 or newer of Eigen. +# +# Once done this will define +# +# EIGEN_FOUND - system has eigen lib with correct version +# EIGEN_INCLUDE_DIR - the eigen include directory +# EIGEN_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Copyright (c) 2009 Benoit Jacob +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + +if(NOT Eigen_FIND_VERSION) + if(NOT Eigen_FIND_VERSION_MAJOR) + set(Eigen_FIND_VERSION_MAJOR 2) + endif(NOT Eigen_FIND_VERSION_MAJOR) + if(NOT Eigen_FIND_VERSION_MINOR) + set(Eigen_FIND_VERSION_MINOR 91) + endif(NOT Eigen_FIND_VERSION_MINOR) + if(NOT Eigen_FIND_VERSION_PATCH) + set(Eigen_FIND_VERSION_PATCH 0) + endif(NOT Eigen_FIND_VERSION_PATCH) + + set(Eigen_FIND_VERSION "${Eigen_FIND_VERSION_MAJOR}.${Eigen_FIND_VERSION_MINOR}.${Eigen_FIND_VERSION_PATCH}") +endif(NOT Eigen_FIND_VERSION) + +macro(_eigen3_check_version) + file(READ "${EIGEN_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(Eigen_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(Eigen_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(Eigen_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN_VERSION ${Eigen_WORLD_VERSION}.${Eigen_MAJOR_VERSION}.${Eigen_MINOR_VERSION}) + if(${EIGEN_VERSION} VERSION_LESS ${Eigen_FIND_VERSION}) + set(EIGEN_VERSION_OK FALSE) + else(${EIGEN_VERSION} VERSION_LESS ${Eigen_FIND_VERSION}) + set(EIGEN_VERSION_OK TRUE) + endif(${EIGEN_VERSION} VERSION_LESS ${Eigen_FIND_VERSION}) + + if(NOT EIGEN_VERSION_OK) + message(STATUS "Eigen version ${EIGEN_VERSION} found in ${EIGEN_INCLUDE_DIR}, " + "but at least version ${Eigen_FIND_VERSION} is required") + endif(NOT EIGEN_VERSION_OK) +endmacro(_eigen3_check_version) + +if (EIGEN_INCLUDE_DIR) + # in cache already + _eigen3_check_version() + set(EIGEN_FOUND ${EIGEN_VERSION_OK}) +else() + find_path(EIGEN_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + PATHS + third_party/eigen + ../eigen + ../../eigen + /usr/local/include + /opt/local/include + ${CMAKE_INSTALL_PREFIX}/include + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 eigen + ) + + if(EIGEN_INCLUDE_DIR) + _eigen3_check_version() + endif(EIGEN_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen DEFAULT_MSG EIGEN_INCLUDE_DIR EIGEN_VERSION_OK) + + mark_as_advanced(EIGEN_INCLUDE_DIR) +endif() + +# In case anyone relies on the plural form. +set(EIGEN_INCLUDE_DIRS "${EIGEN_INCLUDE_DIR}") diff --git a/thirdparty/Pangolin/CMakeModules/FindFFMPEG.cmake b/thirdparty/Pangolin/CMakeModules/FindFFMPEG.cmake new file mode 100644 index 00000000..6a67ef57 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindFFMPEG.cmake @@ -0,0 +1,97 @@ +# Try to find the ffmpeg libraries and headers for avcodec avformat swscale +# +# FFMPEG_INCLUDE_DIRS +# FFMPEG_LIBRARIES +# FFMPEG_FOUND + +# Find header files +FIND_PATH( + AVCODEC_INCLUDE_DIR libavcodec/avcodec.h + /usr/include /usr/local/include /opt/local/include /usr/include/x86_64-linux-gnu +) +FIND_PATH( + AVFORMAT_INCLUDE_DIR libavformat/avformat.h + /usr/include /usr/local/include /opt/local/include /usr/include/x86_64-linux-gnu +) +FIND_PATH( + AVDEVICE_INCLUDE_DIR libavdevice/avdevice.h + /usr/include /usr/local/include /opt/local/include /usr/include/x86_64-linux-gnu +) +FIND_PATH( + AVUTIL_INCLUDE_DIR libavutil/avutil.h + /usr/include /usr/local/include /opt/local/include /usr/include/x86_64-linux-gnu +) +FIND_PATH( + SWSCALE_INCLUDE_DIR libswscale/swscale.h + /usr/include /usr/local/include /opt/local/include /usr/include/x86_64-linux-gnu +) + +# Find Library files +FIND_LIBRARY( + AVCODEC_LIBRARY + NAMES avcodec + PATH /usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu +) +FIND_LIBRARY( + AVFORMAT_LIBRARY + NAMES avformat + PATH /usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu +) +FIND_LIBRARY( + AVDEVICE_LIBRARY + NAMES avdevice + PATH /usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu +) +FIND_LIBRARY( + AVUTIL_LIBRARY + NAMES avutil + PATH /usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu +) +FIND_LIBRARY( + SWSCALE_LIBRARY + NAMES swscale + PATH /usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu +) + +IF( EXISTS "${AVUTIL_INCLUDE_DIR}/libavutil/pixdesc.h" ) + SET( AVUTIL_HAVE_PIXDESC TRUE) +endif() + +IF(AVCODEC_INCLUDE_DIR AND AVFORMAT_INCLUDE_DIR AND AVUTIL_INCLUDE_DIR AND AVDEVICE_INCLUDE_DIR AND SWSCALE_INCLUDE_DIR AND AVCODEC_LIBRARY AND AVFORMAT_LIBRARY AND AVUTIL_LIBRARY AND SWSCALE_LIBRARY AND AVDEVICE_LIBRARY AND AVUTIL_HAVE_PIXDESC) + SET(FFMPEG_FOUND TRUE) + SET(FFMPEG_LIBRARIES ${AVCODEC_LIBRARY} ${AVFORMAT_LIBRARY} ${AVUTIL_LIBRARY} ${SWSCALE_LIBRARY} ${AVDEVICE_LIBRARY}) + SET(FFMPEG_INCLUDE_DIRS ${AVCODEC_INCLUDE_DIR} ${AVFORMAT_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${SWSCALE_INCLUDE_DIR} ${AVDEVICE_INCLUDE_DIR}) + + include(CheckCXXSourceCompiles) + + SET(CMAKE_REQUIRED_INCLUDES ${FFMPEG_INCLUDE_DIRS}) + + CHECK_CXX_SOURCE_COMPILES( + "#include \"${AVCODEC_INCLUDE_DIR}/libavformat/avformat.h\" + int main() { + sizeof(AVFormatContext::max_analyze_duration); + }" HAVE_FFMPEG_MAX_ANALYZE_DURATION + ) + CHECK_CXX_SOURCE_COMPILES( + "#include \"${AVCODEC_INCLUDE_DIR}/libavformat/avformat.h\" + int main() { + &avformat_alloc_output_context2; + }" HAVE_FFMPEG_AVFORMAT_ALLOC_OUTPUT_CONTEXT2 + ) + CHECK_CXX_SOURCE_COMPILES( + "#include \"${AVCODEC_INCLUDE_DIR}/libavutil/pixdesc.h\" + int main() { + AVPixelFormat test = AV_PIX_FMT_GRAY8; + }" HAVE_FFMPEG_AVPIXELFORMAT + ) +ENDIF() + +IF (FFMPEG_FOUND) + IF (NOT FFMPEG_FIND_QUIETLY) + MESSAGE(STATUS "Found FFMPEG: ${FFMPEG_LIBRARIES}") + ENDIF (NOT FFMPEG_FIND_QUIETLY) +ELSE (FFMPEG_FOUND) + IF (FFMPEG_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find FFMPEG") + ENDIF (FFMPEG_FIND_REQUIRED) +ENDIF (FFMPEG_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/FindFREEGLUT.cmake b/thirdparty/Pangolin/CMakeModules/FindFREEGLUT.cmake new file mode 100644 index 00000000..b3e32b06 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindFREEGLUT.cmake @@ -0,0 +1,44 @@ +# Try to find the FREEGLUT library +# +# FREEGLUT_INCLUDE_DIR +# FREEGLUT_LIBRARY +# FREEGLUT_FOUND + +FIND_PATH( + FREEGLUT_INCLUDE_DIR GL/freeglut.h + ${CMAKE_INCLUDE_PATH} + $ENV{include} + ${OPENGL_INCLUDE_DIR} + /usr/include + /usr/local/include +) + +SET(STORE_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) +SET(CMAKE_FIND_FRAMEWORK NEVER) + +FIND_LIBRARY( + FREEGLUT_LIBRARY + NAMES freeglut_static freeglut glut + PATH + /opt/local/lib + ${CMAKE_LIBRARY_PATH} + $ENV{lib} + /usr/lib + /usr/local/lib +) + +SET(CMAKE_FIND_FRAMEWORK ${STORE_CMAKE_FIND_FRAMEWORK}) + +IF (FREEGLUT_INCLUDE_DIR AND FREEGLUT_LIBRARY) + SET(FREEGLUT_FOUND TRUE) +ENDIF (FREEGLUT_INCLUDE_DIR AND FREEGLUT_LIBRARY) + +IF (FREEGLUT_FOUND) + IF (NOT FREEGLUT_FIND_QUIETLY) + MESSAGE(STATUS "Found FREEGLUT: ${FREEGLUT_LIBRARY}") + ENDIF (NOT FREEGLUT_FIND_QUIETLY) +ELSE (FREEGLUT_FOUND) + IF (FREEGLUT_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find FREEGLUT") + ENDIF (FREEGLUT_FIND_REQUIRED) +ENDIF (FREEGLUT_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/FindGLEW.cmake b/thirdparty/Pangolin/CMakeModules/FindGLEW.cmake new file mode 100644 index 00000000..65ef6f9b --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindGLEW.cmake @@ -0,0 +1,53 @@ +# +# Try to find GLEW library and include path. +# Once done this will define +# +# GLEW_FOUND +# GLEW_INCLUDE_DIR +# GLEW_LIBRARY +# + +IF (WIN32) + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h + $ENV{PROGRAMFILES}/GLEW/include + ${PROJECT_SOURCE_DIR}/src/nvgl/glew/include + DOC "The directory where GL/glew.h resides") + FIND_LIBRARY( GLEW_LIBRARY + NAMES glew GLEW glew32 glew32s + PATHS + $ENV{PROGRAMFILES}/GLEW/lib + ${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin + ${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib + DOC "The GLEW library") +ELSE (WIN32) + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h + /usr/include + /usr/local/include + /sw/include + /opt/local/include + DOC "The directory where GL/glew.h resides") + FIND_LIBRARY( GLEW_LIBRARY + NAMES GLEW glew + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /sw/lib + /opt/local/lib + DOC "The GLEW library") +ENDIF (WIN32) + +IF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) + SET( GLEW_FOUND TRUE ) +ENDIF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) + +IF (GLEW_FOUND) + IF (NOT GLEW_FIND_QUIETLY) + MESSAGE(STATUS "Found GLEW: ${GLEW_LIBRARY}") + ENDIF (NOT GLEW_FIND_QUIETLY) +ELSE (GLEW_FOUND) + IF (GLEW_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find GLEW") + ENDIF (GLEW_FIND_REQUIRED) +ENDIF (GLEW_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/FindGLUES.cmake b/thirdparty/Pangolin/CMakeModules/FindGLUES.cmake new file mode 100644 index 00000000..2c64fe8a --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindGLUES.cmake @@ -0,0 +1,38 @@ +# Try to find the GLUES lib and include files +# +# GLUES_INCLUDE_DIR +# GLUES_LIBRARIES +# GLUES_FOUND + +FIND_PATH( GLUES_INCLUDE_DIR glues/glues.h + /usr/include + /usr/local/include + /opt/include + /opt/local/include + ${CMAKE_INSTALL_PREFIX}/include +) + +FIND_LIBRARY( GLUES_LIBRARY glues + /usr/lib64 + /usr/lib + /usr/local/lib + /opt/local/lib + /opt/local/lib64 + ${CMAKE_INSTALL_PREFIX}/lib +) + +IF(GLUES_INCLUDE_DIR AND GLUES_LIBRARY) + SET( GLUES_FOUND TRUE ) + SET( GLUES_LIBRARIES ${GLUES_LIBRARY} ) +ENDIF(GLUES_INCLUDE_DIR AND GLUES_LIBRARY) + +IF(GLUES_FOUND) + IF(NOT GLUES_FIND_QUIETLY) + MESSAGE(STATUS "Found GLUES: ${GLUES_LIBRARY}") + ENDIF(NOT GLUES_FIND_QUIETLY) +ELSE(GLUES_FOUND) + IF(GLUES_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find GLUES") + ENDIF(GLUES_FIND_REQUIRED) +ENDIF(GLUES_FOUND) + diff --git a/thirdparty/Pangolin/CMakeModules/FindLibRealSense.cmake b/thirdparty/Pangolin/CMakeModules/FindLibRealSense.cmake new file mode 100644 index 00000000..a8d7a82f --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindLibRealSense.cmake @@ -0,0 +1,33 @@ +# -*- mode: cmake; -*- +############################################################################### +# Find librealsense https://github.com/IntelRealSense/librealsense +# +# This sets the following variables: +# LIBREALSENSE_FOUND - True if OPENNI was found. +# LIBREALSENSE_INCLUDE_DIRS - Directories containing the OPENNI include files. +# LIBREALSENSE_LIBRARIES - Libraries needed to use OPENNI. +# LIBREALSENSE_DEFINITIONS - Compiler flags for OPENNI. +# +# File forked from augmented_dev, project of alantrrs +# (https://github.com/alantrrs/augmented_dev). + +find_package(PkgConfig) +if(${CMAKE_VERSION} VERSION_LESS 2.8.2) +endif() + +#add a hint so that it can find it without the pkg-config +find_path(LIBREALSENSE_INCLUDE_DIR librealsense/rs.h + HINTS /usr/include/ /usr/local/include) +#add a hint so that it can find it without the pkg-config +find_library(LIBREALSENSE_LIBRARY + NAMES librealsense.so + HINTS /usr/lib /usr/local/lib ) + + set(LIBREALSENSE_INCLUDE_DIRS ${LIBREALSENSE_INCLUDE_DIR}) + set(LIBREALSENSE_LIBRARIES ${LIBREALSENSE_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibRealSense DEFAULT_MSG + LIBREALSENSE_LIBRARY LIBREALSENSE_INCLUDE_DIR) + +mark_as_advanced(LIBREALSENSE_LIBRARY LIBREALSENSE_INCLUDE_DIR) diff --git a/thirdparty/Pangolin/CMakeModules/FindLibRealSense2.cmake b/thirdparty/Pangolin/CMakeModules/FindLibRealSense2.cmake new file mode 100644 index 00000000..12ae95d5 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindLibRealSense2.cmake @@ -0,0 +1,33 @@ +# -*- mode: cmake; -*- +############################################################################### +# Find librealsense2 https://github.com/IntelRealSense/librealsense +# +# This sets the following variables: +# LIBREALSENSE2_FOUND - True if LIBREALSENSE2 was found. +# LIBREALSENSE2_INCLUDE_DIRS - Directories containing the LIBREALSENSE2 include files. +# LIBREALSENSE2_LIBRARIES - Libraries needed to use LIBREALSENSE2. +# LIBREALSENSE2_DEFINITIONS - Compiler flags for LIBREALSENSE2. +# +# File forked from augmented_dev, project of alantrrs +# (https://github.com/alantrrs/augmented_dev). + +find_package(PkgConfig) +if(${CMAKE_VERSION} VERSION_LESS 2.8.2) +endif() + +#add a hint so that it can find it without the pkg-config +find_path(LIBREALSENSE2_INCLUDE_DIR librealsense2/rs.h + HINTS /usr/include/ /usr/local/include) +#add a hint so that it can find it without the pkg-config +find_library(LIBREALSENSE2_LIBRARY + NAMES librealsense2.so + HINTS /usr/lib /usr/local/lib ) + + set(LIBREALSENSE2_INCLUDE_DIRS ${LIBREALSENSE2_INCLUDE_DIR}) + set(LIBREALSENSE2_LIBRARIES ${LIBREALSENSE2_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibRealSense2 DEFAULT_MSG + LIBREALSENSE2_LIBRARY LIBREALSENSE2_INCLUDE_DIR) + +mark_as_advanced(LIBREALSENSE2_LIBRARY LIBREALSENSE2_INCLUDE_DIR) diff --git a/thirdparty/Pangolin/CMakeModules/FindLz4.cmake b/thirdparty/Pangolin/CMakeModules/FindLz4.cmake new file mode 100644 index 00000000..14bbf9e5 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindLz4.cmake @@ -0,0 +1,26 @@ + +find_path(Lz4_INCLUDE_DIRS + NAMES lz4frame.h + PATHS + /opt/local/include + /usr/local/include + /usr/include + ) + +find_library(Lz4_LIBRARIES + NAMES lz4 + PATHS + /usr/local/lib + /opt/local/lib + /user/local/lib + /usr/lib + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Lz4 REQUIRED_VARS Lz4_LIBRARIES Lz4_INCLUDE_DIRS) + +mark_as_advanced( + Lz4_INCLUDE_DIRS + Lz4_LIBRARIES + Lz4_FOUND +) diff --git a/thirdparty/Pangolin/CMakeModules/FindMediaFoundation.cmake b/thirdparty/Pangolin/CMakeModules/FindMediaFoundation.cmake new file mode 100644 index 00000000..0d8f47a8 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindMediaFoundation.cmake @@ -0,0 +1,20 @@ +# - Find MediaFoundation +# Find the Windows SDK MediaFoundation libraries +# +# MediaFoundation_LIBRARIES - List of libraries when using MediaFoundation +# MediaFoundation_FOUND - True if MediaFoundation found + +IF (MSVC) + SET( MediaFoundation_LIBRARIES mf.lib mfplat.lib mfreadwrite.lib mfuuid.lib strmiids.lib ) + SET( MediaFoundation_FOUND true ) +ENDIF (MSVC) + +IF (MediaFoundation_FOUND) + IF (NOT MediaFoundation_FIND_QUIETLY) + MESSAGE(STATUS "Found MediaFoundation: ${MediaFoundation_LIBRARIES}") + ENDIF (NOT MediaFoundation_FIND_QUIETLY) +ELSE (MediaFoundation_FOUND) + IF (MediaFoundation_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find MediaFoundation") + ENDIF (MediaFoundation_FIND_REQUIRED) +ENDIF (MediaFoundation_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/FindOculus.cmake b/thirdparty/Pangolin/CMakeModules/FindOculus.cmake new file mode 100644 index 00000000..04081628 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindOculus.cmake @@ -0,0 +1,63 @@ +# - Try to find Oculus Rift SDK +# +# Oculus_FOUND - system has libuvc +# Oculus_INCLUDE_DIRS - the libuvc include directories +# Oculus_LIBRARIES - link these to use libuvc + +FIND_PATH( + Oculus_INCLUDE_DIRS + NAMES OVR.h + PATHS + ${CMAKE_SOURCE_DIR}/../LibOVR/Include + ${CMAKE_SOURCE_DIR}/../OculusSDK/LibOVR/Include + /usr/include/LibOVR/Include + /usr/local/include/LibOVR/Include + /opt/local/include/LibOVR/Include + /usr/include/ + /usr/local/include + /opt/local/include +) + +FIND_LIBRARY( + Oculus_LIBRARIES + NAMES ovr + PATHS + ${CMAKE_SOURCE_DIR}/../LibOVR/Lib/MacOS/Release + ${CMAKE_SOURCE_DIR}/../OculusSDK/LibOVR/Lib/Linux/Release/x86_64 + /usr/include/LibOVR/Lib + /usr/local/include/LibOVR/Lib + /opt/local/include/LibOVR/Lib + /usr/lib + /usr/local/lib + /opt/local/lib +) + +IF(Oculus_INCLUDE_DIRS AND Oculus_LIBRARIES) + IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + find_library(CARBON_LIBRARIES NAMES Carbon) + find_library(IOKIT_LIBRARIES NAMES IOKit) + list(APPEND Oculus_LIBRARIES ${CARBON_LIBRARIES}) + list(APPEND Oculus_LIBRARIES ${IOKIT_LIBRARIES}) + SET(Oculus_FOUND TRUE) + ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + FIND_PACKAGE(Xrandr QUIET) + IF( Xrandr_FOUND ) + list(APPEND Oculus_LIBRARIES ${Xrandr_LIBRARIES} -ludev -lXrandr -lXinerama ) + SET(Oculus_FOUND TRUE) + ENDIF() + ENDIF() +ENDIF(Oculus_INCLUDE_DIRS AND Oculus_LIBRARIES) + + + +IF(Oculus_FOUND) + IF(NOT Oculus_FIND_QUIETLY) + MESSAGE(STATUS "Found Oculus: ${Oculus_LIBRARIES}") + MESSAGE(STATUS "Found Oculus: ${Oculus_INCLUDE_DIRS}") + ENDIF(NOT Oculus_FIND_QUIETLY) +ELSE(Oculus_FOUND) +message(STATUS "Oculus NOT found") + IF(Oculus_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Oculus") + ENDIF(Oculus_FIND_REQUIRED) +ENDIF(Oculus_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/FindOpenEXR.cmake b/thirdparty/Pangolin/CMakeModules/FindOpenEXR.cmake new file mode 100644 index 00000000..f4f5d8a5 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindOpenEXR.cmake @@ -0,0 +1,33 @@ +# Try to find the OpenEXR v2 lib and include files +# +# OpenEXR_INCLUDE_DIR +# OpenEXR_LIBRARIES +# OpenEXR_FOUND + +FIND_PATH( OpenEXR_INCLUDE_DIR ImfHeader.h + /usr/include + /usr/local/include + PATH_SUFFIXES OpenEXR +) + +FIND_LIBRARY( OpenEXR_LIBRARY IlmImf + /usr/lib64 + /usr/lib + /usr/local/lib +) + +IF(OpenEXR_INCLUDE_DIR AND OpenEXR_LIBRARY) + SET( OpenEXR_FOUND TRUE ) + SET( OpenEXR_LIBRARIES ${OpenEXR_LIBRARY} ) +ENDIF() + +IF(OpenEXR_FOUND) + IF(NOT OpenEXR_FIND_QUIETLY) + MESSAGE(STATUS "Found OpenEXR: ${OpenEXR_LIBRARY}") + ENDIF(NOT OpenEXR_FIND_QUIETLY) +ELSE(OpenEXR_FOUND) + IF(OpenEXR_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find libOpenEXR") + ENDIF(OpenEXR_FIND_REQUIRED) +ENDIF(OpenEXR_FOUND) + diff --git a/thirdparty/Pangolin/CMakeModules/FindOpenNI.cmake b/thirdparty/Pangolin/CMakeModules/FindOpenNI.cmake new file mode 100644 index 00000000..b5e9d9c8 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindOpenNI.cmake @@ -0,0 +1,49 @@ +# -*- mode: cmake; -*- +############################################################################### +# Find OpenNI +# +# This sets the following variables: +# OPENNI_FOUND - True if OPENNI was found. +# OPENNI_INCLUDE_DIRS - Directories containing the OPENNI include files. +# OPENNI_LIBRARIES - Libraries needed to use OPENNI. +# OPENNI_DEFINITIONS - Compiler flags for OPENNI. +# +# File forked from augmented_dev, project of alantrrs +# (https://github.com/alantrrs/augmented_dev). + +find_package(PkgConfig) +if(${CMAKE_VERSION} VERSION_LESS 2.8.2) + pkg_check_modules(PC_OPENNI openni-dev) +else() + pkg_check_modules(PC_OPENNI QUIET openni-dev) +endif() + +set(OPENNI_DEFINITIONS ${PC_OPENNI_CFLAGS_OTHER}) + +#using the 64bit version of OpenNi if generating for 64bit +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PROGRAMFILES_ "$ENV{PROGRAMW6432}") + set(OPENNI_SUFFIX "64") +else(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PROGRAMFILES_ "$ENV{PROGRAMFILES}") + set(OPENNI_SUFFIX "") +endif(CMAKE_SIZEOF_VOID_P EQUAL 8) + +#add a hint so that it can find it without the pkg-config +find_path(OPENNI_INCLUDE_DIR XnStatus.h + HINTS ${PC_OPENNI_INCLUDEDIR} ${PC_OPENNI_INCLUDE_DIRS} /usr/include/ni /usr/include/openni + "${PROGRAMFILES_}/OpenNI/Include" + PATH_SUFFIXES openni) +#add a hint so that it can find it without the pkg-config +find_library(OPENNI_LIBRARY + NAMES OpenNI64 OpenNI + HINTS ${PC_OPENNI_LIBDIR} ${PC_OPENNI_LIBRARY_DIRS} /usr/lib "${PROGRAMFILES_}/OpenNI/Lib${OPENNI_SUFFIX}") + +set(OPENNI_INCLUDE_DIRS ${OPENNI_INCLUDE_DIR}) +set(OPENNI_LIBRARIES ${OPENNI_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenNI DEFAULT_MSG + OPENNI_LIBRARY OPENNI_INCLUDE_DIR) + +mark_as_advanced(OPENNI_LIBRARY OPENNI_INCLUDE_DIR) diff --git a/thirdparty/Pangolin/CMakeModules/FindOpenNI2.cmake b/thirdparty/Pangolin/CMakeModules/FindOpenNI2.cmake new file mode 100644 index 00000000..2beb7aae --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindOpenNI2.cmake @@ -0,0 +1,59 @@ +############################################################################### +# Find OpenNI2 +# +# This sets the following variables: +# OPENNI2_FOUND - True if OPENNI was found. +# OPENNI2_INCLUDE_DIRS - Directories containing the OPENNI include files. +# OPENNI2_LIBRARIES - Libraries needed to use OPENNI. + +find_package(PkgConfig) +if(${CMAKE_VERSION} VERSION_LESS 2.8.2) + pkg_check_modules(PC_OPENNI openni2-dev) +else() + pkg_check_modules(PC_OPENNI QUIET openni2-dev) +endif() + +set(OPENNI2_DEFINITIONS ${PC_OPENNI_CFLAGS_OTHER}) + +#add a hint so that it can find it without the pkg-config +find_path(OPENNI2_INCLUDE_DIR OpenNI.h + HINTS + ${PC_OPENNI_INCLUDEDIR} + ${PC_OPENNI_INCLUDE_DIRS} + PATHS + "${PROGRAM_FILES}/OpenNI2/Include" + "${CMAKE_SOURCE_DIR}/../OpenNI2/Include" + /usr/include + /user/include + PATH_SUFFIXES openni2 ni2 +) + +if(${CMAKE_CL_64}) + set(OPENNI_PATH_SUFFIXES lib64 lib) +else() + set(OPENNI_PATH_SUFFIXES lib) +endif() + +#add a hint so that it can find it without the pkg-config +find_library(OPENNI2_LIBRARY + NAMES OpenNI2 + HINTS + ${PC_OPENNI_LIBDIR} + ${PC_OPENNI_LIBRARY_DIRS} + PATHS + "${PROGRAM_FILES}/OpenNI2/Redist" + "${PROGRAM_FILES}/OpenNI2" + "${CMAKE_SOURCE_DIR}/../OpenNI2/Bin/x64-Release" + /usr/lib + /user/lib + PATH_SUFFIXES ${OPENNI_PATH_SUFFIXES} +) + +set(OPENNI2_INCLUDE_DIRS ${OPENNI2_INCLUDE_DIR}) +set(OPENNI2_LIBRARIES ${OPENNI2_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenNI2 DEFAULT_MSG + OPENNI2_LIBRARY OPENNI2_INCLUDE_DIR) + +mark_as_advanced(OPENNI2_LIBRARY OPENNI2_INCLUDE_DIR) diff --git a/thirdparty/Pangolin/CMakeModules/FindPleora.cmake b/thirdparty/Pangolin/CMakeModules/FindPleora.cmake new file mode 100644 index 00000000..6a4a94df --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindPleora.cmake @@ -0,0 +1,143 @@ +# - Try to find Pleora SDK +# +# Pleora_FOUND - system has pleora eUSB SDK +# Pleora_INCLUDE_DIRS - the pleora eUSB SDK include directories +# Pleora_LIBRARIES - link these to use pleora eUSB SDK +# Pleora_BASE_DIR - set env varivales to this to use pleora eUSB SDK + +set( INCLUDE_SEARCH_PATHS + "/opt/pleora/ebus_sdk/Ubuntu-12.04-x86_64/include" + "/opt/pleora/ebus_sdk/Ubuntu-14.04-x86_64/include" + "$ENV{ProgramFiles}/Pleora Technologies Inc/eBUS SDK/Includes" +) + +set( LIBRARIES_SEARCH_PATHS + "/opt/pleora/ebus_sdk/Ubuntu-12.04-x86_64/lib" + "/opt/pleora/ebus_sdk/Ubuntu-14.04-x86_64/lib" + "$ENV{ProgramFiles}/Pleora Technologies Inc/eBUS SDK/Libraries" +) + +set( GENAPI_SEARCH_PATHS + "/opt/pleora/ebus_sdk/Ubuntu-12.04-x86_64/lib/genicam/bin/Linux64_x64" + "/opt/pleora/ebus_sdk/Ubuntu-12.04-x86_64/lib/genicam/bin/Linux32_ARM" + "/opt/pleora/ebus_sdk/Ubuntu-14.04-x86_64/lib/genicam/bin/Linux64_x64" + "/opt/pleora/ebus_sdk/Ubuntu-14.04-x86_64/lib/genicam/bin/Linux32_ARM" + "$ENV{ProgramW6432}/GenICam_v2_4/library/CPP/lib/Win64_x64" +) + +IF (${CMAKE_CL_64}) + set (LIB_NAME_SUFFIX "64") +ELSE() + set (LIB_NAME_SUFFIX "") +ENDIF() + +# Find header files +FIND_PATH( + PVBASE_INCLUDE_DIR PvBase.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) +FIND_PATH( + PVDEVICE_INCLUDE_DIR PvDevice.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) +FIND_PATH( + PVBUFFER_INCLUDE_DIR PvBuffer.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) +FIND_PATH( + PVGENICAM_INCLUDE_DIR PvGenICamLib.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) +FIND_PATH( + PVSTREAM_INCLUDE_DIR PvStream.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) +FIND_PATH( + PVTRANSMITTER_INCLUDE_DIR PvTransmitterLib.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) +FIND_PATH( + PVVIRTUALDEVICE_INCLUDE_DIR PvVirtualDeviceLib.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) +FIND_PATH( + PVSAMPLEUTILS_INCLUDE_DIR PvSampleUtils.h + HINTS ${PC_PLEORA_DIR}/include + PATHS ${INCLUDE_SEARCH_PATHS} +) + +# Find Library files +FIND_LIBRARY( + PVBASE_LIBRARY + NAMES "PvBase${LIB_NAME_SUFFIX}" + HINTS ${PC_PLEORA_DIR}/lib + PATH ${LIBRARIES_SEARCH_PATHS} +) +FIND_LIBRARY( + PVDEVICE_LIBRARY + NAMES "PvDevice${LIB_NAME_SUFFIX}" + HINTS ${PC_PLEORA_DIR}/lib + PATH ${LIBRARIES_SEARCH_PATHS} +) + +FIND_LIBRARY( + PVBUFFER_LIBRARY + NAMES "PvBuffer${LIB_NAME_SUFFIX}" + HINTS ${PC_PLEORA_DIR}/lib + PATH ${LIBRARIES_SEARCH_PATHS} +) +FIND_LIBRARY( + PVGENICAM_LIBRARY + NAMES "PvGenICam${LIB_NAME_SUFFIX}" + HINTS ${PC_PLEORA_DIR}/lib + PATH ${LIBRARIES_SEARCH_PATHS} +) +FIND_LIBRARY( + PVSTREAM_LIBRARY + NAMES "PvStream${LIB_NAME_SUFFIX}" + HINTS ${PC_PLEORA_DIR}/lib + PATH ${LIBRARIES_SEARCH_PATHS} +) +FIND_LIBRARY( + PVTRANSMITTER_LIBRARY + NAMES "PvTransmitter${LIB_NAME_SUFFIX}" + HINTS ${PC_PLEORA_DIR}/lib + PATH ${LIBRARIES_SEARCH_PATHS} +) +FIND_LIBRARY( + PVVIRTUALDEVICE_LIBRARY + NAMES "PvVirtualDevice${LIB_NAME_SUFFIX}" + HINTS ${PC_PLEORA_DIR}/lib + PATH ${LIBRARIES_SEARCH_PATHS} +) +FIND_LIBRARY( + GENAPI_LIBRARY + NAMES GenApi_gcc40_v2_4 GenApi_gcc43_v2_4 GenApi_MD_VC80_v2_4 + HINTS ${PC_GENAPI_LIBRARY_DIR} + PATH ${GENAPI_SEARCH_PATHS} +) + +IF(PVBASE_INCLUDE_DIR AND PVDEVICE_INCLUDE_DIR AND PVBUFFER_INCLUDE_DIR AND PVGENICAM_INCLUDE_DIR AND PVSTREAM_INCLUDE_DIR AND PVTRANSMITTER_INCLUDE_DIR AND PVVIRTUALDEVICE_INCLUDE_DIR AND PVSAMPLEUTILS_INCLUDE_DIR AND PVBASE_LIBRARY AND PVDEVICE_LIBRARY AND PVBUFFER_LIBRARY AND PVGENICAM_LIBRARY AND PVSTREAM_LIBRARY AND PVTRANSMITTER_LIBRARY AND PVVIRTUALDEVICE_LIBRARY AND GENAPI_LIBRARY) + SET(Pleora_FOUND TRUE) + string(REGEX REPLACE "include$" "" Pleora_BASE_DIR ${PVBASE_INCLUDE_DIR}) + SET(Pleora_LIBRARIES ${PVBASE_LIBRARY} ${PVDEVICE_LIBRARY} ${PVBUFFER_LIBRARY} ${PVGENICAM_LIBRARY} ${PVSTREAM_LIBRARY} ${PVTRANSMITTER_LIBRARY} ${PVVIRTUALDEVICE_LIBRARY} ${GENAPI_LIBRARY}) + SET(Pleora_INCLUDE_DIRS ${PVBASE_INCLUDE_DIR} ${PVDEVICE_INCLUDE_DIR} ${PVBUFFER_INCLUDE_DIR} ${PVGENICAM_INCLUDE_DIR} ${PVSTREAM_INCLUDE_DIR} ${PVTRANSMITTER_INCLUDE_DIR} ${PVVIRTUALDEVICE_INCLUDE_DIR} ${PVSAMPLEUTILS_INCLUDE_DIR}) +ENDIF() + + +IF (Pleora_FOUND) + IF (NOT Pleora_FIND_QUIETLY) + message(STATUS "Found Pleora: ${Pleora_LIBRARIES}") + ENDIF (NOT Pleora_FIND_QUIETLY) +ELSE (Pleora_FOUND) + IF (Pleora_FIND_REQUIRED) + message(FATAL_ERROR "Could not find Pleora") + ENDIF (Pleora_FIND_REQUIRED) +ENDIF (Pleora_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/FindROBOTVISION.cmake b/thirdparty/Pangolin/CMakeModules/FindROBOTVISION.cmake new file mode 100644 index 00000000..ea600d11 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindROBOTVISION.cmake @@ -0,0 +1,31 @@ +# - Try to find librobotvision +# +# ROBOTVISION_FOUND - system has librobotvision +# ROBOTVISION_INCLUDE_DIR - the librobotvision include directories +# ROBOTVISION_LIBRARY - link these to use librobotvision + +FIND_PATH( + ROBOTVISION_INCLUDE_DIR + NAMES robotvision/bundle_adjuster.h + PATHS ${CMAKE_SOURCE_DIR}/.. /usr/include/robotvision /usr/local/include/robotvision +) + +FIND_LIBRARY( + ROBOTVISION_LIBRARY + NAMES robotvision + PATHS ${CMAKE_SOURCE_DIR}/../robotvision/release /usr/lib /usr/local/lib +) + +IF (ROBOTVISION_INCLUDE_DIR AND ROBOTVISION_LIBRARY) + SET(ROBOTVISION_FOUND TRUE) +ENDIF (ROBOTVISION_INCLUDE_DIR AND ROBOTVISION_LIBRARY) + +IF (ROBOTVISION_FOUND) + IF (NOT ROBOTVISION_FIND_QUIETLY) + MESSAGE(STATUS "Found ROBOTVISION: ${ROBOTVISION_LIBRARY}") + ENDIF (NOT ROBOTVISION_FIND_QUIETLY) +ELSE (ROBOTVISION_FOUND) + IF (ROBOTVISION_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find ROBOTVISION") + ENDIF (ROBOTVISION_FIND_REQUIRED) +ENDIF (ROBOTVISION_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/FindTeliCam.cmake b/thirdparty/Pangolin/CMakeModules/FindTeliCam.cmake new file mode 100644 index 00000000..d2f70321 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindTeliCam.cmake @@ -0,0 +1,58 @@ +############################################################################### +# Find Toshiba TeliCam +# +# This sets the following variables: +# TeliCam_FOUND - True if TeliCam was found. +# TeliCam_INCLUDE_DIRS - Directories containing the TeliCam include files. +# TeliCam_LIBRARIES - Libraries needed to use TeliCam. + +find_path( + TeliCam_INCLUDE_DIR TeliCamApi.h + PATHS + "${PROGRAM_FILES}/Toshiba Teli/TeliCamSDK/TeliCamApi/Include" + "${CMAKE_SOURCE_DIR}/../TeliCamSDK/TeliCamApi/Include" + /usr/include + /user/include + /opt/TeliCamSDK/include + PATH_SUFFIXES TeliCam +) + +if(${CMAKE_CL_64}) + set(TELI_PATH_SUFFIXES x64) +else() + set(TELI_PATH_SUFFIXES x86) +endif() + +find_library( + TeliCamApi_LIBRARY + NAMES TeliCamApi TeliCamApi64 TeliCamApi_64 + PATHS + "${PROGRAM_FILES}/Toshiba Teli/TeliCamSDK/TeliCamApi/lib" + "${CMAKE_SOURCE_DIR}/../TeliCamSDK/TeliCamApi/lib" + /usr/lib + /user/lib + /opt/TeliCamSDK/lib + PATH_SUFFIXES ${TELI_PATH_SUFFIXES} +) + +find_library( + TeliCamUtl_LIBRARY + NAMES TeliCamUtl TeliCamUtl64 TeliCamUtl_64 + PATHS + "${PROGRAM_FILES}/Toshiba Teli/TeliCamSDK/TeliCamApi/lib" + "${CMAKE_SOURCE_DIR}/../TeliCamSDK/TeliCamApi/lib" + /usr/lib + /user/lib + /opt/TeliCamSDK/lib + PATH_SUFFIXES ${TELI_PATH_SUFFIXES} +) + +set(TeliCam_INCLUDE_DIRS ${TeliCam_INCLUDE_DIR}) +set(TeliCam_LIBRARY "${TeliCamApi_LIBRARY}" "${TeliCamUtl_LIBRARY}") +set(TeliCam_LIBRARIES ${TeliCam_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( TeliCam + FOUND_VAR TeliCam_FOUND + REQUIRED_VARS TeliCamApi_LIBRARY TeliCamUtl_LIBRARY TeliCam_INCLUDE_DIR +) diff --git a/thirdparty/Pangolin/CMakeModules/FindTooN.cmake b/thirdparty/Pangolin/CMakeModules/FindTooN.cmake new file mode 100644 index 00000000..13ce3d53 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindTooN.cmake @@ -0,0 +1,28 @@ +# - Try to find libTooN +# +# TooN_FOUND - system has libTooN +# TooN_INCLUDE_DIR - the libTooN include directories + +FIND_PATH( + TooN_INCLUDE_DIR + NAMES TooN/TooN.h + PATHS + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/.. + /usr/include + /usr/local/include +) + +IF(TooN_INCLUDE_DIR) + SET(TooN_FOUND TRUE) +ENDIF() + +IF(TooN_FOUND) + IF(NOT TooN_FIND_QUIETLY) + MESSAGE(STATUS "Found TooN: ${TooN_INCLUDE_DIR}") + ENDIF() +ELSE() + IF(TooN_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find TooN") + ENDIF() +ENDIF() diff --git a/thirdparty/Pangolin/CMakeModules/FindWayland.cmake b/thirdparty/Pangolin/CMakeModules/FindWayland.cmake new file mode 100644 index 00000000..f93218b8 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindWayland.cmake @@ -0,0 +1,66 @@ +# Try to find Wayland on a Unix system +# +# This will define: +# +# WAYLAND_FOUND - True if Wayland is found +# WAYLAND_LIBRARIES - Link these to use Wayland +# WAYLAND_INCLUDE_DIR - Include directory for Wayland +# WAYLAND_DEFINITIONS - Compiler flags for using Wayland +# +# In addition the following more fine grained variables will be defined: +# +# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES +# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES +# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES +# +# Copyright (c) 2013 Martin Gräßlin +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES) + # In the cache already + SET(WAYLAND_FIND_QUIETLY TRUE) + ENDIF () + + # Use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor) + + SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS}) + + FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + + FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + + set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR}) + + set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES}) + + list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR) + + MARK_AS_ADVANCED( + WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES + WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES + WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES + WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES + WAYLAND_CURSOR_INCLUDE_DIR WAYLAND_CURSOR_LIBRARIES + ) + +ENDIF () diff --git a/thirdparty/Pangolin/CMakeModules/FindXrandr.cmake b/thirdparty/Pangolin/CMakeModules/FindXrandr.cmake new file mode 100644 index 00000000..0ec84406 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/FindXrandr.cmake @@ -0,0 +1,32 @@ +# - Try to find Xrandr +# +# Xrandr_FOUND - system has libXrandr +# Xrandr_INCLUDE_DIRS - the libXrandr include directories +# Xrandr_LIBRARIES - link these to use libXrandr + +FIND_PATH( + Xrandr_INCLUDE_DIRS + NAMES X11/extensions/Xrandr.h + PATH_SUFFIXES X11/extensions + DOC "The Xrandr include directory" +) + +FIND_LIBRARY( + Xrandr_LIBRARIES + NAMES Xrandr + DOC "The Xrandr library" +) + +IF (Xrandr_INCLUDE_DIRS AND Xrandr_LIBRARIES) + SET(Xrandr_FOUND TRUE) +ENDIF (Xrandr_INCLUDE_DIRS AND Xrandr_LIBRARIES) + +IF (Xrandr_FOUND) + IF (NOT Xrandr_FIND_QUIETLY) + MESSAGE(STATUS "Found Xrandr: ${Xrandr_LIBRARIES}") + ENDIF (NOT Xrandr_FIND_QUIETLY) +ELSE (Xrandr_FOUND) + IF (Xrandr_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Xrandr") + ENDIF (Xrandr_FIND_REQUIRED) +ENDIF (Xrandr_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/Findlibusb1.cmake b/thirdparty/Pangolin/CMakeModules/Findlibusb1.cmake new file mode 100644 index 00000000..a2087285 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/Findlibusb1.cmake @@ -0,0 +1,42 @@ +# - Try to find libusb1 +# +# libusb1_FOUND - system has libusb1 +# libusb1_INCLUDE_DIRS - the libusb1 include directories +# libusb1_LIBRARIES - link these to use libusb1 + +FIND_PATH( + libusb1_INCLUDE_DIRS + NAMES libusb-1.0/libusb.h + PATHS + c:/dev/sysroot32/usr/include + ${CMAKE_SOURCE_DIR}/../libusb1/include + /usr/include/ + /usr/local/include + /opt/local/include +) + +FIND_LIBRARY( + libusb1_LIBRARIES + NAMES libusb-1.0 + PATHS + c:/dev/sysroot32/usr/lib + ${CMAKE_SOURCE_DIR}/../libusb1/lib + /usr/lib + /usr/local/lib + /opt/local/lib +) + +IF(libusb1_INCLUDE_DIRS AND libusb1_LIBRARIES) + SET(libusb1_FOUND TRUE) +ENDIF(libusb1_INCLUDE_DIRS AND libusb1_LIBRARIES) + +IF(libusb1_FOUND) + IF(NOT libusb1_FIND_QUIETLY) + MESSAGE(STATUS "Found libusb1: ${libusb1_LIBRARIES}") + ENDIF(NOT libusb1_FIND_QUIETLY) +ELSE(libusb1_FOUND) +message(STATUS "libusb1 NOT found") + IF(libusb1_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find libusb1") + ENDIF(libusb1_FIND_REQUIRED) +ENDIF(libusb1_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/Findpthread.cmake b/thirdparty/Pangolin/CMakeModules/Findpthread.cmake new file mode 100644 index 00000000..a1362aba --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/Findpthread.cmake @@ -0,0 +1,42 @@ +# - Try to find pthread +# +# pthread_FOUND - system has pthread +# pthread_INCLUDE_DIRS - the pthread include directories +# pthread_LIBRARIES - link these to use pthread + +FIND_PATH( + pthread_INCLUDE_DIRS + NAMES pthread.h + PATHS + c:/dev/sysroot32/usr/include + ${CMAKE_SOURCE_DIR}/../pthread/include + /usr/include/ + /usr/local/include + /opt/local/include +) + +FIND_LIBRARY( + pthread_LIBRARIES + NAMES pthreadVSE2 pthread + PATHS + c:/dev/sysroot32/usr/lib + ${CMAKE_SOURCE_DIR}/../pthread/lib + /usr/lib + /usr/local/lib + /opt/local/lib +) + +IF(pthread_INCLUDE_DIRS AND pthread_LIBRARIES) + SET(pthread_FOUND TRUE) +ENDIF(pthread_INCLUDE_DIRS AND pthread_LIBRARIES) + +IF(pthread_FOUND) + IF(NOT pthread_FIND_QUIETLY) + MESSAGE(STATUS "Found pthread: ${pthread_LIBRARIES}") + ENDIF(NOT pthread_FIND_QUIETLY) +ELSE(pthread_FOUND) +message(STATUS "pthread NOT found") + IF(pthread_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find pthread") + ENDIF(pthread_FIND_REQUIRED) +ENDIF(pthread_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/Finduvc.cmake b/thirdparty/Pangolin/CMakeModules/Finduvc.cmake new file mode 100644 index 00000000..fefe72f1 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/Finduvc.cmake @@ -0,0 +1,39 @@ +# - Try to find uvc +# +# uvc_FOUND - system has libuvc +# uvc_INCLUDE_DIRS - the libuvc include directories +# uvc_LIBRARIES - link these to use libuvc + +FIND_PATH( + uvc_INCLUDE_DIRS + NAMES libuvc/libuvc.h + PATHS + ${CMAKE_SOURCE_DIR}/.. + /usr/include/ + /usr/local/include + /opt/local/include +) + +FIND_LIBRARY( + uvc_LIBRARIES + NAMES uvc + PATHS + ${CMAKE_SOURCE_DIR}/../uvc/build + /usr/lib + /usr/local/lib + /opt/local/lib +) + +IF (uvc_INCLUDE_DIRS AND uvc_LIBRARIES) + SET(uvc_FOUND TRUE) +ENDIF (uvc_INCLUDE_DIRS AND uvc_LIBRARIES) + +IF (uvc_FOUND) + IF (NOT uvc_FIND_QUIETLY) + MESSAGE(STATUS "Found uvc: ${uvc_LIBRARIES}") + ENDIF (NOT uvc_FIND_QUIETLY) +ELSE (uvc_FOUND) + IF (uvc_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find uvc") + ENDIF (uvc_FIND_REQUIRED) +ENDIF (uvc_FOUND) diff --git a/thirdparty/Pangolin/CMakeModules/Findzstd.cmake b/thirdparty/Pangolin/CMakeModules/Findzstd.cmake new file mode 100644 index 00000000..f4faabb8 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/Findzstd.cmake @@ -0,0 +1,35 @@ +############################################################################### +# Find Toshiba TeliCam +# +# This sets the following variables: +# TeliCam_FOUND - True if TeliCam was found. +# TeliCam_INCLUDE_DIRS - Directories containing the TeliCam include files. +# TeliCam_LIBRARIES - Libraries needed to use TeliCam. + +find_path( + zstd_INCLUDE_DIR zstd.h + PATHS + /opt/local/include + /usr/local/include + /usr/include + PATH_SUFFIXES TeliCam +) + +find_library( + zstd_LIBRARY + NAMES zstd + PATHS + /opt/local/lib + /user/local/lib + /usr/lib +) + +# Plural forms +set(zstd_INCLUDE_DIRS ${zstd_INCLUDE_DIR}) +set(zstd_LIBRARIES ${zstd_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( zstd + FOUND_VAR zstd_FOUND + REQUIRED_VARS zstd_INCLUDE_DIR zstd_LIBRARY +) diff --git a/thirdparty/Pangolin/CMakeModules/SetPlatformVars.cmake b/thirdparty/Pangolin/CMakeModules/SetPlatformVars.cmake new file mode 100644 index 00000000..a07b35a2 --- /dev/null +++ b/thirdparty/Pangolin/CMakeModules/SetPlatformVars.cmake @@ -0,0 +1,56 @@ +## Compiler configuration +IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) + SET(_GCC_ 1) +ENDIF() + +IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + SET(_CLANG_ 1) +ENDIF() + +IF(MSVC) + SET(_MSVC_ 1) +ENDIF() + +## Platform configuration + +IF(WIN32 OR WIN64) + SET(_WIN_ 1) +ENDIF() + +IF(UNIX) + SET(_UNIX_ 1) +ENDIF() + +IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + SET(_OSX_ 1) +ENDIF() + +IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + SET(_LINUX_ 1) +ENDIF() + +IF(ANDROID) + SET(_ANDROID_ 1) +ENDIF() + +IF(IOS) + SET(_APPLE_IOS_ 1) +ENDIF() + + + +## Default search paths + +IF(_WIN_) + IF(${CMAKE_CL_64}) + LIST(APPEND CMAKE_INCLUDE_PATH "c:/dev/sysroot64/usr/include") + LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot64/usr/lib") + LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot64/usr/bin") + set(PROGRAM_FILES "$ENV{PROGRAMW6432}" ) + ELSE() + LIST(APPEND CMAKE_INCLUDE_PATH "c:/dev/sysroot32/usr/include") + LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot32/usr/lib") + LIST(APPEND CMAKE_LIBRARY_PATH "c:/dev/sysroot32/usr/bin") + set(PROGRAM_FILES "$ENV{PROGRAMFILES}" ) + ENDIF() +ENDIF() diff --git a/thirdparty/Pangolin/LICENCE b/thirdparty/Pangolin/LICENCE new file mode 100644 index 00000000..9b3c9002 --- /dev/null +++ b/thirdparty/Pangolin/LICENCE @@ -0,0 +1,22 @@ +Copyright (c) 2011 Steven Lovegrove and Richard Newcombe + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/thirdparty/Pangolin/README.md b/thirdparty/Pangolin/README.md new file mode 100644 index 00000000..676d987a --- /dev/null +++ b/thirdparty/Pangolin/README.md @@ -0,0 +1,176 @@ +What is Pangolin +==================================== + +Pangolin is a lightweight portable rapid development library for managing OpenGL +display / interaction and abstracting video input. At its heart is a simple +OpenGl viewport manager which can help to modularise 3D visualisation without +adding to its complexity, and offers an advanced but intuitive 3D navigation +handler. Pangolin also provides a mechanism for manipulating program variables +through config files and ui integration, and has a flexible real-time plotter +for visualising graphical data. + +The ethos of Pangolin is to reduce the boilerplate code that normally +gets written to visualise and interact with (typically image and 3D +based) systems, without compromising performance. It also enables write-once +code for a number of platforms, currently including Windows, Linux, OSX, Android +and IOS. + +## Code ## + +Find the latest version on [Github](http://github.com/stevenlovegrove/Pangolin): + +``` +git clone https://github.com/stevenlovegrove/Pangolin.git +``` + +## Dependencies ## + +Optional dependencies are enabled when found, otherwise they are silently disabled. +Check the CMake configure output for details. + +### Required Dependencies ### + +* C++11 + +* OpenGL (Desktop / ES / ES2) + * (lin) `sudo apt install libgl1-mesa-dev` + +* Glew + * (win) built automatically (assuming git is on your path) + * (deb) `sudo apt install libglew-dev` + * (mac) `sudo port install glew` + +* CMake (for build environment) + * (win) http://www.cmake.org/cmake/resources/software.html + * (deb) `sudo apt install cmake` + * (mac) `sudo port install cmake` + +### Recommended Dependencies ### + +* Python2 / Python3, for drop-down interactive console + * (win) http://www.python.org/downloads/windows + * (deb) `sudo apt install libpython2.7-dev` + * (mac) preinstalled with osx + * (for pybind11) `git submodule init && git submodule update` + * (useful modules) `sudo python -mpip install numpy pyopengl Pillow pybind11` + +* Wayland + * pkg-config: `sudo apt install pkg-config` + * Wayland and EGL:`sudo apt install libegl1-mesa-dev libwayland-dev libxkbcommon-dev wayland-protocols` + +### Optional Dependencies for video input ### + +* FFMPEG (For video decoding and image rescaling) + * (deb) `sudo apt install ffmpeg libavcodec-dev libavutil-dev libavformat-dev libswscale-dev libavdevice-dev` + +* DC1394 (For firewire input) + * (deb) `sudo apt install libdc1394-22-dev libraw1394-dev` + +* libuvc (For cross-platform webcam video input via libusb) + * git://github.com/ktossell/libuvc.git + +* libjpeg, libpng, libtiff, libopenexr (For reading still-image sequences) + * (deb) `sudo apt install libjpeg-dev libpng12-dev libtiff5-dev libopenexr-dev` + +* OpenNI / OpenNI2 (For Kinect / Xtrion / Primesense capture) + +* DepthSense SDK + +### Very Optional Dependencies ### + +* Eigen / TooN (These matrix types supported in the Pangolin API.) + +* CUDA Toolkit >= 3.2 (Some CUDA header-only interop utilities included) + * http://developer.nvidia.com/cuda-downloads + +* Doxygen for generating html / pdf documentation. + +## Building ## + +Pangolin uses the CMake portable pre-build tool. To checkout and build pangolin in the +directory 'build', execute the following at a shell (or the equivelent using a GUI): + +``` +git clone https://github.com/stevenlovegrove/Pangolin.git +cd Pangolin +mkdir build +cd build +cmake .. +cmake --build . +``` + +If you would like to build the documentation and you have Doxygen installed, you +can execute: + +``` +cmake --build . --target doc +``` + +**On Windows**, Pangolin will attempt to download and build *glew*, *libjpeg*, *libpng* and *zlib* automatically. It does so assuming that git is available on the path - this assumption may be wrong for windows users who have downloaded Pangolin via a zip file on github. You will instead need to download and compile the dependencies manually, and set the BUILD_EXTERN_(lib) options to false for these libraries. The alternate and recommended approach is to install [gitbash](https://git-scm.com/downloads) and work from within their provided console. + +## Issues ## + +Please visit [Github Issues](https://github.com/stevenlovegrove/Pangolin/issues) to view and report problems with Pangolin. Issues and pull requests should be raised against the master branch which contains the current development version. + +Please note; most Pangolin dependencies are optional - to disable a dependency which may be causing trouble on your machine, set the BUILD_PANGOLIN_(option) variable to false with a cmake configuration tool (e.g. ccmake or cmake-gui). + +## Contributions and Continuous Integration ## + +For CI, Pangolin uses [travis-ci.org](https://travis-ci.org/stevenlovegrove/Pangolin) for Ubuntu, OSX and [ci.appveyor.com](https://ci.appveyor.com/project/stevenlovegrove/pangolin) for Windows. + +To contribute to Pangolin, I would appreciate pull requests against the master branch. This will trigger CI builds for your changes automatically, and help me to merge with confidence. + +## Binaries ## + +Binaries are available for Windows x64, as output by the Windows CI server: [Appveyor Artifacts](https://ci.appveyor.com/project/stevenlovegrove/pangolin/build/artifacts). + +## Bindings ## + +### Python ### + +Pangolin python bindings are enabled via [pybind11](www.pybind11.com). These bindings can be used both standalone and from within Pangolin's drop-down console (press the back-tick key, `). + +To enable the bindings, you must checkout the pybind submodule. To use pangolin in python, it's recommend to install a few other python packages too: + +``` +sudo python -mpip install numpy pyopengl Pillow pybind11 +git submodule init && git submodule update +``` + +The python module pypangolin must be on your python path, either through installation, or by setting it explicitly: + +``` +import sys +sys.path.append('path/of/pypangolin.so') +``` + +## Scheme syntax for windowing and video + +Pangolin uses 'URI' syntax for modularising video drivers and windowing backends. The syntax follows along the lines of `module_name:[option1=value1,option2=value2,...]//module_resource_to_open`. Some examples for using this URI syntax with the VideoViewer tool is as follows: + +``` +VideoViewer test:// +VideoViewer uvc:[size=640x480]///dev/video0 +VideoViewer flip://debayer:[tile=rggb,method=downsample]//file://~/somefile.pango +``` + +Notice that for video, some modules support chaining to construct a simple filter graph. See include/pangolin/video/video.h for more examples. + +For windowing, you can also customize default arguments for Pangolin applications by setting the `PANGOLIN_WINDOW_URI` environment variable. For instance, on high-DPI screens (in this example on OSX), you could set: + + +``` +setenv PANGOLIN_WINDOW_URI "cocoa:[HIGHRES=true]//" +``` + +Some window parameters that may be interesting to override are `DISPLAYNAME`, `DOUBLEBUFFER`, `SAMPLE_BUFFERS`, `SAMPLES`, `HIGHRES`. Window modules currently include `x11`, `winapi`, `cocoa`. + +## Acknowledgements ## + +I'd like to thank the growing number of kind contributors to Pangolin for helping to make it more stable and feature rich. Many features of Pangolin have been influenced by other projects such as GFlags, GLConsole, and libcvd in particular. I'd also like to thank the FOSS projects on which Pangolin depends. + +For a summary of those who have made code contributions, execute: + +``` +git shortlog -sne +``` diff --git a/thirdparty/Pangolin/appveyor.yml b/thirdparty/Pangolin/appveyor.yml new file mode 100644 index 00000000..313a1934 --- /dev/null +++ b/thirdparty/Pangolin/appveyor.yml @@ -0,0 +1,25 @@ +os: Visual Studio 2015 + +clone_folder: c:/projects/Pangolin + +platform: x64 +configuration: Release + +build: + verbosity: minimal + project: c:/projects/Pangolin/build/Pangolin.sln + +install: + - ps: wget http://bitbucket.org/eigen/eigen/get/3.2.10.zip -outfile eigen3.zip + - cmd: 7z x eigen3.zip -o"C:/projects" -y > nul + +before_build: + - cd c:/projects/Pangolin + - mkdir bin + - mkdir build + - cd build + - cmake -G "Visual Studio 14 2015 Win64" -D EIGEN3_INCLUDE_DIR=C:/projects/eigen-eigen-b9cd8366d4e8 -D CMAKE_INSTALL_PREFIX=../bin .. + +on_success: + - 7z a pangolin_build.zip "c:/projects/Pangolin/build/src/include" "c:/projects/Pangolin/build/src/Release/pangolin.lib" "c:/projects/Pangolin/build/tools/*/Release/*.exe" "c:/projects/Pangolin/build/examples/*/Release/*.exe" + - appveyor PushArtifact pangolin_build.zip diff --git a/thirdparty/Pangolin/cmake_uninstall.cmake.in b/thirdparty/Pangolin/cmake_uninstall.cmake.in new file mode 100644 index 00000000..6dc07779 --- /dev/null +++ b/thirdparty/Pangolin/cmake_uninstall.cmake.in @@ -0,0 +1,25 @@ +# ----------------------------------------------- +# File that provides "make uninstall" target +# We use the file 'install_manifest.txt' +# ----------------------------------------------- +IF(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + IF(EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) + ELSE(EXISTS "$ENV{DESTDIR}${file}") + MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) diff --git a/thirdparty/Pangolin/examples/CMakeLists.txt b/thirdparty/Pangolin/examples/CMakeLists.txt new file mode 100644 index 00000000..e2caa611 --- /dev/null +++ b/thirdparty/Pangolin/examples/CMakeLists.txt @@ -0,0 +1,33 @@ +# All examples depend on Pangolin GUI +if(BUILD_PANGOLIN_GUI) + add_subdirectory(HelloPangolin) + add_subdirectory(HelloPangolinOffscreen) + add_subdirectory(HelloPangolinThreads) + add_subdirectory(SimpleMultiDisplay) + add_subdirectory(SimpleDisplayImage) + add_subdirectory(SimpleScene) + + if(NOT HAVE_GLES OR HAVE_GLES_2) + add_subdirectory(SimplePlot) + endif() + + ## These samples require Pangolin Var support + if(BUILD_PANGOLIN_VARS) + add_subdirectory(SimpleDisplay) + + ## Video Samples require Pangolin Video support + if(BUILD_PANGOLIN_VIDEO) + add_subdirectory(SimpleVideo) + add_subdirectory(SimpleRecord) + add_subdirectory(SharedMemoryCamera) + endif() + +# # This sample fails on many platforms, so exclude it for now, +# # until we can create a better cmake test for support. +# find_package(CUDA QUIET) +# if( CUDA_FOUND ) +# add_subdirectory(VBODisplay) +# endif() + + endif() +endif() diff --git a/thirdparty/Pangolin/examples/HelloPangolin/CMakeLists.txt b/thirdparty/Pangolin/examples/HelloPangolin/CMakeLists.txt new file mode 100644 index 00000000..f37389aa --- /dev/null +++ b/thirdparty/Pangolin/examples/HelloPangolin/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(HelloPangolin main.cpp) +target_link_libraries(HelloPangolin ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/HelloPangolin/main.cpp b/thirdparty/Pangolin/examples/HelloPangolin/main.cpp new file mode 100644 index 00000000..cc6de199 --- /dev/null +++ b/thirdparty/Pangolin/examples/HelloPangolin/main.cpp @@ -0,0 +1,34 @@ +#include + +int main( int /*argc*/, char** /*argv*/ ) +{ + pangolin::CreateWindowAndBind("Main",640,480); + glEnable(GL_DEPTH_TEST); + + // Define Projection and initial ModelView matrix + pangolin::OpenGlRenderState s_cam( + pangolin::ProjectionMatrix(640,480,420,420,320,240,0.2,100), + pangolin::ModelViewLookAt(-2,2,-2, 0,0,0, pangolin::AxisY) + ); + + // Create Interactive View in window + pangolin::Handler3D handler(s_cam); + pangolin::View& d_cam = pangolin::CreateDisplay() + .SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f) + .SetHandler(&handler); + + while( !pangolin::ShouldQuit() ) + { + // Clear screen and activate view to render into + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + d_cam.Activate(s_cam); + + // Render OpenGL Cube + pangolin::glDrawColouredCube(); + + // Swap frames and Process Events + pangolin::FinishFrame(); + } + + return 0; +} diff --git a/thirdparty/Pangolin/examples/HelloPangolinOffscreen/CMakeLists.txt b/thirdparty/Pangolin/examples/HelloPangolinOffscreen/CMakeLists.txt new file mode 100644 index 00000000..8653de32 --- /dev/null +++ b/thirdparty/Pangolin/examples/HelloPangolinOffscreen/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.5 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(HelloPangolinOffscreen main.cpp) +target_link_libraries(HelloPangolinOffscreen ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/HelloPangolinOffscreen/main.cpp b/thirdparty/Pangolin/examples/HelloPangolinOffscreen/main.cpp new file mode 100644 index 00000000..e26df9a3 --- /dev/null +++ b/thirdparty/Pangolin/examples/HelloPangolinOffscreen/main.cpp @@ -0,0 +1,48 @@ +#include + +int main( int /*argc*/, char** /*argv*/ ) +{ + static const int w = 640; + static const int h = 480; + + pangolin::CreateWindowAndBind("Main",w,h,pangolin::Params({{"scheme", "headless"}})); + glEnable(GL_DEPTH_TEST); + + // Define Projection and initial ModelView matrix + pangolin::OpenGlRenderState s_cam( + pangolin::ProjectionMatrix(w,h,420,420,320,240,0.2,100), + pangolin::ModelViewLookAt(-2,2,-2, 0,0,0, pangolin::AxisY) + ); + + // Create Interactive View in window + pangolin::Handler3D handler(s_cam); + pangolin::View& d_cam = pangolin::CreateDisplay() + .SetBounds(0.0, 1.0, 0.0, 1.0, -float(w)/float(h)) + .SetHandler(&handler); + + pangolin::SaveWindowOnRender("window"); + + // create a frame buffer object with colour and depth buffer + pangolin::GlTexture color_buffer(w,h); + pangolin::GlRenderBuffer depth_buffer(w,h); + pangolin::GlFramebuffer fbo_buffer(color_buffer, depth_buffer); + fbo_buffer.Bind(); + + // Clear screen and activate view to render into + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + d_cam.Activate(s_cam); + + // Render OpenGL Cube + pangolin::glDrawColouredCube(); + + // Swap frames and Process Events + pangolin::FinishFrame(); + + fbo_buffer.Unbind(); + // download and save the colour buffer + color_buffer.Save("fbo.png", false); + + pangolin::QuitAll(); + + return 0; +} diff --git a/thirdparty/Pangolin/examples/HelloPangolinThreads/CMakeLists.txt b/thirdparty/Pangolin/examples/HelloPangolinThreads/CMakeLists.txt new file mode 100644 index 00000000..78f02a31 --- /dev/null +++ b/thirdparty/Pangolin/examples/HelloPangolinThreads/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.5 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(HelloPangolinThreads main.cpp) +target_link_libraries(HelloPangolinThreads ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/HelloPangolinThreads/main.cpp b/thirdparty/Pangolin/examples/HelloPangolinThreads/main.cpp new file mode 100644 index 00000000..04803322 --- /dev/null +++ b/thirdparty/Pangolin/examples/HelloPangolinThreads/main.cpp @@ -0,0 +1,64 @@ +#include +#include + +static const std::string window_name = "HelloPangolinThreads"; + +void setup() { + // create a window and bind its context to the main thread + pangolin::CreateWindowAndBind(window_name, 640, 480); + + // enable depth + glEnable(GL_DEPTH_TEST); + + // unset the current context from the main thread + pangolin::GetBoundWindow()->RemoveCurrent(); +} + +void run() { + // fetch the context and bind it to this thread + pangolin::BindToContext(window_name); + + // we manually need to restore the properties of the context + glEnable(GL_DEPTH_TEST); + + // Define Projection and initial ModelView matrix + pangolin::OpenGlRenderState s_cam( + pangolin::ProjectionMatrix(640,480,420,420,320,240,0.2,100), + pangolin::ModelViewLookAt(-2,2,-2, 0,0,0, pangolin::AxisY) + ); + + // Create Interactive View in window + pangolin::Handler3D handler(s_cam); + pangolin::View& d_cam = pangolin::CreateDisplay() + .SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f) + .SetHandler(&handler); + + while( !pangolin::ShouldQuit() ) + { + // Clear screen and activate view to render into + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + d_cam.Activate(s_cam); + + // Render OpenGL Cube + pangolin::glDrawColouredCube(); + + // Swap frames and Process Events + pangolin::FinishFrame(); + } + + // unset the current context from the main thread + pangolin::GetBoundWindow()->RemoveCurrent(); +} + +int main( int /*argc*/, char** /*argv*/ ) +{ + // create window and context in the main thread + setup(); + + // use the context in a separate rendering thread + std::thread render_loop; + render_loop = std::thread(run); + render_loop.join(); + + return 0; +} diff --git a/thirdparty/Pangolin/examples/SharedMemoryCamera/CMakeLists.txt b/thirdparty/Pangolin/examples/SharedMemoryCamera/CMakeLists.txt new file mode 100644 index 00000000..567aeed4 --- /dev/null +++ b/thirdparty/Pangolin/examples/SharedMemoryCamera/CMakeLists.txt @@ -0,0 +1,7 @@ +if(UNIX) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SharedMemoryCamera main.cpp) +target_link_libraries(SharedMemoryCamera ${Pangolin_LIBRARIES}) +endif() diff --git a/thirdparty/Pangolin/examples/SharedMemoryCamera/main.cpp b/thirdparty/Pangolin/examples/SharedMemoryCamera/main.cpp new file mode 100644 index 00000000..29ba6ae2 --- /dev/null +++ b/thirdparty/Pangolin/examples/SharedMemoryCamera/main.cpp @@ -0,0 +1,53 @@ +#include + +#include +#include +#include + +#include +#include + +// This sample acts as a soft camera. It writes a pattern of GRAY8 pixels to the +// shared memory space. It can be seen in Pangolin's SimpleVideo sample using +// the shmem:[size=640x480]//example video URI. + +using namespace pangolin; + +unsigned char generate_value(double t) +{ + // 10s sinusoid + const double d = std::sin(t * 10.0 / M_PI) * 128.0 + 128.0; + return static_cast(d); +} + +int main(/*int argc, char *argv[]*/) +{ + std::string shmem_name = "/example"; + + std::shared_ptr shmem_buffer = + create_named_shared_memory_buffer(shmem_name, 640 * 480); + if (!shmem_buffer) { + perror("Unable to create shared memory buffer"); + exit(1); + } + + std::string cond_name = shmem_name + "_cond"; + std::shared_ptr buffer_full = + create_named_condition_variable(cond_name); + + // Sit in a loop and write gray values based on some timing pattern. + while (true) { + shmem_buffer->lock(); + unsigned char *ptr = shmem_buffer->ptr(); + unsigned char value = generate_value(std::chrono::system_clock::now().time_since_epoch().count()); + + for (int i = 0; i < 640*480; ++i) { + ptr[i] = value; + } + + shmem_buffer->unlock(); + buffer_full->signal(); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } +} diff --git a/thirdparty/Pangolin/examples/SimpleDisplay/CMakeLists.txt b/thirdparty/Pangolin/examples/SimpleDisplay/CMakeLists.txt new file mode 100644 index 00000000..fe858589 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleDisplay/CMakeLists.txt @@ -0,0 +1,7 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SimpleDisplay main.cpp) +target_link_libraries(SimpleDisplay ${Pangolin_LIBRARIES} ) + diff --git a/thirdparty/Pangolin/examples/SimpleDisplay/app.cfg b/thirdparty/Pangolin/examples/SimpleDisplay/app.cfg new file mode 100644 index 00000000..cf3661b9 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleDisplay/app.cfg @@ -0,0 +1,26 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Pangolin Sample configuration file +% Comments start with '%' or '#' +% +% Declarations are name value pairs, +% seperated with '=' and terminated with ';' + +% We can set any variable referenced in code directly +ui.A Double = 3.2; +ui.A Checkbox = false; + +% We can set unreferenced variables too +a.b = 1; +a.c = 2; +z.b = 3; +z.c = 4; +start = z; + +% Which we might refer to by reference +ui.An Int = ${${start}.c}; + +% Declarations can span multiple lines +M = +[1, 0, 0 + 0, 1, 0 + 0, 0, 1]; diff --git a/thirdparty/Pangolin/examples/SimpleDisplay/main.cpp b/thirdparty/Pangolin/examples/SimpleDisplay/main.cpp new file mode 100644 index 00000000..850bde4d --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleDisplay/main.cpp @@ -0,0 +1,129 @@ +#include +#include + +struct CustomType +{ + CustomType() + : x(0), y(0.0f) {} + + CustomType(int x, float y, std::string z) + : x(x), y(y), z(z) {} + + int x; + float y; + std::string z; +}; + +std::ostream& operator<< (std::ostream& os, const CustomType& o){ + os << o.x << " " << o.y << " " << o.z; + return os; +} + +std::istream& operator>> (std::istream& is, CustomType& o){ + is >> o.x; + is >> o.y; + is >> o.z; + return is; +} + +void SampleMethod() +{ + std::cout << "You typed ctrl-r or pushed reset" << std::endl; +} + + +int main(/*int argc, char* argv[]*/) +{ + // Load configuration data + pangolin::ParseVarsFile("app.cfg"); + + // Create OpenGL window in single line + pangolin::CreateWindowAndBind("Main",640,480); + + // 3D Mouse handler requires depth testing to be enabled + glEnable(GL_DEPTH_TEST); + + // Define Camera Render Object (for view / scene browsing) + pangolin::OpenGlRenderState s_cam( + pangolin::ProjectionMatrix(640,480,420,420,320,240,0.1,1000), + pangolin::ModelViewLookAt(-0,0.5,-3, 0,0,0, pangolin::AxisY) + ); + + const int UI_WIDTH = 180; + + // Add named OpenGL viewport to window and provide 3D Handler + pangolin::View& d_cam = pangolin::CreateDisplay() + .SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, -640.0f/480.0f) + .SetHandler(new pangolin::Handler3D(s_cam)); + + // Add named Panel and bind to variables beginning 'ui' + // A Panel is just a View with a default layout and input handling + pangolin::CreatePanel("ui") + .SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH)); + + // Safe and efficient binding of named variables. + // Specialisations mean no conversions take place for exact types + // and conversions between scalar types are cheap. + pangolin::Var a_button("ui.A_Button",false,false); + pangolin::Var a_double("ui.A_Double",3,0,5); + pangolin::Var an_int("ui.An_Int",2,0,5); + pangolin::Var a_double_log("ui.Log_scale var",3,1,1E4, true); + pangolin::Var a_checkbox("ui.A_Checkbox",false,true); + pangolin::Var an_int_no_input("ui.An_Int_No_Input",2); + pangolin::Var any_type("ui.Some_Type", CustomType(0,1.2f,"Hello") ); + + pangolin::Var save_window("ui.Save_Window",false,false); + pangolin::Var save_cube("ui.Save_Cube",false,false); + + pangolin::Var record_cube("ui.Record_Cube",false,false); + + // std::function objects can be used for Var's too. These work great with C++11 closures. + pangolin::Var > reset("ui.Reset", SampleMethod); + + // Demonstration of how we can register a keyboard hook to alter a Var + pangolin::RegisterKeyPressCallback(pangolin::PANGO_CTRL + 'b', pangolin::SetVarFunctor("ui.A_Double", 3.5)); + + // Demonstration of how we can register a keyboard hook to trigger a method + pangolin::RegisterKeyPressCallback(pangolin::PANGO_CTRL + 'r', SampleMethod); + + // Default hooks for exiting (Esc) and fullscreen (tab). + while( !pangolin::ShouldQuit() ) + { + // Clear entire screen + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if( pangolin::Pushed(a_button) ) + std::cout << "You Pushed a button!" << std::endl; + + // Overloading of Var operators allows us to treat them like + // their wrapped types, eg: + if( a_checkbox ) + an_int = (int)a_double; + + if( !any_type->z.compare("robot")) + any_type = CustomType(1,2.3f,"Boogie"); + + an_int_no_input = an_int; + + if( pangolin::Pushed(save_window) ) + pangolin::SaveWindowOnRender("window"); + + if( pangolin::Pushed(save_cube) ) + d_cam.SaveOnRender("cube"); + + if( pangolin::Pushed(record_cube) ) + pangolin::DisplayBase().RecordOnRender("ffmpeg:[fps=50,bps=8388608,unique_filename]//screencap.avi"); + + // Activate efficiently by object + d_cam.Activate(s_cam); + + // Render some stuff + glColor3f(1.0,1.0,1.0); + pangolin::glDrawColouredCube(); + + // Swap frames and Process Events + pangolin::FinishFrame(); + } + + return 0; +} diff --git a/thirdparty/Pangolin/examples/SimpleDisplayImage/CMakeLists.txt b/thirdparty/Pangolin/examples/SimpleDisplayImage/CMakeLists.txt new file mode 100644 index 00000000..57f37b03 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleDisplayImage/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SimpleDisplayImage main.cpp) +target_link_libraries(SimpleDisplayImage ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/SimpleDisplayImage/main.cpp b/thirdparty/Pangolin/examples/SimpleDisplayImage/main.cpp new file mode 100644 index 00000000..5dd87b43 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleDisplayImage/main.cpp @@ -0,0 +1,72 @@ +#include +#include +#include + +void setImageData(unsigned char * imageArray, int size){ + for(int i = 0 ; i < size;i++) { + imageArray[i] = (unsigned char)(rand()/(RAND_MAX/255.0)); + } +} + +int main(/*int argc, char* argv[]*/) +{ + // Create OpenGL window in single line + pangolin::CreateWindowAndBind("Main",640,480); + + // 3D Mouse handler requires depth testing to be enabled + glEnable(GL_DEPTH_TEST); + + pangolin::OpenGlRenderState s_cam( + pangolin::ProjectionMatrix(640,480,420,420,320,240,0.1,1000), + pangolin::ModelViewLookAt(-1,1,-1, 0,0,0, pangolin::AxisY) + ); + + // Aspect ratio allows us to constrain width and height whilst fitting within specified + // bounds. A positive aspect ratio makes a view 'shrink to fit' (introducing empty bars), + // whilst a negative ratio makes the view 'grow to fit' (cropping the view). + pangolin::View& d_cam = pangolin::Display("cam") + .SetBounds(0,1.0f,0,1.0f,-640/480.0) + .SetHandler(new pangolin::Handler3D(s_cam)); + + // This view will take up no more than a third of the windows width or height, and it + // will have a fixed aspect ratio to match the image that it will display. When fitting + // within the specified bounds, push to the top-left (as specified by SetLock). + pangolin::View& d_image = pangolin::Display("image") + .SetBounds(2/3.0f,1.0f,0,1/3.0f,640.0/480) + .SetLock(pangolin::LockLeft, pangolin::LockTop); + + std::cout << "Resize the window to experiment with SetBounds, SetLock and SetAspect." << std::endl; + std::cout << "Notice that the cubes aspect is maintained even though it covers the whole screen." << std::endl; + + const int width = 64; + const int height = 48; + + unsigned char* imageArray = new unsigned char[3*width*height]; + pangolin::GlTexture imageTexture(width,height,GL_RGB,false,0,GL_RGB,GL_UNSIGNED_BYTE); + + // Default hooks for exiting (Esc) and fullscreen (tab). + while(!pangolin::ShouldQuit()) + { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + d_cam.Activate(s_cam); + + glColor3f(1.0,1.0,1.0); + pangolin::glDrawColouredCube(); + + //Set some random image data and upload to GPU + setImageData(imageArray,3*width*height); + imageTexture.Upload(imageArray,GL_RGB,GL_UNSIGNED_BYTE); + + //display the image + d_image.Activate(); + glColor3f(1.0,1.0,1.0); + imageTexture.RenderToViewport(); + + pangolin::FinishFrame(); + } + + delete[] imageArray; + + return 0; +} diff --git a/thirdparty/Pangolin/examples/SimpleMultiDisplay/CMakeLists.txt b/thirdparty/Pangolin/examples/SimpleMultiDisplay/CMakeLists.txt new file mode 100644 index 00000000..3d91937b --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleMultiDisplay/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SimpleMultiDisplay main.cpp) +target_link_libraries(SimpleMultiDisplay ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/SimpleMultiDisplay/app.cfg b/thirdparty/Pangolin/examples/SimpleMultiDisplay/app.cfg new file mode 100644 index 00000000..08c9c8c7 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleMultiDisplay/app.cfg @@ -0,0 +1,28 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Pangolin Sample configuration file +% Comments start with '%' or '#' +% +% Declarations are name value pairs, +% seperated with '=' and terminated with ';' + +% We can set any variable referenced in code directly +ui.A Double = 3.2; + +% We can set unreferenced variables too +a.b = 1; +a.c = 2; +z.b = 3; +z.c = 4; +start = z; + +% Which we might refer to by reference +ui.An Int = ${${start}.c}; + +% Declarations can span multiple lines +M = +[1, 0, 0 + 0, 1, 0 + 0, 0, 1]; + +ui.Aliased Double = @ui.A Double; +ui.Aliased Double = 2.0; diff --git a/thirdparty/Pangolin/examples/SimpleMultiDisplay/main.cpp b/thirdparty/Pangolin/examples/SimpleMultiDisplay/main.cpp new file mode 100644 index 00000000..79bb22b7 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleMultiDisplay/main.cpp @@ -0,0 +1,106 @@ +#include +#include + +void setImageData(unsigned char * imageArray, int size){ + for(int i = 0 ; i < size;i++) { + imageArray[i] = (unsigned char)(rand()/(RAND_MAX/255.0)); + } +} + +int main(/*int argc, char* argv[]*/) +{ + // Create OpenGL window in single line + pangolin::CreateWindowAndBind("Main",640,480); + + // 3D Mouse handler requires depth testing to be enabled + glEnable(GL_DEPTH_TEST); + + // Issue specific OpenGl we might need + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Define Camera Render Object (for view / scene browsing) + pangolin::OpenGlMatrix proj = pangolin::ProjectionMatrix(640,480,420,420,320,240,0.1,1000); + pangolin::OpenGlRenderState s_cam(proj, pangolin::ModelViewLookAt(1,0.5,-2,0,0,0, pangolin::AxisY) ); + pangolin::OpenGlRenderState s_cam2(proj, pangolin::ModelViewLookAt(0,0,-2,0,0,0, pangolin::AxisY) ); + + // Add named OpenGL viewport to window and provide 3D Handler + pangolin::View& d_cam1 = pangolin::Display("cam1") + .SetAspect(640.0f/480.0f) + .SetHandler(new pangolin::Handler3D(s_cam)); + + pangolin::View& d_cam2 = pangolin::Display("cam2") + .SetAspect(640.0f/480.0f) + .SetHandler(new pangolin::Handler3D(s_cam2)); + + pangolin::View& d_cam3 = pangolin::Display("cam3") + .SetAspect(640.0f/480.0f) + .SetHandler(new pangolin::Handler3D(s_cam)); + + pangolin::View& d_cam4 = pangolin::Display("cam4") + .SetAspect(640.0f/480.0f) + .SetHandler(new pangolin::Handler3D(s_cam2)); + + pangolin::View& d_img1 = pangolin::Display("img1") + .SetAspect(640.0f/480.0f); + + pangolin::View& d_img2 = pangolin::Display("img2") + .SetAspect(640.0f/480.0f); + + // LayoutEqual is an EXPERIMENTAL feature - it requires that all sub-displays + // share the same aspect ratio, placing them in a raster fasion in the + // viewport so as to maximise display size. + pangolin::Display("multi") + .SetBounds(0.0, 1.0, 0.0, 1.0) + .SetLayout(pangolin::LayoutEqual) + .AddDisplay(d_cam1) + .AddDisplay(d_img1) + .AddDisplay(d_cam2) + .AddDisplay(d_img2) + .AddDisplay(d_cam3) + .AddDisplay(d_cam4); + + const int width = 64; + const int height = 48; + unsigned char* imageArray = new unsigned char[3*width*height]; + pangolin::GlTexture imageTexture(width,height,GL_RGB,false,0,GL_RGB,GL_UNSIGNED_BYTE); + + // Default hooks for exiting (Esc) and fullscreen (tab). + while( !pangolin::ShouldQuit() ) + { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Generate random image and place in texture memory for display + setImageData(imageArray,3*width*height); + imageTexture.Upload(imageArray,GL_RGB,GL_UNSIGNED_BYTE); + + glColor3f(1.0,1.0,1.0); + + d_cam1.Activate(s_cam); + pangolin::glDrawColouredCube(); + + d_cam2.Activate(s_cam2); + pangolin::glDrawColouredCube(); + + d_cam3.Activate(s_cam); + pangolin::glDrawColouredCube(); + + d_cam4.Activate(s_cam2); + pangolin::glDrawColouredCube(); + + d_img1.Activate(); + glColor4f(1.0f,1.0f,1.0f,1.0f); + imageTexture.RenderToViewport(); + + d_img2.Activate(); + glColor4f(1.0f,1.0f,1.0f,1.0f); + imageTexture.RenderToViewport(); + + // Swap frames and Process Events + pangolin::FinishFrame(); + } + + delete[] imageArray; + + return 0; +} diff --git a/thirdparty/Pangolin/examples/SimplePlot/CMakeLists.txt b/thirdparty/Pangolin/examples/SimplePlot/CMakeLists.txt new file mode 100644 index 00000000..62a6de77 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimplePlot/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SimplePlot main.cpp) +target_link_libraries(SimplePlot ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/SimplePlot/main.cpp b/thirdparty/Pangolin/examples/SimplePlot/main.cpp new file mode 100644 index 00000000..a931e4e4 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimplePlot/main.cpp @@ -0,0 +1,49 @@ +#include + +#include + +int main(/*int argc, char* argv[]*/) +{ + // Create OpenGL window in single line + pangolin::CreateWindowAndBind("Main",640,480); + + // Data logger object + pangolin::DataLog log; + + // Optionally add named labels + std::vector labels; + labels.push_back(std::string("sin(t)")); + labels.push_back(std::string("cos(t)")); + labels.push_back(std::string("sin(t)+cos(t)")); + log.SetLabels(labels); + + const float tinc = 0.01f; + + // OpenGL 'view' of data. We might have many views of the same data. + pangolin::Plotter plotter(&log,0.0f,4.0f*(float)M_PI/tinc,-2.0f,2.0f,(float)M_PI/(4.0f*tinc),0.5f); + plotter.SetBounds(0.0, 1.0, 0.0, 1.0); + plotter.Track("$i"); + + // Add some sample annotations to the plot + plotter.AddMarker(pangolin::Marker::Vertical, -1000, pangolin::Marker::LessThan, pangolin::Colour::Blue().WithAlpha(0.2f) ); + plotter.AddMarker(pangolin::Marker::Horizontal, 100, pangolin::Marker::GreaterThan, pangolin::Colour::Red().WithAlpha(0.2f) ); + plotter.AddMarker(pangolin::Marker::Horizontal, 10, pangolin::Marker::Equal, pangolin::Colour::Green().WithAlpha(0.2f) ); + + pangolin::DisplayBase().AddDisplay(plotter); + + float t = 0; + + // Default hooks for exiting (Esc) and fullscreen (tab). + while( !pangolin::ShouldQuit() ) + { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + log.Log(sin(t),cos(t),sin(t)+cos(t)); + t += tinc; + + // Render graph, Swap frames and Process Events + pangolin::FinishFrame(); + } + + return 0; +} diff --git a/thirdparty/Pangolin/examples/SimpleRecord/CMakeLists.txt b/thirdparty/Pangolin/examples/SimpleRecord/CMakeLists.txt new file mode 100644 index 00000000..8977c0ef --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleRecord/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SimpleRecord main.cpp) +target_link_libraries(SimpleRecord ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/SimpleRecord/main.cpp b/thirdparty/Pangolin/examples/SimpleRecord/main.cpp new file mode 100644 index 00000000..9999adf6 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleRecord/main.cpp @@ -0,0 +1,94 @@ +#include + +void RecordSample(const std::string input_uri, const std::string record_uri) +{ + // Setup Video Source + pangolin::VideoInput video(input_uri); + const pangolin::PixelFormat vid_fmt = video.PixFormat(); + const unsigned w = video.Width(); + const unsigned h = video.Height(); + + pangolin::VideoOutput recorder( record_uri ); + recorder.SetStreams(video.Streams()); + + // Create OpenGL window + pangolin::CreateWindowAndBind("Main",w,h); + + // Create viewport for video with fixed aspect + pangolin::View vVideo((float)w/h); + + // OpenGl Texture for video frame + pangolin::GlTexture texVideo(w,h,GL_RGBA); + + // Allocate image buffer. The +1 is to give ffmpeg some alignment slack + // swscale seems to have a bug which goes over the array by 1... + unsigned char* img = new unsigned char[video.SizeBytes() + 1]; + + while( !pangolin::ShouldQuit() ) + { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + if( video.GrabNext(img,true) ) + { + // Upload to GPU as texture for display + texVideo.Upload(img, vid_fmt.channels==1 ? GL_LUMINANCE:GL_RGB, GL_UNSIGNED_BYTE); + + // Record video frame + recorder.WriteStreams(img); + } + + // Activate video viewport and render texture + vVideo.Activate(); + texVideo.RenderToViewportFlipY(); + + // Swap back buffer with front and process window events + pangolin::FinishFrame(); + } + + delete[] img; +} + +int main( int argc, char* argv[] ) +{ + std::string record_uri = "ffmpeg:[fps=30,bps=8388608]//video.avi"; + + std::string input_uris[] = { + "dc1394:[fps=30,dma=10,size=640x480,iso=400]//0", + "convert:[fmt=RGB24]//v4l:///dev/video0", + "convert:[fmt=RGB24]//v4l:///dev/video1", + "" + }; + + if( argc >= 2 ) { + const std::string uri = std::string(argv[1]); + if( argc == 3 ) { + record_uri = std::string(argv[2]); + } + RecordSample(uri, record_uri); + }else{ + std::cout << "Usage : SimpleRecord [video-uri] [output-uri]" << std::endl << std::endl; + std::cout << "Where video-uri describes a stream or file resource, e.g." << std::endl; + std::cout << "\tfile:[realtime=1]///home/user/video/movie.pvn" << std::endl; + std::cout << "\tfile:///home/user/video/movie.avi" << std::endl; + std::cout << "\tfiles:///home/user/seqiemce/foo%03d.jpeg" << std::endl; + std::cout << "\tdc1394:[fmt=RGB24,size=640x480,fps=30,iso=400,dma=10]//0" << std::endl; + std::cout << "\tdc1394:[fmt=FORMAT7_1,size=640x480,pos=2+2,iso=400,dma=10]//0" << std::endl; + std::cout << "\tv4l:///dev/video0" << std::endl; + std::cout << "\tconvert:[fmt=RGB24]//v4l:///dev/video0" << std::endl; + std::cout << "\tmjpeg://http://127.0.0.1/?action=stream" << std::endl; + std::cout << std::endl; + + // Try to open some video device + for(int i=0; !input_uris[i].empty(); ++i ) + { + try{ + std::cout << "Trying: " << input_uris[i] << std::endl; + RecordSample(input_uris[i], record_uri); + return 0; + }catch(const pangolin::VideoException&) {} + } + } + + return 0; + +} diff --git a/thirdparty/Pangolin/examples/SimpleScene/CMakeLists.txt b/thirdparty/Pangolin/examples/SimpleScene/CMakeLists.txt new file mode 100644 index 00000000..2ad25497 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleScene/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SimpleScene main.cpp) +target_link_libraries(SimpleScene ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/SimpleScene/main.cpp b/thirdparty/Pangolin/examples/SimpleScene/main.cpp new file mode 100644 index 00000000..2423dc6d --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleScene/main.cpp @@ -0,0 +1,40 @@ +#include +#include +#include + +int main( int /*argc*/, char** /*argv*/ ) +{ + pangolin::CreateWindowAndBind("Main",640,480); + glEnable(GL_DEPTH_TEST); + + // Define Projection and initial ModelView matrix + pangolin::OpenGlRenderState s_cam( + pangolin::ProjectionMatrix(640,480,420,420,320,240,0.2,100), + pangolin::ModelViewLookAt(-2,2,-2, 0,0,0, pangolin::AxisY) + ); + + pangolin::Renderable tree; + tree.Add( std::make_shared() ); + + // Create Interactive View in window + pangolin::SceneHandler handler(tree, s_cam); + pangolin::View& d_cam = pangolin::CreateDisplay() + .SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f) + .SetHandler(&handler); + + d_cam.SetDrawFunction([&](pangolin::View& view){ + view.Activate(s_cam); + tree.Render(); + }); + + while( !pangolin::ShouldQuit() ) + { + // Clear screen and activate view to render into + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Swap frames and Process Events + pangolin::FinishFrame(); + } + + return 0; +} diff --git a/thirdparty/Pangolin/examples/SimpleVideo/CMakeLists.txt b/thirdparty/Pangolin/examples/SimpleVideo/CMakeLists.txt new file mode 100644 index 00000000..0be7165d --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleVideo/CMakeLists.txt @@ -0,0 +1,6 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) + +add_executable(SimpleVideo main.cpp) +target_link_libraries(SimpleVideo ${Pangolin_LIBRARIES}) diff --git a/thirdparty/Pangolin/examples/SimpleVideo/main.cpp b/thirdparty/Pangolin/examples/SimpleVideo/main.cpp new file mode 100644 index 00000000..81c03448 --- /dev/null +++ b/thirdparty/Pangolin/examples/SimpleVideo/main.cpp @@ -0,0 +1,111 @@ +/** + * @author Steven Lovegrove + * Copyright (C) 2010 Steven Lovegrove + * Imperial College London + **/ + +#include + +void SetGlFormat(GLint& glformat, GLenum& gltype, const pangolin::PixelFormat& fmt) +{ + switch( fmt.channels) { + case 1: glformat = GL_LUMINANCE; break; + case 3: glformat = GL_RGB; break; + case 4: glformat = GL_RGBA; break; + default: throw std::runtime_error("Unable to display video format"); + } + + switch (fmt.channel_bits[0]) { + case 8: gltype = GL_UNSIGNED_BYTE; break; + case 16: gltype = GL_UNSIGNED_SHORT; break; + case 32: gltype = GL_FLOAT; break; + default: throw std::runtime_error("Unknown channel format"); + } +} + +void VideoSample(const std::string uri) +{ + // Setup Video Source + pangolin::VideoInput video(uri); + const pangolin::PixelFormat vid_fmt = video.PixFormat(); + const unsigned w = video.Width(); + const unsigned h = video.Height(); + + // Work out appropriate GL channel and format options + GLint glformat; + GLenum gltype; + SetGlFormat(glformat, gltype, vid_fmt); + + // Create OpenGL window + pangolin::CreateWindowAndBind("Main",w,h); + + // Create viewport for video with fixed aspect + pangolin::View& vVideo = pangolin::Display("Video").SetAspect((float)w/h); + + // OpenGl Texture for video frame. + pangolin::GlTexture texVideo(w,h,glformat,false,0,glformat,gltype); + + unsigned char* img = new unsigned char[video.SizeBytes()]; + + for(int frame=0; !pangolin::ShouldQuit(); ++frame) + { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + if( video.GrabNext(img,true) ) { + texVideo.Upload( img, glformat, gltype ); + } + + // Activate video viewport and render texture + vVideo.Activate(); + texVideo.RenderToViewportFlipY(); + + // Swap back buffer with front and process window events + pangolin::FinishFrame(); + } + + delete[] img; +} + + +int main( int argc, char* argv[] ) +{ + std::string uris[] = { + "dc1394:[fps=30,dma=10,size=640x480,iso=400]//0", + "convert:[fmt=RGB24]//v4l:///dev/video0", + "convert:[fmt=RGB24]//v4l:///dev/video1", + "openni:[img1=rgb]//", + "pleora:[sn=00000215,size=640x480,pos=64x64]//", + "test:[size=160x120,n=1,fmt=RGB24]//" + "" + }; + + if( argc > 1 ) { + const std::string uri = std::string(argv[1]); + VideoSample(uri); + }else{ + std::cout << "Usage : SimpleRecord [video-uri]" << std::endl << std::endl; + std::cout << "Where video-uri describes a stream or file resource, e.g." << std::endl; + std::cout << "\tfile:[realtime=1]///home/user/video/movie.pvn" << std::endl; + std::cout << "\tfile:///home/user/video/movie.avi" << std::endl; + std::cout << "\tfiles:///home/user/seqiemce/foo%03d.jpeg" << std::endl; + std::cout << "\tdc1394:[fmt=RGB24,size=640x480,fps=30,iso=400,dma=10]//0" << std::endl; + std::cout << "\tdc1394:[fmt=FORMAT7_1,size=640x480,pos=2+2,iso=400,dma=10]//0" << std::endl; + std::cout << "\tv4l:///dev/video0" << std::endl; + std::cout << "\tconvert:[fmt=RGB24]//v4l:///dev/video0" << std::endl; + std::cout << "\tmjpeg://http://127.0.0.1/?action=stream" << std::endl; + std::cout << "\topenni:[img1=rgb]//" << std::endl; + std::cout << std::endl; + + // Try to open some video device + for(int i=0; !uris[i].empty(); ++i ) + { + try{ + std::cout << "Trying: " << uris[i] << std::endl; + VideoSample(uris[i]); + return 0; + }catch(const pangolin::VideoException&) { } + } + } + + return 0; +} diff --git a/thirdparty/Pangolin/examples/VBODisplay/CMakeLists.txt b/thirdparty/Pangolin/examples/VBODisplay/CMakeLists.txt new file mode 100644 index 00000000..28a5b7e1 --- /dev/null +++ b/thirdparty/Pangolin/examples/VBODisplay/CMakeLists.txt @@ -0,0 +1,19 @@ +# Find Pangolin (https://github.com/stevenlovegrove/Pangolin) +find_package(Pangolin 0.4 REQUIRED) +include_directories(${Pangolin_INCLUDE_DIRS}) +link_directories(${Pangolin_LIBRARY_DIRS}) +link_libraries(${Pangolin_LIBRARIES}) + +find_package(CUDA QUIET) + +# This example could be made to work with C++11, but the kernel code must be +# compiled without it. +if(CUDA_FOUND) + cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + + cuda_add_executable( + VBODisplay + main.cpp kernal.cu + ) + +endif() diff --git a/thirdparty/Pangolin/examples/VBODisplay/kernal.cu b/thirdparty/Pangolin/examples/VBODisplay/kernal.cu new file mode 100644 index 00000000..07d06ba4 --- /dev/null +++ b/thirdparty/Pangolin/examples/VBODisplay/kernal.cu @@ -0,0 +1,30 @@ +// Colour Sine wave Kernal +// Based on kernal_colour in kernelVBO.cpp by Rob Farber +__global__ void kernel(float4* dVertexArray, uchar4 *dColorArray, + unsigned int width, unsigned int height, float time) +{ + unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; + unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; + + // Each thread is unique point (u,v) in interval [-1,1],[-1,1] + const float u = 2.0f* (x/(float)width) - 1.0f; + const float v = 2.0f* (y/(float)height) - 1.0f; + const float w = 0.5f * sinf(4.0f*u + time) * cosf(4.0f*v + time); + + // Update vertex array for point + dVertexArray[y*width+x] = make_float4(u, w, v, 1.0f); + + // Update colour array for point + dColorArray[y*width+x].w = 0.0f; + dColorArray[y*width+x].x = 255.0f *0.5f*(1.f+sinf(w+x)); + dColorArray[y*width+x].y = 255.0f *0.5f*(1.f+sinf(x)*cosf(y)); + dColorArray[y*width+x].z = 255.0f *0.5f*(1.f+sinf(w+time/10.0f)); +} + +extern "C" void launch_kernel(float4* dVertexArray, uchar4* dColourArray, + unsigned int width, unsigned int height, float time) +{ + dim3 block(8, 8, 1); + dim3 grid(width / block.x, height / block.y, 1); + kernel<<< grid, block>>>(dVertexArray, dColourArray, width, height, time); +} diff --git a/thirdparty/Pangolin/examples/VBODisplay/main.cpp b/thirdparty/Pangolin/examples/VBODisplay/main.cpp new file mode 100644 index 00000000..6b7f778a --- /dev/null +++ b/thirdparty/Pangolin/examples/VBODisplay/main.cpp @@ -0,0 +1,84 @@ +#include + +#include + +#include +#include +#include + +#include +#include +#include + +using namespace pangolin; +using namespace std; + +// Mesh size +const int mesh_width=256; +const int mesh_height=256; + +extern "C" void launch_kernel(float4* dVertexArray, uchar4* dColourArray, unsigned int width, unsigned int height, float time); + +int main( int /*argc*/, char* argv[] ) +{ +// cudaGLSetGLDevice(0); + + pangolin::CreateWindowAndBind("Main",640,480); + glewInit(); + + // 3D Mouse handler requires depth testing to be enabled + glEnable(GL_DEPTH_TEST); + + // Create vertex and colour buffer objects and register them with CUDA + GlBufferCudaPtr vertex_array( + GlArrayBuffer, mesh_width*mesh_height, GL_FLOAT, 4, + cudaGraphicsMapFlagsWriteDiscard, GL_STREAM_DRAW + ); + GlBufferCudaPtr colour_array( + GlArrayBuffer, mesh_width*mesh_height, GL_UNSIGNED_BYTE, 4, + cudaGraphicsMapFlagsWriteDiscard, GL_STREAM_DRAW + ); + + // Define Camera Render Object (for view / scene browsing) + pangolin::OpenGlRenderState s_cam( + ProjectionMatrix(640,480,420,420,320,240,0.1,1000), + ModelViewLookAt(-0,2,-2, 0,0,0, AxisY) + ); + const int UI_WIDTH = 180; + + // Add named OpenGL viewport to window and provide 3D Handler + View& d_cam = pangolin::Display("cam") + .SetBounds(0.0, 1.0, Attach::Pix(UI_WIDTH), 1.0, -640.0f/480.0f) + .SetHandler(new Handler3D(s_cam)); + + // Add named Panel and bind to variables beginning 'ui' + // A Panel is just a View with a default layout and input handling + View& d_panel = pangolin::CreatePanel("ui") + .SetBounds(0.0, 1.0, 0.0, Attach::Pix(UI_WIDTH)); + + // Default hooks for exiting (Esc) and fullscreen (tab). + for(int frame=0; !pangolin::ShouldQuit(); ++frame) + { + static double time = 0; + static Var delta("ui.time delta", 0.001, 0, 0.005); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + d_cam.Activate(s_cam); + glColor3f(1.0,1.0,1.0); + + { + CudaScopedMappedPtr var(vertex_array); + CudaScopedMappedPtr car(colour_array); + launch_kernel((float4*)*var,(uchar4*)*car,mesh_width,mesh_height,time); + time += delta; + } + + pangolin::RenderVboCbo(vertex_array, colour_array); + + // Swap frames and Process Events + pangolin::FinishFrame(); + } + + return 0; +} diff --git a/thirdparty/Pangolin/external/CMakeLists.txt b/thirdparty/Pangolin/external/CMakeLists.txt new file mode 100644 index 00000000..c247f4cb --- /dev/null +++ b/thirdparty/Pangolin/external/CMakeLists.txt @@ -0,0 +1,153 @@ +include(ExternalProject) + +set(ExternConfig "") + +if( BUILD_EXTERN_GLEW ) + +######################################################### +# GLEW +######################################################### +ExternalProject_Add( __glew + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/glew" + GIT_REPOSITORY https://github.com/Perlmint/glew-cmake.git + GIT_TAG 7574ab4d00b683e56adbfdec7da636529dfe65d8 + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} + -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} + -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} + -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} +) + +add_library(_glew STATIC IMPORTED GLOBAL) +add_dependencies(_glew __glew) +set_target_properties(_glew PROPERTIES + IMPORTED_LOCATION_RELWITHDEBINFO ${CMAKE_INSTALL_PREFIX}/lib/glew.lib + IMPORTED_LOCATION_RELEASE ${CMAKE_INSTALL_PREFIX}/lib/glew.lib + IMPORTED_LOCATION_DEBUG ${CMAKE_INSTALL_PREFIX}/lib/glewd.lib +) + +set(GLEW_FOUND true PARENT_SCOPE) +set(GLEW_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include" PARENT_SCOPE) +set(GLEW_LIBRARY _glew PARENT_SCOPE) +set(GLEW_STATIC 1 PARENT_SCOPE) +set(ExternConfig "${ExternConfig} + add_library(_glew STATIC IMPORTED) + set_target_properties(_glew PROPERTIES + IMPORTED_LOCATION_RELWITHDEBINFO \"${CMAKE_INSTALL_PREFIX}/lib/glew.lib\" + IMPORTED_LOCATION_RELEASE \"${CMAKE_INSTALL_PREFIX}/lib/glew.lib\" + IMPORTED_LOCATION_DEBUG \"${CMAKE_INSTALL_PREFIX}/lib/glewd.lib\" + )") +endif() + +if( BUILD_EXTERN_LIBPNG ) + +######################################################### +# zlib +######################################################### + +ExternalProject_Add( __zlib + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/zlib" + GIT_REPOSITORY https://github.com/madler/zlib.git + GIT_TAG v1.2.8 + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} + -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} + -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} + -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} +) +add_library(_zlib STATIC IMPORTED GLOBAL) +add_dependencies(_zlib __zlib) +set_target_properties(_zlib PROPERTIES + IMPORTED_LOCATION_RELEASE ${CMAKE_INSTALL_PREFIX}/lib/zlibstatic.lib + IMPORTED_LOCATION_RELWITHDEBINFO ${CMAKE_INSTALL_PREFIX}/lib/zlibstatic.lib + IMPORTED_LOCATION_DEBUG ${CMAKE_INSTALL_PREFIX}/lib/zlibstaticd.lib +) + +######################################################### +# libpng +######################################################### + +ExternalProject_Add( __libpng + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/libpng" + GIT_REPOSITORY https://github.com/glennrp/libpng.git + GIT_TAG v1.6.18 + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DZLIB_INCLUDE_DIR=${CMAKE_INSTALL_PREFIX}/include + -DZLIB_LIBRARY=${CMAKE_INSTALL_PREFIX}/lib/zlibstatic*.lib + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} + -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} + -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} + -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} + DEPENDS __zlib +) + +add_library(_libpng STATIC IMPORTED GLOBAL) +add_dependencies(_libpng __libpng) +set_target_properties(_libpng PROPERTIES + IMPORTED_LOCATION_RELWITHDEBINFO ${CMAKE_INSTALL_PREFIX}/lib/libpng16_static.lib + IMPORTED_LOCATION_RELEASE ${CMAKE_INSTALL_PREFIX}/lib/libpng16_static.lib + IMPORTED_LOCATION_DEBUG ${CMAKE_INSTALL_PREFIX}/lib/libpng16_staticd.lib +) + +set(PNG_FOUND true PARENT_SCOPE) +set(PNG_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include" PARENT_SCOPE) +set(PNG_LIBRARY _libpng PARENT_SCOPE) +set(ZLIB_LIBRARY _zlib PARENT_SCOPE) +set(ExternConfig "${ExternConfig} + add_library(_zlib STATIC IMPORTED) + set_target_properties(_zlib PROPERTIES + IMPORTED_LOCATION_RELEASE \"${CMAKE_INSTALL_PREFIX}/lib/zlibstatic.lib\" + IMPORTED_LOCATION_RELWITHDEBINFO \"${CMAKE_INSTALL_PREFIX}/lib/zlibstatic.lib\" + IMPORTED_LOCATION_DEBUG \"${CMAKE_INSTALL_PREFIX}/lib/zlibstaticd.lib\" + ) + add_library(_libpng STATIC IMPORTED) + set_target_properties(_libpng PROPERTIES + IMPORTED_LOCATION_RELEASE \"${CMAKE_INSTALL_PREFIX}/lib/libpng16_static.lib\" + IMPORTED_LOCATION_RELWITHDEBINFO \"${CMAKE_INSTALL_PREFIX}/lib/libpng16_static.lib\" + IMPORTED_LOCATION_DEBUG \"${CMAKE_INSTALL_PREFIX}/lib/libpng16_staticd.lib\" + )") +endif() + +if( BUILD_EXTERN_LIBJPEG ) + +######################################################### +# libjpg +######################################################### + +ExternalProject_Add( __libjpeg + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/libjpeg" + GIT_REPOSITORY https://github.com/LuaDist/libjpeg.git + GIT_TAG bc8f8be222287fec977ec3f47a5cb065cceb2ee9 + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DBUILD_SHARED_LIBS=false + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} + -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} + -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} + -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} +) + +add_library(_libjpeg STATIC IMPORTED GLOBAL) +add_dependencies(_libjpeg __libjpeg) +set_target_properties(_libjpeg PROPERTIES + IMPORTED_LOCATION ${CMAKE_INSTALL_PREFIX}/lib/jpeg.lib +) + +set(JPEG_FOUND true PARENT_SCOPE) +set(JPEG_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include" PARENT_SCOPE) +set(JPEG_LIBRARY _libjpeg PARENT_SCOPE) +set(ExternConfig "${ExternConfig} + add_library(_libjpeg STATIC IMPORTED) + set_target_properties(_libjpeg PROPERTIES + IMPORTED_LOCATION \"${CMAKE_INSTALL_PREFIX}/lib/jpeg.lib\" + )") +endif() + +set(ExternConfig "${ExternConfig}" PARENT_SCOPE) diff --git a/thirdparty/Pangolin/include/experimental/optional.hpp b/thirdparty/Pangolin/include/experimental/optional.hpp new file mode 100644 index 00000000..e3722b0c --- /dev/null +++ b/thirdparty/Pangolin/include/experimental/optional.hpp @@ -0,0 +1,1067 @@ +// Copyright (C) 2011 - 2012 Andrzej Krzemienski. +// +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The idea and interface is based on Boost.Optional library +// authored by Fernando Luis Cacciola Carballal + +# ifndef ___OPTIONAL_HPP___ +# define ___OPTIONAL_HPP___ + +# include +# include +# include +# include +# include +# include +# include + +# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false + +# if defined __GNUC__ // NOTE: GNUC is also defined for Clang +# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) +# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +# endif +# +# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7) +# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +# endif +# +# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# endif +# endif +# +# if defined __clang_major__ +# if (__clang_major__ == 3 && __clang_minor__ >= 5) +# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# elif (__clang_major__ > 3) +# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# endif +# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2) +# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +# endif +# endif +# +# if defined _MSC_VER +# if (_MSC_VER >= 1900) +# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +# endif +# endif + +# if defined __clang__ +# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# else +# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +# endif +# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# else +# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +# endif + + +# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1 +# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr +# else +# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0 +# define OPTIONAL_CONSTEXPR_INIT_LIST +# endif + +# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L) +# define OPTIONAL_HAS_MOVE_ACCESSORS 1 +# else +# define OPTIONAL_HAS_MOVE_ACCESSORS 0 +# endif + +# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr +# if (defined __cplusplus) && (__cplusplus == 201103L) +# define OPTIONAL_MUTABLE_CONSTEXPR +# else +# define OPTIONAL_MUTABLE_CONSTEXPR constexpr +# endif + +namespace std{ + +namespace experimental{ + +// BEGIN workaround for missing is_trivially_destructible +# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ + // leave it: it is already there +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS + // leave it: the user doesn't want it +# else + template + using is_trivially_destructible = std::has_trivial_destructor; +# endif +// END workaround for missing is_trivially_destructible + +# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___) + // leave it; our metafunctions are already defined. +# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ + // leave it; our metafunctions are already defined. +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS + // leave it: the user doesn't want it +# else + + +// workaround for missing traits in GCC and CLANG +template +struct is_nothrow_move_constructible +{ + constexpr static bool value = std::is_nothrow_constructible::value; +}; + + +template +struct is_assignable +{ + template + constexpr static bool has_assign(...) { return false; } + + template () = std::declval(), true)) > + // the comma operator is necessary for the cases where operator= returns void + constexpr static bool has_assign(bool) { return true; } + + constexpr static bool value = has_assign(true); +}; + + +template +struct is_nothrow_move_assignable +{ + template + struct has_nothrow_move_assign { + constexpr static bool value = false; + }; + + template + struct has_nothrow_move_assign { + constexpr static bool value = noexcept( std::declval() = std::declval() ); + }; + + constexpr static bool value = has_nothrow_move_assign::value>::value; +}; +// end workaround + + +# endif + + + +// 20.5.4, optional for object types +template class optional; + +// 20.5.5, optional for lvalue reference types +template class optional; + + +// workaround: std utility functions aren't constexpr yet +template inline constexpr T&& constexpr_forward(typename std::remove_reference::type& t) noexcept +{ + return static_cast(t); +} + +template inline constexpr T&& constexpr_forward(typename std::remove_reference::type&& t) noexcept +{ + static_assert(!std::is_lvalue_reference::value, "!!"); + return static_cast(t); +} + +template inline constexpr typename std::remove_reference::type&& constexpr_move(T&& t) noexcept +{ + return static_cast::type&&>(t); +} + + +#if defined NDEBUG +# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR) +#else +# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR))) +#endif + + +namespace detail_ +{ + +// static_addressof: a constexpr version of addressof +template +struct has_overloaded_addressof +{ + template + constexpr static bool has_overload(...) { return false; } + + template ().operator&()) > + constexpr static bool has_overload(bool) { return true; } + + constexpr static bool value = has_overload(true); +}; + +template )> +constexpr T* static_addressof(T& ref) +{ + return &ref; +} + +template )> +T* static_addressof(T& ref) +{ + return std::addressof(ref); +} + + +// the call to convert(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A +template +constexpr U convert(U v) { return v; } + + +namespace swap_ns +{ + using std::swap; + + template + void adl_swap(T& t, T& u) noexcept(noexcept(swap(t, u))) + { + swap(t, u); + } + +} // namespace swap_ns + +} // namespace detail + + +constexpr struct trivial_init_t{} trivial_init{}; + + +// 20.5.6, In-place construction +constexpr struct in_place_t{} in_place{}; + + +// 20.5.7, Disengaged state indicator +struct nullopt_t +{ + struct init{}; + constexpr explicit nullopt_t(init){} +}; +constexpr nullopt_t nullopt{nullopt_t::init()}; + + +// 20.5.8, class bad_optional_access +class bad_optional_access : public logic_error { +public: + explicit bad_optional_access(const string& what_arg) : logic_error{what_arg} {} + explicit bad_optional_access(const char* what_arg) : logic_error{what_arg} {} +}; + + +template +union storage_t +{ + unsigned char dummy_; + T value_; + + constexpr storage_t( trivial_init_t ) noexcept : dummy_() {}; + + template + constexpr storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + + ~storage_t(){} +}; + + +template +union constexpr_storage_t +{ + unsigned char dummy_; + T value_; + + constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {}; + + template + constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + + ~constexpr_storage_t() = default; +}; + + +template +struct optional_base +{ + bool init_; + storage_t storage_; + + constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {}; + + explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {} + + explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + + template explicit optional_base(in_place_t, Args&&... args) + : init_(true), storage_(constexpr_forward(args)...) {} + + template >)> + explicit optional_base(in_place_t, std::initializer_list il, Args&&... args) + : init_(true), storage_(il, std::forward(args)...) {} + + ~optional_base() { if (init_) storage_.value_.T::~T(); } +}; + + +template +struct constexpr_optional_base +{ + bool init_; + constexpr_storage_t storage_; + + constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {}; + + explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {} + + explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + + template explicit constexpr constexpr_optional_base(in_place_t, Args&&... args) + : init_(true), storage_(constexpr_forward(args)...) {} + + template >)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list il, Args&&... args) + : init_(true), storage_(il, std::forward(args)...) {} + + ~constexpr_optional_base() = default; +}; + +template +using OptionalBase = typename std::conditional< + is_trivially_destructible::value, // if possible + constexpr_optional_base::type>, // use base with trivial destructor + optional_base::type> +>::type; + + + +template +class optional : private OptionalBase +{ + static_assert( !std::is_same::type, nullopt_t>::value, "bad T" ); + static_assert( !std::is_same::type, in_place_t>::value, "bad T" ); + + + constexpr bool initialized() const noexcept { return OptionalBase::init_; } + typename std::remove_const::type* dataptr() { return std::addressof(OptionalBase::storage_.value_); } + constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase::storage_.value_); } + +# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + constexpr const T& contained_val() const& { return OptionalBase::storage_.value_; } +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } + OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase::storage_.value_; } +# else + T& contained_val() & { return OptionalBase::storage_.value_; } + T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } +# endif +# else + constexpr const T& contained_val() const { return OptionalBase::storage_.value_; } + T& contained_val() { return OptionalBase::storage_.value_; } +# endif + + void clear() noexcept { + if (initialized()) dataptr()->T::~T(); + OptionalBase::init_ = false; + } + + template + void initialize(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) + { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) T(std::forward(args)...); + OptionalBase::init_ = true; + } + + template + void initialize(std::initializer_list il, Args&&... args) noexcept(noexcept(T(il, std::forward(args)...))) + { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) T(il, std::forward(args)...); + OptionalBase::init_ = true; + } + +public: + typedef T value_type; + + // 20.5.5.1, constructors + constexpr optional() noexcept : OptionalBase() {}; + constexpr optional(nullopt_t) noexcept : OptionalBase() {}; + + optional(const optional& rhs) + : OptionalBase() + { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(*rhs); + OptionalBase::init_ = true; + } + } + + optional(optional&& rhs) noexcept(is_nothrow_move_constructible::value) + : OptionalBase() + { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(std::move(*rhs)); + OptionalBase::init_ = true; + } + } + + constexpr optional(const T& v) : OptionalBase(v) {} + + constexpr optional(T&& v) : OptionalBase(constexpr_move(v)) {} + + template + explicit constexpr optional(in_place_t, Args&&... args) + : OptionalBase(in_place_t{}, constexpr_forward(args)...) {} + + template >)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list il, Args&&... args) + : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {} + + // 20.5.4.2, Destructor + ~optional() = default; + + // 20.5.4.3, assignment + optional& operator=(nullopt_t) noexcept + { + clear(); + return *this; + } + + optional& operator=(const optional& rhs) + { + if (initialized() == true && rhs.initialized() == false) clear(); + else if (initialized() == false && rhs.initialized() == true) initialize(*rhs); + else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs; + return *this; + } + + optional& operator=(optional&& rhs) + noexcept(is_nothrow_move_assignable::value && is_nothrow_move_constructible::value) + { + if (initialized() == true && rhs.initialized() == false) clear(); + else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs)); + else if (initialized() == true && rhs.initialized() == true) contained_val() = std::move(*rhs); + return *this; + } + + template + auto operator=(U&& v) + -> typename enable_if + < + is_same::type, T>::value, + optional& + >::type + { + if (initialized()) { contained_val() = std::forward(v); } + else { initialize(std::forward(v)); } + return *this; + } + + + template + void emplace(Args&&... args) + { + clear(); + initialize(std::forward(args)...); + } + + template + void emplace(initializer_list il, Args&&... args) + { + clear(); + initialize(il, std::forward(args)...); + } + + // 20.5.4.4, Swap + void swap(optional& rhs) noexcept(is_nothrow_move_constructible::value + && noexcept(detail_::swap_ns::adl_swap(declval(), declval()))) + { + if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); } + else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); } + else if (initialized() == true && rhs.initialized() == true) { using std::swap; swap(**this, *rhs); } + } + + // 20.5.4.5, Observers + + explicit constexpr operator bool() const noexcept { return initialized(); } + constexpr bool has_value() const noexcept { return initialized(); } + + constexpr T const* operator ->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr()); + } + +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() { + assert (initialized()); + return dataptr(); + } + + constexpr T const& operator *() const& { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & { + assert (initialized()); + return contained_val(); + } + + OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && { + assert (initialized()); + return constexpr_move(contained_val()); + } + + constexpr T const& value() const& { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T& value() & { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T&& value() && { + if (!initialized()) throw bad_optional_access("bad optional access"); + return std::move(contained_val()); + } + +# else + + T* operator ->() { + assert (initialized()); + return dataptr(); + } + + constexpr T const& operator *() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + + T& operator *() { + assert (initialized()); + return contained_val(); + } + + constexpr T const& value() const { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + T& value() { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + +# endif + +# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + + template + constexpr T value_or(V&& v) const& + { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + template + OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) && + { + return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); + } + +# else + + template + T value_or(V&& v) && + { + return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); + } + +# endif + +# else + + template + constexpr T value_or(V&& v) const + { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +# endif + + // 20.6.3.6, modifiers + void reset() noexcept { clear(); } +}; + + +template +class optional +{ + static_assert( !std::is_same::value, "bad T" ); + static_assert( !std::is_same::value, "bad T" ); + T* ref; + +public: + + // 20.5.5.1, construction/destruction + constexpr optional() noexcept : ref(nullptr) {} + + constexpr optional(nullopt_t) noexcept : ref(nullptr) {} + + constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {} + + optional(T&&) = delete; + + constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {} + + explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {} + + explicit optional(in_place_t, T&&) = delete; + + ~optional() = default; + + // 20.5.5.2, mutation + optional& operator=(nullopt_t) noexcept { + ref = nullptr; + return *this; + } + + // optional& operator=(const optional& rhs) noexcept { + // ref = rhs.ref; + // return *this; + // } + + // optional& operator=(optional&& rhs) noexcept { + // ref = rhs.ref; + // return *this; + // } + + template + auto operator=(U&& rhs) noexcept + -> typename enable_if + < + is_same::type, optional>::value, + optional& + >::type + { + ref = rhs.ref; + return *this; + } + + template + auto operator=(U&& rhs) noexcept + -> typename enable_if + < + !is_same::type, optional>::value, + optional& + >::type + = delete; + + void emplace(T& v) noexcept { + ref = detail_::static_addressof(v); + } + + void emplace(T&&) = delete; + + + void swap(optional& rhs) noexcept + { + std::swap(ref, rhs.ref); + } + + // 20.5.5.3, observers + constexpr T* operator->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref); + } + + constexpr T& operator*() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref); + } + + constexpr T& value() const { + return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref); + } + + explicit constexpr operator bool() const noexcept { + return ref != nullptr; + } + + constexpr bool has_value() const noexcept { + return ref != nullptr; + } + + template + constexpr typename decay::type value_or(V&& v) const + { + return *this ? **this : detail_::convert::type>(constexpr_forward(v)); + } + + // x.x.x.x, modifiers + void reset() noexcept { ref = nullptr; } +}; + + +template +class optional +{ + static_assert( sizeof(T) == 0, "optional rvalue references disallowed" ); +}; + + +// 20.5.8, Relational operators +template constexpr bool operator==(const optional& x, const optional& y) +{ + return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y; +} + +template constexpr bool operator!=(const optional& x, const optional& y) +{ + return !(x == y); +} + +template constexpr bool operator<(const optional& x, const optional& y) +{ + return (!y) ? false : (!x) ? true : *x < *y; +} + +template constexpr bool operator>(const optional& x, const optional& y) +{ + return (y < x); +} + +template constexpr bool operator<=(const optional& x, const optional& y) +{ + return !(y < x); +} + +template constexpr bool operator>=(const optional& x, const optional& y) +{ + return !(x < y); +} + + +// 20.5.9, Comparison with nullopt +template constexpr bool operator==(const optional& x, nullopt_t) noexcept +{ + return (!x); +} + +template constexpr bool operator==(nullopt_t, const optional& x) noexcept +{ + return (!x); +} + +template constexpr bool operator!=(const optional& x, nullopt_t) noexcept +{ + return bool(x); +} + +template constexpr bool operator!=(nullopt_t, const optional& x) noexcept +{ + return bool(x); +} + +template constexpr bool operator<(const optional&, nullopt_t) noexcept +{ + return false; +} + +template constexpr bool operator<(nullopt_t, const optional& x) noexcept +{ + return bool(x); +} + +template constexpr bool operator<=(const optional& x, nullopt_t) noexcept +{ + return (!x); +} + +template constexpr bool operator<=(nullopt_t, const optional&) noexcept +{ + return true; +} + +template constexpr bool operator>(const optional& x, nullopt_t) noexcept +{ + return bool(x); +} + +template constexpr bool operator>(nullopt_t, const optional&) noexcept +{ + return false; +} + +template constexpr bool operator>=(const optional&, nullopt_t) noexcept +{ + return true; +} + +template constexpr bool operator>=(nullopt_t, const optional& x) noexcept +{ + return (!x); +} + + + +// 20.5.10, Comparison with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + + +// Comparison of optional with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + +// Comparison of optional with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + + +// 20.5.12, Specialized algorithms +template +void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))) +{ + x.swap(y); +} + + +template +constexpr optional::type> make_optional(T&& v) +{ + return optional::type>(constexpr_forward(v)); +} + +template +constexpr optional make_optional(reference_wrapper v) +{ + return optional(v.get()); +} + + +} // namespace experimental +} // namespace std + +namespace std +{ + template + struct hash> + { + typedef typename hash::result_type result_type; + typedef std::experimental::optional argument_type; + + constexpr result_type operator()(argument_type const& arg) const { + return arg ? std::hash{}(*arg) : result_type{}; + } + }; + + template + struct hash> + { + typedef typename hash::result_type result_type; + typedef std::experimental::optional argument_type; + + constexpr result_type operator()(argument_type const& arg) const { + return arg ? std::hash{}(*arg) : result_type{}; + } + }; +} + +# undef TR2_OPTIONAL_REQUIRES +# undef TR2_OPTIONAL_ASSERTED_EXPRESSION + +# endif //___OPTIONAL_HPP___ + diff --git a/thirdparty/Pangolin/include/mpark/variant.hpp b/thirdparty/Pangolin/include/mpark/variant.hpp new file mode 100644 index 00000000..fb2cf061 --- /dev/null +++ b/thirdparty/Pangolin/include/mpark/variant.hpp @@ -0,0 +1,2468 @@ +// MPark.Variant +// +// Copyright Michael Park, 2015-2017 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef MPARK_VARIANT_HPP +#define MPARK_VARIANT_HPP + +/* + variant synopsis + +namespace std { + + // 20.7.2, class template variant + template + class variant { + public: + + // 20.7.2.1, constructors + constexpr variant() noexcept(see below); + variant(const variant&); + variant(variant&&) noexcept(see below); + + template constexpr variant(T&&) noexcept(see below); + + template + constexpr explicit variant(in_place_type_t, Args&&...); + + template + constexpr explicit variant( + in_place_type_t, initializer_list, Args&&...); + + template + constexpr explicit variant(in_place_index_t, Args&&...); + + template + constexpr explicit variant( + in_place_index_t, initializer_list, Args&&...); + + // 20.7.2.2, destructor + ~variant(); + + // 20.7.2.3, assignment + variant& operator=(const variant&); + variant& operator=(variant&&) noexcept(see below); + + template variant& operator=(T&&) noexcept(see below); + + // 20.7.2.4, modifiers + template + T& emplace(Args&&...); + + template + T& emplace(initializer_list, Args&&...); + + template + variant_alternative& emplace(Args&&...); + + template + variant_alternative& emplace(initializer_list, Args&&...); + + // 20.7.2.5, value status + constexpr bool valueless_by_exception() const noexcept; + constexpr size_t index() const noexcept; + + // 20.7.2.6, swap + void swap(variant&) noexcept(see below); + }; + + // 20.7.3, variant helper classes + template struct variant_size; // undefined + + template + constexpr size_t variant_size_v = variant_size::value; + + template struct variant_size; + template struct variant_size; + template struct variant_size; + + template + struct variant_size>; + + template struct variant_alternative; // undefined + + template + using variant_alternative_t = typename variant_alternative::type; + + template struct variant_alternative; + template struct variant_alternative; + template struct variant_alternative; + + template + struct variant_alternative>; + + constexpr size_t variant_npos = -1; + + // 20.7.4, value access + template + constexpr bool holds_alternative(const variant&) noexcept; + + template + constexpr variant_alternative_t>& + get(variant&); + + template + constexpr variant_alternative_t>&& + get(variant&&); + + template + constexpr variant_alternative_t> const& + get(const variant&); + + template + constexpr variant_alternative_t> const&& + get(const variant&&); + + template + constexpr T& get(variant&); + + template + constexpr T&& get(variant&&); + + template + constexpr const T& get(const variant&); + + template + constexpr const T&& get(const variant&&); + + template + constexpr add_pointer_t>> + get_if(variant*) noexcept; + + template + constexpr add_pointer_t>> + get_if(const variant*) noexcept; + + template + constexpr add_pointer_t + get_if(variant*) noexcept; + + template + constexpr add_pointer_t + get_if(const variant*) noexcept; + + // 20.7.5, relational operators + template + constexpr bool operator==(const variant&, const variant&); + + template + constexpr bool operator!=(const variant&, const variant&); + + template + constexpr bool operator<(const variant&, const variant&); + + template + constexpr bool operator>(const variant&, const variant&); + + template + constexpr bool operator<=(const variant&, const variant&); + + template + constexpr bool operator>=(const variant&, const variant&); + + // 20.7.6, visitation + template + constexpr see below visit(Visitor&&, Variants&&...); + + // 20.7.7, class monostate + struct monostate; + + // 20.7.8, monostate relational operators + constexpr bool operator<(monostate, monostate) noexcept; + constexpr bool operator>(monostate, monostate) noexcept; + constexpr bool operator<=(monostate, monostate) noexcept; + constexpr bool operator>=(monostate, monostate) noexcept; + constexpr bool operator==(monostate, monostate) noexcept; + constexpr bool operator!=(monostate, monostate) noexcept; + + // 20.7.9, specialized algorithms + template + void swap(variant&, variant&) noexcept(see below); + + // 20.7.10, class bad_variant_access + class bad_variant_access; + + // 20.7.11, hash support + template struct hash; + template struct hash>; + template <> struct hash; + +} // namespace std + +*/ + +#include +#include +#include +#include +#include +#include +#include + +// MPark.Variant +// +// Copyright Michael Park, 2015-2017 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef MPARK_CONFIG_HPP +#define MPARK_CONFIG_HPP + +// MSVC 2015 Update 3. +#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210) +#error "MPark.Variant requires C++11 support." +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +#ifndef __has_include +#define __has_include(x) 0 +#endif + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if __has_builtin(__builtin_addressof) || \ + (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER) +#define MPARK_BUILTIN_ADDRESSOF +#endif + +#if __has_builtin(__builtin_unreachable) +#define MPARK_BUILTIN_UNREACHABLE +#endif + +#if __has_builtin(__type_pack_element) +#define MPARK_TYPE_PACK_ELEMENT +#endif + +#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304 +#define MPARK_CPP14_CONSTEXPR +#endif + +#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \ + (defined(_MSC_VER) && defined(_CPPUNWIND)) +#define MPARK_EXCEPTIONS +#endif + +#if defined(__cpp_generic_lambdas) || defined(_MSC_VER) +#define MPARK_GENERIC_LAMBDAS +#endif + +#if defined(__cpp_lib_integer_sequence) +#define MPARK_INTEGER_SEQUENCE +#endif + +#if defined(__cpp_return_type_deduction) || defined(_MSC_VER) +#define MPARK_RETURN_TYPE_DEDUCTION +#endif + +#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER) +#define MPARK_TRANSPARENT_OPERATORS +#endif + +#if defined(__cpp_variable_templates) || defined(_MSC_VER) +#define MPARK_VARIABLE_TEMPLATES +#endif + +#if !defined(__GLIBCXX__) || __has_include() // >= libstdc++-5 +#define MPARK_TRIVIALITY_TYPE_TRAITS +#endif + +#endif // MPARK_CONFIG_HPP + +// MPark.Variant +// +// Copyright Michael Park, 2015-2017 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef MPARK_IN_PLACE_HPP +#define MPARK_IN_PLACE_HPP + +#include + + +namespace mpark { + + struct in_place_t { explicit in_place_t() = default; }; + + template + struct in_place_index_t { explicit in_place_index_t() = default; }; + + template + struct in_place_type_t { explicit in_place_type_t() = default; }; + +#ifdef MPARK_VARIABLE_TEMPLATES + constexpr in_place_t in_place{}; + + template constexpr in_place_index_t in_place_index{}; + + template constexpr in_place_type_t in_place_type{}; +#endif + +} // namespace mpark + +#endif // MPARK_IN_PLACE_HPP + +// MPark.Variant +// +// Copyright Michael Park, 2015-2017 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef MPARK_LIB_HPP +#define MPARK_LIB_HPP + +#include +#include +#include +#include + + +#define RETURN(...) -> decltype(__VA_ARGS__) { return __VA_ARGS__; } + +namespace mpark { + namespace lib { + template + struct identity { using type = T; }; + + inline namespace cpp14 { + template + struct array { + constexpr const T &operator[](std::size_t index) const { + return data[index]; + } + + T data[N == 0 ? 1 : N]; + }; + + template + using add_pointer_t = typename std::add_pointer::type; + + template + using common_type_t = typename std::common_type::type; + + template + using decay_t = typename std::decay::type; + + template + using enable_if_t = typename std::enable_if::type; + + template + using remove_const_t = typename std::remove_const::type; + + template + using remove_reference_t = typename std::remove_reference::type; + + template + inline constexpr T &&forward(remove_reference_t &t) noexcept { + return static_cast(t); + } + + template + inline constexpr T &&forward(remove_reference_t &&t) noexcept { + static_assert(!std::is_lvalue_reference::value, + "can not forward an rvalue as an lvalue"); + return static_cast(t); + } + + template + inline constexpr remove_reference_t &&move(T &&t) noexcept { + return static_cast &&>(t); + } + +#ifdef MPARK_INTEGER_SEQUENCE + using std::integer_sequence; + using std::index_sequence; + using std::make_index_sequence; + using std::index_sequence_for; +#else + template + struct integer_sequence { + using value_type = T; + static constexpr std::size_t size() noexcept { return sizeof...(Is); } + }; + + template + using index_sequence = integer_sequence; + + template + struct make_index_sequence_concat; + + template + struct make_index_sequence_concat, + index_sequence> + : identity> {}; + + template + struct make_index_sequence_impl; + + template + using make_index_sequence = typename make_index_sequence_impl::type; + + template + struct make_index_sequence_impl + : make_index_sequence_concat, + make_index_sequence> {}; + + template <> + struct make_index_sequence_impl<0> : identity> {}; + + template <> + struct make_index_sequence_impl<1> : identity> {}; + + template + using index_sequence_for = make_index_sequence; +#endif + + // +#ifdef MPARK_TRANSPARENT_OPERATORS + using equal_to = std::equal_to<>; +#else + struct equal_to { + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + RETURN(lib::forward(lhs) == lib::forward(rhs)) + }; +#endif + +#ifdef MPARK_TRANSPARENT_OPERATORS + using not_equal_to = std::not_equal_to<>; +#else + struct not_equal_to { + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + RETURN(lib::forward(lhs) != lib::forward(rhs)) + }; +#endif + +#ifdef MPARK_TRANSPARENT_OPERATORS + using less = std::less<>; +#else + struct less { + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + RETURN(lib::forward(lhs) < lib::forward(rhs)) + }; +#endif + +#ifdef MPARK_TRANSPARENT_OPERATORS + using greater = std::greater<>; +#else + struct greater { + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + RETURN(lib::forward(lhs) > lib::forward(rhs)) + }; +#endif + +#ifdef MPARK_TRANSPARENT_OPERATORS + using less_equal = std::less_equal<>; +#else + struct less_equal { + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + RETURN(lib::forward(lhs) <= lib::forward(rhs)) + }; +#endif + +#ifdef MPARK_TRANSPARENT_OPERATORS + using greater_equal = std::greater_equal<>; +#else + struct greater_equal { + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + RETURN(lib::forward(lhs) >= lib::forward(rhs)) + }; +#endif + } // namespace cpp14 + + inline namespace cpp17 { + + // + template + using bool_constant = std::integral_constant; + + template + struct voider : identity {}; + + template + using void_t = typename voider::type; + + namespace detail { + namespace swappable { + + using std::swap; + + template + struct is_swappable { + private: + template (), + std::declval()))> + inline static std::true_type test(int); + + template + inline static std::false_type test(...); + + public: + static constexpr bool value = decltype(test(0))::value; + }; + + template ::value> + struct is_nothrow_swappable { +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnoexcept" +#endif + static constexpr bool value = + noexcept(swap(std::declval(), std::declval())); +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + }; + + template + struct is_nothrow_swappable : std::false_type {}; + + } // namespace swappable + } // namespace detail + + using detail::swappable::is_swappable; + using detail::swappable::is_nothrow_swappable; + + // +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4100) +#endif + template + inline constexpr auto invoke(F &&f, As &&... as) + RETURN(lib::forward(f)(lib::forward(as)...)) +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + template + inline constexpr auto invoke(T B::*pmv, D &&d) + RETURN(lib::forward(d).*pmv) + + template + inline constexpr auto invoke(Pmv pmv, Ptr &&ptr) + RETURN((*lib::forward(ptr)).*pmv) + + template + inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as) + RETURN((lib::forward(d).*pmf)(lib::forward(as)...)) + + template + inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as) + RETURN(((*lib::forward(ptr)).*pmf)(lib::forward(as)...)) + + namespace detail { + + template + struct invoke_result {}; + + template + struct invoke_result(), std::declval()...))>, + F, + Args...> + : identity(), std::declval()...))> {}; + + } // namespace detail + + template + using invoke_result = detail::invoke_result; + + template + using invoke_result_t = typename invoke_result::type; + + namespace detail { + + template + struct is_invocable : std::false_type {}; + + template + struct is_invocable>, F, Args...> + : std::true_type {}; + + template + struct is_invocable_r : std::false_type {}; + + template + struct is_invocable_r>, + R, + F, + Args...> + : std::is_convertible, R> {}; + + } // namespace detail + + template + using is_invocable = detail::is_invocable; + + template + using is_invocable_r = detail::is_invocable_r; + + // +#ifdef MPARK_BUILTIN_ADDRESSOF + template + inline constexpr T *addressof(T &arg) noexcept { + return __builtin_addressof(arg); + } +#else + namespace detail { + + namespace has_addressof_impl { + + struct fail; + + template + inline fail operator&(T &&); + + template + inline static constexpr bool impl() { + return (std::is_class::value || std::is_union::value) && + !std::is_same()), fail>::value; + } + + } // namespace has_addressof_impl + + template + using has_addressof = bool_constant()>; + + template + inline constexpr T *addressof(T &arg, std::true_type) noexcept { + return std::addressof(arg); + } + + template + inline constexpr T *addressof(T &arg, std::false_type) noexcept { + return &arg; + } + + } // namespace detail + + template + inline constexpr T *addressof(T &arg) noexcept { + return detail::addressof(arg, detail::has_addressof{}); + } +#endif + + template + inline constexpr T *addressof(const T &&) = delete; + + } // namespace cpp17 + + template + struct remove_all_extents : identity {}; + + template + struct remove_all_extents> : remove_all_extents {}; + + template + using remove_all_extents_t = typename remove_all_extents::type; + + template + using size_constant = std::integral_constant; + + template + struct indexed_type : size_constant, identity {}; + + template + using all = std::is_same, + integer_sequence>; + +#ifdef MPARK_TYPE_PACK_ELEMENT + template + using type_pack_element_t = __type_pack_element; +#else + template + struct type_pack_element_impl { + private: + template + struct set; + + template + struct set> : indexed_type... {}; + + template + inline static std::enable_if impl(indexed_type); + + inline static std::enable_if impl(...); + + public: + using type = decltype(impl(set>{})); + }; + + template + using type_pack_element = typename type_pack_element_impl::type; + + template + using type_pack_element_t = typename type_pack_element::type; +#endif + +#ifdef MPARK_TRIVIALITY_TYPE_TRAITS + using std::is_trivially_copy_constructible; + using std::is_trivially_move_constructible; + using std::is_trivially_copy_assignable; + using std::is_trivially_move_assignable; +#else + template + struct is_trivially_copy_constructible + : bool_constant< + std::is_copy_constructible::value && __has_trivial_copy(T)> {}; + + template + struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {}; + + template + struct is_trivially_copy_assignable + : bool_constant< + std::is_copy_assignable::value && __has_trivial_assign(T)> {}; + + template + struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {}; +#endif + + template + struct dependent_type : T {}; + + template + struct push_back; + + template + using push_back_t = typename push_back::type; + + template + struct push_back, J> { + using type = index_sequence; + }; + + } // namespace lib +} // namespace mpark + +#undef RETURN + +#endif // MPARK_LIB_HPP + + +namespace mpark { + +#ifdef MPARK_RETURN_TYPE_DEDUCTION + +#define AUTO auto +#define AUTO_RETURN(...) { return __VA_ARGS__; } + +#define AUTO_REFREF auto && +#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; } + +#define DECLTYPE_AUTO decltype(auto) +#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; } + +#else + +#define AUTO auto +#define AUTO_RETURN(...) \ + -> lib::decay_t { return __VA_ARGS__; } + +#define AUTO_REFREF auto +#define AUTO_REFREF_RETURN(...) \ + -> decltype((__VA_ARGS__)) { \ + static_assert(std::is_reference::value, ""); \ + return __VA_ARGS__; \ + } + +#define DECLTYPE_AUTO auto +#define DECLTYPE_AUTO_RETURN(...) \ + -> decltype(__VA_ARGS__) { return __VA_ARGS__; } + +#endif + + class bad_variant_access : public std::exception { + public: + virtual const char *what() const noexcept { return "bad_variant_access"; } + }; + + [[noreturn]] inline void throw_bad_variant_access() { +#ifdef MPARK_EXCEPTIONS + throw bad_variant_access{}; +#else + std::terminate(); +#ifdef MPARK_BUILTIN_UNREACHABLE + __builtin_unreachable(); +#endif +#endif + } + + template + class variant; + + template + struct variant_size; + +#ifdef MPARK_VARIABLE_TEMPLATES + template + constexpr std::size_t variant_size_v = variant_size::value; +#endif + + template + struct variant_size : variant_size {}; + + template + struct variant_size : variant_size {}; + + template + struct variant_size : variant_size {}; + + template + struct variant_size> : lib::size_constant {}; + + template + struct variant_alternative; + + template + using variant_alternative_t = typename variant_alternative::type; + + template + struct variant_alternative + : std::add_const> {}; + + template + struct variant_alternative + : std::add_volatile> {}; + + template + struct variant_alternative + : std::add_cv> {}; + + template + struct variant_alternative> { + static_assert(I < sizeof...(Ts), + "Index out of bounds in std::variant_alternative<>"); + using type = lib::type_pack_element_t; + }; + + constexpr std::size_t variant_npos = static_cast(-1); + + namespace detail { + + constexpr std::size_t not_found = static_cast(-1); + constexpr std::size_t ambiguous = static_cast(-2); + +#ifdef MPARK_CPP14_CONSTEXPR + template + inline constexpr std::size_t find_index() { + constexpr lib::array matches = { + {std::is_same::value...} + }; + std::size_t result = not_found; + for (std::size_t i = 0; i < sizeof...(Ts); ++i) { + if (matches[i]) { + if (result != not_found) { + return ambiguous; + } + result = i; + } + } + return result; + } +#else + inline constexpr std::size_t find_index_impl(std::size_t result, + std::size_t) { + return result; + } + + template + inline constexpr std::size_t find_index_impl(std::size_t result, + std::size_t idx, + bool b, + Bs... bs) { + return b ? (result != not_found ? ambiguous + : find_index_impl(idx, idx + 1, bs...)) + : find_index_impl(result, idx + 1, bs...); + } + + template + inline constexpr std::size_t find_index() { + return find_index_impl(not_found, 0, std::is_same::value...); + } +#endif + + template + using find_index_sfinae_impl = + lib::enable_if_t>; + + template + using find_index_sfinae = find_index_sfinae_impl()>; + + template + struct find_index_checked_impl : lib::size_constant { + static_assert(I != not_found, "the specified type is not found."); + static_assert(I != ambiguous, "the specified type is ambiguous."); + }; + + template + using find_index_checked = find_index_checked_impl()>; + + struct valueless_t {}; + + enum class Trait { TriviallyAvailable, Available, Unavailable }; + + template class IsTriviallyAvailable, + template class IsAvailable> + inline constexpr Trait trait() { + return IsTriviallyAvailable::value + ? Trait::TriviallyAvailable + : IsAvailable::value ? Trait::Available + : Trait::Unavailable; + } + +#ifdef MPARK_CPP14_CONSTEXPR + template + inline constexpr Trait common_trait(Traits... traits) { + Trait result = Trait::TriviallyAvailable; + for (Trait t : {traits...}) { + if (static_cast(t) > static_cast(result)) { + result = t; + } + } + return result; + } +#else + inline constexpr Trait common_trait_impl(Trait result) { return result; } + + template + inline constexpr Trait common_trait_impl(Trait result, + Trait t, + Traits... ts) { + return static_cast(t) > static_cast(result) + ? common_trait_impl(t, ts...) + : common_trait_impl(result, ts...); + } + + template + inline constexpr Trait common_trait(Traits... ts) { + return common_trait_impl(Trait::TriviallyAvailable, ts...); + } +#endif + + template + struct traits { + static constexpr Trait copy_constructible_trait = + common_trait(trait()...); + + static constexpr Trait move_constructible_trait = + common_trait(trait()...); + + static constexpr Trait copy_assignable_trait = + common_trait(copy_constructible_trait, + trait()...); + + static constexpr Trait move_assignable_trait = + common_trait(move_constructible_trait, + trait()...); + + static constexpr Trait destructible_trait = + common_trait(trait()...); + }; + + namespace access { + + struct recursive_union { +#ifdef MPARK_RETURN_TYPE_DEDUCTION + template + inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) { + return lib::forward(v).head_; + } + + template + inline static constexpr auto &&get_alt(V &&v, in_place_index_t) { + return get_alt(lib::forward(v).tail_, in_place_index_t{}); + } +#else + template + struct get_alt_impl { + template + inline constexpr AUTO_REFREF operator()(V &&v) const + AUTO_REFREF_RETURN(get_alt_impl{}(lib::forward(v).tail_)) + }; + + template + struct get_alt_impl<0, Dummy> { + template + inline constexpr AUTO_REFREF operator()(V &&v) const + AUTO_REFREF_RETURN(lib::forward(v).head_) + }; + + template + inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t) + AUTO_REFREF_RETURN(get_alt_impl{}(lib::forward(v))) +#endif + }; + + struct base { + template + inline static constexpr AUTO_REFREF get_alt(V &&v) + AUTO_REFREF_RETURN(recursive_union::get_alt( + data(lib::forward(v)), in_place_index_t{})) + }; + + struct variant { + template + inline static constexpr AUTO_REFREF get_alt(V &&v) + AUTO_REFREF_RETURN(base::get_alt(lib::forward(v).impl_)) + }; + + } // namespace access + + namespace visitation { + + struct base { + template + inline static constexpr const T &at(const T &elem) noexcept { + return elem; + } + + template + inline static constexpr const lib::remove_all_extents_t &at( + const lib::array &elems, std::size_t i, Is... is) noexcept { + return at(elems[i], is...); + } + + template + inline static constexpr int visit_visitor_return_type_check() { + static_assert(lib::all::value...>::value, + "`mpark::visit` requires the visitor to have a single " + "return type."); + return 0; + } + + template + inline static constexpr lib::array< + lib::common_type_t...>, + sizeof...(Fs)> + make_farray(Fs &&... fs) { + using result = lib::array...>, + sizeof...(Fs)>; + return visit_visitor_return_type_check...>(), + result{{lib::forward(fs)...}}; + } + + template + struct dispatcher { + template + struct impl { + inline static constexpr DECLTYPE_AUTO dispatch(F f, Vs... vs) + DECLTYPE_AUTO_RETURN(lib::invoke( + static_cast(f), + access::base::get_alt(static_cast(vs))...)) + }; + }; + + template + inline static constexpr AUTO make_dispatch(lib::index_sequence) + AUTO_RETURN(&dispatcher::template impl::dispatch) + + template + inline static constexpr AUTO make_fdiagonal_impl() + AUTO_RETURN(make_dispatch( + lib::index_sequence::value...>{})) + + template + inline static constexpr AUTO make_fdiagonal_impl( + lib::index_sequence) + AUTO_RETURN(make_farray(make_fdiagonal_impl()...)) + + template + inline static constexpr /* auto * */ auto make_fdiagonal() + -> decltype(make_fdiagonal_impl( + lib::make_index_sequence::size()>{})) { + static_assert(lib::all<(lib::decay_t::size() == + lib::decay_t::size())...>::value, + "all of the variants must be the same size."); + return make_fdiagonal_impl( + lib::make_index_sequence::size()>{}); + } + +#ifdef MPARK_RETURN_TYPE_DEDUCTION + template + inline static constexpr auto make_fmatrix_impl(Is is) { + return make_dispatch(is); + } + + template + inline static constexpr auto make_fmatrix_impl( + Is, lib::index_sequence, Ls... ls) { + return make_farray(make_fmatrix_impl( + lib::push_back_t{}, ls...)...); + } + + template + inline static constexpr auto make_fmatrix() { + return make_fmatrix_impl( + lib::index_sequence<>{}, + lib::make_index_sequence::size()>{}...); + } +#else + template + struct make_fmatrix_impl { + template + struct impl; + + template + struct impl { + inline constexpr AUTO operator()() const + AUTO_RETURN(make_dispatch(Is{})) + }; + + template + struct impl, Ls...> { + inline constexpr AUTO operator()() const + AUTO_RETURN( + make_farray(impl, Ls...>{}()...)) + }; + }; + + template + inline static constexpr AUTO make_fmatrix() + AUTO_RETURN( + typename make_fmatrix_impl::template impl< + lib::index_sequence<>, + lib::make_index_sequence::size()>...>{}()) +#endif + }; // namespace base + + template + using FDiagonal = decltype(base::make_fdiagonal()); + + template + struct fdiagonal { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4268) +#endif + static constexpr FDiagonal value = + base::make_fdiagonal(); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + }; + + template + constexpr FDiagonal fdiagonal::value; + + template + using FMatrix = decltype(base::make_fmatrix()); + + template + struct fmatrix { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4268) +#endif + static constexpr FMatrix value = + base::make_fmatrix(); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + }; + + template + constexpr FMatrix fmatrix::value; + + struct alt { + template + inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index, + Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN(base::at( + fdiagonal(vs)))...>::value, + index)(lib::forward(visitor), + as_base(lib::forward(vs))...)) + + template + inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN(base::at( + fmatrix(vs)))...>::value, + vs.index()...)(lib::forward(visitor), + as_base(lib::forward(vs))...)) + }; + + struct variant { + private: + template + struct visit_exhaustive_visitor_check { + static_assert( + lib::is_invocable::value, + "`mpark::visit` requires the visitor to be exhaustive."); + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4100) +#endif + inline constexpr DECLTYPE_AUTO operator()(Visitor &&visitor, + Values &&... values) const + DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward(visitor), + lib::forward(values)...)) +#ifdef _MSC_VER +#pragma warning(pop) +#endif + }; + + template + struct value_visitor { + Visitor &&visitor_; + + template + inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const + DECLTYPE_AUTO_RETURN( + visit_exhaustive_visitor_check< + Visitor, + decltype((lib::forward(alts).value))...>{}( + lib::forward(visitor_), + lib::forward(alts).value...)) + }; + + template + inline static constexpr AUTO make_value_visitor(Visitor &&visitor) + AUTO_RETURN(value_visitor{lib::forward(visitor)}) + + public: + template + inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index, + Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN( + alt::visit_alt_at(index, + lib::forward(visitor), + lib::forward(vs).impl_...)) + + template + inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward(visitor), + lib::forward(vs).impl_...)) + + template + inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index, + Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN( + visit_alt_at(index, + make_value_visitor(lib::forward(visitor)), + lib::forward(vs)...)) + + template + inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor, + Vs &&... vs) + DECLTYPE_AUTO_RETURN( + visit_alt(make_value_visitor(lib::forward(visitor)), + lib::forward(vs)...)) + }; + + } // namespace visitation + + template + struct alt { + using value_type = T; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4244) +#endif + template + inline explicit constexpr alt(in_place_t, Args &&... args) + : value(lib::forward(args)...) {} +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + T value; + }; + + template + union recursive_union; + + template + union recursive_union {}; + +#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor) \ + template \ + union recursive_union { \ + public: \ + inline explicit constexpr recursive_union(valueless_t) noexcept \ + : dummy_{} {} \ + \ + template \ + inline explicit constexpr recursive_union(in_place_index_t<0>, \ + Args &&... args) \ + : head_(in_place_t{}, lib::forward(args)...) {} \ + \ + template \ + inline explicit constexpr recursive_union(in_place_index_t, \ + Args &&... args) \ + : tail_(in_place_index_t{}, lib::forward(args)...) {} \ + \ + recursive_union(const recursive_union &) = default; \ + recursive_union(recursive_union &&) = default; \ + \ + destructor \ + \ + recursive_union &operator=(const recursive_union &) = default; \ + recursive_union &operator=(recursive_union &&) = default; \ + \ + private: \ + char dummy_; \ + alt head_; \ + recursive_union tail_; \ + \ + friend struct access::recursive_union; \ + } + + MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable, + ~recursive_union() = default;); + MPARK_VARIANT_RECURSIVE_UNION(Trait::Available, + ~recursive_union() {}); + MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable, + ~recursive_union() = delete;); + +#undef MPARK_VARIANT_RECURSIVE_UNION + + using index_t = unsigned int; + + template + class base { + public: + inline explicit constexpr base(valueless_t tag) noexcept + : data_(tag), index_(static_cast(-1)) {} + + template + inline explicit constexpr base(in_place_index_t, Args &&... args) + : data_(in_place_index_t{}, lib::forward(args)...), + index_(I) {} + + inline constexpr bool valueless_by_exception() const noexcept { + return index_ == static_cast(-1); + } + + inline constexpr std::size_t index() const noexcept { + return valueless_by_exception() ? variant_npos : index_; + } + + protected: + using data_t = recursive_union; + + friend inline constexpr base &as_base(base &b) { return b; } + friend inline constexpr const base &as_base(const base &b) { return b; } + friend inline constexpr base &&as_base(base &&b) { return lib::move(b); } + friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); } + + friend inline constexpr data_t &data(base &b) { return b.data_; } + friend inline constexpr const data_t &data(const base &b) { return b.data_; } + friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; } + friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; } + + inline static constexpr std::size_t size() { return sizeof...(Ts); } + + data_t data_; + index_t index_; + + friend struct access::base; + friend struct visitation::base; + }; + + struct dtor { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4100) +#endif + template + inline void operator()(Alt &alt) const noexcept { alt.~Alt(); } +#ifdef _MSC_VER +#pragma warning(pop) +#endif + }; + +#if defined(_MSC_VER) && _MSC_VER < 1910 +#define INHERITING_CTOR(type, base) \ + template \ + inline explicit constexpr type(Args &&... args) \ + : base(lib::forward(args)...) {} +#else +#define INHERITING_CTOR(type, base) using base::base; +#endif + + template + class destructor; + +#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \ + template \ + class destructor, destructible_trait> \ + : public base { \ + using super = base; \ + \ + public: \ + INHERITING_CTOR(destructor, super) \ + using super::operator=; \ + \ + destructor(const destructor &) = default; \ + destructor(destructor &&) = default; \ + definition \ + destructor &operator=(const destructor &) = default; \ + destructor &operator=(destructor &&) = default; \ + \ + protected: \ + destroy \ + } + + MPARK_VARIANT_DESTRUCTOR( + Trait::TriviallyAvailable, + ~destructor() = default;, + inline void destroy() noexcept { + this->index_ = static_cast(-1); + }); + + MPARK_VARIANT_DESTRUCTOR( + Trait::Available, + ~destructor() { destroy(); }, + inline void destroy() noexcept { + if (!this->valueless_by_exception()) { + visitation::alt::visit_alt(dtor{}, *this); + } + this->index_ = static_cast(-1); + }); + + MPARK_VARIANT_DESTRUCTOR( + Trait::Unavailable, + ~destructor() = delete;, + inline void destroy() noexcept = delete;); + +#undef MPARK_VARIANT_DESTRUCTOR + + template + class constructor : public destructor { + using super = destructor; + + public: + INHERITING_CTOR(constructor, super) + using super::operator=; + + protected: +#ifndef MPARK_GENERIC_LAMBDAS + struct ctor { + template + inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const { + constructor::construct_alt(lhs_alt, + lib::forward(rhs_alt).value); + } + }; +#endif + + template + inline static T &construct_alt(alt &a, Args &&... args) { + ::new (static_cast(lib::addressof(a))) + alt(in_place_t{}, lib::forward(args)...); + return a.value; + } + + template + inline static void generic_construct(constructor &lhs, Rhs &&rhs) { + lhs.destroy(); + if (!rhs.valueless_by_exception()) { + visitation::alt::visit_alt_at( + rhs.index(), +#ifdef MPARK_GENERIC_LAMBDAS + [](auto &lhs_alt, auto &&rhs_alt) { + constructor::construct_alt( + lhs_alt, lib::forward(rhs_alt).value); + } +#else + ctor{} +#endif + , + lhs, + lib::forward(rhs)); + lhs.index_ = rhs.index_; + } + } + }; + + template + class move_constructor; + +#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \ + template \ + class move_constructor, move_constructible_trait> \ + : public constructor> { \ + using super = constructor>; \ + \ + public: \ + INHERITING_CTOR(move_constructor, super) \ + using super::operator=; \ + \ + move_constructor(const move_constructor &) = default; \ + definition \ + ~move_constructor() = default; \ + move_constructor &operator=(const move_constructor &) = default; \ + move_constructor &operator=(move_constructor &&) = default; \ + } + + MPARK_VARIANT_MOVE_CONSTRUCTOR( + Trait::TriviallyAvailable, + move_constructor(move_constructor &&that) = default;); + + MPARK_VARIANT_MOVE_CONSTRUCTOR( + Trait::Available, + move_constructor(move_constructor &&that) noexcept( + lib::all::value...>::value) + : move_constructor(valueless_t{}) { + this->generic_construct(*this, lib::move(that)); + }); + + MPARK_VARIANT_MOVE_CONSTRUCTOR( + Trait::Unavailable, + move_constructor(move_constructor &&) = delete;); + +#undef MPARK_VARIANT_MOVE_CONSTRUCTOR + + template + class copy_constructor; + +#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \ + template \ + class copy_constructor, copy_constructible_trait> \ + : public move_constructor> { \ + using super = move_constructor>; \ + \ + public: \ + INHERITING_CTOR(copy_constructor, super) \ + using super::operator=; \ + \ + definition \ + copy_constructor(copy_constructor &&) = default; \ + ~copy_constructor() = default; \ + copy_constructor &operator=(const copy_constructor &) = default; \ + copy_constructor &operator=(copy_constructor &&) = default; \ + } + + MPARK_VARIANT_COPY_CONSTRUCTOR( + Trait::TriviallyAvailable, + copy_constructor(const copy_constructor &that) = default;); + + MPARK_VARIANT_COPY_CONSTRUCTOR( + Trait::Available, + copy_constructor(const copy_constructor &that) + : copy_constructor(valueless_t{}) { + this->generic_construct(*this, that); + }); + + MPARK_VARIANT_COPY_CONSTRUCTOR( + Trait::Unavailable, + copy_constructor(const copy_constructor &) = delete;); + +#undef MPARK_VARIANT_COPY_CONSTRUCTOR + + template + class assignment : public copy_constructor { + using super = copy_constructor; + + public: + INHERITING_CTOR(assignment, super) + using super::operator=; + + template + inline /* auto & */ auto emplace(Args &&... args) + -> decltype(this->construct_alt(access::base::get_alt(*this), + lib::forward(args)...)) { + this->destroy(); + auto &result = this->construct_alt(access::base::get_alt(*this), + lib::forward(args)...); + this->index_ = I; + return result; + } + + protected: +#ifndef MPARK_GENERIC_LAMBDAS + template + struct assigner { + template + inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const { + self->assign_alt(this_alt, lib::forward(that_alt).value); + } + assignment *self; + }; +#endif + + template + inline void assign_alt(alt &a, Arg &&arg) { + if (this->index() == I) { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4244) +#endif + a.value = lib::forward(arg); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + } else { + struct { + void operator()(std::true_type) const { + this_->emplace(lib::forward(arg_)); + } + void operator()(std::false_type) const { + this_->emplace(T(lib::forward(arg_))); + } + assignment *this_; + Arg &&arg_; + } impl{this, lib::forward(arg)}; + impl(lib::bool_constant< + std::is_nothrow_constructible::value || + !std::is_nothrow_move_constructible::value>{}); + } + } + + template + inline void generic_assign(That &&that) { + if (this->valueless_by_exception() && that.valueless_by_exception()) { + // do nothing. + } else if (that.valueless_by_exception()) { + this->destroy(); + } else { + visitation::alt::visit_alt_at( + that.index(), +#ifdef MPARK_GENERIC_LAMBDAS + [this](auto &this_alt, auto &&that_alt) { + this->assign_alt( + this_alt, lib::forward(that_alt).value); + } +#else + assigner{this} +#endif + , + *this, + lib::forward(that)); + } + } + }; + + template + class move_assignment; + +#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \ + template \ + class move_assignment, move_assignable_trait> \ + : public assignment> { \ + using super = assignment>; \ + \ + public: \ + INHERITING_CTOR(move_assignment, super) \ + using super::operator=; \ + \ + move_assignment(const move_assignment &) = default; \ + move_assignment(move_assignment &&) = default; \ + ~move_assignment() = default; \ + move_assignment &operator=(const move_assignment &) = default; \ + definition \ + } + + MPARK_VARIANT_MOVE_ASSIGNMENT( + Trait::TriviallyAvailable, + move_assignment &operator=(move_assignment &&that) = default;); + + MPARK_VARIANT_MOVE_ASSIGNMENT( + Trait::Available, + move_assignment & + operator=(move_assignment &&that) noexcept( + lib::all<(std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value)...>::value) { + this->generic_assign(lib::move(that)); + return *this; + }); + + MPARK_VARIANT_MOVE_ASSIGNMENT( + Trait::Unavailable, + move_assignment &operator=(move_assignment &&) = delete;); + +#undef MPARK_VARIANT_MOVE_ASSIGNMENT + + template + class copy_assignment; + +#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \ + template \ + class copy_assignment, copy_assignable_trait> \ + : public move_assignment> { \ + using super = move_assignment>; \ + \ + public: \ + INHERITING_CTOR(copy_assignment, super) \ + using super::operator=; \ + \ + copy_assignment(const copy_assignment &) = default; \ + copy_assignment(copy_assignment &&) = default; \ + ~copy_assignment() = default; \ + definition \ + copy_assignment &operator=(copy_assignment &&) = default; \ + } + + MPARK_VARIANT_COPY_ASSIGNMENT( + Trait::TriviallyAvailable, + copy_assignment &operator=(const copy_assignment &that) = default;); + + MPARK_VARIANT_COPY_ASSIGNMENT( + Trait::Available, + copy_assignment &operator=(const copy_assignment &that) { + this->generic_assign(that); + return *this; + }); + + MPARK_VARIANT_COPY_ASSIGNMENT( + Trait::Unavailable, + copy_assignment &operator=(const copy_assignment &) = delete;); + +#undef MPARK_VARIANT_COPY_ASSIGNMENT + + template + class impl : public copy_assignment> { + using super = copy_assignment>; + + public: + INHERITING_CTOR(impl, super) + using super::operator=; + + template + inline void assign(Arg &&arg) { + this->assign_alt(access::base::get_alt(*this), + lib::forward(arg)); + } + + inline void swap(impl &that) { + if (this->valueless_by_exception() && that.valueless_by_exception()) { + // do nothing. + } else if (this->index() == that.index()) { + visitation::alt::visit_alt_at(this->index(), +#ifdef MPARK_GENERIC_LAMBDAS + [](auto &this_alt, auto &that_alt) { + using std::swap; + swap(this_alt.value, + that_alt.value); + } +#else + swapper{} +#endif + , + *this, + that); + } else { + impl *lhs = this; + impl *rhs = lib::addressof(that); + if (lhs->move_nothrow() && !rhs->move_nothrow()) { + std::swap(lhs, rhs); + } + impl tmp(lib::move(*rhs)); +#ifdef MPARK_EXCEPTIONS + // EXTENSION: When the move construction of `lhs` into `rhs` throws + // and `tmp` is nothrow move constructible then we move `tmp` back + // into `rhs` and provide the strong exception safety guarantee. + try { + this->generic_construct(*rhs, lib::move(*lhs)); + } catch (...) { + if (tmp.move_nothrow()) { + this->generic_construct(*rhs, lib::move(tmp)); + } + throw; + } +#else + this->generic_construct(*rhs, lib::move(*lhs)); +#endif + this->generic_construct(*lhs, lib::move(tmp)); + } + } + + private: +#ifndef MPARK_GENERIC_LAMBDAS + struct swapper { + template + inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const { + using std::swap; + swap(this_alt.value, that_alt.value); + } + }; +#endif + + inline constexpr bool move_nothrow() const { + return this->valueless_by_exception() || + lib::array{ + {std::is_nothrow_move_constructible::value...} + }[this->index()]; + } + }; + + template + struct overload_leaf { + using F = lib::size_constant (*)(T); + operator F() const { return nullptr; } + }; + + template + struct overload_impl { + private: + template + struct impl; + + template + struct impl> : overload_leaf... {}; + + public: + using type = impl>; + }; + + template + using overload = typename overload_impl::type; + + template + using best_match = lib::invoke_result_t, T &&>; + + template + struct is_in_place_index : std::false_type {}; + + template + struct is_in_place_index> : std::true_type {}; + + template + struct is_in_place_type : std::false_type {}; + + template + struct is_in_place_type> : std::true_type {}; + + } // detail + + template + class variant { + static_assert(0 < sizeof...(Ts), + "variant must consist of at least one alternative."); + + static_assert(lib::all::value...>::value, + "variant can not have an array type as an alternative."); + + static_assert(lib::all::value...>::value, + "variant can not have a reference type as an alternative."); + + static_assert(lib::all::value...>::value, + "variant can not have a void type as an alternative."); + + public: + template < + typename Front = lib::type_pack_element_t<0, Ts...>, + lib::enable_if_t::value, int> = 0> + inline constexpr variant() noexcept( + std::is_nothrow_default_constructible::value) + : impl_(in_place_index_t<0>{}) {} + + variant(const variant &) = default; + variant(variant &&) = default; + + template < + typename Arg, + typename Decayed = lib::decay_t, + lib::enable_if_t::value, int> = 0, + lib::enable_if_t::value, int> = 0, + lib::enable_if_t::value, int> = 0, + std::size_t I = detail::best_match::value, + typename T = lib::type_pack_element_t, + lib::enable_if_t::value, int> = 0> + inline constexpr variant(Arg &&arg) noexcept( + std::is_nothrow_constructible::value) + : impl_(in_place_index_t{}, lib::forward(arg)) {} + + template < + std::size_t I, + typename... Args, + typename T = lib::type_pack_element_t, + lib::enable_if_t::value, int> = 0> + inline explicit constexpr variant( + in_place_index_t, + Args &&... args) noexcept(std::is_nothrow_constructible::value) + : impl_(in_place_index_t{}, lib::forward(args)...) {} + + template < + std::size_t I, + typename Up, + typename... Args, + typename T = lib::type_pack_element_t, + lib::enable_if_t &, + Args...>::value, + int> = 0> + inline explicit constexpr variant( + in_place_index_t, + std::initializer_list il, + Args &&... args) noexcept(std:: + is_nothrow_constructible< + T, + std::initializer_list &, + Args...>::value) + : impl_(in_place_index_t{}, il, lib::forward(args)...) {} + + template < + typename T, + typename... Args, + std::size_t I = detail::find_index_sfinae::value, + lib::enable_if_t::value, int> = 0> + inline explicit constexpr variant( + in_place_type_t, + Args &&... args) noexcept(std::is_nothrow_constructible::value) + : impl_(in_place_index_t{}, lib::forward(args)...) {} + + template < + typename T, + typename Up, + typename... Args, + std::size_t I = detail::find_index_sfinae::value, + lib::enable_if_t &, + Args...>::value, + int> = 0> + inline explicit constexpr variant( + in_place_type_t, + std::initializer_list il, + Args &&... args) noexcept(std:: + is_nothrow_constructible< + T, + std::initializer_list &, + Args...>::value) + : impl_(in_place_index_t{}, il, lib::forward(args)...) {} + + ~variant() = default; + + variant &operator=(const variant &) = default; + variant &operator=(variant &&) = default; + + template , variant>::value, + int> = 0, + std::size_t I = detail::best_match::value, + typename T = lib::type_pack_element_t, + lib::enable_if_t<(std::is_assignable::value && + std::is_constructible::value), + int> = 0> + inline variant &operator=(Arg &&arg) noexcept( + (std::is_nothrow_assignable::value && + std::is_nothrow_constructible::value)) { + impl_.template assign(lib::forward(arg)); + return *this; + } + + template < + std::size_t I, + typename... Args, + typename T = lib::type_pack_element_t, + lib::enable_if_t::value, int> = 0> + inline T &emplace(Args &&... args) { + return impl_.template emplace(lib::forward(args)...); + } + + template < + std::size_t I, + typename Up, + typename... Args, + typename T = lib::type_pack_element_t, + lib::enable_if_t &, + Args...>::value, + int> = 0> + inline T &emplace(std::initializer_list il, Args &&... args) { + return impl_.template emplace(il, lib::forward(args)...); + } + + template < + typename T, + typename... Args, + std::size_t I = detail::find_index_sfinae::value, + lib::enable_if_t::value, int> = 0> + inline T &emplace(Args &&... args) { + return impl_.template emplace(lib::forward(args)...); + } + + template < + typename T, + typename Up, + typename... Args, + std::size_t I = detail::find_index_sfinae::value, + lib::enable_if_t &, + Args...>::value, + int> = 0> + inline T &emplace(std::initializer_list il, Args &&... args) { + return impl_.template emplace(il, lib::forward(args)...); + } + + inline constexpr bool valueless_by_exception() const noexcept { + return impl_.valueless_by_exception(); + } + + inline constexpr std::size_t index() const noexcept { + return impl_.index(); + } + + template , + Dummy>::value && + lib::dependent_type, + Dummy>::value)...>::value, + int> = 0> + inline void swap(variant &that) noexcept( + lib::all<(std::is_nothrow_move_constructible::value && + lib::is_nothrow_swappable::value)...>::value) { + impl_.swap(that.impl_); + } + + private: + detail::impl impl_; + + friend struct detail::access::variant; + friend struct detail::visitation::variant; + }; + + template + inline constexpr bool holds_alternative(const variant &v) noexcept { + return v.index() == I; + } + + template + inline constexpr bool holds_alternative(const variant &v) noexcept { + return holds_alternative::value>(v); + } + + namespace detail { + template + struct generic_get_impl { + constexpr generic_get_impl(int) noexcept {} + + constexpr AUTO_REFREF operator()(V &&v) const + AUTO_REFREF_RETURN( + access::variant::get_alt(lib::forward(v)).value) + }; + + template + inline constexpr AUTO_REFREF generic_get(V &&v) + AUTO_REFREF_RETURN(generic_get_impl( + holds_alternative(v) ? 0 : (throw_bad_variant_access(), 0))( + lib::forward(v))) + } // namespace detail + + template + inline constexpr variant_alternative_t> &get( + variant &v) { + return detail::generic_get(v); + } + + template + inline constexpr variant_alternative_t> &&get( + variant &&v) { + return detail::generic_get(lib::move(v)); + } + + template + inline constexpr const variant_alternative_t> &get( + const variant &v) { + return detail::generic_get(v); + } + + template + inline constexpr const variant_alternative_t> &&get( + const variant &&v) { + return detail::generic_get(lib::move(v)); + } + + template + inline constexpr T &get(variant &v) { + return get::value>(v); + } + + template + inline constexpr T &&get(variant &&v) { + return get::value>(lib::move(v)); + } + + template + inline constexpr const T &get(const variant &v) { + return get::value>(v); + } + + template + inline constexpr const T &&get(const variant &&v) { + return get::value>(lib::move(v)); + } + + namespace detail { + + template + inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept + AUTO_RETURN(v && holds_alternative(*v) + ? lib::addressof(access::variant::get_alt(*v).value) + : nullptr) + + } // namespace detail + + template + inline constexpr lib::add_pointer_t>> + get_if(variant *v) noexcept { + return detail::generic_get_if(v); + } + + template + inline constexpr lib::add_pointer_t< + const variant_alternative_t>> + get_if(const variant *v) noexcept { + return detail::generic_get_if(v); + } + + template + inline constexpr lib::add_pointer_t + get_if(variant *v) noexcept { + return get_if::value>(v); + } + + template + inline constexpr lib::add_pointer_t + get_if(const variant *v) noexcept { + return get_if::value>(v); + } + + template + inline constexpr bool operator==(const variant &lhs, + const variant &rhs) { + using detail::visitation::variant; + using lib::equal_to; +#ifdef MPARK_CPP14_CONSTEXPR + if (lhs.index() != rhs.index()) return false; + if (lhs.valueless_by_exception()) return true; + return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs); +#else + return lhs.index() == rhs.index() && + (lhs.valueless_by_exception() || + variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs)); +#endif + } + + template + inline constexpr bool operator!=(const variant &lhs, + const variant &rhs) { + using detail::visitation::variant; + using lib::not_equal_to; +#ifdef MPARK_CPP14_CONSTEXPR + if (lhs.index() != rhs.index()) return true; + if (lhs.valueless_by_exception()) return false; + return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs); +#else + return lhs.index() != rhs.index() || + (!lhs.valueless_by_exception() && + variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs)); +#endif + } + + template + inline constexpr bool operator<(const variant &lhs, + const variant &rhs) { + using detail::visitation::variant; + using lib::less; +#ifdef MPARK_CPP14_CONSTEXPR + if (rhs.valueless_by_exception()) return false; + if (lhs.valueless_by_exception()) return true; + if (lhs.index() < rhs.index()) return true; + if (lhs.index() > rhs.index()) return false; + return variant::visit_value_at(lhs.index(), less{}, lhs, rhs); +#else + return !rhs.valueless_by_exception() && + (lhs.valueless_by_exception() || lhs.index() < rhs.index() || + (lhs.index() == rhs.index() && + variant::visit_value_at(lhs.index(), less{}, lhs, rhs))); +#endif + } + + template + inline constexpr bool operator>(const variant &lhs, + const variant &rhs) { + using detail::visitation::variant; + using lib::greater; +#ifdef MPARK_CPP14_CONSTEXPR + if (lhs.valueless_by_exception()) return false; + if (rhs.valueless_by_exception()) return true; + if (lhs.index() > rhs.index()) return true; + if (lhs.index() < rhs.index()) return false; + return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs); +#else + return !lhs.valueless_by_exception() && + (rhs.valueless_by_exception() || lhs.index() > rhs.index() || + (lhs.index() == rhs.index() && + variant::visit_value_at(lhs.index(), greater{}, lhs, rhs))); +#endif + } + + template + inline constexpr bool operator<=(const variant &lhs, + const variant &rhs) { + using detail::visitation::variant; + using lib::less_equal; +#ifdef MPARK_CPP14_CONSTEXPR + if (lhs.valueless_by_exception()) return true; + if (rhs.valueless_by_exception()) return false; + if (lhs.index() < rhs.index()) return true; + if (lhs.index() > rhs.index()) return false; + return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs); +#else + return lhs.valueless_by_exception() || + (!rhs.valueless_by_exception() && + (lhs.index() < rhs.index() || + (lhs.index() == rhs.index() && + variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs)))); +#endif + } + + template + inline constexpr bool operator>=(const variant &lhs, + const variant &rhs) { + using detail::visitation::variant; + using lib::greater_equal; +#ifdef MPARK_CPP14_CONSTEXPR + if (rhs.valueless_by_exception()) return true; + if (lhs.valueless_by_exception()) return false; + if (lhs.index() > rhs.index()) return true; + if (lhs.index() < rhs.index()) return false; + return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs); +#else + return rhs.valueless_by_exception() || + (!lhs.valueless_by_exception() && + (lhs.index() > rhs.index() || + (lhs.index() == rhs.index() && + variant::visit_value_at( + lhs.index(), greater_equal{}, lhs, rhs)))); +#endif + } + + struct monostate {}; + + inline constexpr bool operator<(monostate, monostate) noexcept { + return false; + } + + inline constexpr bool operator>(monostate, monostate) noexcept { + return false; + } + + inline constexpr bool operator<=(monostate, monostate) noexcept { + return true; + } + + inline constexpr bool operator>=(monostate, monostate) noexcept { + return true; + } + + inline constexpr bool operator==(monostate, monostate) noexcept { + return true; + } + + inline constexpr bool operator!=(monostate, monostate) noexcept { + return false; + } + +#ifdef MPARK_CPP14_CONSTEXPR + namespace detail { + + inline constexpr bool all(std::initializer_list bs) { + for (bool b : bs) { + if (!b) { + return false; + } + } + return true; + } + + } // namespace detail + + template + inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) { + return (detail::all({!vs.valueless_by_exception()...}) + ? (void)0 + : throw_bad_variant_access()), + detail::visitation::variant::visit_value( + lib::forward(visitor), lib::forward(vs)...); + } +#else + namespace detail { + + template + inline constexpr bool all_impl(const lib::array &bs, + std::size_t idx) { + return idx >= N || (bs[idx] && all_impl(bs, idx + 1)); + } + + template + inline constexpr bool all(const lib::array &bs) { + return all_impl(bs, 0); + } + + } // namespace detail + + template + inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs) + DECLTYPE_AUTO_RETURN( + (detail::all( + lib::array{{!vs.valueless_by_exception()...}}) + ? (void)0 + : throw_bad_variant_access()), + detail::visitation::variant::visit_value(lib::forward(visitor), + lib::forward(vs)...)) +#endif + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnoexcept" +#endif + template + inline auto swap(variant &lhs, + variant &rhs) noexcept(noexcept(lhs.swap(rhs))) + -> decltype(lhs.swap(rhs)) { + lhs.swap(rhs); + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + + namespace detail { + + template + using enabled_type = T; + + namespace hash { + + template + constexpr bool meets_requirements() noexcept { + return std::is_copy_constructible::value && + std::is_move_constructible::value && + lib::is_invocable_r::value; + } + + template + constexpr bool is_enabled() noexcept { + using H = std::hash; + return meets_requirements() && + std::is_default_constructible::value && + std::is_copy_assignable::value && + std::is_move_assignable::value; + } + + } // namespace hash + + } // namespace detail + +#undef AUTO +#undef AUTO_RETURN + +#undef AUTO_REFREF +#undef AUTO_REFREF_RETURN + +#undef DECLTYPE_AUTO +#undef DECLTYPE_AUTO_RETURN + +} // namespace mpark + +namespace std { + + template + struct hash, + mpark::lib::enable_if_t>()...>::value>>> { + using argument_type = mpark::variant; + using result_type = std::size_t; + + inline result_type operator()(const argument_type &v) const { + using mpark::detail::visitation::variant; + std::size_t result = + v.valueless_by_exception() + ? 299792458 // Random value chosen by the universe upon creation + : variant::visit_alt( +#ifdef MPARK_GENERIC_LAMBDAS + [](const auto &alt) { + using alt_type = mpark::lib::decay_t; + using value_type = mpark::lib::remove_const_t< + typename alt_type::value_type>; + return hash{}(alt.value); + } +#else + hasher{} +#endif + , + v); + return hash_combine(result, hash{}(v.index())); + } + + private: +#ifndef MPARK_GENERIC_LAMBDAS + struct hasher { + template + inline std::size_t operator()(const Alt &alt) const { + using alt_type = mpark::lib::decay_t; + using value_type = + mpark::lib::remove_const_t; + return hash{}(alt.value); + } + }; +#endif + + static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) { + return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2); + } + }; + + template <> + struct hash { + using argument_type = mpark::monostate; + using result_type = std::size_t; + + inline result_type operator()(const argument_type &) const noexcept { + return 66740831; // return a fundamentally attractive random value. + } + }; + +} // namespace std + +#endif // MPARK_VARIANT_HPP diff --git a/thirdparty/Pangolin/include/pangolin/compat/glutbitmap.h b/thirdparty/Pangolin/include/pangolin/compat/glutbitmap.h new file mode 100644 index 00000000..b4661b07 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/compat/glutbitmap.h @@ -0,0 +1,92 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#ifdef HAVE_GLES +GLfloat g_raster_pos[4]; + +inline void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) +{ + // find object point (x,y,z)' in pixel coords + GLdouble projection[16]; + GLdouble modelview[16]; + GLint view[4]; + +#ifdef HAVE_GLES_2 + std::copy(pangolin::glEngine().projection.top().m, pangolin::glEngine().projection.top().m+16, projection); + std::copy(pangolin::glEngine().modelview.top().m, pangolin::glEngine().modelview.top().m+16, modelview); +#else + glGetDoublev(GL_PROJECTION_MATRIX, projection ); + glGetDoublev(GL_MODELVIEW_MATRIX, modelview ); +#endif + glGetIntegerv(GL_VIEWPORT, view ); + + pangolin::glProject(x, y, z, modelview, projection, view, + g_raster_pos, g_raster_pos + 1, g_raster_pos + 2); +} + +inline void glRasterPos2f(GLfloat x, GLfloat y) +{ + glRasterPos3f(x,y,1.0f); +} + +inline void glRasterPos2i(GLint x, GLint y) +{ + glRasterPos3f((GLfloat)x, (GLfloat)y, 1.0f ); +} + +inline void glRasterPos3fv(const GLfloat *v){ + glRasterPos3f(v[0],v[1],v[2]); +} + +inline void glRasterPos2fv(const GLfloat *v){ + glRasterPos3f(v[0],v[1],1.0f); +} +#endif // HAVE_GLES + +inline void glutBitmapString(void * /*font*/, const unsigned char *str) +{ +#ifndef HAVE_GLES + float g_raster_pos[4]; + glGetFloatv(GL_CURRENT_RASTER_POSITION, g_raster_pos); +#endif + + pangolin::GlFont::I().Text( (const char *)str ).DrawWindow( + g_raster_pos[0], g_raster_pos[1], g_raster_pos[2] + ); +} + +inline int glutBitmapLength(void * /*font*/, const unsigned char *str) +{ + return (int)(pangolin::GlFont::I().Text((const char *)str).Width()); +} + +#define GLUT_BITMAP_HELVETICA_12 0; diff --git a/thirdparty/Pangolin/include/pangolin/compat/optional.h b/thirdparty/Pangolin/include/pangolin/compat/optional.h new file mode 100644 index 00000000..5d021d7c --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/compat/optional.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +// Use either C++17 optional, or the standalone backwards compatible version +#if (__cplusplus >= 201703L) +# include +#else +# include +#endif + +namespace pangolin { +#if (__cplusplus >= 201703L) +template +using optional = std::optional; +#else +template +using optional = std::experimental::optional; +#endif +} diff --git a/thirdparty/Pangolin/include/pangolin/compat/type_traits.h b/thirdparty/Pangolin/include/pangolin/compat/type_traits.h new file mode 100644 index 00000000..30bec5ba --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/compat/type_traits.h @@ -0,0 +1,49 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include + +#include + +// enable_if From Boost +namespace pangolin +{ + template + struct enable_if_c { + typedef T type; + }; + + template + struct enable_if_c {}; + + template + struct enable_if : public enable_if_c {}; +} diff --git a/thirdparty/Pangolin/include/pangolin/compat/variant.h b/thirdparty/Pangolin/include/pangolin/compat/variant.h new file mode 100644 index 00000000..84ee74b0 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/compat/variant.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +// Use either C++17 variant, or the standalone backwards compatible version +// of M. Park. +#if (__cplusplus >= 201703L) +# include +#else +# include +#endif + +namespace pangolin { +#if (__cplusplus >= 201703L) +using std::variant; +using std::get; +using std::get_if; +using std::visit; +#else +using mpark::variant; +using mpark::get; +using mpark::get_if; +using mpark::visit; +#endif +} diff --git a/thirdparty/Pangolin/include/pangolin/console/ConsoleInterpreter.h b/thirdparty/Pangolin/include/pangolin/console/ConsoleInterpreter.h new file mode 100644 index 00000000..31d1e108 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/console/ConsoleInterpreter.h @@ -0,0 +1,80 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +enum ConsoleLineType +{ + ConsoleLineTypeCmd, + ConsoleLineTypeCmdOptions, + ConsoleLineTypeStdout, + ConsoleLineTypeStderr, + ConsoleLineTypeOutput, + ConsoleLineTypeHelp, +}; + +class ConsoleLine +{ +public: + inline ConsoleLine() + : linetype(ConsoleLineTypeCmd) + { + } + + inline ConsoleLine(std::string text, ConsoleLineType linetype = ConsoleLineTypeOutput) + : text(text), linetype(linetype) + { + } + + std::string text; + ConsoleLineType linetype; +}; + +class ConsoleInterpreter +{ +public: + inline virtual ~ConsoleInterpreter() + { + } + + virtual void PushCommand(const std::string& cmd) = 0; + + virtual bool PullLine(ConsoleLine& line) = 0; + + virtual std::vector Complete( + const std::string& cmd, int max_options = 20 + ) = 0; + +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/console/ConsoleView.h b/thirdparty/Pangolin/include/pangolin/console/ConsoleView.h new file mode 100644 index 00000000..e45feab8 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/console/ConsoleView.h @@ -0,0 +1,109 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace pangolin +{ + +class ConsoleView : public pangolin::View, pangolin::Handler +{ +public: + struct Line + { + Line() + : linetype(ConsoleLineTypeCmd) + { + } + + Line(const GlText& text, ConsoleLineType linetype = ConsoleLineTypeCmd ) + : text(text), linetype(linetype) + { + } + + GlText text; + ConsoleLineType linetype; + }; + + + // Construct with interpreter (and take ownership) + ConsoleView(ConsoleInterpreter* interpreter); + + ~ConsoleView(); + + View& ShowWithoutAnimation(bool show=true); + + // Replace implementation in View to account for hiding animation + View& Show(bool show=true); + + // Replace implementation in View to account for hiding animation + void ToggleShow(); + + // Replace implementation in View to account for hiding animation + bool IsShown() const; + + void Render() override; + + void Keyboard(View&, unsigned char key, int x, int y, bool pressed) override; + +private: + void DrawLine(const ConsoleView::Line& l, int carat); + + void ProcessOutputLines(); + + void AddLine(const std::string& text, ConsoleLineType linetype = ConsoleLineTypeCmd); + + Line* GetLine(int id, ConsoleLineType line_type, const std::string& prefix = ""); + + ConsoleInterpreter* interpreter; + + GlFont& font; + + int carat; + Line current_line; + std::deque line_buffer; + + bool hiding; + GLfloat bottom; + + Colour background_colour; + std::map line_colours; + float animation_speed; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/attach.h b/thirdparty/Pangolin/include/pangolin/display/attach.h new file mode 100644 index 00000000..1bc776ca --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/attach.h @@ -0,0 +1,86 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +namespace pangolin +{ + +/// Units for measuring screen distances. +enum Unit { + Fraction, + Pixel, + ReversePixel +}; + +/// Defines absolute or relative position from parent viewport edge. +/// Constructors distinguised by whole pixels, or floating +/// fraction in interval [0,1] +struct PANGOLIN_EXPORT Attach { + /// Attach to Left/Bottom edge + Attach() : unit(Fraction), p(0) {} + + /// General constructor + Attach(Unit unit, GLfloat p) : unit(unit), p(p) {} + + /// Specify relative position in range [0,1]. + /// 0 represents leftmost / bottom-most edge, + /// 1 represents rightmost / topmost edge + Attach(GLfloat p) : unit(Fraction), p(p) { + // Allow for numerical imprecision when checking usage. + if( p < -1E-3 || 1.001 < p ) { + std::cerr << "Pangolin API Change: Display::SetBounds must be used with Attach::Pix or Attach::ReversePix to specify pixel bounds relative to an edge. See the code samples for details." << std::endl; + throw std::exception(); + } + } + + /// Specify absolute position from leftmost / bottom-most edge. + static Attach Pix(int p) { + return Attach(p >=0 ? Pixel : ReversePixel, std::abs((float)p)); + } + + /// Specify absolute position from rightmost / topmost edge. + static Attach ReversePix(int p) { + return Attach(ReversePixel, (GLfloat)p); + } + + /// Specify relative position in range [0,1]. + /// 0 represents leftmost / bottom-most edge, + /// 1 represents rightmost / topmost edge + static Attach Frac(float frac) { + return Attach(frac); + } + + Unit unit; + GLfloat p; +}; + +} // namespace pangolin diff --git a/thirdparty/Pangolin/include/pangolin/display/device/OsxWindow.h b/thirdparty/Pangolin/include/pangolin/display/device/OsxWindow.h new file mode 100644 index 00000000..4d1be5df --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/device/OsxWindow.h @@ -0,0 +1,68 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace pangolin +{ + +struct OsxWindow : public PangolinGl +{ + OsxWindow(const std::string& title, int width, int height, bool USE_RETINA); + + ~OsxWindow(); + + void StartFullScreen(); + + void StopFullScreen(); + + void ToggleFullscreen() override; + + void Move(int x, int y) override; + + void Resize(unsigned int w, unsigned int h) override; + + void MakeCurrent() override; + + void RemoveCurrent() override; + + void SwapBuffers() override; + + void ProcessEvents() override; + +private: + NSWindow* _window; + PangolinNSGLView *view; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/device/PangolinNSApplication.h b/thirdparty/Pangolin/include/pangolin/display/device/PangolinNSApplication.h new file mode 100644 index 00000000..799f3750 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/device/PangolinNSApplication.h @@ -0,0 +1,59 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#import +#import + +//////////////////////////////////////////////////////////////////// +// PangolinNSApplication +//////////////////////////////////////////////////////////////////// + +@interface PangolinNSApplication : NSObject { +} + ++ (void)run_pre; ++ (void)run_step; + +@end + +//////////////////////////////////////////////////////////////////// +// PangolinWindowDelegate +//////////////////////////////////////////////////////////////////// + +@interface PangolinWindowDelegate : NSObject + +@end + +//////////////////////////////////////////////////////////////////// +// PangolinAppDelegate +//////////////////////////////////////////////////////////////////// + +@interface PangolinAppDelegate : NSObject + +@end diff --git a/thirdparty/Pangolin/include/pangolin/display/device/PangolinNSGLView.h b/thirdparty/Pangolin/include/pangolin/display/device/PangolinNSGLView.h new file mode 100644 index 00000000..5b8cef58 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/device/PangolinNSGLView.h @@ -0,0 +1,45 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#import +#import + +#include + +//////////////////////////////////////////////////////////////////// +// PangolinNSGLView +//////////////////////////////////////////////////////////////////// + +@interface PangolinNSGLView : NSOpenGLView +{ + pangolin::PangolinGl* context; + float backing_scale; +} +@end + diff --git a/thirdparty/Pangolin/include/pangolin/display/device/WinWindow.h b/thirdparty/Pangolin/include/pangolin/display/device/WinWindow.h new file mode 100644 index 00000000..35e85adc --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/device/WinWindow.h @@ -0,0 +1,89 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include + +#include + +namespace pangolin +{ + +struct WinWindow : public PangolinGl +{ + WinWindow( + const std::string& title, int width, int height + ); + + ~WinWindow(); + + void StartFullScreen(); + + void StopFullScreen(); + + void ToggleFullscreen() override; + + void Move(int x, int y) override; + + void Resize(unsigned int w, unsigned int h) override; + + void MakeCurrent() override; + + void RemoveCurrent() override; + + void SwapBuffers() override; + + void ProcessEvents() override; + + HGLRC GetGLRenderContext() + { + return hGLRC; + } + +private: + static LRESULT APIENTRY WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + + LRESULT HandleWinMessages(UINT message, WPARAM wParam, LPARAM lParam); + + void RegisterThisClass(HMODULE hCurrentInst); + + void SetupPixelFormat(HDC hdc); + + void SetupPalette(HDC hDC); + + // Owns the Window + HWND hWnd; + HDC hDC; + HGLRC hGLRC; + HPALETTE hPalette; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/device/X11GlContext.h b/thirdparty/Pangolin/include/pangolin/display/device/X11GlContext.h new file mode 100644 index 00000000..e69de29b diff --git a/thirdparty/Pangolin/include/pangolin/display/device/X11Window.h b/thirdparty/Pangolin/include/pangolin/display/device/X11Window.h new file mode 100644 index 00000000..c34c724b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/device/X11Window.h @@ -0,0 +1,109 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +namespace pangolin +{ + +struct X11Display +{ + X11Display(const char* name = 0) { + XInitThreads(); + display = XOpenDisplay(name); + if (!display) { + throw std::runtime_error("Pangolin X11: Failed to open X display"); + } + } + + ~X11Display() { + XCloseDisplay(display); + } + + // Owns the display + ::Display* display; +}; + +struct X11GlContext : public GlContextInterface +{ + X11GlContext(std::shared_ptr &d, ::GLXFBConfig chosenFbc, std::shared_ptr shared_context = std::shared_ptr() ); + ~X11GlContext(); + + std::shared_ptr display; + + std::shared_ptr shared_context; + + // Owns the OpenGl Context + ::GLXContext glcontext; +}; + +struct X11Window : public PangolinGl +{ + X11Window( + const std::string& title, int width, int height, + std::shared_ptr& display, ::GLXFBConfig chosenFbc + ); + + ~X11Window(); + + void ToggleFullscreen() override; + + void Move(int x, int y) override; + + void Resize(unsigned int w, unsigned int h) override; + + void MakeCurrent(GLXContext ctx); + + void MakeCurrent() override; + + void RemoveCurrent() override; + + void SwapBuffers() override; + + void ProcessEvents() override; + + // References the X11 display and context. + std::shared_ptr display; + std::shared_ptr glcontext; + + // Owns the X11 Window and Colourmap + ::Window win; + ::Colormap cmap; + + Atom delete_message; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/device/display_android.h b/thirdparty/Pangolin/include/pangolin/display/device/display_android.h new file mode 100644 index 00000000..b98a9b85 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/device/display_android.h @@ -0,0 +1,333 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "pango", __VA_ARGS__)) +#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "pango", __VA_ARGS__)) +#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "pango", __VA_ARGS__)) + +/* For debug builds, always enable the debug traces in this library */ +#undef NDEBUG +#ifndef NDEBUG +# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "pango", __VA_ARGS__)) +#else +# define LOGV(...) ((void)0) +#endif + +template inline +void Log(T v) { + const std::string sv = pangolin::Convert::Do(v); + LOGI(sv.c_str()); +} + +template inline +void Log(const std::string& str, T v) +{ + const std::string sv = pangolin::Convert::Do(v); + LOGI((str + ":" + sv).c_str()); +} + +namespace pangolin +{ + void CreateAndroidWindowAndBind(std::string name); + void ProcessAndroidEvents(); + void FinishAndroidFrame(); +} + + +#ifdef __cplusplus +extern "C" { +#endif + +struct android_app; + +/** + * Data associated with an ALooper fd that will be returned as the "outData" + * when that source has data ready. + */ +struct android_poll_source { + // The identifier of this source. May be LOOPER_ID_MAIN or + // LOOPER_ID_INPUT. + int32_t id; + + // The android_app this ident is associated with. + struct android_app* app; + + // Function to call to perform the standard processing of data from + // this source. + void (*process)(struct android_app* app, struct android_poll_source* source); +}; + +/** + * This is the interface for the standard glue code of a threaded + * application. In this model, the application's code is running + * in its own thread separate from the main thread of the process. + * It is not required that this thread be associated with the Java + * VM, although it will need to be in order to make JNI calls any + * Java objects. + */ +struct android_app { + // The application can place a pointer to its own state object + // here if it likes. + void* userData; + + // Fill this in with the function to process main app commands (APP_CMD_*) + void (*onAppCmd)(struct android_app* app, int32_t cmd); + + // Fill this in with the function to process input events. At this point + // the event has already been pre-dispatched, and it will be finished upon + // return. Return 1 if you have handled the event, 0 for any default + // dispatching. + int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); + + // The ANativeActivity object instance that this app is running in. + ANativeActivity* activity; + + // The current configuration the app is running in. + AConfiguration* config; + + // This is the last instance's saved state, as provided at creation time. + // It is NULL if there was no state. You can use this as you need; the + // memory will remain around until you call android_app_exec_cmd() for + // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. + // These variables should only be changed when processing a APP_CMD_SAVE_STATE, + // at which point they will be initialized to NULL and you can malloc your + // state and place the information here. In that case the memory will be + // freed for you later. + void* savedState; + size_t savedStateSize; + + // The ALooper associated with the app's thread. + ALooper* looper; + + // When non-NULL, this is the input queue from which the app will + // receive user input events. + AInputQueue* inputQueue; + + // When non-NULL, this is the window surface that the app can draw in. + ANativeWindow* window; + + // Current content rectangle of the window; this is the area where the + // window's content should be placed to be seen by the user. + ARect contentRect; + + // Current state of the app's activity. May be either APP_CMD_START, + // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. + int activityState; + + // This is non-zero when the application's NativeActivity is being + // destroyed and waiting for the app thread to complete. + int destroyRequested; + + // ------------------------------------------------- + // Below are "private" implementation of the glue code. + + pthread_mutex_t mutex; + pthread_cond_t cond; + + int msgread; + int msgwrite; + + pthread_t thread; + + struct android_poll_source cmdPollSource; + struct android_poll_source inputPollSource; + + int running; + int stateSaved; + int destroyed; + int redrawNeeded; + AInputQueue* pendingInputQueue; + ANativeWindow* pendingWindow; + ARect pendingContentRect; + + const char* application_so; +}; + +enum { + /** + * Looper data ID of commands coming from the app's main thread, which + * is returned as an identifier from ALooper_pollOnce(). The data for this + * identifier is a pointer to an android_poll_source structure. + * These can be retrieved and processed with android_app_read_cmd() + * and android_app_exec_cmd(). + */ + LOOPER_ID_MAIN = 1, + + /** + * Looper data ID of events coming from the AInputQueue of the + * application's window, which is returned as an identifier from + * ALooper_pollOnce(). The data for this identifier is a pointer to an + * android_poll_source structure. These can be read via the inputQueue + * object of android_app. + */ + LOOPER_ID_INPUT = 2, + + /** + * Start of user-defined ALooper identifiers. + */ + LOOPER_ID_USER = 3, +}; + +enum { + /** + * Command from main thread: the AInputQueue has changed. Upon processing + * this command, android_app->inputQueue will be updated to the new queue + * (or NULL). + */ + APP_CMD_INPUT_CHANGED, + + /** + * Command from main thread: a new ANativeWindow is ready for use. Upon + * receiving this command, android_app->window will contain the new window + * surface. + */ + APP_CMD_INIT_WINDOW, + + /** + * Command from main thread: the existing ANativeWindow needs to be + * terminated. Upon receiving this command, android_app->window still + * contains the existing window; after calling android_app_exec_cmd + * it will be set to NULL. + */ + APP_CMD_TERM_WINDOW, + + /** + * Command from main thread: the current ANativeWindow has been resized. + * Please redraw with its new size. + */ + APP_CMD_WINDOW_RESIZED, + + /** + * Command from main thread: the system needs that the current ANativeWindow + * be redrawn. You should redraw the window before handing this to + * android_app_exec_cmd() in order to avoid transient drawing glitches. + */ + APP_CMD_WINDOW_REDRAW_NEEDED, + + /** + * Command from main thread: the content area of the window has changed, + * such as from the soft input window being shown or hidden. You can + * find the new content rect in android_app::contentRect. + */ + APP_CMD_CONTENT_RECT_CHANGED, + + /** + * Command from main thread: the app's activity window has gained + * input focus. + */ + APP_CMD_GAINED_FOCUS, + + /** + * Command from main thread: the app's activity window has lost + * input focus. + */ + APP_CMD_LOST_FOCUS, + + /** + * Command from main thread: the current device configuration has changed. + */ + APP_CMD_CONFIG_CHANGED, + + /** + * Command from main thread: the system is running low on memory. + * Try to reduce your memory use. + */ + APP_CMD_LOW_MEMORY, + + /** + * Command from main thread: the app's activity has been started. + */ + APP_CMD_START, + + /** + * Command from main thread: the app's activity has been resumed. + */ + APP_CMD_RESUME, + + /** + * Command from main thread: the app should generate a new saved state + * for itself, to restore from later if needed. If you have saved state, + * allocate it with malloc and place it in android_app.savedState with + * the size in android_app.savedStateSize. The will be freed for you + * later. + */ + APP_CMD_SAVE_STATE, + + /** + * Command from main thread: the app's activity has been paused. + */ + APP_CMD_PAUSE, + + /** + * Command from main thread: the app's activity has been stopped. + */ + APP_CMD_STOP, + + /** + * Command from main thread: the app's activity is being destroyed, + * and waiting for the app thread to clean up and exit before proceeding. + */ + APP_CMD_DESTROY, +}; + +/** + * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next + * app command message. + */ +int8_t android_app_read_cmd(struct android_app* android_app); + +/** + * Call with the command returned by android_app_read_cmd() to do the + * initial pre-processing of the given command. You can perform your own + * actions for the command after calling this function. + */ +void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); + +/** + * Call with the command returned by android_app_read_cmd() to do the + * final post-processing of the given command. You must have done your own + * actions for the command before calling this function. + */ +void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); + +#ifdef __cplusplus +} +#endif diff --git a/thirdparty/Pangolin/include/pangolin/display/display.h b/thirdparty/Pangolin/include/pangolin/display/display.h new file mode 100644 index 00000000..987b90b1 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/display.h @@ -0,0 +1,219 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove, Richard Newcombe + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file display.h + * This file contains a number of global methods for creating and + * querying window state as well as handling user input. + */ + +namespace pangolin +{ + + // CreateWindowAndBind parameter key names. + // X11 Window options: + extern const char* PARAM_DISPLAYNAME; // std::string + extern const char* PARAM_DOUBLEBUFFER; // bool + extern const char* PARAM_SAMPLE_BUFFERS; // int + extern const char* PARAM_SAMPLES; // int + extern const char* PARAM_HIGHRES; // bool - Apple Retina screens only + + // Forward Declarations + struct View; + struct Viewport; + class UserApp; + + /// Give this OpenGL context a name or switch contexts. + /// This is required to initialise Pangolin for use with an + /// externally defined OpenGL context. You needn't call it + /// if you have used CreateWindowAndBind() to create a window + /// or launched a pangolin::UserApp + PANGOLIN_EXPORT + WindowInterface& BindToContext(std::string name); + + /// Initialise OpenGL window (determined by platform) and bind context. + /// This method will choose an available windowing system if one is present. + PANGOLIN_EXPORT + WindowInterface& CreateWindowAndBind(std::string window_title, int w = 640, int h = 480, const Params& params = Params()); + + /// Return pointer to current Pangolin Window context, or nullptr if none bound. + PANGOLIN_EXPORT + WindowInterface* GetBoundWindow(); + + PANGOLIN_EXPORT + void DestroyWindow(const std::string& window_title); + + /// Launch users derived UserApp, controlling OpenGL event loop. + /// This method will block until the application exits, calling app's + /// Init() method to start and Render() method subsequently to draw each frame. + /// @return exit code for use when returning from main. Currently always 0. + PANGOLIN_EXPORT + int LaunchUserApp(UserApp& app); + + /// Perform any post rendering, event processing and frame swapping. + PANGOLIN_EXPORT + void FinishFrame(); + + /// Request that the window close. + PANGOLIN_EXPORT + void Quit(); + + /// Request that all windows close. + PANGOLIN_EXPORT + void QuitAll(); + + /// Returns true if user has requested to close OpenGL window. + PANGOLIN_EXPORT + bool ShouldQuit(); + + /// Returns true if user has interacted with the window since this was last called. + PANGOLIN_EXPORT + bool HadInput(); + + /// Returns true if user has resized the window. + PANGOLIN_EXPORT + bool HasResized(); + + /// Renders any views with default draw methods. + PANGOLIN_EXPORT + void RenderViews(); + + /// Perform any post render events, such as screen recording. + PANGOLIN_EXPORT + void PostRender(); + + /// Request to be notified via functor when key is pressed. + /// Functor may take one parameter which will equal the key pressed + PANGOLIN_EXPORT + void RegisterKeyPressCallback(int key, std::function func); + + /// Save window contents to image. + PANGOLIN_EXPORT + void SaveWindowOnRender(std::string filename_prefix); + + PANGOLIN_EXPORT + void SaveFramebuffer(std::string prefix, const Viewport& v); + + namespace process + { + /// Tell pangolin to process input to drive display. + /// You will need to call this manually if you haven't let + /// Pangolin register callbacks from your windowing system + PANGOLIN_EXPORT + void Keyboard( unsigned char key, int x, int y); + + PANGOLIN_EXPORT + void KeyboardUp(unsigned char key, int x, int y); + + PANGOLIN_EXPORT + void SpecialFunc(int key, int x, int y); + + PANGOLIN_EXPORT + void SpecialFuncUp(int key, int x, int y); + + /// Tell pangolin base window size has changed + /// You will need to call this manually if you haven't let + /// Pangolin register callbacks from your windowing system + PANGOLIN_EXPORT + void Resize(int width, int height); + + /// Event based rendering entry point. Not currently supported. + PANGOLIN_EXPORT + void Display(); + + PANGOLIN_EXPORT + void Mouse( int button, int state, int x, int y); + + PANGOLIN_EXPORT + void MouseMotion( int x, int y); + + PANGOLIN_EXPORT + void PassiveMouseMotion(int x, int y); + + PANGOLIN_EXPORT + void Scroll(float x, float y); + + PANGOLIN_EXPORT + void Zoom(float m); + + PANGOLIN_EXPORT + void Rotate(float r); + + PANGOLIN_EXPORT + void SubpixMotion(float x, float y, float pressure, float rotation, float tiltx, float tilty); + + PANGOLIN_EXPORT + void SpecialInput(InputSpecial inType, float x, float y, float p1, float p2, float p3, float p4); + + } + + /// Retrieve 'base' display, corresponding to entire window. + PANGOLIN_EXPORT + View& DisplayBase(); + + /// Create or retrieve named display managed by pangolin (automatically deleted). + PANGOLIN_EXPORT + View& Display(const std::string& name); + + /// Create unnamed display managed by pangolin (automatically deleted). + PANGOLIN_EXPORT + View& CreateDisplay(); + + /// Switch between windowed and fullscreen mode. + PANGOLIN_EXPORT + void ToggleFullscreen(); + + /// Switch windows/fullscreenmode = fullscreen. + PANGOLIN_EXPORT + void SetFullscreen(bool fullscreen = true); + + /// Toggle display of Pangolin console + PANGOLIN_EXPORT + void ToggleConsole(); + + /// Convenience functor for toggling pangolin::View. + /// Use with RegisterKeyPressCallback for example + struct ToggleViewFunctor { + inline ToggleViewFunctor(View& view); + inline ToggleViewFunctor(const std::string& name); + void operator()(); + View& view; + }; + +} + diff --git a/thirdparty/Pangolin/include/pangolin/display/display_internal.h b/thirdparty/Pangolin/include/pangolin/display/display_internal.h new file mode 100644 index 00000000..a39dea56 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/display_internal.h @@ -0,0 +1,138 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef BUILD_PANGOLIN_VIDEO +# include +#endif // BUILD_PANGOLIN_VIDEO + + +namespace pangolin +{ + +// Forward Declarations +#ifdef HAVE_PYTHON +class ConsoleView; +#endif // HAVE_PYTHON +class GlFont; + +typedef std::map ViewMap; +typedef std::map > KeyhookMap; + +struct PANGOLIN_EXPORT PangolinGl : public WindowInterface +{ + PangolinGl(); + ~PangolinGl(); + + // Base container for displays + View base; + + // Named views which are managed by pangolin (i.e. created / deleted by pangolin) + ViewMap named_managed_views; + + // Optional user app + UserApp* user_app; + + // Global keypress hooks + KeyhookMap keypress_hooks; + + // Manage fullscreen (ToggleFullscreen is quite new) + bool is_double_buffered; + bool is_fullscreen; + GLint windowed_size[2]; + bool is_high_res; + + // State relating to interactivity + bool quit; + int had_input; + int has_resized; + int mouse_state; + View* activeDisplay; + + std::queue > screen_capture; + +#ifdef BUILD_PANGOLIN_VIDEO + View* record_view; + VideoOutput recorder; +#endif + +#ifdef HAVE_PYTHON + ConsoleView* console_view; +#endif + + std::shared_ptr font; + + virtual void ToggleFullscreen() override { + pango_print_warn("ToggleFullscreen: Not available with non-pangolin window.\n"); + } + + virtual void ProcessEvents() override { + pango_print_warn("ProcessEvents: Not available with non-pangolin window.\n"); + } + + virtual void SwapBuffers() override { + pango_print_warn("SwapBuffers: Not available with non-pangolin window.\n"); + } + + virtual void MakeCurrent() override { + pango_print_warn("MakeCurrent: Not available with non-pangolin window.\n"); + } + + virtual void RemoveCurrent() override { + pango_print_warn("RemoveCurrent: Not available with non-pangolin window.\n"); + } + + virtual void Move(int /*x*/, int /*y*/) override { + pango_print_warn("Move: Not available with non-pangolin window.\n"); + } + + virtual void Resize(unsigned int /*w*/, unsigned int /*h*/) override { + pango_print_warn("Resize: Not available with non-pangolin window.\n"); + } + + +}; + +PangolinGl* GetCurrentContext(); +void RegisterNewContext(const std::string& name, std::shared_ptr newcontext); +void DeleteContext(const std::string& name); +PangolinGl *FindContext(const std::string& name); + +} + diff --git a/thirdparty/Pangolin/include/pangolin/display/image_view.h b/thirdparty/Pangolin/include/pangolin/display/image_view.h new file mode 100644 index 00000000..ce53cad2 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/image_view.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace pangolin +{ + +class ImageView : public pangolin::View, public pangolin::ImageViewHandler +{ + public: + ImageView(); + + ~ImageView(); + + void Render() override; + + void Mouse(View& view, pangolin::MouseButton button, int x, int y, bool pressed, int button_state) override; + + void Keyboard(View& view, unsigned char key, int x, int y, bool pressed) override; + + pangolin::GlTexture& Tex(); + + ImageView& SetImage(void* ptr, size_t w, size_t h, size_t pitch, pangolin::GlPixFormat img_fmt, bool delayed_upload = false); + + ImageView& SetImage(const pangolin::Image& img, const pangolin::GlPixFormat& glfmt, bool delayed_upload = false); + + template inline + ImageView& SetImage(const pangolin::Image& img, bool delayed_upload = false) + { + return SetImage(img.template UnsafeReinterpret(), GlPixFormat::FromType(), delayed_upload); + } + + ImageView& SetImage(const pangolin::TypedImage& img, bool delayed_upload = false); + + ImageView& SetImage(const pangolin::GlTexture& texture); + + void LoadPending(); + + ImageView& Clear(); + + std::pair& GetOffsetScale(); + + bool MouseReleased() const; + + bool MousePressed() const; + + void SetRenderOverlay(const bool& val); + +// private: + // img_to_load contains image data that should be uploaded to the texture on + // the next render cycle. The data is owned by this object and should be + // freed after use. + pangolin::ManagedImage img_to_load; + pangolin::GlPixFormat img_fmt_to_load; + + std::pair offset_scale; + pangolin::GlPixFormat fmt; + pangolin::GlTexture tex; + bool lastPressed; + bool mouseReleased; + bool mousePressed; + bool overlayRender; + + std::mutex texlock; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/opengl_render_state.h b/thirdparty/Pangolin/include/pangolin/display/opengl_render_state.h new file mode 100644 index 00000000..60de1b9e --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/opengl_render_state.h @@ -0,0 +1,446 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include + +#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files +#define USE_EIGEN +#endif + +#ifdef USE_EIGEN +#include +#include +#endif + +#ifdef HAVE_TOON +#include +#include +#include +#endif + +#ifdef HAVE_OCULUS +#include +#endif + +namespace pangolin { + +#ifdef HAVE_GLES + typedef float GLprecision; +#else + typedef double GLprecision; +#endif + +/// Capture OpenGL matrix types in enum to typing. +enum OpenGlStack { + GlModelViewStack = 0x1700, // GL_MODELVIEW + GlProjectionStack = 0x1701, // GL_PROJECTION + GlTextureStack = 0x1702 // GL_TEXTURE +}; + +enum AxisDirection +{ + AxisNone, + AxisNegX, AxisX, + AxisNegY, AxisY, + AxisNegZ, AxisZ +}; + +struct CameraSpec { + GLprecision forward[3]; + GLprecision up[3]; + GLprecision right[3]; + GLprecision img_up[2]; + GLprecision img_right[2]; +}; + +const static CameraSpec CameraSpecOpenGl = {{0,0,-1},{0,1,0},{1,0,0},{0,1},{1,0}}; + +const static CameraSpec CameraSpecYDownZForward = {{0,0,1},{0,-1,0},{1,0,0},{0,-1},{1,0}}; + +/// Direction vector for each AxisDirection enum +const static GLprecision AxisDirectionVector[7][3] = { + {0,0,0}, + {-1,0,0}, {1,0,0}, + {0,-1,0}, {0,1,0}, + {0,0,-1}, {0,0,1} +}; + +/// Object representing OpenGl Matrix. +struct PANGOLIN_EXPORT OpenGlMatrix { + static OpenGlMatrix Translate(GLprecision x, GLprecision y, GLprecision z); + static OpenGlMatrix Scale(GLprecision x, GLprecision y, GLprecision z); + static OpenGlMatrix RotateX(GLprecision theta_rad); + static OpenGlMatrix RotateY(GLprecision theta_rad); + static OpenGlMatrix RotateZ(GLprecision theta_rad); + + + template + static OpenGlMatrix ColMajor4x4(const P* col_major_4x4); + + OpenGlMatrix(); + +#ifdef USE_EIGEN + template + OpenGlMatrix(const Eigen::Matrix& mat); + + template + OpenGlMatrix(const Eigen::Transform& mat) : OpenGlMatrix(mat.matrix()) { } + + template + operator Eigen::Matrix() const; + + template + operator Eigen::Transform() const; +#endif // USE_EIGEN + +#ifdef HAVE_TOON + OpenGlMatrix(const TooN::SE3<>& T); + OpenGlMatrix(const TooN::Matrix<4,4>& M); + operator const TooN::SE3<>() const; + operator const TooN::Matrix<4,4>() const; +#endif // HAVE_TOON + +#ifdef HAVE_OCULUS + OpenGlMatrix(const OVR::Matrix4f& M); + operator const OVR::Matrix4f() const; +#endif // HAVE_OCULUS + + // Load matrix on to OpenGl stack + void Load() const; + + void Multiply() const; + + void SetIdentity(); + + OpenGlMatrix Transpose() const; + + OpenGlMatrix Inverse() const; + + GLprecision& operator()(int r, int c) { + return m[4*c +r]; + } + + GLprecision operator()(int r, int c) const { + return m[4 * c + r]; + } + + // Column major Internal buffer + GLprecision m[16]; +}; + +PANGOLIN_EXPORT +OpenGlMatrix operator*(const OpenGlMatrix& lhs, const OpenGlMatrix& rhs); + +PANGOLIN_EXPORT +std::ostream& operator<<(std::ostream& os, const OpenGlMatrix& mat); + +/// Deprecated. +struct PANGOLIN_EXPORT OpenGlMatrixSpec : public OpenGlMatrix { + // Specify which stack this refers to + OpenGlStack type; +}; + +/// Object representing attached OpenGl Matrices / transforms. +class PANGOLIN_EXPORT OpenGlRenderState +{ +public: + OpenGlRenderState(); + OpenGlRenderState(const OpenGlMatrix& projection_matrix); + OpenGlRenderState(const OpenGlMatrix& projection_matrix, const OpenGlMatrix& modelview_matrix); + + static void ApplyIdentity(); + + void Apply() const; + OpenGlRenderState& SetProjectionMatrix(OpenGlMatrix m); + OpenGlRenderState& SetModelViewMatrix(OpenGlMatrix m); + + OpenGlMatrix& GetProjectionMatrix(); + OpenGlMatrix GetProjectionMatrix() const; + + OpenGlMatrix& GetModelViewMatrix(); + OpenGlMatrix GetModelViewMatrix() const; + + OpenGlMatrix GetProjectionModelViewMatrix() const; + OpenGlMatrix GetProjectiveTextureMatrix() const; + + void EnableProjectiveTexturing() const; + void DisableProjectiveTexturing() const; + + //! Seemlessly move OpenGl camera relative to changes in T_wc, + //! whilst still enabling interaction + void Follow(const OpenGlMatrix& T_wc, bool follow = true); + void Unfollow(); + + // Experimental - subject to change + OpenGlMatrix& GetProjectionMatrix(unsigned int view); + OpenGlMatrix GetProjectionMatrix(unsigned int view) const; + OpenGlMatrix& GetViewOffset(unsigned int view); + OpenGlMatrix GetViewOffset(unsigned int view) const; + OpenGlMatrix GetModelViewMatrix(int i) const; + void ApplyNView(int view) const; + + PANGOLIN_DEPRECATED + OpenGlRenderState& Set(OpenGlMatrixSpec spec); + +protected: + OpenGlMatrix modelview; + std::vector projection; + std::vector modelview_premult; + OpenGlMatrix T_cw; + bool follow; +}; + +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrixRUB_BottomLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar ); + +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrixRUB_TopLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar ); + +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrixRDF_TopLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar ); + +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrixRDF_TopRight(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar ); + +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrixRDF_BottomLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar ); + +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrixRDF_BottomRight(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar ); + +//! Use OpenGl's default frame RUB_BottomLeft +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrix(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar ); + +PANGOLIN_EXPORT +OpenGlMatrixSpec ProjectionMatrixOrthographic(GLprecision l, GLprecision r, GLprecision b, GLprecision t, GLprecision n, GLprecision f ); + + +//! Generate glulookat style model view matrix, looking at (lx,ly,lz) +//! X-Right, Y-Up, Z-Back +PANGOLIN_EXPORT +OpenGlMatrix ModelViewLookAtRUB(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz); + +//! Generate glulookat style model view matrix, looking at (lx,ly,lz) +//! X-Right, Y-Down, Z-Forward +PANGOLIN_EXPORT +OpenGlMatrix ModelViewLookAtRDF(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz); + +//! Generate glulookat style model view matrix, OpenGL Default camera convention (XYZ=RUB), looking at (lx,ly,lz) +PANGOLIN_EXPORT +OpenGlMatrix ModelViewLookAt(GLprecision x, GLprecision y, GLprecision z, GLprecision lx, GLprecision ly, GLprecision lz, AxisDirection up); + +PANGOLIN_EXPORT +OpenGlMatrix ModelViewLookAt(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz); + + +PANGOLIN_EXPORT +OpenGlMatrix IdentityMatrix(); + +PANGOLIN_EXPORT +OpenGlMatrixSpec IdentityMatrix(OpenGlStack type); + +PANGOLIN_EXPORT +OpenGlMatrixSpec negIdentityMatrix(OpenGlStack type); + +#ifdef HAVE_TOON +OpenGlMatrixSpec FromTooN(const TooN::SE3<>& T_cw); +OpenGlMatrixSpec FromTooN(OpenGlStack type, const TooN::Matrix<4,4>& M); +TooN::Matrix<4,4> ToTooN(const OpenGlMatrixSpec& ms); +TooN::SE3<> ToTooN_SE3(const OpenGlMatrixSpec& ms); +#endif + +#ifdef HAVE_EIGEN +template +Eigen::Matrix ToEigen(const OpenGlMatrix& ms); +#endif + +} + +// Inline definitions +namespace pangolin +{ + +template +inline OpenGlMatrix OpenGlMatrix::ColMajor4x4(const P* col_major_4x4) +{ + OpenGlMatrix mat; + std::copy(col_major_4x4, col_major_4x4 + 16, mat.m); + return mat; +} + +inline OpenGlMatrix::OpenGlMatrix() { +} + +#ifdef USE_EIGEN +template inline +OpenGlMatrix::OpenGlMatrix(const Eigen::Matrix& mat) +{ + for(int r=0; r<4; ++r ) { + for(int c=0; c<4; ++c ) { + m[c*4+r] = mat(r,c); + } + } +} + +template +OpenGlMatrix::operator Eigen::Matrix() const +{ + return ToEigen

(*this); +} + +template +OpenGlMatrix::operator Eigen::Transform() const +{ + return Eigen::Transform(ToEigen

(*this)); +} + +template inline +Eigen::Matrix ToEigen(const OpenGlMatrix& ms) +{ + Eigen::Matrix mat; + for(int r=0; r<4; ++r ) { + for(int c=0; c<4; ++c ) { + mat(r,c) = (P)ms.m[c*4+r]; + } + } + return mat; +} + +#endif // USE_EIGEN + +#ifdef HAVE_TOON +inline OpenGlMatrix::OpenGlMatrix(const TooN::SE3<>& T) +{ + TooN::Matrix<4,4,GLprecision,TooN::ColMajor> M; + M.slice<0,0,3,3>() = T.get_rotation().get_matrix(); + M.T()[3].slice<0,3>() = T.get_translation(); + M[3] = TooN::makeVector(0,0,0,1); + std::memcpy(m, &(M[0][0]),16*sizeof(GLprecision)); +} + +inline OpenGlMatrix::OpenGlMatrix(const TooN::Matrix<4,4>& M) +{ + // Read in remembering col-major convension for our matrices + int el = 0; + for(int c=0; c<4; ++c) + for(int r=0; r<4; ++r) + m[el++] = M[r][c]; +} + +inline OpenGlMatrix::operator const TooN::SE3<>() const +{ + const TooN::Matrix<4,4> m = *this; + const TooN::SO3<> R(m.slice<0,0,3,3>()); + const TooN::Vector<3> t = m.T()[3].slice<0,3>(); + return TooN::SE3<>(R,t); +} + +inline OpenGlMatrix::operator const TooN::Matrix<4,4>() const +{ + TooN::Matrix<4,4> M; + int el = 0; + for( int c=0; c<4; ++c ) + for( int r=0; r<4; ++r ) + M(r,c) = m[el++]; + return M; +} + +PANGOLIN_DEPRECATED +inline OpenGlMatrixSpec FromTooN(const TooN::SE3<>& T_cw) +{ + TooN::Matrix<4,4,GLprecision,TooN::ColMajor> M; + M.slice<0,0,3,3>() = T_cw.get_rotation().get_matrix(); + M.T()[3].slice<0,3>() = T_cw.get_translation(); + M[3] = TooN::makeVector(0,0,0,1); + + OpenGlMatrixSpec P; + P.type = GlModelViewStack; + std::memcpy(P.m, &(M[0][0]),16*sizeof(GLprecision)); + return P; +} + +PANGOLIN_DEPRECATED +inline OpenGlMatrixSpec FromTooN(OpenGlStack type, const TooN::Matrix<4,4>& M) +{ + // Read in remembering col-major convension for our matrices + OpenGlMatrixSpec P; + P.type = type; + int el = 0; + for(int c=0; c<4; ++c) + for(int r=0; r<4; ++r) + P.m[el++] = M[r][c]; + return P; +} + +PANGOLIN_DEPRECATED +inline TooN::Matrix<4,4> ToTooN(const OpenGlMatrix& ms) +{ + TooN::Matrix<4,4> m; + int el = 0; + for( int c=0; c<4; ++c ) + for( int r=0; r<4; ++r ) + m(r,c) = ms.m[el++]; + return m; +} + +PANGOLIN_DEPRECATED +inline TooN::SE3<> ToTooN_SE3(const OpenGlMatrix& ms) +{ + TooN::Matrix<4,4> m = ms; + const TooN::SO3<> R(m.slice<0,0,3,3>()); + const TooN::Vector<3> t = m.T()[3].slice<0,3>(); + return TooN::SE3<>(R,t); +} + +#endif // HAVE_TOON + +#ifdef HAVE_OCULUS +inline OpenGlMatrix::OpenGlMatrix(const OVR::Matrix4f& mat) +{ + for(int r=0; r<4; ++r ) + for(int c=0; c<4; ++c ) + m[c*4+r] = mat.M[r][c]; +} + +inline OpenGlMatrix::operator const OVR::Matrix4f() const +{ + OVR::Matrix4f mat; + for(int r=0; r<4; ++r ) + for(int c=0; c<4; ++c ) + mat.M[r][c] = m[c*4+r]; + return mat; +} +#endif // HAVE_OCULUS + + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/user_app.h b/thirdparty/Pangolin/include/pangolin/display/user_app.h new file mode 100644 index 00000000..013ad26d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/user_app.h @@ -0,0 +1,43 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT UserApp +{ +public: + virtual ~UserApp() {} + virtual void Init() {} + virtual void Render() = 0; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/view.h b/thirdparty/Pangolin/include/pangolin/display/view.h new file mode 100644 index 00000000..7bc7a0d8 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/view.h @@ -0,0 +1,233 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace pangolin +{ + +enum Layout +{ + LayoutOverlay, + LayoutVertical, + LayoutHorizontal, + LayoutEqual, + LayoutEqualVertical, + LayoutEqualHorizontal +}; + +enum Lock { + LockLeft = 0, + LockBottom = 0, + LockCenter = 1, + LockRight = 2, + LockTop = 2 +}; + +// Forward declarations +struct Handler; + +class OpenGlRenderState; + +/// A Display manages the location and resizing of an OpenGl viewport. +struct PANGOLIN_EXPORT View +{ + View(double aspect=0.0) + : aspect(aspect), top(1.0),left(0.0),right(1.0),bottom(0.0), hlock(LockCenter),vlock(LockCenter), + layout(LayoutOverlay), scroll_offset(0), show(1), zorder(0), handler(0) {} + + virtual ~View() {} + + //! Activate Displays viewport for drawing within this area + void Activate() const; + + //! Activate Displays and set State Matrices + void Activate(const OpenGlRenderState& state ) const; + + //! Activate Displays viewport and Scissor for drawing within this area + void ActivateAndScissor() const; + + //! Activate Displays viewport and Scissor for drawing within this area + void ActivateScissorAndClear() const; + + //! Activate Display and set State Matrices + void ActivateAndScissor(const OpenGlRenderState& state ) const; + + //! Activate Display and set State Matrices + void ActivateScissorAndClear(const OpenGlRenderState& state ) const; + + //! Activate Display and setup coordinate system for 2d pixel View coordinates + void ActivatePixelOrthographic() const; + + //! Activate Display and reset coordinate system to OpenGL default + void ActivateIdentity() const; + + //! Return closest depth buffer value within radius of window (winx,winy) + GLfloat GetClosestDepth(int winx, int winy, int radius) const; + + //! Obtain camera space coordinates of scene at pixel (winx, winy, winzdepth) + //! winzdepth can be obtained from GetClosestDepth + void GetCamCoordinates(const OpenGlRenderState& cam_state, double winx, double winy, double winzdepth, GLdouble& x, GLdouble& y, GLdouble& z) const; + + //! Obtain object space coordinates of scene at pixel (winx, winy, winzdepth) + //! winzdepth can be obtained from GetClosestDepth + void GetObjectCoordinates(const OpenGlRenderState& cam_state, double winx, double winy, double winzdepth, GLdouble& x, GLdouble& y, GLdouble& z) const; + + //! Given the specification of Display, compute viewport + virtual void Resize(const Viewport& parent); + + //! Instruct all children to resize + virtual void ResizeChildren(); + + //! Perform any automatic rendering for this View. + //! Default implementation simply instructs children to render themselves. + virtual void Render(); + + //! Instruct all children to render themselves if appropriate + virtual void RenderChildren(); + + //! Set this view as the active View to receive input + View& SetFocus(); + + //! Returns true iff this view currently has focus and will receive user input + bool HasFocus() const; + + //! Set bounds for the View using mixed fractional / pixel coordinates (OpenGl view coordinates) + View& SetBounds(Attach bottom, Attach top, Attach left, Attach right); + + //! Set bounds for the View using mixed fractional / pixel coordinates (OpenGl view coordinates) + View& SetBounds(Attach bottom, Attach top, Attach left, Attach right, bool keep_aspect); + + //! Set bounds for the View using mixed fractional / pixel coordinates (OpenGl view coordinates) + View& SetBounds(Attach bottom, Attach top, Attach left, Attach right, double aspect); + + //! Designate handler for accepting mouse / keyboard input. + View& SetHandler(Handler* handler); + + //! Set drawFunc as the drawing function for this view + View& SetDrawFunction(const std::function& drawFunc); + + //! Force this view to have the given aspect, whilst fitting snuggly + //! within the parent. A negative value with 'over-draw', fitting the + //! smaller side of the parent. + View& SetAspect(double aspect); + + //! Set how this view should be positioned relative to its parent + View& SetLock(Lock horizontal, Lock vertical ); + + //! Set layout policy for this view + View& SetLayout(Layout layout); + + //! Add view as child + View& AddDisplay(View& view); + + //! Show / hide this view + View& Show(bool show=true); + + //! Toggle this views visibility + void ToggleShow(); + + //! Return whether this view should be shown. + //! This method should be checked if drawing manually + bool IsShown() const; + + //! Returns viewport reflecting space that will actually get drawn + //! The minimum of vp and v + Viewport GetBounds() const; + + //! Specify that this views region in the framebuffer should be saved to + //! a file just before the buffer is flipped. + void SaveOnRender(const std::string& filename_prefix); + + //! Specify that this views region in the framebuffer should be saved to + //! a video just before the buffer is flipped + void RecordOnRender(const std::string& record_uri); + + //! Uses the views default render method to draw into an FBO 'scale' times + //! the size of the view and save to a file. + void SaveRenderNow(const std::string& filename_prefix, float scale = 1); + + //! Return number of child views attached to this view + size_t NumChildren() const; + + //! Return (i)th child of this view + View& operator[](size_t i); + + //! Return number of visible child views attached to this view. + size_t NumVisibleChildren() const; + + //! Return visible child by index. + View& VisibleChild(size_t i); + + //! Return visible child at window coords x,y + View* FindChild(int x, int y); + + // Desired width / height aspect (0 if dynamic) + double aspect; + + // Bounds to fit display within + Attach top, left, right, bottom; + Lock hlock; + Lock vlock; + Layout layout; + + int scroll_offset; + + // Cached client area (space allocated from parent) + Viewport vp; + + // Cached absolute viewport (recomputed on resize - respects aspect) + Viewport v; + + // Should this view be displayed? + bool show; + + // Child views are rendered in order of low to high z-order + // Views default to 0 z-order + int zorder; + + // Input event handler (if any) + Handler* handler; + + // Map for sub-displays (if any) + std::vector views; + + // External draw function + std::function extern_draw_function; + +private: + // Private copy constructor + View(View&) { /* Do Not copy - take reference instead*/ } +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/viewport.h b/thirdparty/Pangolin/include/pangolin/display/viewport.h new file mode 100644 index 00000000..f3d75f1a --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/viewport.h @@ -0,0 +1,65 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +/// Encapsulates OpenGl Viewport. +struct PANGOLIN_EXPORT Viewport +{ + Viewport() : l(0),b(0),w(0),h(0) {} + Viewport(GLint l,GLint b,GLint w,GLint h) : l(l),b(b),w(w),h(h) {} + + void Activate() const; + void ActivateIdentity() const; + void ActivatePixelOrthographic() const; + + void Scissor() const; + void ActivateAndScissor() const; + + bool Contains(int x, int y) const; + + Viewport Inset(int i) const; + Viewport Inset(int horiz, int vert) const; + Viewport Intersect(const Viewport& vp) const; + + void GetCamCoordinates(const OpenGlRenderState& cam_state, double winx, double winy, double winzdepth, GLdouble& x, GLdouble& y, GLdouble& z) const; + + static void DisableScissor(); + + GLint r() const { return l+w;} + GLint t() const { return b+h;} + GLfloat aspect() const { return (GLfloat)w / (GLfloat)h; } + GLint l,b,w,h; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/widgets/widgets.h b/thirdparty/Pangolin/include/pangolin/display/widgets/widgets.h new file mode 100644 index 00000000..1991ee80 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/widgets/widgets.h @@ -0,0 +1,141 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace pangolin +{ + +PANGOLIN_EXPORT +View& CreatePanel(const std::string& name); + +struct PANGOLIN_EXPORT Panel : public View +{ + Panel(); + Panel(const std::string& auto_register_var_prefix); + void Render(); + void ResizeChildren(); + static void AddVariable(void* data, const std::string& name, VarValueGeneric& var, bool brand_new); +}; + +template +struct Widget : public View, Handler, Var +{ + Widget(std::string title, VarValueGeneric& tv) + : Var(tv), title(title) + { + handler = this; + } + + std::string title; +}; + +struct PANGOLIN_EXPORT Button : public Widget +{ + Button(std::string title, VarValueGeneric& tv); + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state); + void Render(); + + //Cache params on resize + void ResizeChildren(); + GlText gltext; + GLfloat raster[2]; + bool down; +}; + +struct PANGOLIN_EXPORT FunctionButton : public Widget > +{ + FunctionButton(std::string title, VarValueGeneric& tv); + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state); + void Render(); + + //Cache params on resize + void ResizeChildren(); + GlText gltext; + GLfloat raster[2]; + bool down; +}; + +struct PANGOLIN_EXPORT Checkbox : public Widget +{ + Checkbox(std::string title, VarValueGeneric& tv); + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state); + void Render(); + + //Cache params on resize + void ResizeChildren(); + GlText gltext; + GLfloat raster[2]; + Viewport vcb; +}; + +struct PANGOLIN_EXPORT Slider : public Widget +{ + Slider(std::string title, VarValueGeneric& tv); + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state); + void MouseMotion(View&, int x, int y, int mouse_state); + void Keyboard(View&, unsigned char key, int x, int y, bool pressed); + void Render(); + + //Cache params on resize + void ResizeChildren(); + GlText gltext; + GLfloat raster[2]; + bool lock_bounds; + bool logscale; + bool is_integral_type; +}; + +struct PANGOLIN_EXPORT TextInput : public Widget +{ + TextInput(std::string title, VarValueGeneric& tv); + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state); + void MouseMotion(View&, int x, int y, int mouse_state); + void Keyboard(View&, unsigned char key, int x, int y, bool pressed); + void Render(); + + std::string edit; + GlText gledit; + + //Cache params on resize + void ResizeChildren(); + GlText gltext; + GLfloat raster[2]; + bool can_edit; + bool do_edit; + int sel[2]; +}; + + +} diff --git a/thirdparty/Pangolin/include/pangolin/display/window.h b/thirdparty/Pangolin/include/pangolin/display/window.h new file mode 100644 index 00000000..7e2dd598 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/display/window.h @@ -0,0 +1,90 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2016 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once +#include +#include +#include + +namespace pangolin +{ + +class GlContextInterface +{ +public: + virtual ~GlContextInterface() {} +}; + +class WindowInterface +{ +public: + virtual ~WindowInterface() {} + + virtual void ToggleFullscreen() = 0; + + virtual void Move(int x, int y) = 0; + + virtual void Resize(unsigned int w, unsigned int h) = 0; + + /** + * @brief MakeCurrent set the current context + * to be called in a thread before accessing OpenGL + */ + virtual void MakeCurrent() = 0; + + /** + * @brief RemoveCurrent remove the current context + * to be called at the end of a thread + */ + virtual void RemoveCurrent() = 0; + + virtual void ProcessEvents() = 0; + + virtual void SwapBuffers() = 0; +}; + + +struct PANGOLIN_EXPORT WindowException : std::exception +{ + WindowException(std::string str) : desc(str) {} + WindowException(std::string str, std::string detail) { + desc = str + "\n\t" + detail; + } + ~WindowException() throw() {} + const char* what() const throw() { return desc.c_str(); } + std::string desc; +}; + +struct PANGOLIN_EXPORT WindowExceptionNoKnownHandler : public WindowException +{ + WindowExceptionNoKnownHandler(const std::string& scheme) + : WindowException("No known window handler for URI '" + scheme + "'") + { + } +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/factory/factory_registry.h b/thirdparty/Pangolin/include/pangolin/factory/factory_registry.h new file mode 100644 index 00000000..1ca8382d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/factory/factory_registry.h @@ -0,0 +1,114 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011-2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include + +namespace pangolin +{ + +template +struct FactoryInterface +{ + typedef T FactoryItem; + + virtual ~FactoryInterface() = default; + virtual std::unique_ptr Open(const Uri& uri) = 0; +}; + +template +class FactoryRegistry +{ +public: + // IMPORTANT: Implement for each templated instantiation within a seperate compilation unit. + static FactoryRegistry& I(); + + ~FactoryRegistry() + { + } + + void RegisterFactory(std::shared_ptr> factory, uint32_t precedence, const std::string& scheme_name ) + { + FactoryItem item = {precedence, scheme_name, factory}; + factories.push_back( item ); + std::sort(factories.begin(), factories.end()); + } + + void UnregisterFactory(FactoryInterface* factory) + { + for( auto i = factories.end()-1; i != factories.begin(); --i) + { + if( i->factory.get() == factory ) { + factories.erase(i); + } + } + } + + void UnregisterAllFactories() + { + factories.clear(); + } + + std::unique_ptr Open(const Uri& uri) + { + // Iterate over all registered factories in order of precedence. + for(auto& item : factories) { + if( item.scheme == uri.scheme) { + std::unique_ptr video = item.factory->Open(uri); + if(video) { + return video; + } + } + } + + return std::unique_ptr(); + } + +private: + struct FactoryItem + { + uint32_t precedence; + std::string scheme; + std::shared_ptr> factory; + + bool operator<(const FactoryItem& rhs) const { + return precedence < rhs.precedence; + } + }; + + // Priority, Factory tuple + std::vector factories; +}; + +#define PANGOLIN_REGISTER_FACTORY(x) void Register ## x ## Factory() + +} diff --git a/thirdparty/Pangolin/include/pangolin/geometry/geometry.h b/thirdparty/Pangolin/include/pangolin/geometry/geometry.h new file mode 100644 index 00000000..4c6e78f8 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/geometry/geometry.h @@ -0,0 +1,96 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PANGOLIN_GEOMETRY_H +#define PANGOLIN_GEOMETRY_H + +#include +#include +#include +#include +#include + +#ifdef HAVE_EIGEN +#include +#endif + +namespace pangolin +{ + +struct Geometry +{ + struct Element : public ManagedImage { + Element() = default; + Element(Element&&) = default; + Element& operator=(Element&&) = default; + Element& operator=(const Element&) = default; + + Element(size_t stride_bytes, size_t num_elements) + : ManagedImage(stride_bytes, num_elements) + {} + + using Attribute = variant,Image,Image,Image>; + // "vertex", "rgb", "normal", "uv", "tris", "quads", ... + std::map attributes; + }; + + // Store vertices and attributes + std::map buffers; + // Stores index buffers for each sub-object + std::multimap objects; + // Stores pixmaps + std::map textures; +}; + +pangolin::Geometry::Element::Attribute MakeAttribute(uint32_t gldatatype, size_t num_items, size_t count_per_item, void* ptr, size_t pitch_bytes); + +pangolin::Geometry LoadGeometry(const std::string& filename); + +#ifdef HAVE_EIGEN +inline Eigen::AlignedBox3f GetAxisAlignedBox(const Geometry& geom) +{ + Eigen::AlignedBox3f box; + box.setEmpty(); + + for(const auto& b : geom.buffers) { + const auto& it_vert = b.second.attributes.find("vertex"); + if(it_vert != b.second.attributes.end()) { + const Image& vs = get>(it_vert->second); + for(size_t i=0; i < vs.h; ++i) { + const Eigen::Map v(vs.RowPtr(i)); + box.extend(v); + } + } + } + + return box; +} +#endif + +} + +#endif // PANGOLIN_GEOMETRY_H diff --git a/thirdparty/Pangolin/include/pangolin/geometry/geometry_obj.h b/thirdparty/Pangolin/include/pangolin/geometry/geometry_obj.h new file mode 100644 index 00000000..9e2570bc --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/geometry/geometry_obj.h @@ -0,0 +1,34 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +namespace pangolin { + +pangolin::Geometry LoadGeometryObj(const std::string& filename); + +} diff --git a/thirdparty/Pangolin/include/pangolin/geometry/geometry_ply.h b/thirdparty/Pangolin/include/pangolin/geometry/geometry_ply.h new file mode 100644 index 00000000..3c3f1c1c --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/geometry/geometry_ply.h @@ -0,0 +1,157 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +namespace pangolin +{ + +#define PLY_GROUP_LIST(m) m(PlyHeader) m(PlyFormat) m(PlyType) +#define PLY_HEADER_LIST(m) m(ply) m(format) m(comment) m(property) m(element) m(end_header) +#define PLY_FORMAT_LIST(m) m(ascii) m(binary_big_endian) m(binary_little_endian) +#define PLY_TYPE_LIST(m) m(char) m(uchar) m(short) m(ushort) m(int) m(uint) m(float) m(double) m(list) + +// Define Enums / strings +enum PlyHeader { +#define FORMAT_ENUM(x) PlyHeader_##x, + PLY_HEADER_LIST(FORMAT_ENUM) + PlyHeaderSize +#undef FORMAT_ENUM +}; + +enum PlyFormat { +#define FORMAT_ENUM(x) PlyFormat_##x, + PLY_FORMAT_LIST(FORMAT_ENUM) + PlyFormatSize +#undef FORMAT_ENUM +}; + +enum PlyType { +#define FORMAT_ENUM(x) PlyType_##x, + PLY_TYPE_LIST(FORMAT_ENUM) + PlyTypeSize +#undef FORMAT_ENUM +}; +const size_t PlyTypeGl[] = { +// GL_BYTE, GL_UNSIGNED_BYTE, + 0x1400, 0x1401, +// GL_SHORT, GL_UNSIGNED_SHORT, + 0x1402, 0x1403, +// GL_INT, GL_UNSIGNED_INT, + 0x1404, 0x1405, +// GL_FLOAT, GL_DOUBLE, + 0x1406, 0x140A, +// GL_NONE, + 0 +}; + +#undef FORMAT_ENUM + +struct PlyPropertyDetails +{ + std::string name; + + // Type of property (GLenum) + size_t type; + + // Type of list index if a list, or 0 otherwise. (GLenum) + size_t list_index_type; + + // Offset from element start + size_t offset_bytes; + + // Number of items in the list. 1 if not a list. -1 if unknown. + int num_items; + + bool isList() const { + return list_index_type > 0; + } +}; + +struct PlyElementDetails +{ + std::string name; + int num_items; + int stride_bytes; + std::vector properties; + + inline std::vector::iterator FindProperty(const std::string& name) + { + return std::find_if(properties.begin(), properties.end(), + [&name](const PlyPropertyDetails& p){ return p.name == name;} + ); + } +}; + +struct PlyHeaderDetails +{ + PlyFormat format; + std::string version; + std::vector elements; + + inline std::vector::iterator FindElement(const std::string& name) + { + return std::find_if(elements.begin(), elements.end(), + [&name](const PlyElementDetails& el){ return el.name == name;} + ); + } +}; + +void ParsePlyHeader(PlyHeaderDetails& ply, std::istream& is); + +struct PlyBuffer +{ + size_t index_size_bytes; + size_t element_item_size_bytes; + std::vector data; +}; + +void ParsePlyAscii(pangolin::Geometry& /*geom*/, const PlyHeaderDetails& /*ply*/, std::istream& /*is*/); + +// Convert Seperate "x","y","z" attributes into a single "vertex" attribute +void StandardizeXyzToVertex(pangolin::Geometry& geom); + +// The Artec scanner saves with these attributes, for example +void StandardizeMultiTextureFaceToXyzuv(pangolin::Geometry& geom); + +void Standardize(pangolin::Geometry& geom); + +void ParsePlyLE(pangolin::Geometry& geom, PlyHeaderDetails& ply, std::istream& is); + +void ParsePlyBE(pangolin::Geometry& /*geom*/, const PlyHeaderDetails& /*ply*/, std::istream& /*is*/); + +void AttachAssociatedTexturesPly(pangolin::Geometry& geom, const std::string& filename); + +pangolin::Geometry LoadGeometryPly(const std::string& filename); + +} diff --git a/thirdparty/Pangolin/include/pangolin/geometry/glgeometry.h b/thirdparty/Pangolin/include/pangolin/geometry/glgeometry.h new file mode 100644 index 00000000..a034b0ad --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/geometry/glgeometry.h @@ -0,0 +1,87 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +namespace pangolin { + +struct GlGeometry +{ + GlGeometry() = default; + GlGeometry(GlGeometry&&) = default; + GlGeometry& operator=(GlGeometry&&) = default; + + struct Element : public GlBufferData + { + Element() = default; + Element(Element&&) = default; + Element& operator=(Element&&) = default; + + Element(GlBufferType buffer_type, size_t size_bytes, GLenum gluse, uint8_t* data) + : GlBufferData(buffer_type, size_bytes, gluse, data) + {} + + inline bool HasAttribute(const std::string& name) const { + return attributes.find(name) != attributes.end(); + } + + struct Attribute { + // Stuff needed by glVertexAttribPointer + GLenum gltype; + size_t count_per_element; + size_t num_elements; + size_t offset; + size_t stride_bytes; + }; + std::map attributes; + }; + + inline bool HasAttribute(const std::string& name) const + { + for(const auto& b : buffers) if(b.second.HasAttribute(name)) return true; + return false; + } + + // Store vertices and attributes + std::map buffers; + // Stores index buffers for each sub-object + std::multimap objects; + // Stores pixmaps + std::map textures; +}; + +GlGeometry::Element ToGlGeometry(const Geometry::Element& el, GlBufferType buffertype); + +GlGeometry ToGlGeometry(const Geometry& geom); + +void GlDraw(GlSlProgram& prog, const GlGeometry& geom, const GlTexture *matcap); + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/cg.h b/thirdparty/Pangolin/include/pangolin/gl/cg.h new file mode 100644 index 00000000..dd83901d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/cg.h @@ -0,0 +1,283 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +// Cg includes +#include +#include + +#include "gl.h" + +#ifdef HAVE_TOON +#include +#endif // HAVE_TOON + +namespace pangolin +{ + +//////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////// + +/// Lightweight object wrapper for NVidia Cg Shader program objects. +class CgProgram +{ + friend class CgLoader; +public: + void SetUniform(const std::string& name, GlTexture& tex); + void SetUniform(const std::string& name, float f); + void SetUniform(const std::string& name, float v0, float v1); + void SetUniform(const std::string& name, float v0, float v1, float v2, float v3); + +#ifdef HAVE_TOON + void SetUniform(const std::string& name, const TooN::Vector<2>& v ); + void SetUniform(const std::string& name, const TooN::Vector<3>& v ); + + template + void SetUniform(const std::string& name, const TooN::Matrix& M ); +#endif + + void UpdateParams(); + +protected: + CGprogram mProg; + CGcontext mContext; + CGprofile mProfile; +}; + +class CgLoader +{ +public: + CgLoader(); + ~CgLoader(); + + // Call AFTER glewInit (or similar) + void Initialise(); + + CgProgram LoadProgramFromFile(const std::string& file, const std::string& function, bool isVertexShader ); + + void EnableProgram(CgProgram program); + void DisablePrograms(); + + void RenderDummyQuad(); + void RenderDummyQuadWithTexCoords(int w, int h); + +protected: + CGcontext mContext; + CGprofile mFragmentProfile; + CGprofile mVertexProfile; +}; + + + + +//////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////// + +inline bool cgOkay() +{ + CGerror error; + const char *string = cgGetLastErrorString(&error); + + if (error != CG_NO_ERROR) { + std::cout << "CG Error: " << string << std::endl; + // assert(0); + return false; + } + return true; +} + +inline CgLoader::CgLoader() + :mContext(0) +{ +} + +inline CgLoader::~CgLoader() +{ + if(mContext) + { + // Destroying context destroys all programs associated with it + cgDestroyContext(mContext); + } +} + + +inline void CgLoader::Initialise() +{ + mContext = cgCreateContext(); + cgSetParameterSettingMode(mContext, CG_DEFERRED_PARAMETER_SETTING); + cgOkay(); + + mFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); + cgGLSetOptimalOptions(mFragmentProfile); + cgOkay(); + + mVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); + cgGLSetOptimalOptions(mVertexProfile); + cgOkay(); +} + +inline CgProgram CgLoader::LoadProgramFromFile(const std::string& file, const std::string& function, bool isVertexShader ) +{ + if( !mContext ) { + Initialise(); + } + + CgProgram prog; + + prog.mContext = mContext; + prog.mProfile = isVertexShader ? mVertexProfile : mFragmentProfile; + prog.mProg = cgCreateProgramFromFile( prog.mContext, CG_SOURCE, file.c_str(), prog.mProfile, function.c_str(), NULL); + + if( !cgOkay() ) + { + std::cout << cgGetLastListing(mContext) << std::endl; + assert(0); + } + + cgGLLoadProgram(prog.mProg); + if( !cgOkay() ) + { + const char* err = cgGetProgramString( prog.mProg, CG_COMPILED_PROGRAM ); + int pos; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos); + std::cout << err << std::endl; + std::cout << "@ " << pos << std::endl; + assert(0); + } + return prog; +} + +inline void CgLoader::EnableProgram(CgProgram program) +{ + cgGLBindProgram(program.mProg); + cgGLEnableProfile(program.mProfile); + cgOkay(); +} + +inline void CgLoader::DisablePrograms() +{ + cgGLDisableProfile(mFragmentProfile); + cgGLDisableProfile(mVertexProfile); +} + +inline void CgLoader::RenderDummyQuad() +{ + glBegin(GL_QUADS); + glVertex2d(-1,1); + glVertex2d(1,1); + glVertex2d(1,-1); + glVertex2d(-1,-1); + glEnd(); +} + +inline void CgLoader::RenderDummyQuadWithTexCoords(int w, int h) +{ + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2d(-1,-1); + glTexCoord2f(w, 0); + glVertex2d(1,-1); + glTexCoord2f(w, h); + glVertex2d(1,1); + glTexCoord2f(0, h); + glVertex2d(-1,1); + glEnd(); +} + +void CgProgram::SetUniform(const std::string& name, float f) +{ + CGparameter p = cgGetNamedParameter( mProg, name.c_str()); + cgSetParameter1f( p, f ); + cgUpdateProgramParameters(mProg); +} + +void CgProgram::SetUniform(const std::string& name, GlTexture& tex) +{ + CGparameter p = cgGetNamedParameter( mProg, name.c_str()); + cgGLSetTextureParameter(p, tex.tid ); + cgGLEnableTextureParameter(p); + cgUpdateProgramParameters(mProg); +} + +void CgProgram::SetUniform(const std::string& name, float v0, float v1, float v2, float v3) +{ + CGparameter p = cgGetNamedParameter( mProg, name.c_str()); + cgGLSetParameter4f(p, v0,v1,v2,v3); + cgUpdateProgramParameters(mProg); +} + +void CgProgram::SetUniform(const std::string& name, float v0, float v1) +{ + CGparameter p = cgGetNamedParameter( mProg, name.c_str()); + cgGLSetParameter2f(p, v0,v1); + cgUpdateProgramParameters(mProg); +} + +#ifdef HAVE_TOON +void CgProgram::SetUniform(const std::string& name, const TooN::Vector<2>& v ) +{ + CGparameter p = cgGetNamedParameter( mProg, name.c_str()); + cgGLSetParameter2f(p, v[0],v[1] ); + cgUpdateProgramParameters(mProg); +} + +void CgProgram::SetUniform(const std::string& name, const TooN::Vector<3>& v ) +{ + CGparameter p = cgGetNamedParameter( mProg, name.c_str()); + cgGLSetParameter3f(p, v[0],v[1],v[2] ); + cgUpdateProgramParameters(mProg); +} + +template +void CgProgram::SetUniform(const std::string& name, const TooN::Matrix& M ) +{ + CGparameter p = cgGetNamedParameter( mProg, name.c_str()); + float Mdata[R*C]; + + int i=0; + for( int r=0; r + +#include + +namespace pangolin +{ + +/// Represent OpenGL floating point colour: Red, Green and Blue with alpha. +struct Colour +{ + inline static Colour White() { + return Colour(1.0f,1.0f,1.0f,1.0f); + } + inline static Colour Black() { + return Colour(0.0f,0.0f,0.0f,1.0f); + } + inline static Colour Red() { + return Colour(1.0f,0.0f,0.0f,1.0f); + } + inline static Colour Green() { + return Colour(0.0f,1.0f,0.0f,1.0f); + } + inline static Colour Blue() { + return Colour(0.0f,0.0f,1.0f,1.0f); + } + inline static Colour Unspecified() { + return Colour( + std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN() + ); + } + + /// Default constructs white. + inline Colour() + : red(1.0f), green(1.0f), blue(1.0f), alpha(1.0f) + { + } + + /// Construct from component values + inline Colour(const float red, const float green, const float blue, const float alpha = 1.0f) + : red(red), green(green), blue(blue), alpha(alpha) + { + } + + /// Construct from rgba array. + inline Colour(const float rgba[4]) + { + r = rgba[0]; + g = rgba[1]; + b = rgba[2]; + a = rgba[3]; + } + + /// Return pointer to OpenGL compatible RGBA array. + inline float* Get() + { + return c; + } + + /// Return this colour with alpha adjusted. + inline Colour WithAlpha(const float alpha) + { + return Colour(r,g,b,alpha); + } + + /// Construct from HSV Colour + /// @param hue Colour hue in range [0,1] + /// @param sat Saturation in range [0,1] + /// @param val Value / Brightness in range [0,1]. + static inline Colour Hsv(const float hue, const float sat = 1.0f, const float val = 1.0f, const float alpha = 1.0f) + { + const float h = 6.0f * hue; + const int i = (int)floor(h); + const float f = (i%2 == 0) ? 1-(h-i) : h-i; + const float m = val * (1-sat); + const float n = val * (1-sat*f); + + switch(i) + { + case 0: return Colour(val,n,m,alpha); + case 1: return Colour(n,val,m,alpha); + case 2: return Colour(m,val,n,alpha); + case 3: return Colour(m,n,val,alpha); + case 4: return Colour(n,m,val,alpha); + case 5: return Colour(val,m,n,alpha); + default: + throw std::runtime_error("Found extra colour in rainbow."); + } + } + + union { + struct { + float red; + float green; + float blue; + float alpha; + }; + struct { + float r; + float g; + float b; + float a; + }; + float c[4]; + }; + +}; + +/// A ColourWheel is like a continuous colour palate that can be sampled. +/// In the future, different ColourWheels will be supported, but this one +/// is based on sampling hues in HSV colourspace. An indefinite number of +/// unique colours are sampled using the golden angle. +class ColourWheel +{ +public: + /// Construct ColourWheel with Saturation, Value and Alpha constant. + inline ColourWheel(float saturation = 0.5f, float value = 1.0f, float alpha = 1.0f) + : unique_colours(0), sat(saturation), val(value), alpha(alpha) + { + + } + + /// Use Golden ratio (/angle) to pick well spaced colours. + inline Colour GetColourBin(int i) const + { + float hue = i * 0.5f * (3.0f - sqrt(5.0f)); + hue -= (int)hue; + return Colour::Hsv(hue,sat,val,alpha); + } + + /// Return next unique colour from ColourWheel. + inline Colour GetUniqueColour() + { + return GetColourBin(unique_colours++); + } + +protected: + int unique_colours; + float sat; + float val; + float alpha; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/compat/gl2engine.h b/thirdparty/Pangolin/include/pangolin/gl/compat/gl2engine.h new file mode 100644 index 00000000..184aa60c --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/compat/gl2engine.h @@ -0,0 +1,320 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include + +namespace pangolin { + +class GlEngine +{ +public: + const char* vert = + "attribute vec4 a_position;\n" + "attribute vec4 a_color;\n" + "attribute vec3 a_normal;\n" + "attribute vec2 a_texcoord;\n" + "uniform vec4 u_color;\n" + "uniform mat4 u_modelViewMatrix;\n" + "uniform mat4 u_modelViewProjectionMatrix;\n" + "varying vec4 v_frontColor;\n" + "varying vec2 v_texcoord;\n" + "void main() {\n" + " gl_Position = u_modelViewProjectionMatrix * a_position;\n" + " v_frontColor = u_color;\n" + " v_texcoord = a_texcoord;\n" + "}\n"; + + const char* frag = + #ifdef HAVE_GLES_2 + "precision mediump float;\n" + #endif // HAVE_GLES_2 + "varying vec4 v_frontColor;\n" + "varying vec2 v_texcoord;\n" + "uniform sampler2D u_texture;\n" + "uniform bool u_textureEnable;\n" + "void main() {\n" + " gl_FragColor = v_frontColor;\n" + " if(u_textureEnable) {\n" + " gl_FragColor *= texture2D(u_texture, v_texcoord);\n" + " }\n" + "}\n"; + + GlEngine() + { + // Initialise default state + projection.push(IdentityMatrix()); + modelview.push(IdentityMatrix()); + currentmatrix = &modelview; + + // Set GL_TEXTURE0 as default active texture + glActiveTexture(GL_TEXTURE0); + + // Compile and link shaders + prog_fixed.AddShader(GlSlVertexShader, vert); + prog_fixed.AddShader(GlSlFragmentShader, frag); + prog_fixed.BindPangolinDefaultAttribLocationsAndLink(); + + // Save locations of uniforms + u_color = prog_fixed.GetUniformHandle("u_color"); + u_modelViewMatrix = prog_fixed.GetUniformHandle("u_modelViewMatrix"); + u_modelViewProjectionMatrix = prog_fixed.GetUniformHandle("u_modelViewProjectionMatrix"); + u_texture = prog_fixed.GetUniformHandle("u_texture"); + u_textureEnable = prog_fixed.GetUniformHandle("u_textureEnable"); + + // Initialise default uniform values + UpdateMatrices(); + SetColor(1.0,1.0,1.0,1.0); + } + + void UpdateMatrices() + { + OpenGlMatrix pmv = projection.top() * modelview.top(); + prog_fixed.SaveBind(); + glUniformMatrix4fv( u_modelViewMatrix, 1, false, modelview.top().m ); + glUniformMatrix4fv( u_modelViewProjectionMatrix, 1, false, pmv.m ); + prog_fixed.Unbind(); + } + + void SetColor(float r, float g, float b, float a) + { + prog_fixed.SaveBind(); + glUniform4f( u_color, r, g, b, a); + prog_fixed.Unbind(); + } + + void EnableTexturing(GLboolean v) + { + prog_fixed.SaveBind(); + glUniform1i( u_textureEnable, v); + prog_fixed.Unbind(); + } + +//protected: + std::stack projection; + std::stack modelview; + std::stack* currentmatrix; + + GLenum matrixmode; + + float color[4]; + + GlSlProgram prog_fixed; + + GLint u_color; + GLint u_modelViewMatrix; + GLint u_modelViewProjectionMatrix; + GLint u_texture; + GLint u_textureEnable; +}; + +GlEngine& glEngine(); + +} + +/////////////////////////////////////////////////////////////////////////////// +// OpenGL 1.0 compatibility - Emulate fixed pipeline +/////////////////////////////////////////////////////////////////////////////// + +// Missing defines that we'll be using +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_SHADE_MODEL 0x0B54 +#define GL_POINT_SIZE 0x0B11 + +#define GL_MULTISAMPLE 0x809D + +#define GL_LIGHTING 0x0B50 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_COLOR_MATERIAL 0x0B57 + +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 + +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_ADD 0x0104 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 + +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 + +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_TEXTURE_COORD_ARRAY 0x8078 + +inline void glEnableClientState(GLenum cap) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + if(cap == GL_VERTEX_ARRAY) { + glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_POSITION); + }else if(cap == GL_COLOR_ARRAY) { + glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_COLOUR); + }else if(cap == GL_NORMAL_ARRAY) { + glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_NORMAL); + }else if(cap == GL_TEXTURE_COORD_ARRAY) { + glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_TEXCOORD); + gl.EnableTexturing(true); + }else{ + pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__); + } +} + +inline void glDisableClientState(GLenum cap) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + if(cap == GL_VERTEX_ARRAY) { + glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_POSITION); + }else if(cap == GL_COLOR_ARRAY) { + glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_COLOUR); + }else if(cap == GL_NORMAL_ARRAY) { + glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_NORMAL); + }else if(cap == GL_TEXTURE_COORD_ARRAY) { + glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_TEXCOORD); + gl.EnableTexturing(false); + }else{ + pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__); + } +} + +inline void glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) +{ + glVertexAttribPointer(pangolin::DEFAULT_LOCATION_POSITION, size, type, GL_FALSE, stride, pointer); +} + +inline void glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) +{ + glVertexAttribPointer(pangolin::DEFAULT_LOCATION_TEXCOORD, size, type, GL_FALSE, stride, pointer); +} + +inline void glMatrixMode(GLenum mode) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + gl.currentmatrix = (mode == pangolin::GlProjectionStack) ? &gl.projection : &gl.modelview; +} + +inline void glLoadIdentity() +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + gl.currentmatrix->top() = pangolin::IdentityMatrix(); + gl.UpdateMatrices(); +} + +inline void glLoadMatrixf(const GLfloat* m) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + pangolin::GLprecision* cm = gl.currentmatrix->top().m; + for(int i=0; i<16; ++i) cm[i] = (pangolin::GLprecision)m[i]; + gl.UpdateMatrices(); +} + +inline void glLoadMatrixd(const GLdouble* m) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + pangolin::GLprecision* cm = gl.currentmatrix->top().m; + for(int i=0; i<16; ++i) cm[i] = (pangolin::GLprecision)m[i]; + gl.UpdateMatrices(); +} + +inline void glMultMatrixf(const GLfloat* m) +{ +// pangolin::GlEngine& gl = pangolin::glEngine(); +// float res[16]; +// pangolin::MatMul<4,4,4,float>(res, m, gl.currentmatrix->m ); +// std::memcpy(gl.currentmatrix->m, res, sizeof(float) * 16 ); + pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__); +} + +inline void glMultMatrixd(const GLdouble* m) +{ + pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__); +} + +inline void glPushMatrix(void) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + gl.currentmatrix->push(gl.currentmatrix->top()); +} + +inline void glPopMatrix(void) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + gl.currentmatrix->pop(); + gl.UpdateMatrices(); +} + +inline void glTranslatef(GLfloat x, GLfloat y, GLfloat z ) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + pangolin::GLprecision* cm = gl.currentmatrix->top().m; + cm[12] += x; + cm[13] += y; + cm[14] += z; + gl.UpdateMatrices(); +} + +inline void glOrtho( + GLdouble l, GLdouble r, + GLdouble b, GLdouble t, + GLdouble n, GLdouble f) +{ + pangolin::GlEngine& gl = pangolin::glEngine(); + gl.currentmatrix->top() = pangolin::ProjectionMatrixOrthographic(l,r,b,t,n,f); + gl.UpdateMatrices(); +} + +inline void glColor4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + pangolin::glEngine().SetColor(red,green,blue,alpha); +} + +inline void glShadeModel( GLenum mode) +{ + pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__); +} + +inline void glPointSize(GLfloat size) +{ + pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__); +} + +inline void glTexEnvf( GLenum target, + GLenum pname, + GLfloat param) +{ + pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__); +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/compat/gl_es_compat.h b/thirdparty/Pangolin/include/pangolin/gl/compat/gl_es_compat.h new file mode 100644 index 00000000..1c1fdb3b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/compat/gl_es_compat.h @@ -0,0 +1,60 @@ +#pragma once + +#include + +#define GLdouble GLfloat +#define glClearDepth glClearDepthf +#define glFrustum glFrustumf + +#define glColor4fv(a) glColor4f(a[0], a[1], a[2], a[3]) +#define glColor3fv(a) glColor4f(a[0], a[1], a[2], 1.0f) +#define glColor3f(a,b,c) glColor4f(a, b, c, 1.0f) + +#define GL_CLAMP GL_CLAMP_TO_EDGE + +#ifdef HAVE_GLES_2 + #define glGenFramebuffersEXT glGenFramebuffers + #define glDeleteFramebuffersEXT glDeleteFramebuffers + #define glBindFramebufferEXT glBindFramebuffer + #define glDrawBuffers glDrawBuffers + #define glFramebufferTexture2DEXT glFramebufferTexture2D + #define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER + #define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT16 // <---- + #define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0 + #define GL_DEPTH_ATTACHMENT_EXT GL_DEPTH_ATTACHMENT +#else + #define glOrtho glOrthof + #define glGenFramebuffersEXT glGenFramebuffersOES + #define glDeleteFramebuffersEXT glDeleteFramebuffersOES + #define glBindFramebufferEXT glBindFramebufferOES + #define glDrawBuffers glDrawBuffersOES + #define glFramebufferTexture2DEXT glFramebufferTexture2DOES + #define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES + #define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES + #define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES +#endif + +#define glGetDoublev glGetFloatv + +#ifdef HAVE_GLES_2 +#include +#endif + +inline void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ + GLfloat verts[] = { x1,y1, x2,y1, x2,y2, x1,y2 }; + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, verts); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisableClientState(GL_VERTEX_ARRAY); +} + +inline void glRecti(int x1, int y1, int x2, int y2) +{ + GLfloat verts[] = { (float)x1,(float)y1, (float)x2,(float)y1, + (float)x2,(float)y2, (float)x1,(float)y2 }; + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, verts); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisableClientState(GL_VERTEX_ARRAY); +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/gl.h b/thirdparty/Pangolin/include/pangolin/gl/gl.h new file mode 100644 index 00000000..4330e73c --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/gl.h @@ -0,0 +1,273 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files +#define USE_EIGEN +#endif + +#ifdef USE_EIGEN +#include +#endif + +#include +#include +#include + +namespace pangolin +{ + +//////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////// + +class PANGOLIN_EXPORT GlTexture +{ +public: + //! internal_format normally one of GL_RGBA8, GL_LUMINANCE8, GL_INTENSITY16 + GlTexture(GLint width, GLint height, GLint internal_format = GL_RGBA8, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL ); + + // Construct this texture from a CPU image + GlTexture(const TypedImage& img, bool sampling_linear=true); + + //! Move Constructor / asignment + GlTexture(GlTexture&& tex); + GlTexture& operator=(GlTexture&& tex); + + //! Default constructor represents 'no texture' + GlTexture(); + virtual ~GlTexture(); + + bool IsValid() const; + + //! Delete OpenGL resources and fall back to representing 'no texture' + void Delete(); + + //! Reinitialise teture width / height / format + virtual void Reinitialise(GLsizei width, GLsizei height, GLint internal_format = GL_RGBA8, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL ); + + void Bind() const; + void Unbind() const; + + //! data_layout normally one of GL_LUMINANCE, GL_RGB, ... + //! data_type normally one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT + void Upload(const void* image, GLenum data_format = GL_LUMINANCE, GLenum data_type = GL_FLOAT); + + //! Upload data to texture, overwriting a sub-region of it. + //! data ptr contains packed data_w x data_h of pixel data. + void Upload(const void* data, + GLsizei tex_x_offset, GLsizei tex_y_offset, + GLsizei data_w, GLsizei data_h, + GLenum data_format, GLenum data_type + ); + + void Load(const TypedImage& image, bool sampling_linear = true); + + void LoadFromFile(const std::string& filename, bool sampling_linear = true); + + void Download(void* image, GLenum data_layout = GL_LUMINANCE, GLenum data_type = GL_FLOAT) const; + + void Download(TypedImage& image) const; + + void CopyFrom(const GlTexture& tex); + + void Save(const std::string& filename, bool top_line_first = true); + + void SetLinear(); + void SetNearestNeighbour(); + + void RenderToViewport(const bool flip) const; + void RenderToViewport() const; + void RenderToViewport(Viewport tex_vp, bool flipx=false, bool flipy=false) const; + void RenderToViewportFlipY() const; + void RenderToViewportFlipXFlipY() const; + + GLint internal_format; + GLuint tid; + GLint width; + GLint height; + +private: + // Private copy constructor + GlTexture(const GlTexture&) {} +}; + +struct PANGOLIN_EXPORT GlRenderBuffer +{ + GlRenderBuffer(); + GlRenderBuffer(GLint width, GLint height, GLint internal_format = GL_DEPTH_COMPONENT24); + + void Reinitialise(GLint width, GLint height, GLint internal_format = GL_DEPTH_COMPONENT24); + + //! Move Constructor + GlRenderBuffer(GlRenderBuffer&& tex); + + ~GlRenderBuffer(); + + GLint width; + GLint height; + GLuint rbid; + +private: + // Private copy constructor + GlRenderBuffer(const GlRenderBuffer&) {} +}; + +struct PANGOLIN_EXPORT GlFramebuffer +{ + GlFramebuffer(); + ~GlFramebuffer(); + + GlFramebuffer(GlTexture& colour, GlRenderBuffer& depth); + GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlRenderBuffer& depth); + GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlRenderBuffer& depth); + GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlTexture& colour3, GlRenderBuffer& depth); + + void Bind() const; + void Unbind() const; + + void Reinitialise(); + + // Attach Colour texture to frame buffer + // Return attachment texture is bound to (e.g. GL_COLOR_ATTACHMENT0_EXT) + GLenum AttachColour(GlTexture& tex); + + // Attach Depth render buffer to frame buffer + void AttachDepth(GlRenderBuffer& rb); + + GLuint fbid; + unsigned attachments; +}; + +enum GlBufferType +{ + GlUndefined = 0, + GlArrayBuffer = GL_ARRAY_BUFFER, // VBO's, CBO's, NBO's + GlElementArrayBuffer = GL_ELEMENT_ARRAY_BUFFER, // IBO's +#ifndef HAVE_GLES + GlPixelPackBuffer = GL_PIXEL_PACK_BUFFER, // PBO's + GlPixelUnpackBuffer = GL_PIXEL_UNPACK_BUFFER, + GlShaderStorageBuffer = GL_SHADER_STORAGE_BUFFER +#endif +}; + +// This encapsulates a GL Buffer object. +struct PANGOLIN_EXPORT GlBufferData +{ + //! Default constructor represents 'no buffer' + GlBufferData(); + GlBufferData(GlBufferType buffer_type, GLuint size_bytes, GLenum gluse = GL_DYNAMIC_DRAW, const unsigned char* data = 0 ); + virtual ~GlBufferData(); + void Free(); + + //! Move Constructor + GlBufferData(GlBufferData&& tex); + GlBufferData& operator=(GlBufferData&& tex); + + bool IsValid() const; + + size_t SizeBytes() const; + + void Reinitialise(GlBufferType buffer_type, GLuint size_bytes, GLenum gluse = GL_DYNAMIC_DRAW, const unsigned char* data = 0 ); + + void Bind() const; + void Unbind() const; + void Upload(const GLvoid* data, GLsizeiptr size_bytes, GLintptr offset = 0); + void Download(GLvoid* ptr, GLsizeiptr size_bytes, GLintptr offset = 0) const; + + GLuint bo; + GlBufferType buffer_type; + GLenum gluse; + GLuint size_bytes; + +private: + GlBufferData(const GlBufferData&) {} +}; + +// This encapsulates a GL Buffer object, also storing information about its contents. +// You should try to use GlBufferData instead. +struct PANGOLIN_EXPORT GlBuffer : public GlBufferData +{ + //! Default constructor represents 'no buffer' + GlBuffer(); + GlBuffer(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse = GL_DYNAMIC_DRAW ); + GlBuffer(const GlBuffer&) = delete; + + //! Move Constructor + GlBuffer(GlBuffer&& tex); + GlBuffer& operator=(GlBuffer&& tex); + + void Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse, const unsigned char* data = nullptr ); + void Reinitialise(GlBuffer const& other ); + void Resize(GLuint num_elements); + + GLenum datatype; + GLuint num_elements; + GLuint count_per_element; +}; + +class PANGOLIN_EXPORT GlSizeableBuffer + : public pangolin::GlBuffer +{ +public: + GlSizeableBuffer(pangolin::GlBufferType buffer_type, GLuint initial_num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse = GL_DYNAMIC_DRAW ); + + void Clear(); + +#ifdef USE_EIGEN + template + void Add(const Eigen::DenseBase& vec); + + template + void Update(const Eigen::DenseBase& vec, size_t position = 0); +#endif + + size_t start() const; + + size_t size() const; + +protected: + void CheckResize(size_t num_verts); + + size_t NextSize(size_t min_size) const; + + size_t m_num_verts; +}; + +size_t GlFormatChannels(GLenum data_layout); + +size_t GlDataTypeBytes(GLenum type); + +} + +// Include implementation +#include diff --git a/thirdparty/Pangolin/include/pangolin/gl/gl.hpp b/thirdparty/Pangolin/include/pangolin/gl/gl.hpp new file mode 100644 index 00000000..51f55a91 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/gl.hpp @@ -0,0 +1,864 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace pangolin +{ + +//////////////////////////////////////////////// +// Implementation of gl.h +//////////////////////////////////////////////// + +#ifndef HAVE_GLES +const int MAX_ATTACHMENTS = 8; +const static GLuint attachment_buffers[] = { + GL_COLOR_ATTACHMENT0_EXT, + GL_COLOR_ATTACHMENT1_EXT, + GL_COLOR_ATTACHMENT2_EXT, + GL_COLOR_ATTACHMENT3_EXT, + GL_COLOR_ATTACHMENT4_EXT, + GL_COLOR_ATTACHMENT5_EXT, + GL_COLOR_ATTACHMENT6_EXT, + GL_COLOR_ATTACHMENT7_EXT +}; +#else // HAVE_GLES +const int MAX_ATTACHMENTS = 1; +const static GLuint attachment_buffers[] = { + GL_COLOR_ATTACHMENT0_EXT +}; +#endif // HAVE_GLES + +const static size_t datatype_bytes[] = { + 1, // #define GL_BYTE 0x1400 + 1, // #define GL_UNSIGNED_BYTE 0x1401 + 2, // #define GL_SHORT 0x1402 + 2, // #define GL_UNSIGNED_SHORT 0x1403 + 4, // #define GL_INT 0x1404 + 4, // #define GL_UNSIGNED_INT 0x1405 + 4, // #define GL_FLOAT 0x1406 + 2, // #define GL_2_BYTES 0x1407 + 3, // #define GL_3_BYTES 0x1408 + 4, // #define GL_4_BYTES 0x1409 + 8 // #define GL_DOUBLE 0x140A +}; + +const static size_t format_channels[] = { + 1, // #define GL_RED 0x1903 + 1, // #define GL_GREEN 0x1904 + 1, // #define GL_BLUE 0x1905 + 1, // #define GL_ALPHA 0x1906 + 3, // #define GL_RGB 0x1907 + 4, // #define GL_RGBA 0x1908 + 1, // #define GL_LUMINANCE 0x1909 + 2 // #define GL_LUMINANCE_ALPHA 0x190A +}; + +inline size_t GlDataTypeBytes(GLenum type) +{ + return datatype_bytes[type - GL_BYTE]; +} + +inline size_t GlFormatChannels(GLenum data_layout) +{ + return format_channels[data_layout - GL_RED]; +} + +//template +//struct GlDataTypeTrait {}; +//template<> struct GlDataTypeTrait{ static const GLenum type = GL_FLOAT; }; +//template<> struct GlDataTypeTrait{ static const GLenum type = GL_INT; }; +//template<> struct GlDataTypeTrait{ static const GLenum type = GL_UNSIGNED_BYTE; }; + +inline GlTexture::GlTexture() + : internal_format(0), tid(0), width(0), height(0) +{ + // Not a texture constructor +} + +inline GlTexture::GlTexture(GLint width, GLint height, GLint internal_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid* data ) + : internal_format(0), tid(0) +{ + Reinitialise(width,height,internal_format,sampling_linear,border,glformat,gltype,data); +} + +inline GlTexture::GlTexture(const TypedImage& img, bool sampling_linear) +{ + this->Load(img, sampling_linear); +} + +inline GlTexture::GlTexture(GlTexture&& tex) +{ + *this = std::move(tex); +} + +inline GlTexture& GlTexture::operator=(GlTexture&& tex) +{ + if (&tex != this) { + internal_format = tex.internal_format; + tid = tex.tid; + width = tex.width; + height = tex.height; + + tex.internal_format = 0; + tex.tid = 0; + } + return *this; +} + +inline bool GlTexture::IsValid() const +{ + return tid != 0; +} + +inline void GlTexture::Delete() +{ + // We have no GL context whilst exiting. + if(internal_format!=0 && !pangolin::ShouldQuit() ) { + glDeleteTextures(1,&tid); + internal_format = 0; + tid = 0; + width = 0; + height = 0; + } +} + +inline GlTexture::~GlTexture() +{ + // We have no GL context whilst exiting. + if(internal_format!=0 && !pangolin::ShouldQuit() ) { + glDeleteTextures(1,&tid); + } +} + +inline void GlTexture::Bind() const +{ + glBindTexture(GL_TEXTURE_2D, tid); +} + +inline void GlTexture::Unbind() const +{ + glBindTexture(GL_TEXTURE_2D, 0); +} + +inline void GlTexture::Reinitialise(GLsizei w, GLsizei h, GLint int_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid* data ) +{ + if(tid!=0) { + glDeleteTextures(1,&tid); + } + + internal_format = int_format; + width = w; + height = h; + + glGenTextures(1,&tid); + Bind(); + + // GL_LUMINANCE and GL_FLOAT don't seem to actually affect buffer, but some values are required + // for call to succeed. + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, border, glformat, gltype, data); + + if(sampling_linear) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + }else{ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + CheckGlDieOnError(); +} + +inline void GlTexture::Upload( + const void* data, + GLenum data_format, GLenum data_type +) { + Bind(); + glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,data_format,data_type,data); + CheckGlDieOnError(); +} + +inline void GlTexture::Upload( + const void* data, + GLsizei tex_x_offset, GLsizei tex_y_offset, + GLsizei data_w, GLsizei data_h, + GLenum data_format, GLenum data_type ) +{ + Bind(); + glTexSubImage2D(GL_TEXTURE_2D,0,tex_x_offset,tex_y_offset,data_w,data_h,data_format,data_type,data); + CheckGlDieOnError(); +} + +inline void GlTexture::Load(const TypedImage& image, bool sampling_linear) +{ + GlPixFormat fmt(image.fmt); + Reinitialise((GLint)image.w, (GLint)image.h, GL_RGBA32F, sampling_linear, 0, fmt.glformat, fmt.gltype, image.ptr ); +} + +inline void GlTexture::LoadFromFile(const std::string& filename, bool sampling_linear) +{ + TypedImage image = LoadImage(filename); + Load(image, sampling_linear); +} + +#ifndef HAVE_GLES +inline void GlTexture::Download(void* image, GLenum data_layout, GLenum data_type) const +{ + Bind(); + glGetTexImage(GL_TEXTURE_2D, 0, data_layout, data_type, image); + Unbind(); +} + +inline void GlTexture::Download(TypedImage& image) const +{ + switch (internal_format) + { + case GL_LUMINANCE8: + image.Reinitialise(width, height, PixelFormatFromString("GRAY8") ); + Download(image.ptr, GL_LUMINANCE, GL_UNSIGNED_BYTE); + break; + case GL_LUMINANCE16: + image.Reinitialise(width, height, PixelFormatFromString("GRAY16LE") ); + Download(image.ptr, GL_LUMINANCE, GL_UNSIGNED_SHORT); + break; + case GL_RGB8: + image.Reinitialise(width, height, PixelFormatFromString("RGB24")); + Download(image.ptr, GL_RGB, GL_UNSIGNED_BYTE); + break; + case GL_RGBA8: + image.Reinitialise(width, height, PixelFormatFromString("RGBA32")); + Download(image.ptr, GL_RGBA, GL_UNSIGNED_BYTE); + break; + case GL_RGB16: + image.Reinitialise(width, height, PixelFormatFromString("RGB48")); + Download(image.ptr, GL_RGB, GL_UNSIGNED_SHORT); + break; + case GL_RGBA16: + image.Reinitialise(width, height, PixelFormatFromString("RGBA64")); + Download(image.ptr, GL_RGBA, GL_UNSIGNED_SHORT); + break; + case GL_LUMINANCE: + case GL_LUMINANCE32F_ARB: + image.Reinitialise(width, height, PixelFormatFromString("GRAY32F")); + Download(image.ptr, GL_LUMINANCE, GL_FLOAT); + break; + case GL_RGB: + case GL_RGB32F: + image.Reinitialise(width, height, PixelFormatFromString("RGB96F")); + Download(image.ptr, GL_RGB, GL_FLOAT); + break; + case GL_RGBA: + case GL_RGBA32F: + image.Reinitialise(width, height, PixelFormatFromString("RGBA128F")); + Download(image.ptr, GL_RGBA, GL_FLOAT); + break; + default: + throw std::runtime_error( + "GlTexture::Download - Unknown internal format (" + + pangolin::Convert::Do(internal_format) + + ")" + ); + } + +} + +inline void GlTexture::CopyFrom(const GlTexture& tex) +{ + if(!tid || width != tex.width || height != tex.height || + internal_format != tex.internal_format) + { + Reinitialise(tex.width, tex.height, tex.internal_format, true); + } + + glCopyImageSubData(tex.tid, GL_TEXTURE_2D, 0, 0, 0, 0, + tid, GL_TEXTURE_2D, 0, 0, 0, 0, + width, height, 1); + CheckGlDieOnError(); +} + +inline void GlTexture::Save(const std::string& filename, bool top_line_first) +{ + TypedImage image; + Download(image); + pangolin::SaveImage(image, filename, top_line_first); +} +#endif // HAVE_GLES + +inline void GlTexture::SetLinear() +{ + Bind(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + Unbind(); +} + +inline void GlTexture::SetNearestNeighbour() +{ + Bind(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + Unbind(); +} + +inline void GlTexture::RenderToViewport(const bool flip) const +{ + if(flip) { + RenderToViewportFlipY(); + }else{ + RenderToViewport(); + } +} + +inline void GlTexture::RenderToViewport() const +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 }; + glVertexPointer(2, GL_FLOAT, 0, sq_vert); + glEnableClientState(GL_VERTEX_ARRAY); + + GLfloat sq_tex[] = { 0,0, 1,0, 1,1, 0,1 }; + glTexCoordPointer(2, GL_FLOAT, 0, sq_tex); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnable(GL_TEXTURE_2D); + Bind(); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(GL_TEXTURE_2D); +} + +inline void GlTexture::RenderToViewport(Viewport tex_vp, bool flipx, bool flipy) const +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 }; + glVertexPointer(2, GL_FLOAT, 0, sq_vert); + glEnableClientState(GL_VERTEX_ARRAY); + + GLfloat l = tex_vp.l / (float)(width); + GLfloat b = tex_vp.b / (float)(height); + GLfloat r = (tex_vp.l+tex_vp.w) / (float)(width); + GLfloat t = (tex_vp.b+tex_vp.h) / (float)(height); + + if(flipx) std::swap(l,r); + if(flipy) std::swap(b,t); + + GLfloat sq_tex[] = { l,b, r,b, r,t, l,t }; + glTexCoordPointer(2, GL_FLOAT, 0, sq_tex); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnable(GL_TEXTURE_2D); + Bind(); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(GL_TEXTURE_2D); +} + +inline void GlTexture::RenderToViewportFlipY() const +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 }; + glVertexPointer(2, GL_FLOAT, 0, sq_vert); + glEnableClientState(GL_VERTEX_ARRAY); + + GLfloat sq_tex[] = { 0,1, 1,1, 1,0, 0,0 }; + glTexCoordPointer(2, GL_FLOAT, 0, sq_tex); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnable(GL_TEXTURE_2D); + Bind(); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(GL_TEXTURE_2D); +} + +inline void GlTexture::RenderToViewportFlipXFlipY() const +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + GLfloat sq_vert[] = { 1,1, -1,1, -1,-1, 1,-1 }; + glVertexPointer(2, GL_FLOAT, 0, sq_vert); + glEnableClientState(GL_VERTEX_ARRAY); + + GLfloat sq_tex[] = { 0,0, 1,0, 1,1, 0,1 }; + glTexCoordPointer(2, GL_FLOAT, 0, sq_tex); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnable(GL_TEXTURE_2D); + Bind(); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(GL_TEXTURE_2D); +} + +//////////////////////////////////////////////////////////////////////////// + +inline GlRenderBuffer::GlRenderBuffer() + : width(0), height(0), rbid(0) +{ +} + +inline GlRenderBuffer::GlRenderBuffer(GLint width, GLint height, GLint internal_format ) + : width(0), height(0), rbid(0) +{ + Reinitialise(width,height,internal_format); +} + +#ifndef HAVE_GLES +inline void GlRenderBuffer::Reinitialise(GLint width, GLint height, GLint internal_format) +{ + if( this->width != 0 ) { + glDeleteRenderbuffersEXT(1, &rbid); + } + + this->width = width; + this->height = height; + glGenRenderbuffersEXT(1, &rbid); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbid); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internal_format, width, height); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); +} + +inline GlRenderBuffer::~GlRenderBuffer() +{ + // We have no GL context whilst exiting. + if( width!=0 && !pangolin::ShouldQuit() ) { + glDeleteRenderbuffersEXT(1, &rbid); + } +} +#else +inline void GlRenderBuffer::Reinitialise(GLint width, GLint height, GLint internal_format) +{ + if( width!=0 ) { + glDeleteTextures(1, &rbid); + } + + // Use a texture instead... + glGenTextures(1, &rbid); + glBindTexture(GL_TEXTURE_2D, rbid); + + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, + width, height, + 0, internal_format, GL_UNSIGNED_SHORT, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +} + +inline GlRenderBuffer::~GlRenderBuffer() +{ + // We have no GL context whilst exiting. + if( width!=0 && !pangolin::ShouldQuit() ) { + glDeleteTextures(1, &rbid); + } +} +#endif // HAVE_GLES + +inline GlRenderBuffer::GlRenderBuffer(GlRenderBuffer&& tex) + : width(tex.width), height(tex.height), rbid(tex.rbid) +{ + tex.rbid = tex.width = tex.height = 0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline GlFramebuffer::GlFramebuffer() + : fbid(0), attachments(0) +{ +} + +inline GlFramebuffer::~GlFramebuffer() +{ + if(fbid) { + glDeleteFramebuffersEXT(1, &fbid); + } +} + +inline GlFramebuffer::GlFramebuffer(GlTexture& colour, GlRenderBuffer& depth) + : attachments(0) +{ + glGenFramebuffersEXT(1, &fbid); + AttachColour(colour); + AttachDepth(depth); + CheckGlDieOnError(); +} + +inline GlFramebuffer::GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlRenderBuffer& depth) + : attachments(0) +{ + glGenFramebuffersEXT(1, &fbid); + AttachColour(colour0); + AttachColour(colour1); + AttachDepth(depth); + CheckGlDieOnError(); +} + +inline GlFramebuffer::GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlRenderBuffer& depth) + : attachments(0) +{ + glGenFramebuffersEXT(1, &fbid); + AttachColour(colour0); + AttachColour(colour1); + AttachColour(colour2); + AttachDepth(depth); + CheckGlDieOnError(); +} + +inline GlFramebuffer::GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlTexture& colour3, GlRenderBuffer& depth) + : attachments(0) +{ + glGenFramebuffersEXT(1, &fbid); + AttachColour(colour0); + AttachColour(colour1); + AttachColour(colour2); + AttachColour(colour3); + AttachDepth(depth); + CheckGlDieOnError(); +} + +inline void GlFramebuffer::Bind() const +{ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbid); +#ifndef HAVE_GLES + glDrawBuffers( attachments, attachment_buffers ); +#endif +} + +inline void GlFramebuffer::Reinitialise() +{ + if(fbid) { + glDeleteFramebuffersEXT(1, &fbid); + } + glGenFramebuffersEXT(1, &fbid); +} + +inline void GlFramebuffer::Unbind() const +{ +#ifndef HAVE_GLES + glDrawBuffers( 1, attachment_buffers ); +#endif + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +} + +inline GLenum GlFramebuffer::AttachColour(GlTexture& tex ) +{ + if(!fbid) Reinitialise(); + + const GLenum color_attachment = GL_COLOR_ATTACHMENT0_EXT + attachments; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbid); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, color_attachment, GL_TEXTURE_2D, tex.tid, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + attachments++; + CheckGlDieOnError(); + return color_attachment; +} + +inline void GlFramebuffer::AttachDepth(GlRenderBuffer& rb ) +{ + if(!fbid) Reinitialise(); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbid); +#if !defined(HAVE_GLES) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb.rbid); +#elif defined(HAVE_GLES_2) + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, rb.rbid, 0); +#else + throw std::exception(); +#endif + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + CheckGlDieOnError(); +} + +//////////////////////////////////////////////////////////////////////////// + +inline GlBufferData::GlBufferData() + : bo(0) +{ +} + +inline GlBufferData::GlBufferData(GlBufferType buffer_type, GLuint size_bytes, GLenum gluse, const unsigned char* data ) + : bo(0) +{ + Reinitialise(buffer_type, size_bytes, gluse, data ); +} + +//! Move Constructor +inline GlBufferData::GlBufferData(GlBufferData&& tex) + : bo(0) +{ + *this = std::move(tex); +} +inline GlBufferData& GlBufferData::operator=(GlBufferData&& tex) +{ + Free(); + this->bo = tex.bo; + this->buffer_type = tex.buffer_type; + this->gluse = tex.gluse; + this->size_bytes = tex.size_bytes; + tex.bo = 0; + return *this; +} + +inline GlBufferData::~GlBufferData() +{ + Free(); +} + +inline void GlBufferData::Free() +{ + if(bo!=0) { + glDeleteBuffers(1, &bo); + } +} + +inline bool GlBufferData::IsValid() const +{ + return bo != 0; +} + +inline size_t GlBufferData::SizeBytes() const +{ + return size_bytes; +} + +inline void GlBufferData::Reinitialise(GlBufferType buffer_type, GLuint size_bytes, GLenum gluse, const unsigned char* data ) +{ + if(!bo) { + glGenBuffers(1, &bo); + } + + this->buffer_type = buffer_type; + this->gluse = gluse; + this->size_bytes = size_bytes; + + Bind(); + glBufferData(buffer_type, size_bytes, data, gluse); + Unbind(); +} + +inline void GlBufferData::Bind() const +{ + glBindBuffer(buffer_type, bo); +} + +inline void GlBufferData::Unbind() const +{ + glBindBuffer(buffer_type, 0); +} + +inline void GlBufferData::Upload(const GLvoid* data, GLsizeiptr size_bytes, GLintptr offset) +{ + if(offset + size_bytes > this->size_bytes) { + throw std::runtime_error("GlBufferData: Trying to upload past capacity."); + } + + Bind(); + glBufferSubData(buffer_type,offset,size_bytes,data); + Unbind(); +} + +inline void GlBufferData::Download(GLvoid* data, GLsizeiptr size_bytes, GLintptr offset) const +{ + Bind(); + glGetBufferSubData(buffer_type, offset, size_bytes, data); + Unbind(); +} + +//////////////////////////////////////////////////////////////////////////// + +inline GlBuffer::GlBuffer() + : GlBufferData(), num_elements(0) +{ +} + +inline GlBuffer::GlBuffer(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse ) + : GlBufferData(buffer_type, num_elements * count_per_element * GlDataTypeBytes(datatype), gluse), + datatype(datatype), num_elements(num_elements), count_per_element(count_per_element) +{ +} + + +inline GlBuffer::GlBuffer(GlBuffer&& o) + : GlBufferData() +{ + *this = std::move(o); +} + +inline GlBuffer& GlBuffer::operator=(GlBuffer&& o) +{ + datatype = o.datatype; + num_elements = o.num_elements; + count_per_element = o.count_per_element; + GlBufferData::operator =(std::move(o)); + return *this; +} + +inline void GlBuffer::Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse, const unsigned char* data ) +{ + this->datatype = datatype; + this->num_elements = num_elements; + this->count_per_element = count_per_element; + const GLuint size_bytes = num_elements * count_per_element * GlDataTypeBytes(datatype); + GlBufferData::Reinitialise(buffer_type, size_bytes, gluse, data); +} + +inline void GlBuffer::Reinitialise(GlBuffer const& other ) +{ + Reinitialise(other.buffer_type, other.num_elements, other.datatype, other.count_per_element, other.gluse); +} + +inline void GlBuffer::Resize(GLuint new_num_elements) +{ + if(bo!=0) { +#ifndef HAVE_GLES + // Backup current data, reinit memory, restore old data + const size_t backup_elements = std::min(new_num_elements,num_elements); + const size_t backup_size_bytes = backup_elements*GlDataTypeBytes(datatype)*count_per_element; + unsigned char* backup = new unsigned char[backup_size_bytes]; + Bind(); + glGetBufferSubData(buffer_type, 0, backup_size_bytes, backup); + glBufferData(buffer_type, new_num_elements*GlDataTypeBytes(datatype)*count_per_element, 0, gluse); + glBufferSubData(buffer_type, 0, backup_size_bytes, backup); + Unbind(); + delete[] backup; +#else + throw std::exception(); +#endif + }else{ + Reinitialise(buffer_type, new_num_elements, datatype, count_per_element, gluse); + } + num_elements = new_num_elements; +} + + +//////////////////////////////////////////////////////////////////////////// + +inline GlSizeableBuffer::GlSizeableBuffer(GlBufferType buffer_type, GLuint initial_num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse ) + : GlBuffer(buffer_type, initial_num_elements, datatype, count_per_element, gluse), m_num_verts(0) +{ + +} + +inline void GlSizeableBuffer::Clear() +{ + m_num_verts = 0; +} + +#ifdef USE_EIGEN +template inline +void GlSizeableBuffer::Add(const Eigen::DenseBase& vec) +{ + typedef typename Eigen::DenseBase::Scalar Scalar; + assert(vec.rows()==GlBuffer::count_per_element); + CheckResize(m_num_verts + 1); + // TODO: taking address of first element is really dodgey. Need to work out + // when this is okay! + Upload(&vec(0,0), sizeof(Scalar)*vec.rows()*vec.cols(), sizeof(Scalar)*vec.rows()*m_num_verts); + m_num_verts += vec.cols(); +} + +template inline +void GlSizeableBuffer::Update(const Eigen::DenseBase& vec, size_t position ) +{ + typedef typename Eigen::DenseBase::Scalar Scalar; + assert(vec.rows()==GlBuffer::count_per_element); + CheckResize(position + vec.cols() ); + // TODO: taking address of first element is really dodgey. Need to work out + // when this is okay! + Upload(&vec(0,0), sizeof(Scalar)*vec.rows()*vec.cols(), sizeof(Scalar)*vec.rows()*position ); + m_num_verts = std::max(position+vec.cols(), m_num_verts); +} +#endif + +inline size_t GlSizeableBuffer::start() const { + return 0; +} + +inline size_t GlSizeableBuffer::size() const { + return m_num_verts; +} + +inline void GlSizeableBuffer::CheckResize(size_t num_verts) +{ + if( num_verts > GlBuffer::num_elements) { + const size_t new_size = NextSize(num_verts); + GlBuffer::Resize((GLuint)new_size); + } +} + +inline size_t GlSizeableBuffer::NextSize(size_t min_size) const +{ + size_t new_size = std::max(GlBuffer::num_elements, 1u); + while(new_size < min_size) { + new_size *= 2; + } + return new_size; +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glchar.h b/thirdparty/Pangolin/include/pangolin/gl/glchar.h new file mode 100644 index 00000000..000d0da2 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glchar.h @@ -0,0 +1,78 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin { + +struct PANGOLIN_EXPORT XYUV +{ + XYUV() {} + XYUV(GLfloat x, GLfloat y, GLfloat tu, GLfloat tv) + : x(x), y(y), tu(tu), tv(tv) {} + + XYUV operator+(float dx) const { + return XYUV(x+dx,y,tu,tv); + } + + GLfloat x, y, tu, tv; +}; + +class PANGOLIN_EXPORT GlChar +{ +public: + GlChar(); + GlChar(int tw, int th, int x, int y, int w, int h, GLfloat x_step, GLfloat ox, GLfloat oy); + + inline const XYUV& GetVert(size_t i) const { + return vs[i]; + } + + inline GLfloat StepX() const { + return x_step; + } + + inline GLfloat YMin() const { + return y_min; + } + + inline GLfloat YMax() const { + return y_max; + } + + void Draw() const; + +protected: + XYUV vs[4]; + GLfloat x_step; + GLfloat y_min, y_max; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glcuda.h b/thirdparty/Pangolin/include/pangolin/gl/glcuda.h new file mode 100644 index 00000000..9fbf1411 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glcuda.h @@ -0,0 +1,258 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include "gl.h" + +namespace pangolin +{ + +//////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////// + +struct GlBufferCudaPtr : public GlBuffer +{ + //! Default constructor represents 'no buffer' + GlBufferCudaPtr(); + + GlBufferCudaPtr(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ); + GlBufferCudaPtr(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ); + + PANGOLIN_DEPRECATED + GlBufferCudaPtr(GlBufferType buffer_type, GLuint width, GLuint height, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ); + + ~GlBufferCudaPtr(); + + void Reinitialise(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ); + void Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ); + + /** + * Use parameters from another @c GlBufferCudaPtr to initialize this buffer. + */ + void Reinitialise(const GlBufferCudaPtr& other); + + unsigned int cuda_use; + cudaGraphicsResource* cuda_res; +}; + +struct GlTextureCudaArray : GlTexture +{ + GlTextureCudaArray(); + // Some internal_formats aren't accepted. I have trouble with GL_RGB8 + GlTextureCudaArray(int width, int height, GLint internal_format, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL); + ~GlTextureCudaArray(); + + void Reinitialise(int width, int height, GLint internal_format, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL) override; + cudaGraphicsResource* cuda_res; +}; + +struct CudaScopedMappedPtr +{ + CudaScopedMappedPtr(const GlBufferCudaPtr& buffer); + ~CudaScopedMappedPtr(); + void* operator*(); + cudaGraphicsResource* res; + +private: + CudaScopedMappedPtr(const CudaScopedMappedPtr&) {} +}; + +struct CudaScopedMappedArray +{ + CudaScopedMappedArray(const GlTextureCudaArray& tex); + ~CudaScopedMappedArray(); + cudaArray* operator*(); + cudaGraphicsResource* res; + +private: + CudaScopedMappedArray(const CudaScopedMappedArray&) {} +}; + +void CopyPboToTex(GlBufferCudaPtr& buffer, GlTexture& tex); + +void swap(GlBufferCudaPtr& a, GlBufferCudaPtr& b); + +//////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////// + +inline GlBufferCudaPtr::GlBufferCudaPtr() + : cuda_res(0) +{ +} + +inline GlBufferCudaPtr::GlBufferCudaPtr(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ) + : cuda_res(0) +{ + Reinitialise(buffer_type, size_bytes, cudause, gluse); +} + +inline GlBufferCudaPtr::GlBufferCudaPtr(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause, GLenum gluse ) + : cuda_res(0) +{ + Reinitialise(buffer_type, num_elements, datatype, count_per_element, cudause, gluse); +} + +inline GlBufferCudaPtr::GlBufferCudaPtr(GlBufferType buffer_type, GLuint width, GLuint height, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ) + : cuda_res(0) +{ + Reinitialise(buffer_type, width*height, datatype, count_per_element, cudause, gluse); +} + +inline GlBufferCudaPtr::~GlBufferCudaPtr() +{ + if(cuda_res) { + cudaGraphicsUnregisterResource(cuda_res); + } +} + +inline void GlBufferCudaPtr::Reinitialise(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ) +{ + GlBufferCudaPtr::Reinitialise(buffer_type, size_bytes, GL_BYTE, 1, cudause, gluse); +} + +inline void GlBufferCudaPtr::Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ ) +{ + if(cuda_res) { + cudaGraphicsUnregisterResource(cuda_res); + } + GlBuffer::Reinitialise(buffer_type, num_elements, datatype, count_per_element, gluse); + + cuda_use = cudause; + cudaGraphicsGLRegisterBuffer( &cuda_res, bo, cudause ); +} + +inline void GlBufferCudaPtr::Reinitialise(const GlBufferCudaPtr& other) +{ + Reinitialise(other.buffer_type, other.num_elements, other.datatype, other.count_per_element, other.cuda_use, other.gluse); +} + +inline GlTextureCudaArray::GlTextureCudaArray() + : GlTexture(), cuda_res(0) +{ + // Not a texture +} + +inline GlTextureCudaArray::GlTextureCudaArray(int width, int height, GLint internal_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid *data) + :GlTexture(width,height,internal_format, sampling_linear, border, glformat, gltype, data) +{ + // TODO: specify flags too + const cudaError_t err = cudaGraphicsGLRegisterImage(&cuda_res, tid, GL_TEXTURE_2D, cudaGraphicsMapFlagsNone); + if( err != cudaSuccess ) { + std::cout << "cudaGraphicsGLRegisterImage failed: " << err << std::endl; + } +} + +inline GlTextureCudaArray::~GlTextureCudaArray() +{ + if(cuda_res) { + cudaGraphicsUnregisterResource(cuda_res); + } +} + +inline void GlTextureCudaArray::Reinitialise(int width, int height, GLint internal_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid* data) +{ + if(cuda_res) { + cudaGraphicsUnregisterResource(cuda_res); + } + + GlTexture::Reinitialise(width, height, internal_format, sampling_linear, border, glformat, gltype, data); + + const cudaError_t err = cudaGraphicsGLRegisterImage(&cuda_res, tid, GL_TEXTURE_2D, cudaGraphicsMapFlagsNone); + if( err != cudaSuccess ) { + std::cout << "cudaGraphicsGLRegisterImage failed: " << err << std::endl; + } +} + +inline CudaScopedMappedPtr::CudaScopedMappedPtr(const GlBufferCudaPtr& buffer) + : res(buffer.cuda_res) +{ + cudaGraphicsMapResources(1, &res, 0); +} + +inline CudaScopedMappedPtr::~CudaScopedMappedPtr() +{ + cudaGraphicsUnmapResources(1, &res, 0); +} + +inline void* CudaScopedMappedPtr::operator*() +{ + size_t num_bytes; + void* d_ptr; + cudaGraphicsResourceGetMappedPointer(&d_ptr,&num_bytes,res); + return d_ptr; +} + +inline CudaScopedMappedArray::CudaScopedMappedArray(const GlTextureCudaArray& tex) + : res(tex.cuda_res) +{ + cudaGraphicsMapResources(1, &res); +} + +inline CudaScopedMappedArray::~CudaScopedMappedArray() +{ + cudaGraphicsUnmapResources(1, &res); +} + +inline cudaArray* CudaScopedMappedArray::operator*() +{ + cudaArray* array; + cudaGraphicsSubResourceGetMappedArray(&array, res, 0, 0); + return array; +} + +inline void CopyPboToTex(const GlBufferCudaPtr& buffer, GlTexture& tex, GLenum buffer_layout, GLenum buffer_data_type ) +{ + buffer.Bind(); + tex.Bind(); + glTexImage2D(GL_TEXTURE_2D, 0, tex.internal_format, tex.width, tex.height, 0, buffer_layout, buffer_data_type, 0); + buffer.Unbind(); + tex.Unbind(); +} + +template +inline void CopyDevMemtoTex(T* d_img, size_t pitch, GlTextureCudaArray& tex ) +{ + CudaScopedMappedArray arr_tex(tex); + cudaMemcpy2DToArray(*arr_tex, 0, 0, d_img, pitch, tex.width*sizeof(T), tex.height, cudaMemcpyDeviceToDevice ); +} + +inline void swap(GlBufferCudaPtr& a, GlBufferCudaPtr& b) +{ + std::swap(a.bo, b.bo); + std::swap(a.cuda_res, b.cuda_res); + std::swap(a.buffer_type, b.buffer_type); +} + + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/gldraw.h b/thirdparty/Pangolin/include/pangolin/gl/gldraw.h new file mode 100644 index 00000000..2ac0be71 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/gldraw.h @@ -0,0 +1,518 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include + +#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files +#define USE_EIGEN +#endif + +#ifdef USE_EIGEN +#include +#include +#endif // USE_EIGEN + +namespace pangolin +{ + +// h [0,360) +// s [0,1] +// v [0,1] +inline void glColorHSV( GLfloat hue, GLfloat s=1.0f, GLfloat v=1.0f ) +{ + const GLfloat h = hue / 60.0f; + const int i = (int)floor(h); + const GLfloat f = (i%2 == 0) ? 1-(h-i) : h-i; + const GLfloat m = v * (1-s); + const GLfloat n = v * (1-s*f); + switch(i) + { + case 0: glColor4f(v,n,m,1); break; + case 1: glColor4f(n,v,m,1); break; + case 2: glColor4f(m,v,n,1); break; + case 3: glColor4f(m,n,v,1); break; + case 4: glColor4f(n,m,v,1); break; + case 5: glColor4f(v,m,n,1); break; + default: + break; + } +} + +inline void glColorBin( int bin, int max_bins, GLfloat sat=1.0f, GLfloat val=1.0f ) +{ + if( bin >= 0 ) { + const GLfloat hue = (GLfloat)(bin%max_bins) * 360.0f / (GLfloat)max_bins; + glColorHSV(hue,sat,val); + }else{ + glColor4f(1,1,1,1); + } +} + +template +inline void glDrawVertices( + size_t num_vertices, const T* const vertex_ptr, GLenum mode, + size_t elements_per_vertex = GlFormatTraits::components, + size_t vertex_stride_bytes = 0 ) +{ + if(num_vertices > 0) + { + PANGO_ENSURE(vertex_ptr != nullptr); + PANGO_ENSURE(mode != GL_LINES || num_vertices % 2 == 0, "number of vertices (%) must be even in GL_LINES mode", num_vertices ); + + glVertexPointer(elements_per_vertex, GlFormatTraits::gltype, vertex_stride_bytes, vertex_ptr); + glEnableClientState(GL_VERTEX_ARRAY); + glDrawArrays(mode, 0, num_vertices); + glDisableClientState(GL_VERTEX_ARRAY); + } +} + +template +inline void glDrawColoredVertices( + size_t num_vertices, const TV* const vertex_ptr, const TC* const color_ptr, GLenum mode, + size_t elements_per_vertex = GlFormatTraits::components, + size_t elements_per_color = GlFormatTraits::components, + size_t vertex_stride_bytes = 0, + size_t color_stride_bytes = 0 +) { + if(color_ptr) { + glColorPointer(elements_per_color, GlFormatTraits::gltype, color_stride_bytes, color_ptr); + glEnableClientState(GL_COLOR_ARRAY); + glDrawVertices(num_vertices, vertex_ptr, mode, elements_per_vertex, vertex_stride_bytes); + glDisableClientState(GL_COLOR_ARRAY); + }else{ + glDrawVertices(num_vertices, vertex_ptr, mode, elements_per_vertex, vertex_stride_bytes); + } +} + +inline void glDrawLine( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + const GLfloat verts[] = { x1,y1, x2,y2 }; + glDrawVertices(2, verts, GL_LINES, 2); +} + +inline void glDrawLine( GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2) +{ + const GLfloat verts[] = { x1,y1,z1, x2,y2,z2 }; + glDrawVertices(2, verts, GL_LINES, 3); +} + +inline void glDrawCross( GLfloat x, GLfloat y, GLfloat rad ) +{ + const GLfloat verts[] = { x-rad,y, x+rad, y, x,y-rad, x, y+rad}; + glDrawVertices(4, verts, GL_LINES, 2); +} + +inline void glDrawCross( GLfloat x, GLfloat y, GLfloat z, GLfloat rad ) +{ + const GLfloat verts[] = { x-rad,y,z, x+rad,y,z, x,y-rad,z, x,y+rad,z, x,y,z-rad, x,y,z+rad }; + glDrawVertices(6, verts, GL_LINES, 3); +} + +inline void glDrawAxis(float s) +{ + const GLfloat cols[] = { 1,0,0, 1,0,0, 0,1,0, 0,1,0, 0,0,1, 0,0,1 }; + const GLfloat verts[] = { 0,0,0, s,0,0, 0,0,0, 0,s,0, 0,0,0, 0,0,s }; + glDrawColoredVertices(6, verts, cols, GL_LINES, 3, 3); +} + +inline void glDrawRect( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLenum mode = GL_TRIANGLE_FAN ) +{ + const GLfloat verts[] = { x1,y1, x2,y1, x2,y2, x1,y2 }; + glDrawVertices(4, verts, mode, 2); +} + +inline void glDrawRectPerimeter( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + glDrawRect(x1,y1, x2,y2, GL_LINE_LOOP); +} + +inline void glDrawCirclePerimeter( float x, float y, float rad ) +{ + const int N = 50; + GLfloat verts[N*2]; + + const float TAU_DIV_N = 2*(float)M_PI/N; + for(int i = 0; i < N*2; i+=2) { + verts[i] = x + rad * cos(i*TAU_DIV_N); + verts[i+1] = y + rad * sin(i*TAU_DIV_N); + } + + glDrawVertices(N, verts, GL_LINES, 2); +} + +inline void glDrawCircle( GLfloat x, GLfloat y, GLfloat rad ) +{ + const int N = 50; + GLfloat verts[N*2]; + + // Draw vertices anticlockwise for front face + const float TAU_DIV_N = 2*(float)M_PI/N; + for(int i = 0; i < N*2; i+=2) { + verts[i] = x + rad * cos(-i*TAU_DIV_N); + verts[i+1] = y + rad * sin(-i*TAU_DIV_N); + } + + // Render filled shape and outline (to make it look smooth) + glVertexPointer(2, GL_FLOAT, 0, verts); + glEnableClientState(GL_VERTEX_ARRAY); + glDrawArrays(GL_TRIANGLE_FAN, 0, N); + glDrawArrays(GL_LINE_STRIP, 0, N); + glDisableClientState(GL_VERTEX_ARRAY); +} + +inline void glDrawColouredCube(GLfloat axis_min=-0.5f, GLfloat axis_max = +0.5f) +{ + const GLfloat l = axis_min; + const GLfloat h = axis_max; + + const GLfloat verts[] = { + l,l,h, h,l,h, l,h,h, h,h,h, // FRONT + l,l,l, l,h,l, h,l,l, h,h,l, // BACK + l,l,h, l,h,h, l,l,l, l,h,l, // LEFT + h,l,l, h,h,l, h,l,h, h,h,h, // RIGHT + l,h,h, h,h,h, l,h,l, h,h,l, // TOP + l,l,h, l,l,l, h,l,h, h,l,l // BOTTOM + }; + + glVertexPointer(3, GL_FLOAT, 0, verts); + glEnableClientState(GL_VERTEX_ARRAY); + + glColor4f(1.0f, 0.0f, 0.0f, 1.0f); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); + + glColor4f(0.0f, 1.0f, 0.0f, 1.0f); + glDrawArrays(GL_TRIANGLE_STRIP, 8, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 12, 4); + + glColor4f(0.0f, 0.0f, 1.0f, 1.0f); + glDrawArrays(GL_TRIANGLE_STRIP, 16, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 20, 4); + + glDisableClientState(GL_VERTEX_ARRAY); +} + +inline void glDraw_x0(GLfloat scale, int grid) +{ + const GLfloat maxord = grid*scale; + for (int i = -grid; i <= grid; ++i) { + glDrawLine(0.0, i*scale, -maxord, 0.0, i*scale, +maxord); + glDrawLine(0.0, -maxord, i*scale, 0.0, +maxord, i*scale); + } +} + +inline void glDraw_y0(GLfloat scale, int grid) +{ + const GLfloat maxord = grid*scale; + for (int i = -grid; i <= grid; ++i) { + glDrawLine(i*scale, 0.0, -maxord, i*scale, 0.0, +maxord); + glDrawLine(-maxord, 0.0, i*scale, +maxord, 0.0, i*scale); + } +} + +inline void glDraw_z0(GLfloat scale, int grid) +{ + const GLfloat maxord = grid*scale; + for(int i=-grid; i<=grid; ++i ) { + glDrawLine(i*scale,-maxord, i*scale,+maxord); + glDrawLine(-maxord, i*scale, +maxord, i*scale); + } +} + +inline void glDrawFrustum( GLfloat u0, GLfloat v0, GLfloat fu, GLfloat fv, int w, int h, GLfloat scale ) +{ + const GLfloat xl = scale * u0; + const GLfloat xh = scale * (w*fu + u0); + const GLfloat yl = scale * v0; + const GLfloat yh = scale * (h*fv + v0); + + const GLfloat verts[] = { + xl,yl,scale, xh,yl,scale, + xh,yh,scale, xl,yh,scale, + xl,yl,scale, 0,0,0, + xh,yl,scale, 0,0,0, + xl,yh,scale, 0,0,0, + xh,yh,scale + }; + + glDrawVertices(11, verts, GL_LINE_STRIP, 3); +} + +inline void glDrawTexture(GLenum target, GLuint texid) +{ + glBindTexture(target, texid); + glEnable(target); + + const GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 }; + glVertexPointer(2, GL_FLOAT, 0, sq_vert); + glEnableClientState(GL_VERTEX_ARRAY); + + const GLfloat sq_tex[] = { 0,0, 1,0, 1,1, 0,1 }; + glTexCoordPointer(2, GL_FLOAT, 0, sq_tex); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glColor4f(1,1,1,1); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(target); +} + +inline void glDrawTextureFlipY(GLenum target, GLuint texid) +{ + glBindTexture(target, texid); + glEnable(target); + + const GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 }; + glVertexPointer(2, GL_FLOAT, 0, sq_vert); + glEnableClientState(GL_VERTEX_ARRAY); + + const GLfloat sq_tex[] = { 0,1, 1,1, 1,0, 0,0 }; + glTexCoordPointer(2, GL_FLOAT, 0, sq_tex); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glColor4f(1,1,1,1); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(target); +} + + +#ifdef USE_EIGEN + +#ifndef HAVE_GLES +inline void glVertex( const Eigen::Vector3d& p ) +{ + glVertex3dv(p.data()); +} +#endif + +inline void glDrawLine( const Eigen::Vector2d& p1, const Eigen::Vector2d& p2 ) +{ + glDrawLine((GLfloat)p1(0), (GLfloat)p1(1), (GLfloat)p2(0), (GLfloat)p2(1)); +} + +// Draws a vector of 2d or 3d vertices using provided ``mode``. +// +// Preconditions: +// - ``mode`` must be GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, etc +// - If ``mode == GL_LINES``, then ``vertices.size()`` must be a multiple of 2. +// +template +void glDrawVertices(const std::vector, Allocator>& vertices, GLenum mode) +{ + glDrawVertices(vertices.size(), vertices.data(), mode); +} + +// Draws a vector of 2d or 3d points. +// +template +void glDrawPoints(const std::vector, Allocator>& vertices) +{ + glDrawVertices(vertices, GL_POINTS); +} + +// Draws a vector of 2d or 3d lines. +// +// Precondition: ``vertices.size()`` must be a multiple of 2. +// +template +void glDrawLines(const std::vector, Allocator>& vertices) +{ + glDrawVertices(vertices, GL_LINES); +} + +// Draws a 2d or 3d line strip. +// +template +void glDrawLineStrip(const std::vector, Allocator>& vertices) +{ + glDrawVertices(vertices, GL_LINE_STRIP); +} + +// Draws a 2d or 3d line loop. +// +template +void glDrawLineLoop(const std::vector, Allocator>& vertices) +{ + glDrawVertices(vertices, GL_LINE_LOOP); +} + +inline void glDrawCross( const Eigen::Vector2d& p, double r = 5.0 ) +{ + glDrawCross((GLfloat)p(0), (GLfloat)p(1), (GLfloat)r); +} + +inline void glDrawCross( const Eigen::Vector3d& p, double r = 5.0 ) +{ + glDrawCross((GLfloat)p(0), (GLfloat)p(1), (GLfloat)p(2), (GLfloat)r); +} + +inline void glDrawCircle( const Eigen::Vector2d& p, double radius = 5.0 ) +{ + glDrawCircle((GLfloat)p(0), (GLfloat)p(1), (GLfloat)radius); +} + +inline void glDrawCirclePerimeter( const Eigen::Vector2d& p, double radius = 5.0 ) +{ + glDrawCirclePerimeter((GLfloat)p(0), (GLfloat)p(1), (GLfloat)radius); +} + +inline void glSetFrameOfReference( const Eigen::Matrix4f& T_wf ) +{ + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMultMatrixf( T_wf.data() ); +} + +inline void glSetFrameOfReference( const Eigen::Matrix4d& T_wf ) +{ + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); +#ifndef HAVE_GLES + glMultMatrixd( T_wf.data() ); +#else + const Eigen::Matrix4f fT_wf = T_wf.cast(); + glMultMatrixf( fT_wf.data() ); +#endif +} + +inline void glSetFrameOfReference( const pangolin::OpenGlMatrix& T_wf ) +{ + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMultMatrixd( T_wf.m ); +} + +inline void glUnsetFrameOfReference() +{ + glPopMatrix(); +} + +template +inline void glDrawAxis( const T& T_wf, S scale ) +{ + glSetFrameOfReference(T_wf); + glDrawAxis(scale); + glUnsetFrameOfReference(); +} + +template +inline void glDrawFrustum( const Eigen::Matrix& Kinv, int w, int h, GLfloat scale ) +{ + glDrawFrustum((GLfloat)Kinv(0,2), (GLfloat)Kinv(1,2), (GLfloat)Kinv(0,0), (GLfloat)Kinv(1,1), w, h, scale); +} + +template +inline void glDrawFrustum( const Eigen::Matrix& Kinv, int w, int h, const Eigen::Matrix& T_wf, T scale ) +{ + glSetFrameOfReference(T_wf); + glDrawFrustum(Kinv,w,h,scale); + glUnsetFrameOfReference(); +} + +template +inline void glDrawAlignedBox( const Eigen::AlignedBox& box, GLenum mode = GL_TRIANGLE_FAN ) +{ + const Eigen::Matrix l = box.min().template cast(); + const Eigen::Matrix h = box.max().template cast(); + + GLfloat verts[] = { + l[0], l[1], + h[0], l[1], + h[0], h[1], + l[0], h[1] + }; + + glDrawVertices(4, verts, mode, 2); +} + +template +inline void glDrawAlignedBoxPerimeter( const Eigen::AlignedBox& box) +{ + glDrawAlignedBox(box, GL_LINE_LOOP); +} + +template +inline void glDrawAlignedBox( const Eigen::AlignedBox& box) +{ + const Eigen::Matrix l = box.min().template cast(); + const Eigen::Matrix h = box.max().template cast(); + + GLfloat verts[] = { + l[0], l[1], l[2], + l[0], l[1], h[2], + h[0], l[1], h[2], + h[0], l[1], l[2], + l[0], l[1], l[2], + l[0], h[1], l[2], + h[0], h[1], l[2], + h[0], l[1], l[2], + h[0], h[1], l[2], + h[0], h[1], h[2], + l[0], h[1], h[2], + l[0], h[1], l[2], + l[0], h[1], h[2], + l[0], l[1], h[2], + h[0], l[1], h[2], + h[0], h[1], h[2] + }; + + glDrawVertices(16, verts, GL_LINE_STRIP, 3); +} + +#endif // USE_EIGEN + +#ifndef HAVE_GLES +inline void glPixelTransferScale( float r, float g, float b ) +{ + glPixelTransferf(GL_RED_SCALE,r); + glPixelTransferf(GL_GREEN_SCALE,g); + glPixelTransferf(GL_BLUE_SCALE,b); +} + +inline void glPixelTransferScale( float scale ) +{ + glPixelTransferScale(scale,scale,scale); +} +#endif + +void glRecordGraphic(float x, float y, float radius); + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glfont.h b/thirdparty/Pangolin/include/pangolin/gl/glfont.h new file mode 100644 index 00000000..2304c2f3 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glfont.h @@ -0,0 +1,78 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2015 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include + +namespace pangolin { + +class PANGOLIN_EXPORT GlFont +{ +public: + // Singleton instance if requested. + static GlFont& I(); + + // Load GL Font data. Delay uploading as texture until first use. + GlFont(const unsigned char* ttf_buffer, float pixel_height, int tex_w=512, int tex_h=512); + GlFont(const std::string& filename, float pixel_height, int tex_w=512, int tex_h=512); + + virtual ~GlFont(); + + // Generate renderable GlText object from this font. + GlText Text( const char* fmt, ... ); + + GlText Text( const std::string& str ); + + inline float Height() const { + return font_height_px; + } + +protected: + void InitialiseFont(const unsigned char* ttf_buffer, float pixel_height, int tex_w, int tex_h); + + // This can only be called once GL context is initialised + void InitialiseGlTexture(); + + const static int FIRST_CHAR = 32; + const static int NUM_CHARS = 96; + + float font_height_px; + + int tex_w; + int tex_h; + unsigned char* font_bitmap; + GlTexture mTex; + + GlChar chardata[NUM_CHARS]; + GLfloat kern_table[NUM_CHARS*NUM_CHARS]; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glformattraits.h b/thirdparty/Pangolin/include/pangolin/gl/glformattraits.h new file mode 100644 index 00000000..7c1dc588 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glformattraits.h @@ -0,0 +1,214 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#ifdef HAVE_EIGEN +# include +#endif + +namespace pangolin +{ + +template +struct GlFormatTraits; +//{ +// static const GLint glinternalformat = 0; +// static const GLenum glformat = 0; +// static const GLenum gltype = 0; +// static const T glmin = 0; +// static const T glmax = 0; +//}; + +template<> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_LUMINANCE8; + static const GLenum glformat = GL_LUMINANCE; + static const GLenum gltype = GL_UNSIGNED_BYTE; + static const size_t components = 1; +}; + +template<> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_LUMINANCE16; + static const GLenum glformat = GL_LUMINANCE; + static const GLenum gltype = GL_UNSIGNED_SHORT; + static const size_t components = 1; +}; + +template<> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_LUMINANCE32I_EXT; + static const GLenum glformat = GL_LUMINANCE; + static const GLenum gltype = GL_UNSIGNED_INT; + static const size_t components = 1; +}; + +template<> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_LUMINANCE32I_EXT; + static const GLenum glformat = GL_LUMINANCE; + static const GLenum gltype = GL_INT; + static const size_t components = 1; +}; + +template<> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_LUMINANCE32F_ARB; + static const GLenum glformat = GL_LUMINANCE; + static const GLenum gltype = GL_FLOAT; + static const size_t components = 1; +}; + +template<> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_LUMINANCE32F_ARB; + static const GLenum glformat = GL_LUMINANCE; + static const GLenum gltype = GL_DOUBLE; + static const size_t components = 1; +}; + + + +#ifdef HAVE_EIGEN + +////////////////////////////////////////////////////////////////// + +template <> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_RG32I; + static const GLenum glformat = GL_RG; + static const GLenum gltype = GL_INT; + static const size_t components = 2; +}; + +template <> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_RG32F; + static const GLenum glformat = GL_RG; + static const GLenum gltype = GL_FLOAT; + static const size_t components = 2; +}; + +template <> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_RG32F; + static const GLenum glformat = GL_RG; + static const GLenum gltype = GL_DOUBLE; + static const size_t components = 2; +}; + +////////////////////////////////////////////////////////////////// + +template <> +struct GlFormatTraits> +{ + static const GLint glinternalformat = GL_RGB8; + static const GLenum glformat = GL_RGB; + static const GLenum gltype = GL_UNSIGNED_BYTE; + static const size_t components = 3; +}; + +template <> +struct GlFormatTraits> +{ + static const GLint glinternalformat = GL_RGBA16; + static const GLenum glformat = GL_RGB; + static const GLenum gltype = GL_UNSIGNED_SHORT; + static const size_t components = 3; +}; + +template <> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_RGB32F; + static const GLenum glformat = GL_RGB; + static const GLenum gltype = GL_FLOAT; + static const size_t components = 3; +}; + +template <> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_RGB32F; + static const GLenum glformat = GL_RGB; + static const GLenum gltype = GL_DOUBLE; + static const size_t components = 3; +}; + +////////////////////////////////////////////////////////////////// + +template <> +struct GlFormatTraits> +{ + static const GLint glinternalformat = GL_RGBA8; + static const GLenum glformat = GL_RGBA; + static const GLenum gltype = GL_UNSIGNED_BYTE; + static const size_t components = 4; +}; + +template <> +struct GlFormatTraits> +{ + static const GLint glinternalformat = GL_RGBA16; + static const GLenum glformat = GL_RGBA; + static const GLenum gltype = GL_UNSIGNED_SHORT; + static const size_t components = 4; +}; + +template <> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_RGBA32F; + static const GLenum glformat = GL_RGBA; + static const GLenum gltype = GL_FLOAT; + static const size_t components = 4; +}; + +template <> +struct GlFormatTraits +{ + static const GLint glinternalformat = GL_RGBA32F; + static const GLenum glformat = GL_RGBA; + static const GLenum gltype = GL_DOUBLE; + static const size_t components = 4; +}; + +#endif // HAVE_EIGEN + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glinclude.h b/thirdparty/Pangolin/include/pangolin/gl/glinclude.h new file mode 100644 index 00000000..2174b8f0 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glinclude.h @@ -0,0 +1,46 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove, Richard Newcombe + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#ifdef HAVE_GLES +#include +#endif + +#define CheckGlDieOnError() pangolin::_CheckGlDieOnError( __FILE__, __LINE__ ); +namespace pangolin { +inline void _CheckGlDieOnError( const char *sFile, const int nLine ) +{ + GLenum glError = glGetError(); + if( glError != GL_NO_ERROR ) { + pango_print_error( "OpenGL Error: %s (%x)\n", glErrorString(glError), glError ); + pango_print_error("In: %s, line %d\n", sFile, nLine); + } +} +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glpangoglu.h b/thirdparty/Pangolin/include/pangolin/gl/glpangoglu.h new file mode 100644 index 00000000..c6f5dae6 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glpangoglu.h @@ -0,0 +1,80 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +namespace pangolin { + +/// Clone of gluProject +PANGOLIN_EXPORT +const GLubyte* glErrorString(GLenum error); + +/// Clone of gluProject +PANGOLIN_EXPORT +GLint glProject( + float objx, float objy, float objz, + const float modelMatrix[16], + const float projMatrix[16], + const GLint viewport[4], + float* winx, float* winy, float* winz +); + + +/// Clone of gluUnProject +PANGOLIN_EXPORT +GLint glUnProject( + float winx, float winy, float winz, + const float modelMatrix[16], + const float projMatrix[16], + const GLint viewport[4], + float* objx, float* objy, float* objz +); + +/// Clone of gluProject +PANGOLIN_EXPORT +GLint glProject( + double objx, double objy, double objz, + const double modelMatrix[16], + const double projMatrix[16], + const GLint viewport[4], + double* winx, double* winy, double* winz +); + + +/// Clone of gluUnProject +PANGOLIN_EXPORT +GLint glUnProject( + double winx, double winy, double winz, + const double modelMatrix[16], + const double projMatrix[16], + const GLint viewport[4], + double* objx, double* objy, double* objz +); + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glpixformat.h b/thirdparty/Pangolin/include/pangolin/gl/glpixformat.h new file mode 100644 index 00000000..2ceebd5b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glpixformat.h @@ -0,0 +1,95 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include + +namespace pangolin { + +// This class may dissapear in the future +struct GlPixFormat +{ + GlPixFormat() {} + + GlPixFormat(const PixelFormat& fmt) + { + switch( fmt.channels) { + case 1: glformat = GL_LUMINANCE; break; + case 3: glformat = (fmt.format == "BGR24" || fmt.format == "BGR48") ? GL_BGR : GL_RGB; break; + case 4: glformat = (fmt.format == "BGRA24" || fmt.format == "BGRA32" || fmt.format == "BGRA48") ? GL_BGRA : GL_RGBA; break; + default: throw std::runtime_error("Unable to form OpenGL format from video format: '" + fmt.format + "'."); + } + + const bool is_integral = fmt.format.find('F') == std::string::npos; + + switch (fmt.channel_bits[0]) { + case 8: gltype = GL_UNSIGNED_BYTE; break; + case 16: gltype = GL_UNSIGNED_SHORT; break; + case 32: gltype = (is_integral ? GL_UNSIGNED_INT : GL_FLOAT); break; + case 64: gltype = (is_integral ? GL_UNSIGNED_INT64_NV : GL_DOUBLE); break; + default: throw std::runtime_error("Unknown OpenGL data type for video format: '" + fmt.format + "'."); + } + + if(glformat == GL_LUMINANCE) { + if(gltype == GL_UNSIGNED_BYTE) { + scalable_internal_format = GL_LUMINANCE8; + }else if(gltype == GL_UNSIGNED_SHORT){ + scalable_internal_format = GL_LUMINANCE16; + }else{ + scalable_internal_format = GL_LUMINANCE32F_ARB; + } + }else{ + if(gltype == GL_UNSIGNED_BYTE) { + scalable_internal_format = GL_RGBA8; + }else if(gltype == GL_UNSIGNED_SHORT) { + scalable_internal_format = GL_RGBA16; + }else{ + scalable_internal_format = GL_RGBA32F; + } + } + } + + template + static GlPixFormat FromType() + { + GlPixFormat fmt; + fmt.glformat = GlFormatTraits::glformat; + fmt.gltype = GlFormatTraits::gltype; + fmt.scalable_internal_format = GlFormatTraits::glinternalformat; + return fmt; + } + + GLint glformat; + GLenum gltype; + GLint scalable_internal_format; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glplatform.h b/thirdparty/Pangolin/include/pangolin/gl/glplatform.h new file mode 100644 index 00000000..caa0ad30 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glplatform.h @@ -0,0 +1,83 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +////////////////////////////////////////////////////////// +// Attempt to portably include Necessary OpenGL headers +////////////////////////////////////////////////////////// + +#include + +#ifdef _WIN_ + // Define maths quantities when using to match posix systems + #ifndef _USE_MATH_DEFINES + # define _USE_MATH_DEFINES + #endif + + // Don't define min / max macros in windows.h or other unnecessary macros + #ifndef NOMINMAX + # define NOMINMAX + #endif + #ifndef WIN32_LEAN_AND_MEAN + # define WIN32_LEAN_AND_MEAN + #endif + #include + + // Undef nuisance Windows.h macros which interfere with our methods + #undef LoadImage + #undef near + #undef far + #undef ERROR +#endif + +#include + +#ifdef HAVE_GLES + #if defined(_ANDROID_) + #include + #ifdef HAVE_GLES_2 + #include + #include + #else + #include + #define GL_GLEXT_PROTOTYPES + #include + #endif + #elif defined(_APPLE_IOS_) + #include + #include + #endif +#else + #ifdef _OSX_ + #include + #else + #include + #endif +#endif // HAVE_GLES + +#include diff --git a/thirdparty/Pangolin/include/pangolin/gl/glsl.h b/thirdparty/Pangolin/include/pangolin/gl/glsl.h new file mode 100644 index 00000000..beea7b33 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glsl.h @@ -0,0 +1,738 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_GLES + #define GLhandleARB GLuint +#endif + +#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files +#define USE_EIGEN +#endif + +#ifdef USE_EIGEN +#include +#endif // USE_EIGEN + +namespace pangolin +{ + +//////////////////////////////////////////////// +// Standard attribute locations +//////////////////////////////////////////////// + +const GLuint DEFAULT_LOCATION_POSITION = 0; +const GLuint DEFAULT_LOCATION_COLOUR = 1; +const GLuint DEFAULT_LOCATION_NORMAL = 2; +const GLuint DEFAULT_LOCATION_TEXCOORD = 3; + +const char DEFAULT_NAME_POSITION[] = "a_position"; +const char DEFAULT_NAME_COLOUR[] = "a_color"; +const char DEFAULT_NAME_NORMAL[] = "a_normal"; +const char DEFAULT_NAME_TEXCOORD[] = "a_texcoord"; + +//////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////// + +enum GlSlShaderType +{ + GlSlAnnotatedShader = 0, + GlSlFragmentShader = GL_FRAGMENT_SHADER, + GlSlVertexShader = GL_VERTEX_SHADER, + GlSlGeometryShader = 0x8DD9 /*GL_GEOMETRY_SHADER*/, + GlSlComputeShader = 0x91B9 /*GL_COMPUTE_SHADER*/ +}; + +class GlSlProgram +{ +public: + GlSlProgram(); + + //! Move Constructor + GlSlProgram(GlSlProgram&& tex); + + ~GlSlProgram(); + + bool AddShader( + GlSlShaderType shader_type, + const std::string& source_code, + const std::map& program_defines = std::map(), + const std::vector& search_path = std::vector() + ); + + bool AddShaderFromFile( + GlSlShaderType shader_type, + const std::string& filename, + const std::map& program_defines = std::map(), + const std::vector& search_path = std::vector() + ); + + bool Link(); + + // Remove all shaders from this program, and reload from files. + bool ReloadShaderFiles(); + + GLint GetAttributeHandle(const std::string& name); + GLint GetUniformHandle(const std::string& name); + + // Before setting uniforms, be sure to Bind() the GlSl program first. + void SetUniform(const std::string& name, int x); + void SetUniform(const std::string& name, int x1, int x2); + void SetUniform(const std::string& name, int x1, int x2, int x3); + void SetUniform(const std::string& name, int x1, int x2, int x3, int x4); + + void SetUniform(const std::string& name, float f); + void SetUniform(const std::string& name, float f1, float f2); + void SetUniform(const std::string& name, float f1, float f2, float f3); + void SetUniform(const std::string& name, float f1, float f2, float f3, float f4); + + void SetUniform(const std::string& name, Colour c); + + void SetUniform(const std::string& name, const OpenGlMatrix& m); + +#ifdef HAVE_EIGEN + void SetUniform(const std::string& name, const Eigen::Matrix3f& m); + void SetUniform(const std::string& name, const Eigen::Matrix4f& m); + void SetUniform(const std::string& name, const Eigen::Matrix3d& m); + void SetUniform(const std::string& name, const Eigen::Matrix4d& m); +#endif + +#if GL_VERSION_4_3 + GLint GetProgramResourceIndex(const std::string& name); + void SetShaderStorageBlock(const std::string& name, const int& bindingIndex); +#endif + + void Bind(); + void SaveBind(); + void Unbind(); + + + void BindPangolinDefaultAttribLocationsAndLink(); + + // Unlink all shaders from program + void ClearShaders(); + + GLint ProgramId() const { + return prog; + } + + bool Valid() const { + return ProgramId() != 0; + } + +protected: + struct ShaderFileOrCode + { + GlSlShaderType shader_type; + std::string filename; + std::string code; + std::map program_defines; + std::vector search_path; + }; + + + // Convenience method to load shader description + bool AddShaderFile(const ShaderFileOrCode &shader_file); + + std::string ParseIncludeFilename( + const std::string& location + ); + + std::string SearchIncludePath( + const std::string& filename, + const std::vector& search_path, + const std::string& current_path + ); + + bool AddPreprocessedShader( + GlSlShaderType shader_type, + const std::string& source_code, + const std::string& name_for_errors + ); + + void PreprocessGLSL( + std::istream& input, + std::ostream& output, + const std::map& program_defines, + const std::vector& search_path, + const std::string& current_path + ); + + // Split 'code' into several code blocks per shader type + // shader blocks in 'code' must be annotated with: + // @start vertex, @start fragment, @start geometry or @start compute + static std::map + SplitAnnotatedShaders(const std::string& code); + + bool linked; + std::vector shaders; + GLenum prog; + GLint prev_prog; + std::vector shader_files; +}; + +class GlSlUtilities +{ +public: + inline static GlSlProgram& OffsetAndScale(float offset, float scale) { + GlSlProgram& prog = Instance().prog_offsetscale; + prog.Bind(); + prog.SetUniform("offset", offset); + prog.SetUniform("scale", scale); + return prog; + } + + inline static GlSlProgram& Scale(float scale, float bias = 0.0f) { + GlSlProgram& prog = Instance().prog_scale; + prog.Bind(); + prog.SetUniform("scale", scale); + prog.SetUniform("bias", bias); + return prog; + } + + inline static void UseNone() + { + glUseProgram(0); + } + +protected: + static GlSlUtilities& Instance() { + // TODO: BUG: The GlSLUtilities instance needs to be tied + // to the OpenGL context, not the thread, or globally. +#ifndef PANGO_NO_THREADLOCAL + thread_local +#else + static +#endif + GlSlUtilities instance; + return instance; + } + + // protected constructor + GlSlUtilities() { + const char* source_scale = + "uniform float scale;" + "uniform float bias;" + "uniform sampler2D tex;" + "void main() {" + " vec2 uv = gl_TexCoord[0].st;" + " if(0.0 <= uv.x && uv.x <= 1.0 && 0.0 <= uv.y && uv.y <= 1.0) {" + " gl_FragColor = texture2D(tex,uv);" + " gl_FragColor.xyz *= scale;" + " gl_FragColor.xyz += vec3(bias,bias,bias);" + " }else{" + " float v = 0.1;" + " gl_FragColor.xyz = vec3(v,v,v);" + " }" + "}"; + prog_scale.AddShader(GlSlFragmentShader, source_scale); + prog_scale.Link(); + + const char* source_offsetscale = + "uniform float offset;" + "uniform float scale;" + "uniform sampler2D tex;" + "void main() {" + " vec2 uv = gl_TexCoord[0].st;" + " if(0.0 <= uv.x && uv.x <= 1.0 && 0.0 <= uv.y && uv.y <= 1.0) {" + " gl_FragColor = texture2D(tex,gl_TexCoord[0].st);" + " gl_FragColor.xyz += vec3(offset,offset,offset);" + " gl_FragColor.xyz *= scale;" + " }else{" + " float v = 0.1;" + " gl_FragColor.xyz = vec3(v,v,v);" + " }" + "}"; + prog_offsetscale.AddShader(GlSlFragmentShader, source_offsetscale); + prog_offsetscale.Link(); + } + + GlSlProgram prog_scale; + GlSlProgram prog_offsetscale; +}; + + +//////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////// + +inline bool IsLinkSuccessPrintLog(GLhandleARB prog) +{ + GLint status; + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if(status != GL_TRUE) { + pango_print_error("GLSL Program link failed: "); + const int PROGRAM_LOG_MAX_LEN = 10240; + char infolog[PROGRAM_LOG_MAX_LEN]; + GLsizei len; + glGetProgramInfoLog(prog, PROGRAM_LOG_MAX_LEN, &len, infolog); + if(len) { + pango_print_error("%s\n",infolog); + }else{ + pango_print_error("No details provided.\n"); + } + return false; + } + return true; +} + +inline bool IsCompileSuccessPrintLog(GLhandleARB shader, const std::string& name_for_errors) +{ + GLint status; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(status != GL_TRUE) { + pango_print_error("GLSL Shader compilation failed: "); + const int SHADER_LOG_MAX_LEN = 10240; + char infolog[SHADER_LOG_MAX_LEN]; + GLsizei len; + glGetShaderInfoLog(shader, SHADER_LOG_MAX_LEN, &len, infolog); + if(len) { + pango_print_error("%s:\n%s\n",name_for_errors.c_str(), infolog); + }else{ + pango_print_error("%s:\nNo details provided.\n",name_for_errors.c_str()); + } + return false; + } + return true; +} + +inline GlSlProgram::GlSlProgram() + : linked(false), prog(0), prev_prog(0) +{ +} + +//! Move Constructor +inline GlSlProgram::GlSlProgram(GlSlProgram&& o) + : linked(o.linked), shaders(o.shaders), prog(o.prog), prev_prog(o.prev_prog) +{ + o.prog = 0; +} + +inline GlSlProgram::~GlSlProgram() +{ + if(prog) { + ClearShaders(); + glDeleteProgram(prog); + } +} + +inline void PrintSourceCode(const std::string& src) +{ + std::stringstream ss(src); + std::string line; + + for(int linenum=1; std::getline(ss,line,'\n'); ++linenum) { + std::cout << linenum << ":\t" << line << std::endl; + } +} + +inline bool GlSlProgram::AddPreprocessedShader( + GlSlShaderType shader_type, + const std::string& source_code, + const std::string& name_for_errors +) { + if(!prog) { + prog = glCreateProgram(); + } + +// PrintSourceCode(source_code); + + GLhandleARB shader = glCreateShader(shader_type); + const char* source = source_code.c_str(); + glShaderSource(shader, 1, &source, NULL); + glCompileShader(shader); + bool success = IsCompileSuccessPrintLog(shader, name_for_errors); + if(success) { + glAttachShader(prog, shader); + shaders.push_back(shader); + linked = false; + } + return success; +} + +inline std::string GlSlProgram::ParseIncludeFilename(const std::string& location) +{ + size_t start = location.find_first_of("\"<"); + if(start != std::string::npos) { + size_t end = location.find_first_of("\">", start+1); + if(end != std::string::npos) { + return location.substr(start+1, end - start - 1); + } + } + throw std::runtime_error("GLSL Parser: Unable to parse include location " + location ); +} + +inline std::string GlSlProgram::SearchIncludePath( + const std::string& filename, + const std::vector& search_path, + const std::string& current_path +) { + if(FileExists(current_path + "/" + filename)) { + return current_path + "/" + filename; + }else{ + for(size_t i=0; i < search_path.size(); ++i) { + const std::string hypoth = search_path[i] + "/" + filename; + if( FileExists(hypoth) ) { + return hypoth; + } + } + } + return ""; +} + +inline void GlSlProgram::PreprocessGLSL( + std::istream& input, std::ostream& output, + const std::map& program_defines, + const std::vector &search_path, + const std::string ¤t_path +) { + const size_t MAXLINESIZE = 10240; + char line[MAXLINESIZE]; + + while(!input.eof()) { + // Take like from source + input.getline(line,MAXLINESIZE); + + // Transform + if( !strncmp(line, "#include", 8 ) ) { + // C++ / G3D style include directive + const std::string import_file = ParseIncludeFilename(line+8); + const std::string resolved_file = SearchIncludePath(import_file, search_path, current_path); + + std::ifstream ifs(resolved_file.c_str()); + if(ifs.good()) { + const std::string file_path = pangolin::PathParent(resolved_file); + PreprocessGLSL(ifs, output, program_defines, search_path, file_path); + }else{ + throw std::runtime_error("GLSL Parser: Unable to open " + import_file ); + } + }else if( !strncmp(line, "#expect", 7) ) { + // G3D style 'expect' directive, annotating expected preprocessor + // definition with document string + + // Consume whitespace before token + size_t token_start = 7; + while( std::isspace(line[token_start]) ) ++token_start; + + // Iterate over contigous charecters until \0 or whitespace + size_t token_end = token_start; + while( line[token_end] && !std::isspace(line[token_end]) ) ++token_end; + + std::string token(line+token_start, line+token_end); + std::map::const_iterator it = program_defines.find(token); + if( it == program_defines.end() ) { + pango_print_warn("Expected define missing (defaulting to 0): '%s'\n%s\n", token.c_str(), line + token_end ); + output << "#define " << token << " 0" << std::endl; + }else{ + output << "#define " << token << " " << it->second << std::endl; + } + }else{ + // Output directly + output << line << std::endl; + } + } +} + +inline void GlSlProgram::ClearShaders() +{ + // Remove and delete each shader + for(size_t i=0; i"; + + if(shader_file.shader_type == GlSlAnnotatedShader) { + const std::map split_progs = SplitAnnotatedShaders(code); + for(const auto& type_code : split_progs) { + if(!AddPreprocessedShader(type_code.first, type_code.second, input_name )) { + return false; + } + } + return true; + }else{ + return AddPreprocessedShader(shader_file.shader_type, code, input_name); + } +} + +inline bool GlSlProgram::AddShaderFromFile( + GlSlShaderType shader_type, + const std::string& filename, + const std::map& program_defines, + const std::vector& search_path +) { + ShaderFileOrCode shader_file = { + shader_type, + pangolin::PathExpand(filename), + std::string(), + program_defines, + search_path + }; + shader_files.push_back(shader_file); + return AddShaderFile(shader_file); +} + +inline bool GlSlProgram::AddShader( + GlSlShaderType shader_type, + const std::string& source_code, + const std::map& program_defines, + const std::vector& search_path +) { + ShaderFileOrCode shader_file = { + shader_type, + std::string(), + source_code, + program_defines, + search_path + }; + shader_files.push_back(shader_file); + return AddShaderFile(shader_file); +} + +inline bool GlSlProgram::ReloadShaderFiles() +{ + ClearShaders(); + + for(const auto& sf : shader_files) { + if(!AddShaderFile(sf)) { + return false; + } + } + + Link(); + return true; +} + +inline std::map +GlSlProgram::SplitAnnotatedShaders(const std::string& code) +{ + std::map ret; + + std::stringstream input(code); + std::stringstream output; + + const size_t MAXLINESIZE = 10240; + char line[MAXLINESIZE]; + + GlSlShaderType current_type = GlSlAnnotatedShader; + auto finish_block = [&](GlSlShaderType type){ + if(current_type != GlSlAnnotatedShader) { + ret[current_type] = output.str(); + } + output.str(std::string()); + current_type = type; + }; + + while(!input.eof()) { + // Take like from source + input.getline(line,MAXLINESIZE); + + // Transform + if( !strncmp(line, "@start", 6 ) ) { + const std::string str_shader_type = pangolin::Trim(std::string(line).substr(6)); + if(str_shader_type == "vertex") { + finish_block(GlSlVertexShader); + }else if(str_shader_type == "fragment") { + finish_block(GlSlFragmentShader); + }else if(str_shader_type == "geometry") { + finish_block(GlSlGeometryShader); + }else if(str_shader_type == "compute") { + finish_block(GlSlComputeShader); + } + }else{ + output << line << std::endl; + } + } + + finish_block(GlSlAnnotatedShader); + + return ret; +} + +inline bool GlSlProgram::Link() +{ + glLinkProgram(prog); + return IsLinkSuccessPrintLog(prog); +} + +inline void GlSlProgram::Bind() +{ + prev_prog = 0; + glUseProgram(prog); +} + +inline void GlSlProgram::SaveBind() +{ + glGetIntegerv(GL_CURRENT_PROGRAM, &prev_prog); + glUseProgram(prog); +} + +inline void GlSlProgram::Unbind() +{ + glUseProgram(prev_prog); +} + +inline GLint GlSlProgram::GetAttributeHandle(const std::string& name) +{ + return glGetAttribLocation(prog, name.c_str()); +} + +inline GLint GlSlProgram::GetUniformHandle(const std::string& name) +{ + return glGetUniformLocation(prog, name.c_str()); +} + +inline void GlSlProgram::SetUniform(const std::string& name, int x) +{ + glUniform1i( GetUniformHandle(name), x); +} + +inline void GlSlProgram::SetUniform(const std::string& name, int x1, int x2) +{ + glUniform2i( GetUniformHandle(name), x1, x2); +} + +inline void GlSlProgram::SetUniform(const std::string& name, int x1, int x2, int x3) +{ + glUniform3i( GetUniformHandle(name), x1, x2, x3); +} + +inline void GlSlProgram::SetUniform(const std::string& name, int x1, int x2, int x3, int x4) +{ + glUniform4i( GetUniformHandle(name), x1, x2, x3, x4); +} + +inline void GlSlProgram::SetUniform(const std::string& name, float f) +{ + glUniform1f( GetUniformHandle(name), f); +} + +inline void GlSlProgram::SetUniform(const std::string& name, float f1, float f2) +{ + glUniform2f( GetUniformHandle(name), f1,f2); +} + +inline void GlSlProgram::SetUniform(const std::string& name, float f1, float f2, float f3) +{ + glUniform3f( GetUniformHandle(name), f1,f2,f3); +} + +inline void GlSlProgram::SetUniform(const std::string& name, float f1, float f2, float f3, float f4) +{ + glUniform4f( GetUniformHandle(name), f1,f2,f3,f4); +} + +inline void GlSlProgram::SetUniform(const std::string& name, Colour c) +{ + glUniform4f( GetUniformHandle(name), c.r, c.g, c.b, c.a); +} + +inline void GlSlProgram::SetUniform(const std::string& name, const OpenGlMatrix& mat) +{ + // glUniformMatrix4dv seems to be crashing... + float m[16]; + for (int i = 0; i < 16; ++i) { + m[i] = (float)mat.m[i]; + } + glUniformMatrix4fv( GetUniformHandle(name), 1, GL_FALSE, m); +} + +#ifdef HAVE_EIGEN +inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix3f& m) +{ + glUniformMatrix3fv( GetUniformHandle(name), 1, GL_FALSE, m.data()); +} +inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix4f& m) +{ + glUniformMatrix4fv( GetUniformHandle(name), 1, GL_FALSE, m.data()); +} +inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix3d& m) +{ + glUniformMatrix3dv( GetUniformHandle(name), 1, GL_FALSE, m.data()); +} +inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix4d& m) +{ + glUniformMatrix4dv( GetUniformHandle(name), 1, GL_FALSE, m.data()); +} +#endif + +inline void GlSlProgram::BindPangolinDefaultAttribLocationsAndLink() +{ + glBindAttribLocation(prog, DEFAULT_LOCATION_POSITION, DEFAULT_NAME_POSITION); + glBindAttribLocation(prog, DEFAULT_LOCATION_COLOUR, DEFAULT_NAME_COLOUR); + glBindAttribLocation(prog, DEFAULT_LOCATION_NORMAL, DEFAULT_NAME_NORMAL); + glBindAttribLocation(prog, DEFAULT_LOCATION_TEXCOORD, DEFAULT_NAME_TEXCOORD); + Link(); +} + +#if GL_VERSION_4_3 +inline GLint GlSlProgram::GetProgramResourceIndex(const std::string& name) +{ + return glGetProgramResourceIndex(prog, GL_SHADER_STORAGE_BLOCK, name.c_str()); +} + +inline void GlSlProgram::SetShaderStorageBlock(const std::string& name, const int& bindingIndex) +{ + glShaderStorageBlockBinding(prog, GetProgramResourceIndex(name), bindingIndex); +} +#endif + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glstate.h b/thirdparty/Pangolin/include/pangolin/gl/glstate.h new file mode 100644 index 00000000..0757ba22 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glstate.h @@ -0,0 +1,220 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Vincent Mamo, Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +class GlState { + + class CapabilityState { + public: + + CapabilityState(GLenum cap, GLboolean enable) + : m_cap(cap), m_enable(enable) + { + + } + + void Apply() { + if(m_enable) { + ::glEnable(m_cap); + }else{ + ::glDisable(m_cap); + } + } + + void UnApply() { + if(m_enable) { + ::glDisable(m_cap); + }else{ + ::glEnable(m_cap); + } + } + + protected: + GLenum m_cap; + GLboolean m_enable; + }; + +public: + GlState() + : m_DepthMaskCalled(false), + m_ShadeModelCalled(false), + m_CullFaceCalled(false), + m_PointSizeCalled(false), + m_LineWidthCalled(false), + m_ColorMaskCalled(false), + m_ViewportCalled(false) + { + } + + ~GlState() { + // Restore original state + while (!m_history.empty()) { + m_history.top().UnApply(); + m_history.pop(); + } + + if (m_DepthMaskCalled) { + ::glDepthMask(m_OriginalDepthMask); + } + + if (m_ShadeModelCalled) { + ::glShadeModel(m_OriginalShadeModel); + } + + if (m_CullFaceCalled) { + ::glCullFace(m_OriginalCullFace); + } + + if(m_PointSizeCalled) { + ::glPointSize(m_OriginalPointSize); + } + + if(m_LineWidthCalled) { + ::glLineWidth(m_OriginalLineWidth); + } + + if (m_ColorMaskCalled) { + ::glColorMask(m_OriginalColorMask[0], m_OriginalColorMask[1], m_OriginalColorMask[2], m_OriginalColorMask[3]); + } + + if (m_ViewportCalled) { + ::glViewport(m_OriginalViewport[0], m_OriginalViewport[1], m_OriginalViewport[2], m_OriginalViewport[3]); + } + } + + static inline GLboolean IsEnabled(GLenum cap) + { + GLboolean curVal; + glGetBooleanv(cap, &curVal); + return curVal; + } + + inline void glEnable(GLenum cap) + { + if(!IsEnabled(cap)) { + m_history.push(CapabilityState(cap,true)); + ::glEnable(cap); + } + } + + inline void glDisable(GLenum cap) + { + if(IsEnabled(cap)) { + m_history.push(CapabilityState(cap,false)); + ::glDisable(cap); + } + } + + bool m_DepthMaskCalled; + GLboolean m_OriginalDepthMask; + inline void glDepthMask(GLboolean flag) + { + if(!m_DepthMaskCalled) { + m_DepthMaskCalled = true; + glGetBooleanv(GL_DEPTH_WRITEMASK, &m_OriginalDepthMask); + } + ::glDepthMask(flag); + } + + bool m_ShadeModelCalled; + GLint m_OriginalShadeModel; + inline void glShadeModel(GLint mode) + { + if(!m_ShadeModelCalled) { + m_ShadeModelCalled = true; + glGetIntegerv(GL_SHADE_MODEL, &m_OriginalShadeModel); + } + ::glShadeModel(mode); + } + + bool m_CullFaceCalled; + GLint m_OriginalCullFace; + void glCullFace(GLenum mode) + { + if(!m_ShadeModelCalled) { + m_ShadeModelCalled = true; + glGetIntegerv(GL_CULL_FACE_MODE, &m_OriginalCullFace); + } + ::glCullFace(mode); + } + + bool m_PointSizeCalled; + GLfloat m_OriginalPointSize; + void glPointSize(GLfloat size) + { + if(!m_PointSizeCalled) { + m_PointSizeCalled = true; + glGetFloatv(GL_POINT_SIZE, &m_OriginalPointSize); + } + ::glPointSize(size); + } + + bool m_LineWidthCalled; + GLfloat m_OriginalLineWidth; + void glLineWidth(GLfloat width) + { + if(!m_LineWidthCalled) { + m_LineWidthCalled = true; + glGetFloatv(GL_LINE_WIDTH, &m_OriginalLineWidth); + } + ::glLineWidth(width); + + } + + bool m_ColorMaskCalled; + GLboolean m_OriginalColorMask[4]; + inline void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) + { + if(!m_ColorMaskCalled) { + m_ColorMaskCalled = true; + glGetBooleanv(GL_COLOR_WRITEMASK, m_OriginalColorMask); + } + ::glColorMask(red, green, blue, alpha); + } + + bool m_ViewportCalled; + GLint m_OriginalViewport[4]; + inline void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) + { + if(!m_ViewportCalled) { + m_ViewportCalled = true; + glGetIntegerv(GL_VIEWPORT, m_OriginalViewport); + } + ::glViewport(x, y, width, height); + } + + std::stack m_history; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/gltext.h b/thirdparty/Pangolin/include/pangolin/gl/gltext.h new file mode 100644 index 00000000..1c8f0b27 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/gltext.h @@ -0,0 +1,98 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace pangolin { + +class PANGOLIN_EXPORT GlText +{ +public: + GlText(); + + GlText(const GlText& txt); + + GlText(const GlTexture& font_tex); + + void AddSpace(GLfloat s); + + // Add specified charector to this string. + void Add(unsigned char c, const GlChar& glc); + + // Clear text + void Clear(); + + // Render without transform in text-centric pixel coordinates + void Draw() const; + void DrawGlSl() const; + +#ifdef BUILD_PANGOLIN_GUI + // Render at (x,y,z)' in object coordinates, + // keeping text size and orientation constant + void Draw(GLfloat x, GLfloat y, GLfloat z = 0.0f) const; + + // Render at (x,y,z)' in window coordinates. + void DrawWindow(GLfloat x, GLfloat y, GLfloat z = 0.0f) const; +#endif // BUILD_PANGOLIN_GUI + + // Return text that this object signifies. + const std::string& Text() const { + return str; + } + + // Return width in pixels of this text. + GLfloat Width() const { + return width; + } + + // Return height in pixels of this text. + GLfloat Height() const { + return ymax; + } + + // Return height in pixels of this text, including under baseline + GLfloat FullHeight() const { + return ymax - ymin; + } + +//protected: + const GlTexture* tex; + std::string str; + GLfloat width; + GLfloat ymin; + GLfloat ymax; + + std::vector vs; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/gltexturecache.h b/thirdparty/Pangolin/include/pangolin/gl/gltexturecache.h new file mode 100644 index 00000000..f3ad3030 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/gltexturecache.h @@ -0,0 +1,116 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT TextureCache +{ +public: + static TextureCache& I(); + + GlTexture& GlTex(GLsizei w, GLsizei h, GLint internal_format, GLint glformat, GLenum gltype) + { + const long key = + (((long)internal_format)<<20) ^ + (((long)glformat)<<10) ^ gltype; + + // Lookup texture + std::shared_ptr& ptex = texture_map[key]; + if(!ptex) { + ptex = std::shared_ptr(new GlTexture()); + } + GlTexture& tex = *ptex; + + // Initialise if it didn't already exist or the size was too small + if(!tex.tid || tex.width < w || tex.height < h) { + tex.Reinitialise( + std::max(tex.width,w), std::max(tex.height,h), + internal_format, default_sampling_linear, 0, + glformat, gltype + ); + } + + return tex; + } + + template + GlTexture& GlTex(GLsizei w, GLsizei h) + { + return GlTex( w, h, + GlFormatTraits::glinternalformat, + GlFormatTraits::glformat, + GlFormatTraits::gltype + ); + } + +protected: + bool default_sampling_linear; + std::map > texture_map; + + // Protected constructor + TextureCache() + : default_sampling_linear(true) + { + } +}; + +template +void RenderToViewport(Image& image, bool flipx=false, bool flipy=false) +{ + // Retrieve texture that is at least as large as image and of appropriate type. + GlTexture& tex = TextureCache::I().GlTex(image.w, image.h); + tex.Upload(image.ptr,0,0, image.w, image.h, GlFormatTraits::glformat, GlFormatTraits::gltype); + tex.RenderToViewport(Viewport(0,0,image.w, image.h), flipx, flipy); +} + +// This method may dissapear in the future +inline void RenderToViewport( + Image& image, + const pangolin::GlPixFormat& fmt, + bool flipx=false, bool flipy=false, + bool linear_sampling = true +) { + pangolin::GlTexture& tex = pangolin::TextureCache::I().GlTex((GLsizei)image.w, (GLsizei)image.h, fmt.scalable_internal_format, fmt.glformat, fmt.gltype); + tex.Bind(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_sampling ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_sampling ? GL_LINEAR : GL_NEAREST); + tex.Upload(image.ptr,0,0, (GLsizei)image.w, (GLsizei)image.h, fmt.glformat, fmt.gltype); + tex.RenderToViewport(pangolin::Viewport(0,0,(GLint)image.w, (GLint)image.h), flipx, flipy); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/gl/glvbo.h b/thirdparty/Pangolin/include/pangolin/gl/glvbo.h new file mode 100644 index 00000000..546f6d59 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/gl/glvbo.h @@ -0,0 +1,225 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +namespace pangolin +{ + +//////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////// + +void MakeTriangleStripIboForVbo(GlBuffer& ibo, int w, int h); + +GlBuffer MakeTriangleStripIboForVbo(int w, int h); + +void RenderVbo(GlBuffer& vbo, GLenum mode = GL_POINTS); + +void RenderVboCbo(GlBuffer& vbo, GlBuffer& cbo, bool draw_color = true, GLenum mode = GL_POINTS); + +void RenderVboIbo(GlBuffer& vbo, GlBuffer& ibo, bool draw_mesh = true); + +void RenderVboIboCbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, bool draw_mesh = true, bool draw_color = true); + +void RenderVboIboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& nbo, bool draw_mesh = true, bool draw_normals = true); + +void RenderVboIboCboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, GlBuffer& nbo, bool draw_mesh = true, bool draw_color = true, bool draw_normals = true); + +//////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////// + +inline void MakeTriangleStripIboForVbo(GlBuffer& ibo, int w, int h) +{ + const int num_elements = w*(h-1)*2; + unsigned int* buffer = new unsigned int[num_elements]; + unsigned int* ptr = buffer; + + for(int y=0; y < (h-1);) + { + for(int x=0; x=(h-1)) break; + for(int x=w-1; x>=0; --x) { + (*ptr++) = y*w+x; + (*ptr++) = (y+1)*w+x; + } + ++y; + } + + ibo.Reinitialise(GlElementArrayBuffer, num_elements, GL_UNSIGNED_INT, 1, GL_STATIC_DRAW ); + ibo.Upload(buffer, sizeof(unsigned int)*num_elements ); + + delete[] buffer; +} + +inline GlBuffer MakeTriangleStripIboForVbo(int w, int h) +{ + GlBuffer ibo; + MakeTriangleStripIboForVbo(ibo,w,h); + return ibo; +} + +inline void RenderVbo(GlBuffer& vbo, GLenum mode) +{ + vbo.Bind(); + glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0); + glEnableClientState(GL_VERTEX_ARRAY); + + glDrawArrays(mode, 0, vbo.num_elements); + + glDisableClientState(GL_VERTEX_ARRAY); + vbo.Unbind(); +} + +inline void RenderVboCbo(GlBuffer& vbo, GlBuffer& cbo, bool draw_color, GLenum mode ) +{ + if(draw_color) { + cbo.Bind(); + glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0); + glEnableClientState(GL_COLOR_ARRAY); + } + + RenderVbo(vbo,mode); + + if(draw_color) { + glDisableClientState(GL_COLOR_ARRAY); + cbo.Unbind(); + } +} + +inline void RenderVboIbo(GlBuffer& vbo, GlBuffer& ibo, bool draw_mesh) +{ + vbo.Bind(); + glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0); + glEnableClientState(GL_VERTEX_ARRAY); + + if(draw_mesh) { + ibo.Bind(); + glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0); + ibo.Unbind(); + }else{ + glDrawArrays(GL_POINTS, 0, vbo.num_elements); + } + + glDisableClientState(GL_VERTEX_ARRAY); + vbo.Unbind(); +} + +inline void RenderVboIboCbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, bool draw_mesh, bool draw_color ) +{ + if(draw_color) { + cbo.Bind(); + glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0); + glEnableClientState(GL_COLOR_ARRAY); + } + + RenderVboIbo(vbo,ibo,draw_mesh); + + if(draw_color) { + glDisableClientState(GL_COLOR_ARRAY); + cbo.Unbind(); + } +} + +inline void RenderVboIboCboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, GlBuffer& nbo, bool draw_mesh, bool draw_color, bool draw_normals) +{ + if(draw_color) { + cbo.Bind(); + glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0); + glEnableClientState(GL_COLOR_ARRAY); + } + + if(draw_normals) { + nbo.Bind(); + glNormalPointer(nbo.datatype, (GLsizei)(nbo.count_per_element * GlDataTypeBytes(nbo.datatype)),0); + glEnableClientState(GL_NORMAL_ARRAY); + } + + vbo.Bind(); + glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0); + glEnableClientState(GL_VERTEX_ARRAY); + + if(draw_mesh) { + ibo.Bind(); + glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0); + ibo.Unbind(); + }else{ + glDrawArrays(GL_POINTS, 0, vbo.num_elements); + } + + if(draw_color) { + glDisableClientState(GL_COLOR_ARRAY); + cbo.Unbind(); + } + + if(draw_normals) { + glDisableClientState(GL_NORMAL_ARRAY); + nbo.Unbind(); + } + + glDisableClientState(GL_VERTEX_ARRAY); + vbo.Unbind(); +} + +inline void RenderVboIboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& nbo, bool draw_mesh, bool draw_normals) +{ + vbo.Bind(); + glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0); + glEnableClientState(GL_VERTEX_ARRAY); + + if(draw_normals) { + nbo.Bind(); + glNormalPointer(nbo.datatype, (GLsizei)(nbo.count_per_element * GlDataTypeBytes(nbo.datatype)), 0); + glEnableClientState(GL_NORMAL_ARRAY); + } + + if(draw_mesh) { + ibo.Bind(); + glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0); + ibo.Unbind(); + }else{ + glDrawArrays(GL_POINTS, 0, vbo.num_elements); + } + + if(draw_normals) { + glDisableClientState(GL_NORMAL_ARRAY); + nbo.Unbind(); + } + + glDisableClientState(GL_VERTEX_ARRAY); + vbo.Unbind(); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/handler/handler.h b/thirdparty/Pangolin/include/pangolin/handler/handler.h new file mode 100644 index 00000000..4e1b3267 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/handler/handler.h @@ -0,0 +1,116 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files +#define USE_EIGEN +#endif + +#ifdef USE_EIGEN +#include +#endif + +#ifdef _OSX_ +#define PANGO_DFLT_HANDLER3D_ZF (1.0f/50.0f) +#else +#define PANGO_DFLT_HANDLER3D_ZF (1.0f/10.0f) +#endif + +namespace pangolin +{ + +// Forward declarations +struct View; + +/// Input Handler base class. +/// Virtual methods which recurse into sub-displays. +struct PANGOLIN_EXPORT Handler +{ + virtual ~Handler() {} + virtual void Keyboard(View&, unsigned char key, int x, int y, bool pressed); + virtual void Mouse(View&, MouseButton button, int x, int y, bool pressed, int button_state); + virtual void MouseMotion(View&, int x, int y, int button_state); + virtual void PassiveMouseMotion(View&, int x, int y, int button_state); + virtual void Special(View&, InputSpecial inType, float x, float y, float p1, float p2, float p3, float p4, int button_state); +}; + +struct PANGOLIN_EXPORT HandlerScroll : Handler +{ + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int button_state); + void Special(View&, InputSpecial inType, float x, float y, float p1, float p2, float p3, float p4, int button_state); +}; + +struct PANGOLIN_EXPORT Handler3D : Handler +{ + Handler3D(OpenGlRenderState& cam_state, AxisDirection enforce_up=AxisNone, float trans_scale=0.01f, float zoom_fraction= PANGO_DFLT_HANDLER3D_ZF); + + virtual bool ValidWinDepth(GLprecision depth); + virtual void PixelUnproject( View& view, GLprecision winx, GLprecision winy, GLprecision winz, GLprecision Pc[3]); + virtual void GetPosNormal(View& view, int x, int y, GLprecision p[3], GLprecision Pw[3], GLprecision Pc[3], GLprecision nw[3], GLprecision default_z = 1.0); + + void Keyboard(View&, unsigned char key, int x, int y, bool pressed); + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int button_state); + void MouseMotion(View&, int x, int y, int button_state); + void Special(View&, InputSpecial inType, float x, float y, float p1, float p2, float p3, float p4, int button_state); + +#ifdef USE_EIGEN + // Return selected point in world coordinates + inline Eigen::Vector3d Selected_P_w() const { + return Eigen::Map>(Pw).cast(); + } +#endif + inline int KeyState() const{ + return funcKeyState; + } + +protected: + OpenGlRenderState* cam_state; + const static int hwin = 8; + AxisDirection enforce_up; + float tf; // translation factor + float zf; // zoom fraction + CameraSpec cameraspec; + GLprecision last_z; + float last_pos[2]; + GLprecision rot_center[3]; + + GLprecision p[3]; + GLprecision Pw[3]; + GLprecision Pc[3]; + GLprecision n[3]; + + int funcKeyState; +}; + +static Handler StaticHandler; +static HandlerScroll StaticHandlerScroll; + +} diff --git a/thirdparty/Pangolin/include/pangolin/handler/handler_enums.h b/thirdparty/Pangolin/include/pangolin/handler/handler_enums.h new file mode 100644 index 00000000..389040ff --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/handler/handler_enums.h @@ -0,0 +1,94 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +namespace pangolin +{ + +// Supported Key modifiers for GlobalKeyPressCallback. +// e.g. PANGO_CTRL + 'r', PANGO_SPECIAL + PANGO_KEY_RIGHT, etc. +const int PANGO_SPECIAL = 128; +const int PANGO_CTRL = -96; +const int PANGO_OPTN = 132; + +// Ordinary keys +const int PANGO_KEY_TAB = 9; +const int PANGO_KEY_ESCAPE = 27; + +// Special Keys (same as GLUT_ defines) +const int PANGO_KEY_F1 = 1; +const int PANGO_KEY_F2 = 2; +const int PANGO_KEY_F3 = 3; +const int PANGO_KEY_F4 = 4; +const int PANGO_KEY_F5 = 5; +const int PANGO_KEY_F6 = 6; +const int PANGO_KEY_F7 = 7; +const int PANGO_KEY_F8 = 8; +const int PANGO_KEY_F9 = 9; +const int PANGO_KEY_F10 = 10; +const int PANGO_KEY_F11 = 11; +const int PANGO_KEY_F12 = 12; +const int PANGO_KEY_LEFT = 100; +const int PANGO_KEY_UP = 101; +const int PANGO_KEY_RIGHT = 102; +const int PANGO_KEY_DOWN = 103; +const int PANGO_KEY_PAGE_UP = 104; +const int PANGO_KEY_PAGE_DOWN = 105; +const int PANGO_KEY_HOME = 106; +const int PANGO_KEY_END = 107; +const int PANGO_KEY_INSERT = 108; + +enum MouseButton +{ + MouseButtonLeft = 1, + MouseButtonMiddle = 2, + MouseButtonRight = 4, + MouseWheelUp = 8, + MouseWheelDown = 16, + MouseWheelRight = 32, + MouseWheelLeft = 64, +}; + +enum KeyModifier +{ + KeyModifierShift = 1<<16, + KeyModifierCtrl = 1<<17, + KeyModifierAlt = 1<<18, + KeyModifierCmd = 1<<19, + KeyModifierFnc = 1<<20 +}; + +enum InputSpecial +{ + InputSpecialScroll, + InputSpecialZoom, + InputSpecialRotate, + InputSpecialTablet +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/handler/handler_glbuffer.h b/thirdparty/Pangolin/include/pangolin/handler/handler_glbuffer.h new file mode 100644 index 00000000..3d984f1a --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/handler/handler_glbuffer.h @@ -0,0 +1,48 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef HANDLER_GLBUFFER_H +#define HANDLER_GLBUFFER_H + +#include +#include + +namespace pangolin +{ + +struct Handler3DFramebuffer : public pangolin::Handler3D +{ + Handler3DFramebuffer(GlFramebuffer& fb, pangolin::OpenGlRenderState& cam_state, pangolin::AxisDirection enforce_up=pangolin::AxisNone, float trans_scale=0.01f); + void GetPosNormal(pangolin::View& view, int x, int y, GLprecision p[3], GLprecision Pw[3], GLprecision Pc[3], GLprecision /*n*/[3], GLprecision default_z); + +protected: + GlFramebuffer& fb; +}; + +} + +#endif // HANDLER_GLBUFFER_H diff --git a/thirdparty/Pangolin/include/pangolin/handler/handler_image.h b/thirdparty/Pangolin/include/pangolin/handler/handler_image.h new file mode 100644 index 00000000..00412788 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/handler/handler_image.h @@ -0,0 +1,162 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace pangolin +{ + +class ImageViewHandler : public Handler +{ +public: + struct EventData { + EventData(View& v, ImageViewHandler& h) : view(v), handler(h) {} + View& view; + ImageViewHandler& handler; + }; + + struct OnSelectionEventData : public EventData { + OnSelectionEventData(View& v, ImageViewHandler& h, bool dragging) + : EventData(v,h), dragging(dragging) {} + bool dragging; + }; + + typedef std::function OnSelectionCallbackFn; + + // Default constructor: User must call SetDimensions() once image dimensions are known. + // Default range is [0,1] in x and y. + ImageViewHandler(); + + // View ranges store extremes of image (boundary of pixels) + // in 'discrete' coords, where 0,0 is center of top-left pixel. + ImageViewHandler(size_t w, size_t h); + + void SetDimensions(size_t w, size_t h); + + void UpdateView(); + + void glSetViewOrtho(); + + void glRenderTexture(pangolin::GlTexture& tex); + void glRenderTexture(GLuint tex, GLint width, GLint height); + + void glRenderOverlay(); + + void ScreenToImage(Viewport& v, float xpix, float ypix, float& ximg, float& yimg); + + void ImageToScreen(Viewport& v, float ximg, float yimg, float& xpix, float& ypix); + + bool UseNN() const; + + bool& UseNN(); + + bool& FlipTextureX(); + + bool& FlipTextureY(); + + pangolin::XYRangef& GetViewToRender(); + + float GetViewScale(); + + pangolin::XYRangef& GetView(); + + pangolin::XYRangef& GetDefaultView(); + + pangolin::XYRangef& GetSelection(); + + void GetHover(float& x, float& y); + + void SetView(const pangolin::XYRangef& range); + + void SetViewSmooth(const pangolin::XYRangef& range); + + void ScrollView(float x, float y); + + void ScrollViewSmooth(float x, float y); + + void ScaleView(float x, float y, float cx, float cy); + + void ScaleViewSmooth(float x, float y, float cx, float cy); + + void ResetView(); + + /////////////////////////////////////////////////////// + /// pangolin::Handler + /////////////////////////////////////////////////////// + + void Keyboard(View&, unsigned char key, int /*x*/, int /*y*/, bool pressed) override; + + void Mouse(View& view, pangolin::MouseButton button, int x, int y, bool pressed, int button_state) override; + + void MouseMotion(View& view, int x, int y, int button_state) override; + + void PassiveMouseMotion(View&, int /*x*/, int /*y*/, int /*button_state*/) override; + + void Special(View& view, pangolin::InputSpecial inType, float x, float y, float p1, float p2, float /*p3*/, float /*p4*/, int /*button_state*/) override; + + /////////////////////////////////////////////////////// + /// Callbacks + /////////////////////////////////////////////////////// + + OnSelectionCallbackFn OnSelectionCallback; + +protected: + void FixSelection(XYRangef& sel); + + void AdjustScale(); + + void AdjustTranslation(); + + static ImageViewHandler* to_link; + static float animate_factor; + + ImageViewHandler* linked_view_handler; + + pangolin::XYRangef rview_default; + pangolin::XYRangef rview_max; + pangolin::XYRangef rview; + pangolin::XYRangef target; + pangolin::XYRangef selection; + + float hover_img[2]; + int last_mouse_pos[2]; + + bool use_nn; + bool flipTextureX; + bool flipTextureY; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/copy.h b/thirdparty/Pangolin/include/pangolin/image/copy.h new file mode 100644 index 00000000..160fa6b9 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/copy.h @@ -0,0 +1,45 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +namespace pangolin { + +// Hold a reference to an object to be copied +template +struct CopyObject { + CopyObject(const T& obj) : obj(obj) { } + const T& obj; +}; + +// Return copy wrapper for assignment to another object. +template +typename pangolin::CopyObject Copy(const T& obj) { + return typename pangolin::CopyObject(obj); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/image.h b/thirdparty/Pangolin/include/pangolin/image/image.h new file mode 100644 index 00000000..098638ae --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/image.h @@ -0,0 +1,428 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +#ifdef PANGO_ENABLE_BOUNDS_CHECKS +# define PANGO_BOUNDS_ASSERT(...) PANGO_ENSURE(##__VA_ARGS__) +#else +# define PANGO_BOUNDS_ASSERT(...) ((void)0) +#endif + +// Allow user defined macro to be inserted into Image class. +#ifndef PANGO_EXTENSION_IMAGE +# define PANGO_EXTENSION_IMAGE +#endif + +namespace pangolin +{ + +// Simple image wrapper +template +struct Image +{ + using PixelType = T; + + inline Image() + : pitch(0), ptr(0), w(0), h(0) + { + } + + inline Image(T* ptr, size_t w, size_t h, size_t pitch) + : pitch(pitch), ptr(ptr), w(w), h(h) + { + } + + + PANGO_HOST_DEVICE inline + size_t SizeBytes() const + { + return pitch * h; + } + + PANGO_HOST_DEVICE inline + size_t Area() const + { + return w * h; + } + + PANGO_HOST_DEVICE inline + bool IsValid() const + { + return ptr != 0; + } + + PANGO_HOST_DEVICE inline + bool IsContiguous() const + { + return w*sizeof(T) == pitch; + } + + ////////////////////////////////////////////////////// + // Iterators + ////////////////////////////////////////////////////// + + PANGO_HOST_DEVICE inline + T* begin() + { + return ptr; + } + + PANGO_HOST_DEVICE inline + T* end() + { + return RowPtr(h-1) + w; + } + + PANGO_HOST_DEVICE inline + const T* begin() const + { + return ptr; + } + + PANGO_HOST_DEVICE inline + const T* end() const + { + return RowPtr(h-1) + w; + } + + PANGO_HOST_DEVICE inline + size_t size() const + { + return w*h; + } + + ////////////////////////////////////////////////////// + // Image transforms + ////////////////////////////////////////////////////// + + template + PANGO_HOST_DEVICE inline + void Transform(UnaryOperation unary_op) + { + PANGO_ASSERT(IsValid()); + + for(size_t y=0; y < h; ++y) { + T* el = RowPtr(y); + const T* el_end = el+w; + for( ; el != el_end; ++el) { + *el = unary_op(*el); + } + } + } + + PANGO_HOST_DEVICE inline + void Fill(const T& val) + { + Transform( [&](const T&) {return val;} ); + } + + PANGO_HOST_DEVICE inline + void Replace(const T& oldval, const T& newval) + { + Transform( [&](const T& val) { + return (val == oldval) ? newval : val; + }); + } + + inline + void Memset(unsigned char v = 0) + { + PANGO_ASSERT(IsValid()); + if(IsContiguous()) { + ::pangolin::Memset((char*)ptr, v, pitch*h); + }else{ + for(size_t y=0; y < h; ++y) { + ::pangolin::Memset((char*)RowPtr(y), v, pitch); + } + } + } + + inline + void CopyFrom(const Image& img) + { + if(IsValid() && img.IsValid()) { + PANGO_ASSERT(w >= img.w && h >= img.h); + PitchedCopy((char*)ptr,pitch,(char*)img.ptr,img.pitch, std::min(img.w,w)*sizeof(T), std::min(img.h,h) ); + }else if( img.IsValid() != IsValid() ){ + PANGO_ASSERT(false && "Cannot copy from / to an unasigned image." ); + } + } + + ////////////////////////////////////////////////////// + // Reductions + ////////////////////////////////////////////////////// + + template + PANGO_HOST_DEVICE inline + T Accumulate(const T init, BinaryOperation binary_op) + { + PANGO_ASSERT(IsValid()); + + T val = init; + for(size_t y=0; y < h; ++y) { + T* el = RowPtr(y); + const T* el_end = el+w; + for(; el != el_end; ++el) { + val = binary_op(val, *el); + } + } + return val; + } + + std::pair MinMax() const + { + PANGO_ASSERT(IsValid()); + + std::pair minmax(std::numeric_limits::max(), std::numeric_limits::lowest()); + for(size_t r=0; r < h; ++r) { + const T* ptr = RowPtr(r); + const T* end = ptr + w; + while( ptr != end) { + minmax.first = std::min(*ptr, minmax.first); + minmax.second = std::max(*ptr, minmax.second); + ++ptr; + } + } + return minmax; + } + + template + Tout Sum() const + { + return Accumulate((T)0, [](const T& lhs, const T& rhs){ return lhs + rhs; }); + } + + template + Tout Mean() const + { + return Sum() / Area(); + } + + + ////////////////////////////////////////////////////// + // Direct Pixel Access + ////////////////////////////////////////////////////// + + PANGO_HOST_DEVICE inline + T* RowPtr(size_t y) + { + return (T*)((unsigned char*)(ptr) + y*pitch); + } + + PANGO_HOST_DEVICE inline + const T* RowPtr(size_t y) const + { + return (T*)((unsigned char*)(ptr) + y*pitch); + } + + PANGO_HOST_DEVICE inline + T& operator()(size_t x, size_t y) + { + PANGO_BOUNDS_ASSERT( InBounds(x,y) ); + return RowPtr(y)[x]; + } + + PANGO_HOST_DEVICE inline + const T& operator()(size_t x, size_t y) const + { + PANGO_BOUNDS_ASSERT( InBounds(x,y) ); + return RowPtr(y)[x]; + } + + template + PANGO_HOST_DEVICE inline + T& operator()(const TVec& p) + { + PANGO_BOUNDS_ASSERT( InBounds(p[0],p[1]) ); + return RowPtr(p[1])[p[0]]; + } + + template + PANGO_HOST_DEVICE inline + const T& operator()(const TVec& p) const + { + PANGO_BOUNDS_ASSERT( InBounds(p[0],p[1]) ); + return RowPtr(p[1])[p[0]]; + } + + PANGO_HOST_DEVICE inline + T& operator[](size_t ix) + { + PANGO_BOUNDS_ASSERT( InImage(ptr+ix) ); + return ptr[ix]; + } + + PANGO_HOST_DEVICE inline + const T& operator[](size_t ix) const + { + PANGO_BOUNDS_ASSERT( InImage(ptr+ix) ); + return ptr[ix]; + } + + ////////////////////////////////////////////////////// + // Bounds Checking + ////////////////////////////////////////////////////// + + PANGO_HOST_DEVICE + bool InImage(const T* ptest) const + { + return ptr <= ptest && ptest < RowPtr(h); + } + + PANGO_HOST_DEVICE inline + bool InBounds(int x, int y) const + { + return 0 <= x && x < (int)w && 0 <= y && y < (int)h; + } + + PANGO_HOST_DEVICE inline + bool InBounds(float x, float y, float border) const + { + return border <= x && x < (w-border) && border <= y && y < (h-border); + } + + template + PANGO_HOST_DEVICE inline + bool InBounds( const TVec& p, const TBorder border = (TBorder)0 ) const + { + return border <= p[0] && p[0] < ((int)w - border) && border <= p[1] && p[1] < ((int)h - border); + } + + ////////////////////////////////////////////////////// + // Obtain slices / subimages + ////////////////////////////////////////////////////// + + PANGO_HOST_DEVICE inline + const Image SubImage(size_t x, size_t y, size_t width, size_t height) const + { + PANGO_ASSERT( (x+width) <= w && (y+height) <= h); + return Image( RowPtr(y)+x, width, height, pitch); + } + + PANGO_HOST_DEVICE inline + Image SubImage(size_t x, size_t y, size_t width, size_t height) + { + PANGO_ASSERT( (x+width) <= w && (y+height) <= h); + return Image( RowPtr(y)+x, width, height, pitch); + } + + PANGO_HOST_DEVICE inline + const Image Row(int y) const + { + return SubImage(0,y,w,1); + } + + PANGO_HOST_DEVICE inline + Image Row(int y) + { + return SubImage(0,y,w,1); + } + + PANGO_HOST_DEVICE inline + const Image Col(int x) const + { + return SubImage(x,0,1,h); + } + + PANGO_HOST_DEVICE inline + Image Col(int x) + { + return SubImage(x,0,1,h); + } + + ////////////////////////////////////////////////////// + // Data mangling + ////////////////////////////////////////////////////// + + template + PANGO_HOST_DEVICE inline + Image Reinterpret() const + { + PANGO_ASSERT(sizeof(TRecast) == sizeof(T), "sizeof(TRecast) must match sizeof(T): % != %", sizeof(TRecast), sizeof(T) ); + return UnsafeReinterpret(); + } + + template + PANGO_HOST_DEVICE inline + Image UnsafeReinterpret() const + { + return Image((TRecast*)ptr,w,h,pitch); + } + + ////////////////////////////////////////////////////// + // Deprecated methods + ////////////////////////////////////////////////////// + +// PANGOLIN_DEPRECATED inline + Image(size_t w, size_t h, size_t pitch, T* ptr) + : pitch(pitch), ptr(ptr), w(w), h(h) + { + } + + // Use RAII/move aware pangolin::ManagedImage instead +// PANGOLIN_DEPRECATED inline + void Dealloc() + { + if(ptr) { + ::operator delete(ptr); + ptr = nullptr; + } + } + + // Use RAII/move aware pangolin::ManagedImage instead +// PANGOLIN_DEPRECATED inline + void Alloc(size_t w, size_t h, size_t pitch) + { + Dealloc(); + this->w = w; + this->h = h; + this->pitch = pitch; + this->ptr = (T*)::operator new(h*pitch); + } + + ////////////////////////////////////////////////////// + // Data members + ////////////////////////////////////////////////////// + + size_t pitch; + T* ptr; + size_t w; + size_t h; + + PANGO_EXTENSION_IMAGE +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/image_convert.h b/thirdparty/Pangolin/include/pangolin/image/image_convert.h new file mode 100644 index 00000000..36ae99f5 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/image_convert.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace pangolin +{ + +template +void ImageConvert(Image& dst, const Image& src, To scale = 1.0) +{ + for(unsigned int y = 0; y < dst.h; ++y) + { + const T* prs = src.RowPtr(y); + To* prd = dst.RowPtr(y); + for(unsigned int x = 0; x < dst.w; ++x) + { + *(prd++) = scale * ComponentCast::cast(*(prs++)); + } + } +} + +template +ManagedImage ImageConvert(const Image& src, To scale = 1.0) +{ + ManagedImage dst(src.w, src.h); + ImageConvert(dst,src,scale); + return dst; +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/image_io.h b/thirdparty/Pangolin/include/pangolin/image/image_io.h new file mode 100644 index 00000000..fcc594bd --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/image_io.h @@ -0,0 +1,65 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include + +namespace pangolin { + +PANGOLIN_EXPORT +TypedImage LoadImage(std::istream& in, ImageFileType file_type); + +PANGOLIN_EXPORT +TypedImage LoadImage(const std::string& filename, ImageFileType file_type); + +PANGOLIN_EXPORT +TypedImage LoadImage(const std::string& filename); + +PANGOLIN_EXPORT +TypedImage LoadImage(const std::string& filename, const PixelFormat& raw_fmt, size_t raw_width, size_t raw_height, size_t raw_pitch); + +/// Quality \in [0..100] for lossy formats +PANGOLIN_EXPORT +void SaveImage(const Image& image, const pangolin::PixelFormat& fmt, std::ostream& out, ImageFileType file_type, bool top_line_first = true, float quality = 100.0f); + +/// Quality \in [0..100] for lossy formats +PANGOLIN_EXPORT +void SaveImage(const Image& image, const pangolin::PixelFormat& fmt, const std::string& filename, ImageFileType file_type, bool top_line_first = true, float quality = 100.0f); + +/// Quality \in [0..100] for lossy formats +PANGOLIN_EXPORT +void SaveImage(const Image& image, const pangolin::PixelFormat& fmt, const std::string& filename, bool top_line_first = true, float quality = 100.0f); + +/// Quality \in [0..100] for lossy formats +PANGOLIN_EXPORT +void SaveImage(const TypedImage& image, const std::string& filename, bool top_line_first = true, float quality = 100.0f); + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/image_utils.h b/thirdparty/Pangolin/include/pangolin/image/image_utils.h new file mode 100644 index 00000000..92b59848 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/image_utils.h @@ -0,0 +1,185 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace pangolin +{ + +namespace internal +{ + +template +std::pair GetMinMax(const Image& img, size_t channels) +{ + const size_t max_channels = 3; + const size_t colour_channels = std::min(channels, max_channels); + std::pair chan_mm[max_channels]; + for(size_t c = 0; c < max_channels; ++c) + { + chan_mm[c].first = +std::numeric_limits::max(); + chan_mm[c].second = -std::numeric_limits::max(); + } + + for(size_t y = 0; y < img.h; ++y) + { + T* pix = (T*)((char*)img.ptr + y * img.pitch); + for(size_t x = 0; x < img.w; ++x) + { + for(size_t c = 0; c < colour_channels; ++c) + { + if(pix[c] < chan_mm[c].first) + chan_mm[c].first = (float)pix[c]; + if(pix[c] > chan_mm[c].second) + chan_mm[c].second = (float)pix[c]; + } + + pix += channels; + } + } + + // Find min / max of all channels, ignoring 4th alpha channel + std::pair mm = chan_mm[0]; + for(size_t c = 1; c < colour_channels; ++c) + { + mm.first = std::min(mm.first, chan_mm[c].first); + mm.second = std::max(mm.second, chan_mm[c].second); + } + + return mm; +} + +template +pangolin::Image GetImageRoi( pangolin::Image img, size_t channels, const pangolin::XYRangei& roi ) +{ + return pangolin::Image( + img.RowPtr(std::min(roi.y.min,roi.y.max)) + channels*std::min(roi.x.min,roi.x.max), + roi.x.AbsSize(), roi.y.AbsSize(), + img.pitch + ); +} + +template +std::pair GetOffsetScale(const pangolin::Image& img, size_t channels, float type_max, float format_max) +{ + // Find min / max of all channels, ignoring 4th alpha channel + const std::pair mm = internal::GetMinMax(img,channels); + const float type_scale = format_max / type_max; + const float offset = -type_scale* mm.first; + const float scale = type_max / (mm.second - mm.first); + return std::pair(offset, scale); +} + +template +float GetScaleOnly(const pangolin::Image& img, size_t channels, float type_max, float /*format_max*/) +{ + // Find min / max of all channels, ignoring 4th alpha channel + const std::pair mm = internal::GetMinMax(img,channels); + const float scale = type_max / mm.second; + return scale; +} + +} // internal + +inline std::pair GetMinMax( + const Image& img, + XYRangei iroi, const GlPixFormat& glfmt +) { + using namespace internal; + + iroi.Clamp(0, (int)img.w - 1, 0, (int)img.h - 1); + + const size_t num_channels = pangolin::GlFormatChannels(glfmt.glformat); + + if(glfmt.gltype == GL_UNSIGNED_BYTE) { + return GetMinMax(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels); + } else if(glfmt.gltype == GL_UNSIGNED_SHORT) { + return GetMinMax(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels); + } else if(glfmt.gltype == GL_FLOAT) { + return GetMinMax(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels); + } else if(glfmt.gltype == GL_DOUBLE) { + return GetMinMax(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels); + } else { + return std::pair(std::numeric_limits::max(), std::numeric_limits::lowest()); + } +} + +inline std::pair GetOffsetScale( + const pangolin::Image& img, + pangolin::XYRangei iroi, const pangolin::GlPixFormat& glfmt +) { + using namespace internal; + + iroi.Clamp(0, (int)img.w-1, 0, (int)img.h-1 ); + + const size_t num_channels = pangolin::GlFormatChannels(glfmt.glformat); + + if(glfmt.gltype == GL_UNSIGNED_BYTE) { + return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 255.0f, 1.0f); + }else if(glfmt.gltype == GL_UNSIGNED_SHORT) { + return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 65535.0f, 1.0f); + }else if(glfmt.gltype == GL_FLOAT) { + return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 1.0f, 1.0f); + }else if(glfmt.gltype == GL_DOUBLE) { + return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 1.0f, 1.0f); + }else{ + return std::pair(0.0f, 1.0f); + } +} + +inline float GetScaleOnly( + const pangolin::Image& img, + pangolin::XYRangei iroi, const pangolin::GlPixFormat& glfmt +) { + using namespace internal; + + iroi.Clamp(0, (int)img.w-1, 0, (int)img.h-1 ); + + const size_t num_channels = pangolin::GlFormatChannels(glfmt.glformat); + + if(glfmt.gltype == GL_UNSIGNED_BYTE) { + return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 255.0f, 1.0f); + }else if(glfmt.gltype == GL_UNSIGNED_SHORT) { + return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 65535.0f, 1.0f); + }else if(glfmt.gltype == GL_FLOAT) { + return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 1.0f, 1.0f); + }else if(glfmt.gltype == GL_DOUBLE) { + return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret(), num_channels, iroi), num_channels, 1.0f, 1.0f); + }else{ + return 1.0f; + } +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/managed_image.h b/thirdparty/Pangolin/include/pangolin/image/managed_image.h new file mode 100644 index 00000000..dd21c43e --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/managed_image.h @@ -0,0 +1,175 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin { + +template using DefaultImageAllocator = std::allocator; + +// Image that manages it's own memory, storing a strong pointer to it's memory +template > +class ManagedImage : public Image +{ +public: + // Destructor + inline + ~ManagedImage() + { + Deallocate(); + } + + // Null image + inline + ManagedImage() + { + } + + // Row image + inline + ManagedImage(size_t w) + : Image( + Allocator().allocate(w), + w, 1, w*sizeof(T) + ) + { + } + + inline + ManagedImage(size_t w, size_t h) + : Image( + Allocator().allocate(w*h), + w, h, w*sizeof(T) + ) + { + } + + inline + ManagedImage(size_t w, size_t h, size_t pitch_bytes) + : Image( + Allocator().allocate( (h*pitch_bytes) / sizeof(T) + 1), + w, h, pitch_bytes + ) + { + } + + // Not copy constructable + inline + ManagedImage( const ManagedImage& other ) = delete; + + // Move constructor + inline + ManagedImage(ManagedImage&& img) + { + *this = std::move(img); + } + + // Move asignment + inline + void operator=(ManagedImage&& img) + { + Deallocate(); + Image::pitch = img.pitch; + Image::ptr = img.ptr; + Image::w = img.w; + Image::h = img.h; + img.ptr = nullptr; + } + + // Explicit copy constructor + template + ManagedImage( const CopyObject& other ) + { + CopyFrom(other.obj); + } + + // Explicit copy assignment + template + void operator=(const CopyObject& other) + { + CopyFrom(other.obj); + } + + inline + void Swap(ManagedImage& img) + { + std::swap(img.pitch, Image::pitch); + std::swap(img.ptr, Image::ptr); + std::swap(img.w, Image::w); + std::swap(img.h, Image::h); + } + + inline + void CopyFrom(const Image& img) + { + if(!Image::IsValid() || Image::w != img.w || Image::h != img.h) { + Reinitialise(img.w,img.h); + } + Image::CopyFrom(img); + } + + inline + void Reinitialise(size_t w, size_t h) + { + if(!Image::ptr || Image::w != w || Image::h != h) { + *this = ManagedImage(w,h); + } + } + + inline + void Reinitialise(size_t w, size_t h, size_t pitch) + { + if(!Image::ptr || Image::w != w || Image::h != h || Image::pitch != pitch) { + *this = ManagedImage(w,h,pitch); + } + } + + inline void Deallocate() + { + if (Image::ptr) { + Allocator().deallocate(Image::ptr, (Image::h * Image::pitch) / sizeof(T) ); + Image::ptr = nullptr; + } + } + + // Move asignment + template inline + void OwnAndReinterpret(ManagedImage&& img) + { + Deallocate(); + Image::pitch = img.pitch; + Image::ptr = (T*)img.ptr; + Image::w = img.w; + Image::h = img.h; + img.ptr = nullptr; + } +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/memcpy.h b/thirdparty/Pangolin/include/pangolin/image/memcpy.h new file mode 100644 index 00000000..88d3f0ce --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/memcpy.h @@ -0,0 +1,110 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include + +#ifdef HAVE_CUDA +# include +#endif + +namespace pangolin { + +template +PANGO_HOST_DEVICE inline +bool IsDevicePtr(T* ptr) +{ +#ifdef HAVE_CUDA + cudaPointerAttributes attributes; + cudaError_t res = cudaPointerGetAttributes(&attributes,ptr); + + //Flushing the error flag for future CUDA error checks + if(res != cudaSuccess) + { + cudaGetLastError(); + return false; + } + + return attributes.memoryType == cudaMemoryTypeDevice; +#else + PANGOLIN_UNUSED(ptr); + return false; +#endif +} + +PANGO_HOST_DEVICE inline +void MemCopy(void *dst, const void *src, size_t size_bytes) +{ +#ifdef HAVE_CUDA + cudaMemcpy(dst,src, size_bytes, cudaMemcpyDefault); +#else + std::memcpy(dst, src, size_bytes); +#endif +} + +inline +void PitchedCopy(char* dst, unsigned int dst_pitch_bytes, const char* src, unsigned int src_pitch_bytes, unsigned int width_bytes, unsigned int height) +{ +#ifdef HAVE_CUDA + cudaMemcpy2D(dst, dst_pitch_bytes, src, src_pitch_bytes, width_bytes, height, cudaMemcpyDefault); +#else + if(dst_pitch_bytes == width_bytes && src_pitch_bytes == width_bytes ) { + std::memcpy(dst, src, height * width_bytes); + }else{ + for(unsigned int row=0; row < height; ++row) { + std::memcpy(dst, src, width_bytes); + dst += dst_pitch_bytes; + src += src_pitch_bytes; + } + } +#endif +} + +PANGO_HOST_DEVICE inline +void Memset(char* ptr, unsigned char v, size_t size_bytes) +{ +#ifdef __CUDA_ARCH__ + // Called in kernel + char* end = ptr + size_bytes; + for(char* p=ptr; p != end; ++p) *p = v; +#else +# ifdef HAVE_CUDA + if(IsDevicePtr(ptr)) + { + cudaMemset(ptr, v, size_bytes); + }else +# endif // HAVE_CUDA + { + std::memset(ptr, v, size_bytes); + } +#endif // __CUDA_ARCH__ +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/pixel_format.h b/thirdparty/Pangolin/include/pangolin/image/pixel_format.h new file mode 100644 index 00000000..2494a3a2 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/pixel_format.h @@ -0,0 +1,66 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011-2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +struct PANGOLIN_EXPORT PixelFormat +{ + // Previously, VideoInterface::PixFormat returned a string. + // For compatibility, make this string convertable + inline operator std::string() const { return format; } + + std::string format; + unsigned int channels; + unsigned int channel_bits[4]; //Of the data type + unsigned int bpp; //Of the data type + unsigned int channel_bit_depth; //Of the data + bool planar; +}; + + +//! Return Pixel Format properties given string specification in +//! FFMPEG notation. +PANGOLIN_EXPORT +PixelFormat PixelFormatFromString(const std::string& format); + +//////////////////////////////////////////////////////////////////// +/// Deprecated aliases for above + +PANGOLIN_DEPRECATED +typedef PixelFormat VideoPixelFormat; +PANGOLIN_DEPRECATED +inline PixelFormat VideoFormatFromString(const std::string& format) { + return PixelFormatFromString(format); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/image/typed_image.h b/thirdparty/Pangolin/include/pangolin/image/typed_image.h new file mode 100644 index 00000000..39e5062e --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/image/typed_image.h @@ -0,0 +1,91 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin { + +struct TypedImage : public ManagedImage +{ + typedef ManagedImage Base; + + inline TypedImage() + : Base() + { + } + + inline TypedImage(size_t w, size_t h, const PixelFormat& fmt) + : Base(w,h,w*fmt.bpp/8), fmt(fmt) + { + } + + inline TypedImage(size_t w, size_t h, const PixelFormat& fmt, size_t pitch ) + : Base(w,h, pitch), fmt(fmt) + { + } + + inline + void Reinitialise(size_t w, size_t h, const PixelFormat& fmt) + { + Base::Reinitialise(w, h, w*fmt.bpp/8); + this->fmt = fmt; + } + + inline + void Reinitialise(size_t w, size_t h, const PixelFormat& fmt, size_t pitch) + { + Base::Reinitialise(w, h, pitch); + this->fmt = fmt; + } + + // Not copy constructable + inline + TypedImage( const TypedImage& other ) = delete; + + // Move constructor + inline + TypedImage(TypedImage&& img) + { + *this = std::move(img); + } + + // Move asignment + inline + void operator=(TypedImage&& img) + { + fmt = img.fmt; + Base::operator =( std::move(img)); + } + + + PixelFormat fmt; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/ios/PangolinAppDelegate.h b/thirdparty/Pangolin/include/pangolin/ios/PangolinAppDelegate.h new file mode 100644 index 00000000..6bae2087 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/ios/PangolinAppDelegate.h @@ -0,0 +1,36 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#import + +#import "PangolinUIView.h" + +@interface PangolinAppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/thirdparty/Pangolin/include/pangolin/ios/PangolinUIView.h b/thirdparty/Pangolin/include/pangolin/ios/PangolinUIView.h new file mode 100644 index 00000000..f7aea7ff --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/ios/PangolinUIView.h @@ -0,0 +1,22 @@ +// +// GlTestViewController.h +// gltest +// +// Created by Steven Lovegrove on 30/01/2014. +// Copyright (c) 2014 Steven Lovegrove. All rights reserved. +// + +#import + +#include +#include + +@interface PangolinUIView : UIView { + CAEAGLLayer* _eaglLayer; + EAGLContext* _context; + + GLuint _colorRenderBuffer; + GLuint _depthRenderBuffer; +} + +@end \ No newline at end of file diff --git a/thirdparty/Pangolin/include/pangolin/log/packet.h b/thirdparty/Pangolin/include/pangolin/log/packet.h new file mode 100644 index 00000000..a904373d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/packet.h @@ -0,0 +1,70 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include + +namespace pangolin { + +// Encapsulate serialized reading of Packet from stream. +struct Packet +{ + Packet(PacketStream& s, std::unique_lock&& mutex, std::vector& srcs); + Packet(const Packet&) = delete; + Packet(Packet&& o); + ~Packet(); + + size_t BytesRead() const; + int BytesRemaining() const; + + PacketStream& Stream() + { + return _stream; + } + + PacketStreamSourceId src; + int64_t time; + size_t size; + size_t sequence_num; + picojson::value meta; + std::streampos frame_streampos; + +private: + void ParsePacketHeader(PacketStream& s, std::vector& srcs); + void ReadRemaining(); + + PacketStream& _stream; + + std::unique_lock lock; + + std::streampos data_streampos; + size_t _data_len; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/log/packetstream.h b/thirdparty/Pangolin/include/pangolin/log/packetstream.h new file mode 100644 index 00000000..1b9c0f3b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/packetstream.h @@ -0,0 +1,111 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include + +#include +#include + +namespace pangolin +{ + +class PacketStream: public std::ifstream +{ +public: + PacketStream() + : _is_pipe(false) + { + cclear(); + } + + PacketStream(const std::string& filename) + : Base(filename.c_str(), std::ios::in | std::ios::binary), + _is_pipe(IsPipe(filename)) + { + cclear(); + } + + bool seekable() const + { + return is_open() && !_is_pipe; + } + + void open(const std::string& filename) + { + close(); + _is_pipe = IsPipe(filename); + Base::open(filename.c_str(), std::ios::in | std::ios::binary); + } + + void close() + { + cclear(); + if (Base::is_open()) Base::close(); + } + + void seekg(std::streampos target); + + void seekg(std::streamoff off, std::ios_base::seekdir way); + + std::streampos tellg(); + + size_t read(char* target, size_t len); + + char get(); + + size_t skip(size_t len); + + size_t readUINT(); + + int64_t readTimestamp(); + + pangoTagType peekTag(); + + pangoTagType readTag(); + + pangoTagType readTag(pangoTagType); + + pangoTagType syncToTag(); + +private: + using Base = std::ifstream; + + bool _is_pipe; + pangoTagType _tag; + + // Amount of frame data left to read. Tracks our position within a data block. + + + void cclear() { + _tag = 0; + } +}; + + +} diff --git a/thirdparty/Pangolin/include/pangolin/log/packetstream_reader.h b/thirdparty/Pangolin/include/pangolin/log/packetstream_reader.h new file mode 100644 index 00000000..d929eb4b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/packetstream_reader.h @@ -0,0 +1,120 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include + +#include +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT PacketStreamReader +{ +public: + PacketStreamReader(); + + PacketStreamReader(const std::string& filename); + + ~PacketStreamReader(); + + void Open(const std::string& filename); + + void Close(); + + const std::vector& + Sources() const + { + return _sources; + } + + // Grab Next available frame packetstream + Packet NextFrame(); + + // Grab Next available frame in packetstream from src, discarding other frames. + Packet NextFrame(PacketStreamSourceId src); + + bool Good() const + { + return _stream.good(); + } + + // Jumps to a particular packet. + size_t Seek(PacketStreamSourceId src, size_t framenum); + + // Jumps to the first packet with time >= time + size_t Seek(PacketStreamSourceId src, SyncTime::TimePoint time); + + void FixFileIndex(); + +private: + bool GoodToRead(); + + bool SetupIndex(); + + void ParseHeader(); + + void ParseNewSource(); + + bool ParseIndex(); + + void RebuildIndex(); + + void AppendIndex(); + + std::streampos ParseFooter(); + + void SkipSync(); + + void ReSync() { + _stream.syncToTag(); + } + + std::string _filename; + std::vector _sources; + SyncTime::TimePoint packet_stream_start; + + PacketStream _stream; + std::recursive_mutex _mutex; + + bool _is_pipe; + int _pipe_fd; +}; + + + + + + + + +} diff --git a/thirdparty/Pangolin/include/pangolin/log/packetstream_source.h b/thirdparty/Pangolin/include/pangolin/log/packetstream_source.h new file mode 100644 index 00000000..7a79e490 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/packetstream_source.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include + +namespace pangolin { + +using PacketStreamSourceId = size_t; + +struct PANGOLIN_EXPORT PacketStreamSource +{ + struct PacketInfo + { + std::streampos pos; + int64_t capture_time; + }; + + PacketStreamSource() + : id(static_cast(-1)), + version(0), + data_alignment_bytes(1), + data_size_bytes(0), + next_packet_id(0) + { + } + + std::streampos FindSeekLocation(size_t packet_id) + { + if(packet_id < index.size()) { + return index[packet_id].pos; + }else{ + return std::streampos(-1); + } + + } + + int64_t NextPacketTime() const + { + if(next_packet_id < index.size()) { + return index[next_packet_id].capture_time; + }else{ + return 0; + } + } + + std::string driver; + size_t id; + std::string uri; + picojson::value info; + int64_t version; + int64_t data_alignment_bytes; + std::string data_definitions; + int64_t data_size_bytes; + + // Index keyed by packet_id + std::vector index; + + // Based on current position in stream + size_t next_packet_id; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/log/packetstream_tags.h b/thirdparty/Pangolin/include/pangolin/log/packetstream_tags.h new file mode 100644 index 00000000..13216f3d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/packetstream_tags.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +namespace pangolin { + +using pangoTagType = uint32_t; + +const static std::string PANGO_MAGIC = "PANGO"; + +const static std::string pss_src_driver = "driver"; +const static std::string pss_src_id = "id"; +const static std::string pss_src_info = "info"; +const static std::string pss_src_uri = "uri"; +const static std::string pss_src_packet = "packet"; +const static std::string pss_src_version = "version"; +const static std::string pss_pkt_alignment_bytes = "alignment_bytes"; +const static std::string pss_pkt_definitions = "definitions"; +const static std::string pss_pkt_size_bytes = "size_bytes"; +const static std::string pss_pkt_format_written = "format_written"; + +const unsigned int TAG_LENGTH = 3; + +#define PANGO_TAG(a,b,c) ( (c<<16) | (b<<8) | a) +const uint32_t TAG_PANGO_HDR = PANGO_TAG('L', 'I', 'N'); +const uint32_t TAG_PANGO_MAGIC = PANGO_TAG('P', 'A', 'N'); +const uint32_t TAG_PANGO_SYNC = PANGO_TAG('S', 'Y', 'N'); +const uint32_t TAG_PANGO_STATS = PANGO_TAG('S', 'T', 'A'); +const uint32_t TAG_PANGO_FOOTER = PANGO_TAG('F', 'T', 'R'); +const uint32_t TAG_ADD_SOURCE = PANGO_TAG('S', 'R', 'C'); +const uint32_t TAG_SRC_JSON = PANGO_TAG('J', 'S', 'N'); +const uint32_t TAG_SRC_PACKET = PANGO_TAG('P', 'K', 'T'); +const uint32_t TAG_END = PANGO_TAG('E', 'N', 'D'); +#undef PANGO_TAG + +inline std::string tagName(int v) +{ + char b[4]; + b[0] = v&0xff; + b[1] = (v>>8)&0xff; + b[2] = (v>>16)&0xff; + b[3] = 0x00; + return std::string(b); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/log/packetstream_writer.h b/thirdparty/Pangolin/include/pangolin/log/packetstream_writer.h new file mode 100644 index 00000000..195ff92f --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/packetstream_writer.h @@ -0,0 +1,173 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT PacketStreamWriter +{ +public: + PacketStreamWriter() + : _stream(&_buffer), _indexable(false), _open(false), _bytes_written(0) + { + _stream.exceptions(std::ostream::badbit); + } + + PacketStreamWriter(const std::string& filename, size_t buffer_size = 100*1024*1024) + : _buffer(pangolin::PathExpand(filename), buffer_size), _stream(&_buffer), + _indexable(!IsPipe(filename)), _open(_stream.good()), _bytes_written(0) + { + _stream.exceptions(std::ostream::badbit); + WriteHeader(); + } + + ~PacketStreamWriter() { + Close(); + } + + void Open(const std::string& filename, size_t buffer_size = 100 * 1024 * 1024) + { + Close(); + _buffer.open(filename, buffer_size); + _open = _stream.good(); + _bytes_written = 0; + _indexable = !IsPipe(filename); + WriteHeader(); + } + + void Close() + { + if (_open) + { + if (_indexable) { + WriteEnd(); + } + _buffer.close(); + _open = false; + } + } + + // Does not write footer or index. + void ForceClose() + { + if (_open) + { + _buffer.force_close(); + Close(); + } + } + + + // Writes to the stream immediately upon add. Return source id # and writes + // source id # to argument struct + PacketStreamSourceId AddSource(PacketStreamSource& source); + + // If constructor is called inline + PacketStreamSourceId AddSource(const PacketStreamSource& source); + + void WriteSourcePacket( + PacketStreamSourceId src, const char* source,const int64_t receive_time_us, + size_t sourcelen, const picojson::value& meta = picojson::value() + ); + + // For stream read/write synchronization. Note that this is NOT the same as + // time synchronization on playback of iPacketStreams. + void WriteSync(); + + // Writes the end of the stream data, including the index. Does NOT close + // the underlying ostream. + void WriteEnd(); + + const std::vector& Sources() const { + return _sources; + } + + bool IsOpen() const { + return _open; + } + +private: + void WriteHeader(); + void Write(const PacketStreamSource&); + void WriteMeta(PacketStreamSourceId src, const picojson::value& data); + + threadedfilebuf _buffer; + std::ostream _stream; + bool _indexable, _open; + + std::vector _sources; + size_t _bytes_written; + std::recursive_mutex _lock; +}; + +inline void writeCompressedUnsignedInt(std::ostream& writer, size_t n) +{ + while (n >= 0x80) + { + writer.put(0x80 | (n & 0x7F)); + n >>= 7; + } + writer.put(static_cast(n)); +} + +inline void writeTimestamp(std::ostream& writer, int64_t time_us) +{ + writer.write(reinterpret_cast(&time_us), sizeof(decltype(time_us))); +} + +inline void writeTag(std::ostream& writer, const pangoTagType tag) +{ + writer.write(reinterpret_cast(&tag), TAG_LENGTH); +} + +inline picojson::value SourceStats(const std::vector& srcs) +{ + picojson::value stat; + stat["num_sources"] = srcs.size(); + stat["src_packet_index"] = picojson::array(); + stat["src_packet_times"] = picojson::array(); + + for(auto& src : srcs) { + picojson::array pkt_index, pkt_times; + for (const PacketStreamSource::PacketInfo& frame : src.index) { + pkt_index.emplace_back(frame.pos); + pkt_times.emplace_back(frame.capture_time); + } + stat["src_packet_index"].push_back(std::move(pkt_index)); + stat["src_packet_times"].push_back(std::move(pkt_times)); + } + return stat; +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/log/playback_session.h b/thirdparty/Pangolin/include/pangolin/log/playback_session.h new file mode 100644 index 00000000..fb28d13f --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/playback_session.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace pangolin { + +class Params; + +class PlaybackSession +{ +public: + // Singleton Instance + static std::shared_ptr Default(); + + // Return thread-safe, shared instance of PacketStreamReader, providing + // serialised read for PacketStreamReader + std::shared_ptr Open(const std::string& filename) + { + const std::string path = SanitizePath(PathExpand(filename)); + + auto i = readers.find(path); + if(i == readers.end()) { + auto psr = std::make_shared(path); + readers[path] = psr; + return psr; + }else{ + return i->second; + } + } + + SyncTime& Time() + { + return time; + } + + static std::shared_ptr ChooseFromParams(const Params& params); + +private: + std::map> readers; + SyncTime time; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/log/sync_time.h b/thirdparty/Pangolin/include/pangolin/log/sync_time.h new file mode 100644 index 00000000..10dfe715 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/log/sync_time.h @@ -0,0 +1,230 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace pangolin +{ + +// Lightweight timestamp class to allow synchronized playback from the same (or a different) stream. +// All playback functions called with the same SyncTime will be time-synchronized, and will remain synchronized on seek() if the SyncTime is passed in when seeking. +// Playback with multiple SyncTimes (on the same or different streams) should also be synced, even in different processes or systems (underlying clock sync is not required). +// However, playback with multiple SyncTimes will break on seek(). +class PANGOLIN_EXPORT SyncTime +{ +public: + using Clock = baseclock; + using Duration = Clock::duration; + using TimePoint = Clock::time_point; + + struct SeekInterruption: std::runtime_error + { + SeekInterruption() : std::runtime_error("Time queue invalidated by seek"){} + }; + + SyncTime(Duration virtual_clock_offset = std::chrono::milliseconds(0)) + : seeking(false) + { + SetOffset(virtual_clock_offset); + } + + // No copy constructor + SyncTime(const SyncTime&) = delete; + + void SetOffset(Duration virtual_clock_offset) + { + virtual_offset = virtual_clock_offset; + } + + void SetClock(TimePoint virtual_now) + { + virtual_offset = virtual_now - Clock::now(); + } + + TimePoint TimeNow() const + { + return Clock::now() + virtual_offset; + } + + TimePoint ToVirtual(TimePoint real) const + { + return real + virtual_offset; + } + + TimePoint ToReal(TimePoint virt) const + { + return virt - virtual_offset; + } + + void WaitUntil(TimePoint virtual_time) const + { + std::this_thread::sleep_until( ToReal(virtual_time) ); + } + + int64_t QueueEvent(int64_t new_event_time_us) + { + return WaitDequeueAndQueueEvent(0, new_event_time_us); + } + + void DequeueEvent(int64_t event_time_us) + { + std::unique_lock l(time_mutex); + auto i = std::find(time_queue_us.begin(), time_queue_us.end(), event_time_us); + PANGO_ENSURE(i != time_queue_us.end()); + time_queue_us.erase(i); + queue_changed.notify_all(); + } + + int64_t WaitDequeueAndQueueEvent(int64_t event_time_us, int64_t new_event_time_us =0 ) + { + std::unique_lock l(time_mutex); + + if(event_time_us) { + PANGO_ENSURE(time_queue_us.size()); + + // Wait until we're top the priority-queue + queue_changed.wait(l, [&](){ + if(seeking) { + // Time queue will be invalidated on seek. + // Unblock without action + throw SeekInterruption(); + } + return time_queue_us.back() == event_time_us; + }); + + // Dequeue + time_queue_us.pop_back(); + } + + if(new_event_time_us) { + // Add the new event whilst we still hold the lock, so that our + // event can't be missed + insert_sorted(time_queue_us, new_event_time_us, std::greater()); + + if(time_queue_us.back() == new_event_time_us) { + // Return to avoid yielding when we're next. + return new_event_time_us; + } + } + + // Only yield if another device is next + queue_changed.notify_all(); + return new_event_time_us; + } + + void NotifyAll() + { + queue_changed.notify_all(); + } + + std::mutex& TimeMutex() + { + return time_mutex; + } + + void Stop() + { + seeking = true; + OnTimeStop(); + queue_changed.notify_all(); + } + + void Start() + { + OnTimeStart(); + seeking=false; + } + + void Seek(TimePoint t) + { + Stop(); + OnSeek(t); + Start(); + } + + Signal<> OnTimeStart; + + Signal<> OnTimeStop; + + Signal OnSeek; + +private: + template< typename T, typename Pred > + static typename std::vector::iterator + insert_sorted( std::vector & vec, T const& item, Pred pred ) + { + return vec.insert ( + std::upper_bound( vec.begin(), vec.end(), item, pred ), item + ); + } + + std::vector time_queue_us; + Duration virtual_offset; + std::mutex time_mutex; + std::condition_variable queue_changed; + bool seeking; +}; + +struct SyncTimeEventPromise +{ + SyncTimeEventPromise(SyncTime& sync, int64_t time_us = 0) + : sync(sync), time_us(time_us) + { + sync.QueueEvent(time_us); + } + + ~SyncTimeEventPromise() + { + Cancel(); + } + + void Cancel() + { + if(time_us) { + sync.DequeueEvent(time_us); + time_us = 0; + } + } + + void WaitAndRenew(int64_t new_time_us) + { + time_us = sync.WaitDequeueAndQueueEvent(time_us, new_time_us); + } + +private: + SyncTime& sync; + int64_t time_us; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/pangolin.h b/thirdparty/Pangolin/include/pangolin/pangolin.h new file mode 100644 index 00000000..370752ac --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/pangolin.h @@ -0,0 +1,64 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#ifdef BUILD_PANGOLIN_GUI + #include + #include + #include + #include + #include + #include + #include + #ifdef _ANDROID_ + #include + #endif + #if !defined(HAVE_GLES) || defined(HAVE_GLES_2) + #include + #endif +#endif // BUILD_PANGOLIN_GUI + +#ifdef BUILD_PANGOLIN_VARS + #include + #ifdef BUILD_PANGOLIN_GUI + #include + #endif // BUILD_PANGOLIN_GUI +#endif // BUILD_PANGOLIN_VARS + +#ifdef BUILD_PANGOLIN_VIDEO + #include + #include + #include +#endif // BUILD_PANGOLIN_VIDEO + +#include + +// Let other libraries headers know about Pangolin +#define HAVE_PANGOLIN diff --git a/thirdparty/Pangolin/include/pangolin/platform.h b/thirdparty/Pangolin/include/pangolin/platform.h new file mode 100644 index 00000000..b5a223b7 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/platform.h @@ -0,0 +1,81 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +// Include portable printf-style format macros +#define __STDC_FORMAT_MACROS + +#ifdef _GCC_ +# define PANGOLIN_DEPRECATED __attribute__((deprecated)) +#elif defined _MSVC_ +# define PANGOLIN_DEPRECATED __declspec(deprecated) +#else +# define PANGOLIN_DEPRECATED +#endif + +#ifdef _MSVC_ +# define __thread __declspec(thread) +# include +#else +# define PANGOLIN_EXPORT +#endif //_MSVC_ + +#define PANGOLIN_UNUSED(x) (void)(x) + +#ifdef _APPLE_IOS_ +// Not supported on this platform. +#define __thread +#endif // _APPLE_IOS_ + +// HOST / DEVICE Annotations +#ifdef __CUDACC__ +# include +# define PANGO_HOST_DEVICE __host__ __device__ +#else +# define PANGO_HOST_DEVICE +#endif + +// Non-standard check that header exists (Clang, GCC 5.X) +// Useful for +#if defined(__has_include) +# define PANGO_HEADER_EXISTS(x) __has_include(x) +#else +# define PANGO_HEADER_EXISTS(x) 0 +#endif + +// Workaround for Apple-Clangs lack of thread_local support +#if defined(_CLANG_) && defined(_OSX_) +# if !__has_feature(cxx_thread_local) +# define PANGO_NO_THREADLOCAL +# endif +#endif + +#include +#include diff --git a/thirdparty/Pangolin/include/pangolin/plot/datalog.h b/thirdparty/Pangolin/include/pangolin/plot/datalog.h new file mode 100644 index 00000000..d0120b0d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/plot/datalog.h @@ -0,0 +1,243 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include // std::min, std::max +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files +#define USE_EIGEN +#endif + +#ifdef USE_EIGEN +#include +#endif + +namespace pangolin +{ + +/// Simple statistics recorded for a logged input dimension. +struct DimensionStats +{ + DimensionStats() + { + Reset(); + } + + void Reset() + { + isMonotonic = true; + sum = 0.0f; + sum_sq = 0.0f; + min = std::numeric_limits::max(); + max = std::numeric_limits::lowest(); + } + + void Add(const float v) + { + isMonotonic = isMonotonic && (v >= max); + sum += v; + sum_sq += v*v; + min = std::min(min, v); + max = std::max(max, v); + } + + bool isMonotonic; + float sum; + float sum_sq; + float min; + float max; +}; + +class DataLogBlock +{ +public: + /// @param dim: dimension of sample + /// @param max_samples: maximum number of samples this block can hold + /// @param start_id: index of first sample (from entire dataset) in this buffer + DataLogBlock(size_t dim, size_t max_samples, size_t start_id) + : dim(dim), max_samples(max_samples), samples(0), + start_id(start_id) + { + sample_buffer = std::unique_ptr(new float[dim*max_samples]); +// stats = std::unique_ptr(new DimensionStats[dim]); + } + + ~DataLogBlock() + { + } + + size_t Samples() const + { + return samples; + } + + size_t MaxSamples() const + { + return max_samples; + } + + /// Return how many more samples can fit in this block + size_t SampleSpaceLeft() const + { + return MaxSamples()- Samples(); + } + + bool IsFull() const + { + return Samples() >= MaxSamples(); + } + + /// Add data to block + void AddSamples(size_t num_samples, size_t dimensions, const float* data_dim_major ); + + /// Delete all samples + void ClearLinked() + { + samples = 0; + nextBlock.reset(); + } + + DataLogBlock* NextBlock() const + { + return nextBlock.get(); + } + + size_t StartId() const + { + return start_id; + } + + float* DimData(size_t d) const + { + return sample_buffer.get() + d; + } + + size_t Dimensions() const + { + return dim; + } + + const float* Sample(size_t n) const + { + const int id = (int)n - (int)start_id; + + if( 0 <= id && id < (int)samples ) { + return sample_buffer.get() + dim*id; + }else{ + if(nextBlock) { + return nextBlock->Sample(n); + }else{ + throw std::out_of_range("Index out of range."); + } + } + } + +protected: + size_t dim; + size_t max_samples; + size_t samples; + size_t start_id; + std::unique_ptr sample_buffer; +// std::unique_ptr stats; + std::unique_ptr nextBlock; +}; + +/// A DataLog can efficiently record floating point sample data of any size. +/// Memory is allocated in blocks is transparent to the user. +class PANGOLIN_EXPORT DataLog +{ +public: + /// @param block_samples_alloc number of samples each memory block can hold. + DataLog(unsigned int block_samples_alloc = 10000 ); + + ~DataLog(); + + /// Provide textual labels corresponding to each dimension logged. + /// This information may be used by graphical interfaces to DataLog. + void SetLabels(const std::vector & labels); + const std::vector& Labels() const; + + void Log(size_t dimension, const float * vals, unsigned int samples = 1); + void Log(float v); + void Log(float v1, float v2); + void Log(float v1, float v2, float v3); + void Log(float v1, float v2, float v3, float v4); + void Log(float v1, float v2, float v3, float v4, float v5); + void Log(float v1, float v2, float v3, float v4, float v5, float v6); + void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7); + void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8); + void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9); + void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9, float v10); + void Log(const std::vector & vals); + +#ifdef USE_EIGEN + template + void Log(const Eigen::MatrixBase& M) + { + Log( M.rows() * M.cols(), M.template cast().eval().data() ); + } +#endif + + void Clear(); + void Save(std::string filename); + + // Return first block of stored data + const DataLogBlock* FirstBlock() const; + + // Return last block of stored data + const DataLogBlock* LastBlock() const; + + // Return number of samples stored in this DataLog + size_t Samples() const; + + // Return pointer to stored sample n + const float* Sample(int n) const; + + // Return stats computed for each dimension if enabled. + const DimensionStats& Stats(size_t dim) const; + + std::mutex access_mutex; + +protected: + unsigned int block_samples_alloc; + std::vector labels; + std::unique_ptr block0; + DataLogBlock* blockn; + std::vector stats; + bool record_stats; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/plot/plotter.h b/thirdparty/Pangolin/include/pangolin/plot/plotter.h new file mode 100644 index 00000000..b33219e2 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/plot/plotter.h @@ -0,0 +1,279 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PLOTTER_H +#define PLOTTER_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace pangolin +{ + +enum DrawingMode +{ + DrawingModePoints = GL_POINTS, + DrawingModeDashed = GL_LINES, + DrawingModeLine = GL_LINE_STRIP, + DrawingModeNone, +}; + +struct Marker +{ + enum Direction + { + Horizontal, + Vertical + }; + + enum Equality + { + LessThan = -1, + Equal = 0, + GreaterThan = 1 + }; + + Marker(Direction d, float value, Equality leg = Equal, Colour c = Colour() ) + : colour(c) + { + if(d == Horizontal) { + range.x = Rangef::Open(); + range.y = Rangef::Containing(value); + if(leg == LessThan) { + range.y.Insert(std::numeric_limits::lowest() ); + }else if(leg == GreaterThan) { + range.y.Insert(std::numeric_limits::max() ); + } + }else if(d == Vertical) { + range.x = Rangef::Containing(value); + range.y = Rangef::Open(); + if(leg == LessThan) { + range.x.Insert(std::numeric_limits::lowest() ); + }else if(leg == GreaterThan) { + range.x.Insert(std::numeric_limits::max() ); + } + } + } + + Marker(const XYRangef& range, const Colour& c = Colour() ) + : range(range), colour(c) + { + } + + XYRangef range; + Colour colour; +}; + +class PANGOLIN_EXPORT Plotter : public View, Handler +{ +public: + Plotter( + DataLog* default_log, + float left=0, float right=600, float bottom=-1, float top=1, + float tickx=30, float ticky=0.5, + Plotter* linked_plotter_x = 0, + Plotter* linked_plotter_y = 0 + ); + + virtual ~Plotter(); + + void Render(); + + XYRangef& GetSelection(); + + XYRangef& GetDefaultView(); + void SetDefaultView(const XYRangef& range); + + XYRangef& GetView(); + void SetView(const XYRangef& range); + void SetViewSmooth(const XYRangef& range); + + void ScrollView(float x, float y); + void ScrollViewSmooth(float x, float y); + + void ScaleView(float x, float y, float cx, float cy); + void ScaleViewSmooth(float x, float y, float cx, float cy); + + void ResetView(); + + void SetTicks(float tickx, float ticky); + + void Track(const std::string& x="$i", const std::string& y = ""); + void ToggleTracking(); + + void Trigger(const std::string& x="$0", int edge = -1, float value = 0.0f); + void ToggleTrigger(); + + void SetBackgroundColour(const Colour& col); + void SetAxisColour(const Colour& col); + void SetTickColour(const Colour& col); + + void ScreenToPlot(int xpix, int ypix, float &xplot, float &yplot); + void Keyboard(View&, unsigned char key, int x, int y, bool pressed); + void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state); + void MouseMotion(View&, int x, int y, int mouse_state); + void PassiveMouseMotion(View&, int x, int y, int button_state); + void Special(View&, InputSpecial inType, float x, float y, float p1, float p2, float p3, float p4, int button_state); + + /// Remove all current series plots + void ClearSeries(); + + /// Add series X,Y plot from glsl compatible expressions x_expr, y_expr + /// $i refers to integral index of datum in log. + /// $0, $1, $2, ... refers to nth series in log. + /// e.g. x_expr = "$i", y_expr = "$0" // index - data[0] plot + /// e.g. x_expr = "$0", y_expr = "$1" // data[0], data[1] X-Y plot + /// e.g. x_exptr ="$i", y_expr = "sqrt($1)} // index - sqrt(data[0]) plot + void AddSeries(const std::string& x_expr, const std::string& y_expr, + DrawingMode drawing_mode = DrawingModeLine, Colour colour = Colour::Unspecified(), + const std::string &title = "$y", DataLog* log = nullptr + ); + + std::string PlotTitleFromExpr(const std::string& expr) const; + + /// Remove all current markers + void ClearMarkers(); + + /// Add horizontal or vertical inequality marker; equal-to, less-than, or greater than. + /// This is useful for annotating a critical point or valid region. + Marker& AddMarker( + Marker::Direction d, float value, + Marker::Equality leg = Marker::Equal, Colour c = Colour() + ); + + Marker& AddMarker( const Marker& marker ); + + void ClearImplicitPlots(); + void AddImplicitPlot(); + +protected: + struct PANGOLIN_EXPORT Tick + { + float val; + float factor; + std::string symbol; + }; + + struct PANGOLIN_EXPORT PlotAttrib + { + PlotAttrib(std::string name, int plot_id, int location = -1) + : name(name), plot_id(plot_id), location(location) { } + + std::string name; + int plot_id; + int location; + }; + + struct PANGOLIN_EXPORT PlotSeries + { + PlotSeries(); + void CreatePlot(const std::string& x, const std::string& y, Colour c, std::string title); + + GlSlProgram prog; + GlText title; + bool contains_id; + std::vector attribs; + DataLog* log; + GLenum drawing_mode; + Colour colour; + bool used; + }; + + struct PANGOLIN_EXPORT PlotImplicit + { + // Assign to gl_FragColor + void CreatePlot(const std::string& code); + + // Expression uses x,y and assignes colours [0,1] to r,g,b,a + void CreateColouredPlot(const std::string& code); + + // Expression uses x,y and evaluates to true/false; + void CreateInequality(const std::string& ie, Colour c); + + // Expression uses x,y and evaluates to a number + void CreateDistancePlot(const std::string& dist); + + GlSlProgram prog; + }; + + void FixSelection(); + void UpdateView(); + Tick FindTickFactor(float tick); + + DataLog* default_log; + + ColourWheel colour_wheel; + Colour colour_bg; + Colour colour_tk; + Colour colour_ax; + + GlSlProgram prog_lines; + GlSlProgram prog_text; + + std::vector plotseries; + std::vector plotmarkers; + std::vector plotimplicits; + + Tick tick[2]; + XYRangef rview_default; + XYRangef rview; + XYRangef target; + XYRangef selection; + + void ComputeTrackValue( float track_val[2] ); + XYRangef ComputeAutoSelection(); + + bool track; + std::string track_x; + std::string track_y; + float last_track_val[2]; + + // -1: falling, -0:disable, 1: rising + int trigger_edge; + float trigger_value; + std::string trigger; + + float hover[2]; + int last_mouse_pos[2]; + + Plotter* linked_plotter_x; + Plotter* linked_plotter_y; +}; + +} // namespace pangolin + +#endif // PLOTTER_H diff --git a/thirdparty/Pangolin/include/pangolin/plot/range.h b/thirdparty/Pangolin/include/pangolin/plot/range.h new file mode 100644 index 00000000..ec2906e7 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/plot/range.h @@ -0,0 +1,372 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include + +//prevent including Eigen in cuda files +#if defined(HAVE_EIGEN) && !defined(__CUDACC__) +# define USE_EIGEN +#endif + +#ifdef USE_EIGEN +# include +# include +#endif // USE_EIGEN + +namespace pangolin +{ + + +template +struct Range +{ + static Range Open() + { + return Range(std::numeric_limits::lowest(), std::numeric_limits::max()); + } + + static Range Empty() + { + return Range(std::numeric_limits::max(), std::numeric_limits::lowest()); + } + + static Range Containing(T val) + { + return Range(val, val); + } + + Range() + : min(+std::numeric_limits::max()), + max(-std::numeric_limits::max()) + { + } + + Range(T rmin, T rmax) + : min(rmin), max(rmax) + { + } + + Range operator+(T v) + { + return Range(min+v, max+v); + } + + Range operator-(T v) + { + return Range(min-v, max-v); + } + + Range& operator+=(T v) + { + min += v; + max += v; + return *this; + } + + Range& operator-=(T v) + { + min -= v; + max -= v; + return *this; + } + + Range& operator*=(T v) + { + min *= v; + max *= v; + return *this; + } + + Range& operator/=(T v) + { + min /= v; + max /= v; + return *this; + } + + Range& operator+=(const Range& o) + { + min += o.min; + max += o.max; + return *this; + } + + Range& operator-=(const Range& o) + { + min -= o.min; + max -= o.max; + return *this; + } + + Range operator+(const Range& o) const + { + return Range(min + o.min, max + o.max); + } + + Range operator-(const Range& o) const + { + return Range(min - o.min, max - o.max); + } + + Range operator*(float s) const + { + return Range(T(s*min), T(s*max)); + } + + T Size() const + { + return max - min; + } + + T AbsSize() const + { + return std::abs(Size()); + } + + T Mid() const + { + return (min + max) / (T)2.0f; + } + + void Scale(float s, float center = 0.0f) + { + min = T(s*(min-center) + center); + max = T(s*(max-center) + center); + } + + void Insert(T v) + { + min = std::min(min,v); + max = std::max(max,v); + } + + void Insert(const Range& r) + { + Insert(r.min); + Insert(r.max); + } + + void Clamp(T vmin, T vmax) + { + min = std::min(std::max(vmin, min), vmax); + max = std::min(std::max(vmin, max), vmax); + } + + void Clamp(const Range& o) + { + Clamp(o.min, o.max); + } + + void Clear() + { + min = std::numeric_limits::max(); + max = std::numeric_limits::lowest(); + } + + bool Contains(T v) const + { + return min <= v && v <= max; + } + + bool ContainsWeak(T v) const + { + return (min <= v && v <= max) + || (max <= v && v <= min); + } + + template + Range Cast() const + { + return Range(To(min), To(max)); + } + + T min; + T max; +}; + +template +struct XYRange +{ + static XYRange Open() + { + return XYRange( + Range(std::numeric_limits::lowest(), std::numeric_limits::max()), + Range(std::numeric_limits::lowest(), std::numeric_limits::max()) + ); + } + + static XYRange Empty() + { + return XYRange( + Range(std::numeric_limits::max(), std::numeric_limits::lowest()), + Range(std::numeric_limits::max(), std::numeric_limits::lowest()) + ); + } + + static XYRange Containing(T x, T y) + { + return XYRange( + Range(x, x), + Range(y, y) + ); + } + + XYRange() + { + } + + XYRange(const Range& xrange, const Range& yrange) + : x(xrange), y(yrange) + { + } + + XYRange(T xmin, T xmax, T ymin, T ymax) + : x(xmin,xmax), y(ymin,ymax) + { + } + + XYRange operator-(const XYRange& o) const + { + return XYRange(x - o.x, y - o.y); + } + + XYRange operator*(float s) const + { + return XYRange(x*s, y*s); + } + + XYRange& operator+=(const XYRange& o) + { + x += o.x; + y += o.y; + return *this; + } + + void Scale(float sx, float sy, float centerx, float centery) + { + x.Scale(sx, centerx); + y.Scale(sy, centery); + } + + void Clear() + { + x.Clear(); + y.Clear(); + } + + void Clamp(T xmin, T xmax, T ymin, T ymax) + { + x.Clamp(xmin,xmax); + y.Clamp(ymin,ymax); + } + + void Clamp(const XYRange& o) + { + x.Clamp(o.x); + y.Clamp(o.y); + } + + void Insert(T xval, T yval) + { + x.Insert(xval); + y.Insert(yval); + } + + void Insert(XYRange r) + { + x.Insert(r.x); + y.Insert(r.y); + } + + float Area() const + { + return x.Size() * y.Size(); + } + + bool Contains(float px, float py) const + { + return x.Contains(px) && y.Contains(py); + } + + bool ContainsWeak(float px, float py) const + { + return x.ContainsWeak(px) && y.ContainsWeak(py); + } + + template + XYRange Cast() const + { + return XYRange( + x.template Cast(), + y.template Cast() + ); + } + +#ifdef USE_EIGEN + operator Eigen::AlignedBox() const { + return Eigen::AlignedBox( + Eigen::Matrix(x.min, y.min), + Eigen::Matrix(x.max, y.max) + ); + } + + Eigen::Matrix Center() const { + return Eigen::Matrix(x.Mid(), y.Mid()); + } +#endif + + Range x; + Range y; +}; + +typedef Range Rangei; +typedef Range Rangef; +typedef Range Ranged; + +typedef XYRange XYRangei; +typedef XYRange XYRangef; +typedef XYRange XYRanged; + +template inline +Rangei Round(const Range& r) +{ + return Rangei( int(r.min+0.5), int(r.max+0.5) ); +} + +template inline +XYRangei Round(const XYRange& r) +{ + return XYRangei( Round(r.x), Round(r.y) ); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/python/pyinterpreter.h b/thirdparty/Pangolin/include/pangolin/python/pyinterpreter.h new file mode 100644 index 00000000..8d533bb2 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/python/pyinterpreter.h @@ -0,0 +1,70 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace pangolin +{ + +class PyInterpreter : public ConsoleInterpreter +{ +public: + PyInterpreter(); + + ~PyInterpreter() override; + + void PushCommand(const std::string &cmd) override; + + bool PullLine(ConsoleLine& line) override; + + std::vector Complete( + const std::string& cmd, int max_options + ) override; + + static void AttachPrefix(void* data, const std::string& name, VarValueGeneric& var, bool brand_new ); + +private: + PyObject* pycompleter; + PyObject* pycomplete; + + std::string ToString(PyObject* py); + void CheckPrintClearError(); + PyUniqueObj EvalExec(const std::string& cmd); + + std::queue line_queue; + std::set base_prefixes; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/python/pypangoio.h b/thirdparty/Pangolin/include/pangolin/python/pypangoio.h new file mode 100644 index 00000000..cdfee764 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/python/pypangoio.h @@ -0,0 +1,178 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include + +#include +#include + +namespace pangolin +{ + +struct PyPangoIO { + PyObject_HEAD + + static PyTypeObject Py_type; + static PyMethodDef Py_methods[]; + + PyPangoIO(PyTypeObject *type, std::queue& line_queue, ConsoleLineType line_type) + : line_queue(line_queue), line_type(line_type) + { +#if PY_MAJOR_VERSION >= 3 + ob_base.ob_refcnt = 1; + ob_base.ob_type = type; +#else + ob_refcnt = 1; + ob_type = type; +#endif + } + + static void Py_dealloc(PyPangoIO* self) + { + delete self; + } + + static PyObject * Py_new(PyTypeObject */*type*/, PyObject */*args*/, PyObject */*kwds*/) + { + // Failure. Can only new in c++ + return 0; + } + + static int Py_init(PyPangoIO* /*self*/, PyObject* /*args*/, PyObject* /*kwds*/) + { + return 0; + } + + static PyObject* Py_getattr(PyPangoIO *self, char* name) + { +#if PY_MAJOR_VERSION >= 3 + PyObject* pystr = PyUnicode_FromString(name); +#else + PyObject* pystr = PyString_FromString(name); +#endif + return PyObject_GenericGetAttr((PyObject*)self, pystr ); + } + + static int Py_setattr(PyPangoIO *self, char* name, PyObject* val) + { +#if PY_MAJOR_VERSION >= 3 + PyObject* pystr = PyUnicode_FromString(name); +#else + PyObject* pystr = PyString_FromString(name); +#endif + return PyObject_GenericSetAttr((PyObject*)self, pystr, val); + } + + static PyObject* Py_write(PyPangoIO* self, PyObject *args) + { + const char *text = 0; + if (PyArg_ParseTuple(args, "s", &text)) { + self->buffer += std::string(text); + size_t nl = self->buffer.find_first_of('\n'); + while(nl != std::string::npos) { + const std::string line = self->buffer.substr(0,nl); + self->line_queue.push(ConsoleLine(line,self->line_type)); + self->buffer = self->buffer.substr(nl+1); + nl = self->buffer.find_first_of('\n'); + } + } + Py_RETURN_NONE; + } + + std::string buffer; + std::queue& line_queue; + ConsoleLineType line_type; +}; + +PyMethodDef PyPangoIO::Py_methods[] = { + {"write", (PyCFunction)PyPangoIO::Py_write, METH_VARARGS, "Write to console" }, + {NULL, NULL, 0, NULL} +}; + +#pragma GCC diagnostic push // Ignore python missing initializer warning. +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + +PyTypeObject PyPangoIO::Py_type = { + PyVarObject_HEAD_INIT(NULL,0) + "pangolin.PangoIO", /* tp_name*/ + sizeof(PyPangoIO), /* tp_basicsize*/ + 0, /* tp_itemsize*/ + (destructor)PyPangoIO::Py_dealloc, /* tp_dealloc*/ + 0, /* tp_print*/ + (getattrfunc)PyPangoIO::Py_getattr, /* tp_getattr*/ + (setattrfunc)PyPangoIO::Py_setattr, /* tp_setattr*/ + 0, /* tp_compare*/ + 0, /* tp_repr*/ + 0, /* tp_as_number*/ + 0, /* tp_as_sequence*/ + 0, /* tp_as_mapping*/ + 0, /* tp_hash */ + 0, /* tp_call*/ + 0, /* tp_str*/ + 0, /* tp_getattro*/ + 0, /* tp_setattro*/ + 0, /* tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ + "PyPangoIO object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyPangoIO::Py_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)PyPangoIO::Py_init, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)PyPangoIO::Py_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0 /* tp_version_tag */ +}; + +#pragma GCC diagnostic pop // Return to normal + + +} diff --git a/thirdparty/Pangolin/include/pangolin/python/pypangolin_init.h b/thirdparty/Pangolin/include/pangolin/python/pypangolin_init.h new file mode 100644 index 00000000..8c972cda --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/python/pypangolin_init.h @@ -0,0 +1,40 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include + +namespace pangolin +{ + +PANGOLIN_EXPORT +PyMODINIT_FUNC InitPyPangolinModule(); + +} diff --git a/thirdparty/Pangolin/include/pangolin/python/pyuniqueobj.h b/thirdparty/Pangolin/include/pangolin/python/pyuniqueobj.h new file mode 100644 index 00000000..cb3d3c9e --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/python/pyuniqueobj.h @@ -0,0 +1,111 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +/// Class represents a reference counted PythonObject. +/// PythonObject is appropriately Py_INCREF'd and Py_DECREF'd +class PyUniqueObj +{ +public: + inline + PyUniqueObj() + : obj(0) + { + } + + /// Assumption: PythonObject has already been appropriately INCREF'd. + inline + PyUniqueObj(PyObject* obj) + : obj(obj) + { + } + + inline + PyUniqueObj(const PyUniqueObj& other) + :obj(other.obj) + { + if(obj) Py_INCREF(obj); + } + + inline + ~PyUniqueObj() + { + if(obj) Py_DECREF(obj); + } + + inline + PyUniqueObj(PyUniqueObj&& other) + : obj(other.obj) + { + other.obj = 0; + } + + inline + void operator=(PyUniqueObj&& other) + { + Release(); + obj = other.obj; + other.obj = 0; + } + + inline + void operator=(PyObject* obj) + { + Release(); + this->obj = obj; + } + + inline + void Release() { + if(obj) { + Py_DECREF(obj); + obj = 0; + } + } + + inline + PyObject* operator*() { + return obj; + } + + inline + operator PyObject*() { + return obj; + } + +private: + PyObject* obj; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/python/pyvar.h b/thirdparty/Pangolin/include/pangolin/python/pyvar.h new file mode 100644 index 00000000..ebadd8a0 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/python/pyvar.h @@ -0,0 +1,271 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace pangolin +{ + +PyObject* GetPangoVarAsPython(const std::string& name) +{ + VarState::VarStoreContainer::iterator i = VarState::I().vars.find(name); + if(i != VarState::I().vars.end()) { + VarValueGeneric* var = i->second; + + try{ + if( !strcmp(var->TypeId(), typeid(bool).name() ) ) { + const bool val = Var(*var).Get(); + return PyBool_FromLong( val ); + }else if( !strcmp(var->TypeId(), typeid(short).name() ) || + !strcmp(var->TypeId(), typeid(int).name() ) || + !strcmp(var->TypeId(), typeid(long).name() ) ) { + const long val = Var(*var).Get(); + return PyLong_FromLong( val ); + }else if( !strcmp(var->TypeId(), typeid(double).name() ) || + !strcmp(var->TypeId(), typeid(float).name() ) ) { + const double val = Var(*var).Get(); + return PyFloat_FromDouble(val); + }else{ + const std::string val = var->str->Get(); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(val.c_str()); +#else + return PyString_FromString(val.c_str()); +#endif + } + }catch(const std::exception&) { + } + } + + Py_RETURN_NONE; +} + +void SetPangoVarFromPython(const std::string& name, PyObject* val) +{ + try{ + if (PyFloat_Check(val)) { + pangolin::Var pango_var(name); + pango_var = PyFloat_AsDouble(val); + pango_var.Meta().gui_changed = true; + }else if (PyLong_Check(val)) { + pangolin::Var pango_var(name); + pango_var = PyLong_AsLong(val); + pango_var.Meta().gui_changed = true; + }else if (PyBool_Check(val)) { + pangolin::Var pango_var(name); + pango_var = (val == Py_True) ? true : false; + pango_var.Meta().gui_changed = true; + } +#if PY_MAJOR_VERSION >= 3 + else if (PyUnicode_Check(val)) { + pangolin::Var pango_var(name); + pango_var = PyUnicode_AsUTF8(val); + pango_var.Meta().gui_changed = true; + } +#else + else if (PyString_Check(val)) { + pangolin::Var pango_var(name); + pango_var = PyString_AsString(val); + pango_var.Meta().gui_changed = true; + } else if (PyInt_Check(val)) { + pangolin::Var pango_var(name); + pango_var = PyInt_AsLong(val); + pango_var.Meta().gui_changed = true; + } +#endif + else { + PyUniqueObj pystr = PyObject_Repr(val); +#if PY_MAJOR_VERSION >= 3 + const std::string str = PyUnicode_AsUTF8(pystr); +#else + const std::string str = PyString_AsString(pystr); +#endif + pangolin::Var pango_var(name); + pango_var = str; + pango_var.Meta().gui_changed = true; + } + FlagVarChanged(); + }catch(const std::exception& e) { + pango_print_error("%s\n", e.what()); + } +} + +struct PyVar { + static PyTypeObject Py_type; + PyObject_HEAD + + PyVar(PyTypeObject *type) + { +#if PY_MAJOR_VERSION >= 3 + ob_base.ob_refcnt = 1; + ob_base.ob_type = type; +#else + ob_refcnt = 1; + ob_type = type; +#endif + } + + static void Py_dealloc(PyVar* self) + { + delete self; + } + + static PyObject * Py_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/) + { + PyVar* self = new PyVar(type); + return (PyObject *)self; + } + + static int Py_init(PyVar *self, PyObject *args, PyObject * /*kwds*/) + { + char* cNamespace = 0; + if (!PyArg_ParseTuple(args, "s", &cNamespace)) + return -1; + + self->ns = std::string(cNamespace); + + return 0; + } + + static PyObject* Py_getattr(PyVar *self, char* name) + { + const std::string prefix = self->ns + "."; + const std::string full_name = self->ns.empty() ? name : prefix + std::string(name); + + if( !strcmp(name, "__call__") || + !strcmp(name, "__dict__") || + !strcmp(name, "__methods__") || + !strcmp(name, "__class__") ) + { + // Default behaviour +#if PY_MAJOR_VERSION >= 3 + return PyObject_GenericGetAttr((PyObject*)self, PyUnicode_FromString(name)); +#else + return PyObject_GenericGetAttr((PyObject*)self, PyString_FromString(name)); +#endif + } else if( !strcmp(name, "__members__") ) { + const int nss = prefix.size(); + PyObject* l = PyList_New(0); + for(const std::string& s : VarState::I().var_adds) { + if(!s.compare(0, nss, prefix)) { + size_t dot = s.find_first_of('.', nss); + std::string val = (dot != std::string::npos) ? s.substr(nss, dot - nss) : s.substr(nss); +#if PY_MAJOR_VERSION >= 3 + PyList_Append(l, PyUnicode_FromString(val.c_str())); +#else + PyList_Append(l, PyString_FromString(val.c_str())); +#endif + } + } + + return l; + }else if( pangolin::VarState::I().Exists(full_name) ) { + return GetPangoVarAsPython(full_name); + }else{ + PyVar* obj = (PyVar*)PyVar::Py_new(&PyVar::Py_type,NULL,NULL); + if(obj) { + obj->ns = full_name; + return PyObject_Init((PyObject *)obj,&PyVar::Py_type); + } + return (PyObject *)obj; + } + + Py_RETURN_NONE; + } + + static int Py_setattr(PyVar *self, char* name, PyObject* val) + { + const std::string full_name = self->ns.empty() ? name : self->ns + "." + std::string(name); + SetPangoVarFromPython(full_name, val); + return 0; + } + + std::string ns; +}; + +// The uninitialized variable can be ignored. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + PyTypeObject PyVar::Py_type = { + PyVarObject_HEAD_INIT(NULL,0) + "pypangolin.Var", /* tp_name*/ + sizeof(PyVar), /* tp_basicsize*/ + 0, /* tp_itemsize*/ + (destructor)PyVar::Py_dealloc, /* tp_dealloc*/ + 0, /* tp_print*/ + (getattrfunc)PyVar::Py_getattr, /* tp_getattr*/ + (setattrfunc)PyVar::Py_setattr, /* tp_setattr*/ + 0, /* tp_compare*/ + 0, /* tp_repr*/ + 0, /* tp_as_number*/ + 0, /* tp_as_sequence*/ + 0, /* tp_as_mapping*/ + 0, /* tp_hash */ + 0, /* tp_call*/ + 0, /* tp_str*/ + 0, /* tp_getattro*/ + 0, /* tp_setattro*/ + 0, /* tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ + "PyVar object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)PyVar::Py_init, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)PyVar::Py_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0 /* tp_version_tag */ +}; +#pragma GCC diagnostic pop + +} diff --git a/thirdparty/Pangolin/include/pangolin/scene/axis.h b/thirdparty/Pangolin/include/pangolin/scene/axis.h new file mode 100644 index 00000000..a0a33883 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/scene/axis.h @@ -0,0 +1,117 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#ifdef HAVE_EIGEN +# include +#endif + +namespace pangolin { + +struct Axis : public Renderable, public Interactive +{ + Axis() + : axis_length(1.0), + label_x(InteractiveIndex::I().Store(this)), + label_y(InteractiveIndex::I().Store(this)), + label_z(InteractiveIndex::I().Store(this)) + { + } + + void Render(const RenderParams&) override { + glColor4f(1,0,0,1); + glPushName(label_x.Id()); + glDrawLine(0,0,0, axis_length,0,0); + glPopName(); + + glColor4f(0,1,0,1); + glPushName(label_y.Id()); + glDrawLine(0,0,0, 0,axis_length,0); + glPopName(); + + glColor4f(0,0,1,1); + glPushName(label_z.Id()); + glDrawLine(0,0,0, 0,0,axis_length); + glPopName(); + } + + bool Mouse( + int button, + const GLprecision /*win*/[3], const GLprecision /*obj*/[3], const GLprecision /*normal*/[3], + bool /*pressed*/, int button_state, int pickId + ) override + { + PANGOLIN_UNUSED(button); + PANGOLIN_UNUSED(button_state); + PANGOLIN_UNUSED(pickId); + +#ifdef HAVE_EIGEN + if((button == MouseWheelUp || button == MouseWheelDown) ) { + float scale = (button == MouseWheelUp) ? 0.01f : -0.01f; + if(button_state & KeyModifierShift) scale /= 10; + + Eigen::Vector3d rot = Eigen::Vector3d::Zero(); + Eigen::Vector3d xyz = Eigen::Vector3d::Zero(); + + + if(button_state & KeyModifierCtrl) { + // rotate + if(pickId == label_x.Id()) { + rot << 1,0,0; + }else if(pickId == label_y.Id()) { + rot << 0,1,0; + }else if(pickId == label_z.Id()) { + rot << 0,0,1; + }else{ + return false; + } + }else if(button_state & KeyModifierShift){ + // translate + if(pickId == label_x.Id()) { + xyz << 1,0,0; + }else if(pickId == label_y.Id()) { + xyz << 0,1,0; + }else if(pickId == label_z.Id()) { + xyz << 0,0,1; + }else{ + return false; + } + }else{ + return false; + } + + // old from new + Eigen::Matrix T_on = Eigen::Matrix::Identity(); + T_on.block<3,3>(0,0) = Eigen::AngleAxis(scale,rot).toRotationMatrix(); + T_on.block<3,1>(0,3) = scale*xyz; + + // Update + T_pc = (ToEigen(T_pc) * T_on.inverse()).eval(); + + return true; + } +#endif // HAVE_EIGEN + + return false; + } + + virtual bool MouseMotion( + const GLprecision /*win*/[3], const GLprecision /*obj*/[3], const GLprecision /*normal*/[3], + int /*button_state*/, int /*pickId*/ + ) override + { + return false; + } + + float axis_length; + const InteractiveIndex::Token label_x; + const InteractiveIndex::Token label_y; + const InteractiveIndex::Token label_z; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/scene/interactive.h b/thirdparty/Pangolin/include/pangolin/scene/interactive.h new file mode 100644 index 00000000..6e6ffa21 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/scene/interactive.h @@ -0,0 +1,69 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin { + + +struct Interactive +{ + static __thread GLuint current_id; + + virtual ~Interactive() {} + + virtual bool Mouse( + int button, + const GLprecision win[3], const GLprecision obj[3], const GLprecision normal[3], + bool pressed, int button_state, int pickId + ) = 0; + + virtual bool MouseMotion( + const GLprecision win[3], const GLprecision obj[3], const GLprecision normal[3], + int button_state, int pickId + ) = 0; +}; + +struct RenderParams +{ + RenderParams() + : render_mode(GL_RENDER) + { + } + + GLint render_mode; +}; + +struct Manipulator : public Interactive +{ + virtual void Render(const RenderParams& params) = 0; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/scene/interactive_index.h b/thirdparty/Pangolin/include/pangolin/scene/interactive_index.h new file mode 100644 index 00000000..af9862f6 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/scene/interactive_index.h @@ -0,0 +1,115 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include + +namespace pangolin { + +class InteractiveIndex +{ +public: + class Token + { + public: + friend class InteractiveIndex; + + Token() + : id(0) + { + } + + Token(Token&& o) + : id(o.id) + { + o.id = 0; + } + + GLint Id() const + { + return id; + } + + ~Token() + { + if(id) { + InteractiveIndex::I().Unstore(*this); + } + } + + private: + Token(GLint id) + : id(id) + { + } + + + GLint id; + }; + + static InteractiveIndex& I() + { + static InteractiveIndex instance; + return instance; + } + + Interactive* Find(GLuint id) + { + auto kv = index.find(id); + if(kv != index.end()) { + return kv->second; + } + return nullptr; + } + + Token Store(Interactive* r) + { + index[next_id] = r; + return Token(next_id++); + } + + void Unstore(Token& t) + { + index.erase(t.id); + t.id = 0; + } + +private: + // Private constructor. + InteractiveIndex() + : next_id(1) + { + } + + GLint next_id; + std::map index; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/scene/renderable.h b/thirdparty/Pangolin/include/pangolin/scene/renderable.h new file mode 100644 index 00000000..3e21c727 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/scene/renderable.h @@ -0,0 +1,117 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include + +namespace pangolin { + +class Renderable +{ +public: + using guid_t = GLuint; + + static guid_t UniqueGuid() + { + static std::random_device rd; + static std::mt19937 gen(rd()); + return (guid_t)gen(); + } + + Renderable(const std::weak_ptr& parent = std::weak_ptr()) + : guid(UniqueGuid()), parent(parent), T_pc(IdentityMatrix()), should_show(true) + { + } + + virtual ~Renderable() + { + } + + // Default implementation simply renders children. + virtual void Render(const RenderParams& params = RenderParams()) { + RenderChildren(params); + } + + void RenderChildren(const RenderParams& params) + { + for(auto& p : children) { + Renderable& r = *p.second; + if(r.should_show) { + glPushMatrix(); + r.T_pc.Multiply(); + r.Render(params); + if(r.manipulator) { + r.manipulator->Render(params); + } + glPopMatrix(); + } + } + } + + std::shared_ptr FindChild(guid_t guid) + { + auto o = children.find(guid); + if(o != children.end()) { + return o->second; + } + + for(auto& kv : children ) { + std::shared_ptr c = kv.second->FindChild(guid); + if(c) return c; + } + + return std::shared_ptr(); + } + + Renderable& Add(const std::shared_ptr& child) + { + if(child) { + children[child->guid] = child; + }; + return *this; + } + + // Renderable properties + const guid_t guid; + std::weak_ptr parent; + pangolin::OpenGlMatrix T_pc; + bool should_show; + + // Children + std::map> children; + + // Manipulator (handler, thing) + std::shared_ptr manipulator; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/scene/scenehandler.h b/thirdparty/Pangolin/include/pangolin/scene/scenehandler.h new file mode 100644 index 00000000..c23f1309 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/scene/scenehandler.h @@ -0,0 +1,182 @@ +#pragma once + +#include +#include +#include + +namespace pangolin { + +inline void gluPickMatrix( + GLdouble x, GLdouble y, + GLdouble width, GLdouble height, + GLint viewport[4] +) { + GLfloat m[16]; + GLfloat sx, sy; + GLfloat tx, ty; + sx = viewport[2] / (GLfloat)width; + sy = viewport[3] / (GLfloat)height; + tx = (viewport[2] + 2.0f * (viewport[0] - (GLfloat)x)) / (GLfloat)width; + ty = (viewport[3] + 2.0f * (viewport[1] - (GLfloat)y)) / (GLfloat)height; +#define M(row, col) m[col*4+row] + M(0, 0) = sx; + M(0, 1) = 0.0f; + M(0, 2) = 0.0f; + M(0, 3) = tx; + M(1, 0) = 0.0f; + M(1, 1) = sy; + M(1, 2) = 0.0f; + M(1, 3) = ty; + M(2, 0) = 0.0f; + M(2, 1) = 0.0f; + M(2, 2) = 1.0f; + M(2, 3) = 0.0f; + M(3, 0) = 0.0f; + M(3, 1) = 0.0f; + M(3, 2) = 0.0f; + M(3, 3) = 1.0f; +#undef M + glMultMatrixf(m); +} + + + +struct SceneHandler : public Handler3D +{ + SceneHandler( + Renderable& scene, + OpenGlRenderState& cam_state + ) : Handler3D(cam_state), scene(scene) + { + + } + + void ProcessHitBuffer(GLint hits, GLuint* buf, std::map& hit_map ) + { + GLuint* closestNames = 0; + GLuint closestNumNames = 0; + GLuint closestZ = std::numeric_limits::max(); + for (int i = 0; i < hits; i++) { + if (buf[1] < closestZ) { + closestNames = buf + 3; + closestNumNames = buf[0]; + closestZ = buf[1]; + } + buf += buf[0] + 3; + } + for (unsigned int i = 0; i < closestNumNames; i++) { + const int pickId = closestNames[i]; + hit_map[pickId] = InteractiveIndex::I().Find(pickId); + } + } + + void ComputeHits(pangolin::View& view, + const pangolin::OpenGlRenderState& cam_state, + int x, int y, int grab_width, + std::map& hit_objects ) + { + // Get views viewport / modelview /projection + GLint viewport[4] = {view.v.l, view.v.b, view.v.w, view.v.h}; + pangolin::OpenGlMatrix mv = cam_state.GetModelViewMatrix(); + pangolin::OpenGlMatrix proj = cam_state.GetProjectionMatrix(); + + // Prepare hit buffer object + const unsigned int MAX_SEL_SIZE = 64; + GLuint vSelectBuf[MAX_SEL_SIZE]; + glSelectBuffer(MAX_SEL_SIZE, vSelectBuf); + + // Load and adjust modelview projection matrices + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPickMatrix(x, y, grab_width, grab_width, viewport); + proj.Multiply(); + glMatrixMode(GL_MODELVIEW); + mv.Load(); + + // Render scenegraph in 'select' mode + glRenderMode(GL_SELECT); + glInitNames(); + RenderParams select; + select.render_mode = GL_SELECT; + scene.Render(select); + glFlush(); + + GLint nHits = glRenderMode(GL_RENDER); + // std::cout << " -- Number of Hits are: " << nHits << std::endl; + // std::cout << " -- size of hitobjects: " << hit_objects.size() << std::endl; + if (nHits > 0) { + ProcessHitBuffer(nHits, vSelectBuf, hit_objects); + } + } + + void Mouse(pangolin::View& view, pangolin::MouseButton button, + int x, int y, bool pressed, int button_state) + { + GetPosNormal(view, x, y, p, Pw, Pc, n); + bool handled = false; + + if (pressed) { + m_selected_objects.clear(); + ComputeHits(view, *cam_state, x, y, 2*hwin+1, m_selected_objects); + } + + for (auto kv : m_selected_objects) + { + Interactive* ir = dynamic_cast(kv.second); + handled |= ir && ir->Mouse( button, p, Pw, n, pressed, button_state, kv.first); + } + + if (!handled) { + Handler3D::Mouse(view, button, x, y, pressed, button_state); + } + } + + void MouseMotion(pangolin::View& view, int x, int y, int button_state) + { + GetPosNormal(view, x, y, p, Pw, Pc, n); + bool handled = false; + for (auto kv : m_selected_objects) + { + Interactive* ir = dynamic_cast(kv.second); + + handled |= ir && ir->MouseMotion( p, Pw, n, button_state, kv.first); + } + if (!handled) { + pangolin::Handler3D::MouseMotion(view, x, y, button_state); + } + } + + void Special(pangolin::View& view, pangolin::InputSpecial inType, + float x, float y, float p1, float p2, float p3, float p4, + int button_state) + { + GetPosNormal(view, (int)x, (int)y, p, Pw, Pc, n); + + bool handled = false; + + if (inType == pangolin::InputSpecialScroll) + { + m_selected_objects.clear(); + ComputeHits(view, *cam_state, (int)x, (int)y, 2*hwin+1, m_selected_objects); + + const MouseButton button = p2 > 0 ? MouseWheelUp : MouseWheelDown; + + for (auto kv : m_selected_objects) + { + Interactive* ir = dynamic_cast(kv.second); + handled |= ir && ir->Mouse( button, p, Pw, n, true, button_state, kv.first); + } + } + + if (!handled) { + pangolin::Handler3D::Special(view, inType, x, y, + p1, p2, p3, p4, button_state); + } + } + + std::map m_selected_objects; + Renderable& scene; + unsigned int grab_width; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/scene/tree.h b/thirdparty/Pangolin/include/pangolin/scene/tree.h new file mode 100644 index 00000000..9797b860 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/scene/tree.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include + +namespace pangolin { + +template +struct TreeNode +{ + struct Edge + { + TEdge parent_child; + TreeNode node; + }; + + T item; + std::vector edges; +}; + +template +using NodeFunction = std::function&,const TEdge&)>; + +//template +//void VisitDepthFirst(TreeNode& node, const NodeFunction& func, const TEdge& T_root_node = TEdge()) +//{ +// func(node, T_root_node); +// for(auto& e : node.edges) { +// const TEdge T_root_child = T_root_node * e.parent_child; +// VisitDepthFirst(e.node, func, T_root_child); +// } +//} + +//void Eg() +//{ +// using RenderNode = TreeNode,OpenGlMatrix>; + +// RenderNode root; +// VisitDepthFirst,OpenGlMatrix>( +// root, [](RenderNode& node, const OpenGlMatrix& T_root_node) { +// if(node.item) { +// node.item->DoRender(); +// } +// }, IdentityMatrix()); + +//} + + +} diff --git a/thirdparty/Pangolin/include/pangolin/tools/video_viewer.h b/thirdparty/Pangolin/include/pangolin/tools/video_viewer.h new file mode 100644 index 00000000..c72d1712 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/tools/video_viewer.h @@ -0,0 +1,106 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace pangolin +{ + +PANGOLIN_EXPORT +class VideoViewer +{ +public: + typedef std::function >& images, + const picojson::value& properties)> FrameChangedCallbackFn; + + static constexpr int FRAME_SKIP = 30; + + VideoViewer(const std::string& window_name, const std::string& input_uri, const std::string& output_uri = "video.pango" ); + VideoViewer(const VideoViewer&) = delete; + + virtual ~VideoViewer(); + + void Run(); + void RunAsync(); + + void Quit(); + void QuitAndWait(); + + inline int TotalFrames() const + { + return video_playback ? video_playback->GetTotalFrames() : std::numeric_limits::max(); + } + + // Control playback + void OpenInput(const std::string& input_uri); + void CloseInput(); + + // Control recording + void Record(); + void RecordOneFrame(); + void StopRecording(); + + // Useful for user-control + void TogglePlay(); + void ToggleRecord(); + void ToggleDiscardBufferedFrames(); + void ToggleWaitForFrames(); + void SetDiscardBufferedFrames(bool new_state); + void SetWaitForFrames(bool new_state); + void Skip(int frames); + bool ChangeExposure(int delta_us); + bool ChangeGain(float delta); + void SetActiveCamera(int delta); + void DrawEveryNFrames(int n); + + + // Register to be notified of new image data + void SetFrameChangedCallback(FrameChangedCallbackFn cb); + + void WaitUntilExit(); + + + VideoInput& Video() {return video;} + const VideoInput& Video() const {return video;} + + void SetRecordNthFrame(int record_nth_frame_) { + record_nth_frame = record_nth_frame_; + } + + +protected: + void RegisterDefaultKeyShortcutsAndPangoVariables(); + + std::mutex control_mutex; + std::string window_name; + std::thread vv_thread; + + VideoInput video; + VideoPlaybackInterface* video_playback; + VideoInterface* video_interface; + + std::string output_uri; + + int current_frame; + int grab_until; + int record_nth_frame; + int draw_nth_frame; + bool video_grab_wait; + bool video_grab_newest; + bool should_run; + uint16_t active_cam; + + FrameChangedCallbackFn frame_changed_callback; +}; + + +void PANGOLIN_EXPORT RunVideoViewerUI(const std::string& input_uri, const std::string& output_uri); + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/argagg.hpp b/thirdparty/Pangolin/include/pangolin/utils/argagg.hpp new file mode 100644 index 00000000..70e28526 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/argagg.hpp @@ -0,0 +1,1548 @@ +/* + * @file + * @brief + * Defines a very simple command line argument parser. + * + * @copyright + * Copyright (c) 2017 Viet The Nguyen + * + * @copyright + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * @copyright + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * @copyright + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#pragma once +#ifndef ARGAGG_ARGAGG_ARGAGG_HPP +#define ARGAGG_ARGAGG_ARGAGG_HPP + +#ifdef __unix__ +#include +#include +#endif // #ifdef __unix__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/** + * @brief + * There are only two hard things in Computer Science: cache invalidation and + * naming things (Phil Karlton). + * + * The names of types have to be succint and clear. This has turned out to be a + * more difficult thing than I expected. Here you'll find a quick overview of + * the type names you'll find in this namespace (and thus "library"). + * + * When a program is invoked it is passed a number of "command line arguments". + * Each of these "arguments" is a string (C-string to be more precise). An + * "option" is a command line argument that has special meaning. This library + * recognizes a command line argument as a potential option if it starts with a + * dash ('-') or double-dash ('--'). + * + * A "parser" is a set of "definitions" (not a literal std::set but rather a + * std::vector). A parser is represented by the argagg::parser struct. + * + * A "definition" is a structure with four components that define what + * "options" are recognized. The four components are the name of the option, + * the strings that represent the option, the option's help text, and how many + * arguments the option should expect. "Flags" are the individual strings that + * represent the option ("-v" and "--verbose" are flags for the "verbose" + * option). A definition is represented by the argagg::definition struct. + * + * Note at this point that the word "option" can be used interchangeably to + * mean the notion of an option and the actual instance of an option given a + * set of command line arguments. To be unambiguous we use a "definition" to + * represent the notion of an option and an "option result" to represent an + * actual option parsed from a set of command line arguments. An "option + * result" is represented by the argagg::option_result struct. + * + * There's one more wrinkle to this: an option can show up multiple times in a + * given set of command line arguments. For example, "-n 1 -n 2 -n 3". This + * will parse into three distinct argagg::option_result instances, but all of + * them correspond to the same argagg::definition. We aggregate these into the + * argagg::option_results struct which represents "all parser results for a + * given option definition". This argagg::option_results is basically a + * std::vector of argagg::option_result. + * + * Options aren't the only thing parsed though. Positional arguments are also + * parsed. Thus a parser produces a result that contains both option results + * and positional arguments. The parser results are represented by the + * argagg::parser_results struct. All option results are stored in a mapping + * from option name to the argagg::option_results. All positional arguments are + * simply stored in a vector of C-strings. + */ +namespace argagg { + + +/** + * @brief + * This exception is thrown when a long option is parsed and is given an + * argument using the "=" syntax but the option doesn't expect an argument. + */ +struct unexpected_argument_error +: public std::runtime_error { + using std::runtime_error::runtime_error; +}; + + +/** + * @brief + * This exception is thrown when an option is parsed unexpectedly such as when + * an argument was expected for a previous option or if an option was found + * that has not been defined. + */ +struct unexpected_option_error +: public std::runtime_error { + using std::runtime_error::runtime_error; +}; + + +/** + * @brief + * This exception is thrown when an option requires an argument but is not + * provided one. This can happen if another flag was found after the option or + * if we simply reach the end of the command line arguments. + */ +struct option_lacks_argument_error +: public std::runtime_error { + using std::runtime_error::runtime_error; +}; + + +/** + * @brief + * This exception is thrown when an option's flag is invalid. This can be the + * case if the flag is not prefixed by one or two hyphens or contains non + * alpha-numeric characters after the hypens. See is_valid_flag_definition() + * for more details. + */ +struct invalid_flag +: public std::runtime_error { + using std::runtime_error::runtime_error; +}; + + +/** + * @brief + * The set of template instantiations that convert C-strings to other types for + * the option_result::as(), option_results::as(), parser_results::as(), and + * parser_results::all_as() methods are placed in this namespace. + */ +namespace convert { + + /** + * @brief + * Explicit instantiations of this function are used to convert arguments to + * types. + */ + template + T arg(const char* arg); + +} + + +/** + * @brief + * Represents a single option parse result. + * + * You can check if this has an argument by using the implicit boolean + * conversion. + */ +struct option_result { + + /** + * @brief + * Argument parsed for this single option. If no argument was parsed this + * will be set to nullptr. + */ + const char* arg; + + /** + * @brief + * Converts the argument parsed for this single option instance into the + * given type using the type matched conversion function + * argagg::convert::arg(). If there was not an argument parsed for this + * single option instance then a argagg::option_lacks_argument_error + * exception is thrown. The specific conversion function may throw other + * exceptions. + */ + template + T as() const; + + /** + * @brief + * Converts the argument parsed for this single option instance into the + * given type using the type matched conversion function + * argagg::convert::arg(). If there was not an argument parsed for this + * single option instance then the provided default value is returned + * instead. If the conversion function throws an exception then it is ignored + * and the default value is returned. + */ + template + T as(const T& t) const; + + /** + * @brief + * Since we have the argagg::option_result::as() API we might as well alias + * it as an implicit conversion operator. This performs implicit conversion + * using the argagg::option_result::as() method. + * + * @note + * An implicit boolean conversion specialization exists which returns false + * if there is no argument for this single option instance and true + * otherwise. This specialization DOES NOT convert the argument to a bool. If + * you need to convert the argument to a bool then use the as() API. + */ + template + operator T () const; + +}; + + +/** + * @brief + * Represents multiple option parse results for a single option. If treated as + * a single parse result it defaults to the last parse result. Note that an + * instance of this struct is always created even if no option results are + * parsed for a given definition. In that case it will simply be empty. + * + * To check if the associated option showed up at all simply use the implicit + * boolean conversion or check if count() is greater than zero. + */ +struct option_results { + + /** + * @brief + * All option parse results for this option. + */ + std::vector all; + + /** + * @brief + * Gets the number of times the option shows up. + */ + std::size_t count() const; + + /** + * @brief + * Gets a single option parse result by index. + */ + option_result& operator [] (std::size_t index); + + /** + * @brief + * Gets a single option result by index. + */ + const option_result& operator [] (std::size_t index) const; + + /** + * @brief + * Converts the argument parsed for the LAST option parse result for the + * parent definition to the provided type. For example, if this was for "-f 1 + * -f 2 -f 3" then calling this method for an integer type will return 3. If + * there are no option parse results then a std::out_of_range exception is + * thrown. Any exceptions thrown by option_result::as() are not + * handled. + */ + template + T as() const; + + /** + * @brief + * Converts the argument parsed for the LAST option parse result for the + * parent definition to the provided type. For example, if this was for "-f 1 + * -f 2 -f 3" then calling this method for an integer type will return 3. If + * there are no option parse results then the provided default value is + * returned instead. + */ + template + T as(const T& t) const; + + /** + * @brief + * Since we have the option_results::as() API we might as well alias + * it as an implicit conversion operator. This performs implicit conversion + * using the option_results::as() method. + * + * @note + * An implicit boolean conversion specialization exists which returns false + * if there is no argument for this single option instance and true + * otherwise. This specialization DOES NOT convert the argument to a bool. If + * you need to convert the argument to a bool then use the as() API. + */ + template + operator T () const; + +}; + + +/** + * @brief + * Represents all results of the parser including options and positional + * arguments. + */ +struct parser_results { + + /** + * @brief + * Returns the name of the program from the original arguments list. This is + * always the first argument. + */ + const char* program; + + /** + * @brief + * Maps from definition name to the structure which contains the parser + * results for that definition. + */ + std::unordered_map options; + + /** + * @brief + * Vector of positional arguments. + */ + std::vector pos; + + /** + * @brief + * Used to check if an option was specified at all. + */ + bool has_option(const std::string& name) const; + + /** + * @brief + * Get the parser results for the given definition. If the definition never + * showed up then the exception from the unordered_map access will bubble + * through so check if the flag exists in the first place with has_option(). + */ + option_results& operator [] (const std::string& name); + + /** + * @brief + * Get the parser results for the given definition. If the definition never + * showed up then the exception from the unordered_map access will bubble + * through so check if the flag exists in the first place with has_option(). + */ + const option_results& operator [] (const std::string& name) const; + + /** + * @brief + * Gets the number of positional arguments. + */ + std::size_t count() const; + + /** + * @brief + * Gets a positional argument by index. + */ + const char* operator [] (std::size_t index) const; + + /** + * @brief + * Gets a positional argument converted to the given type. + */ + template + T as(std::size_t i = 0) const; + + /** + * @brief + * Gets all positional arguments converted to the given type. + */ + template + std::vector all_as() const; + +}; + + +/** + * @brief + * An option definition which essentially represents what an option is. + */ +struct definition { + + /** + * @brief + * Name of the option. Option parser results are keyed by this name. + */ + const std::string name; + + /** + * @brief + * List of strings to match that correspond to this option. Should be fully + * specified with hyphens (e.g. "-v" or "--verbose"). + */ + std::vector flags; + + /** + * @brief + * Help string for this option. + */ + std::string help; + + /** + * @brief + * Number of arguments this option requires. Must be 0 or 1. All other values + * have undefined behavior. Okay, the code actually works with positive + * values in general, but it's unorthodox command line behavior. + */ + unsigned int num_args; + + /** + * @brief + * Returns true if this option does not want any arguments. + */ + bool wants_no_arguments() const; + + /** + * @brief + * Returns true if this option requires arguments. + */ + bool requires_arguments() const; + +}; + + +/** + * @brief + * Checks whether or not a command line argument should be processed as an + * option flag. This is very similar to is_valid_flag_definition() but must + * allow for short flag groups (e.g. "-abc") and equal-assigned long flag + * arguments (e.g. "--output=foo.txt"). + */ +bool cmd_line_arg_is_option_flag( + const char* s); + + +/** + * @brief + * Checks whether a flag in an option definition is valid. I suggest reading + * through the function source to understand what dictates a valid. + */ +bool is_valid_flag_definition( + const char* s); + + +/** + * @brief + * Tests whether or not a valid flag is short. Assumes the provided cstring is + * already a valid flag. + */ +bool flag_is_short( + const char* s); + + +/** + * @brief + * Contains two maps which aid in option parsing. The first map, @ref + * short_map, maps from a short flag (just a character) to a pointer to the + * original @ref definition that the flag represents. The second map, @ref + * long_map, maps from a long flag (an std::string) to a pointer to the + * original @ref definition that the flag represents. + * + * This object is usually a temporary that only exists during the parsing + * operation. It is typically constructed using @ref validate_definitions(). + */ +struct parser_map { + + /** + * @brief + * Maps from a short flag (just a character) to a pointer to the original + * @ref definition that the flag represents. + */ + std::array short_map; + + /** + * @brief + * Maps from a long flag (an std::string) to a pointer to the original @ref + * definition that the flag represents. + */ + std::unordered_map long_map; + + /** + * @brief + * Returns true if the provided short flag exists in the map object. + */ + bool known_short_flag( + const char flag) const; + + /** + * @brief + * If the short flag exists in the map object then it is returned by this + * method. If it doesn't then nullptr will be returned. + */ + const definition* get_definition_for_short_flag( + const char flag) const; + + /** + * @brief + * Returns true if the provided long flag exists in the map object. + */ + bool known_long_flag( + const std::string& flag) const; + + /** + * @brief + * If the long flag exists in the map object then it is returned by this + * method. If it doesn't then nullptr will be returned. + */ + const definition* get_definition_for_long_flag( + const std::string& flag) const; + +}; + + +/** + * @brief + * Validates a collection (specifically an std::vector) of @ref definition + * objects by checking if the contained flags are valid. If the set of @ref + * definition objects is not valid then an exception is thrown. Upon successful + * validation a @ref parser_map object is returned. + */ +parser_map validate_definitions( + const std::vector& definitions); + + +/** + * @brief + * A list of option definitions used to inform how to parse arguments. + */ +struct parser { + + /** + * @brief + * Vector of the option definitions which inform this parser how to parse + * the command line arguments. + */ + std::vector definitions; + + /** + * @brief + * Parses the provided command line arguments and returns the results as + * @ref parser_results. + * + * @note + * This method is not thread-safe and assumes that no modifications are made + * to the definitions member field during the extent of this method call. + */ + parser_results parse(int argc, const char** argv) const; + + /** + * @brief + * Through strict interpretation of pointer casting rules, despite this being + * a safe operation, C++ doesn't allow implicit casts from char** to + * const char** so here's an overload that performs a const_cast, + * which is typically frowned upon but is safe here. + */ + parser_results parse(int argc, char** argv) const; + +}; + + +/** + * @brief + * A convenience output stream that will accumulate what is streamed to it and + * then, on destruction, format the accumulated string using the fmt program + * (via the argagg::fmt_string() function) to the provided std::ostream. + * + * Example use: + * + * @code + * { + * argagg::fmt_ostream f(std::cerr); + * f << "Usage: " << really_long_string << std::endl; + * } // on destruction here the formatted string will be streamed to std::cerr + * @endcode + * + * @note + * This only has formatting behavior if the __unix__ preprocessor + * definition is defined since formatting relies on the POSIX API for forking, + * executing a process, and reading/writing to/from file descriptors. If that + * preprocessor definition is not defined then this class has the same overall + * behavior except the output string is not formatted (basically streams + * whatever the accumulated string is). See arggg::fmt_string(). + */ +struct fmt_ostream : public std::ostringstream { + + /** + * @brief + * Reference to the final output stream that the formatted string will be + * streamed to. + */ + std::ostream& output; + + /** + * @brief + * Construct to output to the provided output stream when this object is + * destroyed. + */ + fmt_ostream(std::ostream& output); + + /** + * @brief + * Special destructor that will format the accumulated string using fmt (via + * the argagg::fmt_string() function) and stream it to the std::ostream + * stored. + */ + ~fmt_ostream(); + +}; + + +/** + * @brief + * Processes the provided string using the fmt util and returns the resulting + * output as a string. Not the most efficient (in time or space) but gets the + * job done. + * + * This function is cowardly so if there are any errors encountered such as a + * syscall returning -1 then the input string is returned. + * + * @note + * This only has formatting behavior if the __unix__ preprocessor + * definition is defined since it relies on the POSIX API for forking, + * executing a process, reading/writing to/from file descriptors, and the + * existence of the fmt util. + */ +std::string fmt_string(const std::string& s); + + +} // namespace argagg + + +/** + * @brief + * Writes the option help to the given stream. + */ +std::ostream& operator << (std::ostream& os, const argagg::parser& x); + + +// ---- end of declarations, header-only implementations follow ---- + + +namespace argagg { + + +template +T option_result::as() const +{ + if (this->arg) { + return convert::arg(this->arg); + } else { + throw option_lacks_argument_error("option has no argument"); + } +} + + +template +T option_result::as(const T& t) const +{ + if (this->arg) { + try { + return convert::arg(this->arg); + } catch (...) { + return t; + } + } else { + // I actually think this will never happen. To call this method you have + // to access a specific option_result for an option. If there's a + // specific option_result then the option was found. If the option + // requires an argument then it will definitely have an argument + // otherwise the parser would have complained. + return t; + } +} + + +template +option_result::operator T () const +{ + return this->as(); +} + + +template <> inline +option_result::operator bool () const +{ + return this->arg != nullptr; +} + + +inline +std::size_t option_results::count() const +{ + return this->all.size(); +} + + +inline +option_result& option_results::operator [] (std::size_t index) +{ + return this->all[index]; +} + + +inline +const option_result& option_results::operator [] (std::size_t index) const +{ + return this->all[index]; +} + + +template +T option_results::as() const +{ + if (this->all.size() == 0) { + throw std::out_of_range("no option arguments to convert"); + } + return this->all.back().as(); +} + + +template +T option_results::as(const T& t) const +{ + if (this->all.size() == 0) { + return t; + } + return this->all.back().as(t); +} + + +template +option_results::operator T () const +{ + return this->as(); +} + + +template <> inline +option_results::operator bool () const +{ + return this->all.size() > 0; +} + + +inline +bool parser_results::has_option(const std::string& name) const +{ + const auto it = this->options.find(name); + return ( it != this->options.end()) && it->second.all.size() > 0; +} + + +inline +option_results& parser_results::operator [] (const std::string& name) +{ + return this->options.at(name); +} + + +inline +const option_results& +parser_results::operator [] (const std::string& name) const +{ + return this->options.at(name); +} + + +inline +std::size_t parser_results::count() const +{ + return this->pos.size(); +} + + +inline +const char* parser_results::operator [] (std::size_t index) const +{ + return this->pos[index]; +} + + +template +T parser_results::as(std::size_t i) const +{ + return convert::arg(this->pos[i]); +} + + +template +std::vector parser_results::all_as() const +{ + std::vector v(this->pos.size()); + std::transform( + this->pos.begin(), this->pos.end(), v.begin(), + [](const char* arg) { + return convert::arg(arg); + }); + return v; +} + + +inline +bool definition::wants_no_arguments() const +{ + return this->num_args == 0; +} + + +inline +bool definition::requires_arguments() const +{ + return this->num_args > 0; +} + + +inline +bool cmd_line_arg_is_option_flag( + const char* s) +{ + auto len = std::strlen(s); + + // The shortest possible flag has two characters: a hyphen and an + // alpha-numeric character. + if (len < 2) { + return false; + } + + // All flags must start with a hyphen. + if (s[0] != '-') { + return false; + } + + // Shift the name forward by a character to account for the initial hyphen. + // This means if s was originally "-v" then name will be "v". + const char* name = s + 1; + + // Check if we're dealing with a long flag. + bool is_long = false; + if (s[1] == '-') { + is_long = true; + + // Just -- is not a valid flag. + if (len == 2) { + return false; + } + + // Shift the name forward to account for the extra hyphen. This means if s + // was originally "--output" then name will be "output". + name = s + 2; + } + + // The first character of the flag name must be alpha-numeric. This is to + // prevent things like "---a" from being valid flags. + len = std::strlen(name); + if (!std::isalnum(name[0])) { + return false; + } + + // At this point in is_valid_flag_definition() we would check if the short + // flag has only one character. At command line specification you can group + // short flags together or even add an argument to a short flag without a + // space delimiter. Thus we don't check if this has only one character + // because it might not. + + // If this is a long flag then we expect all characters *up to* an equal sign + // to be alpha-numeric or a hyphen. After the equal sign you are specify the + // argument to a long flag which can be basically anything. + if (is_long) { + bool encountered_equal = false; + return std::all_of(name, name + len, [&](const char& c) { + if (encountered_equal) { + return true; + } else { + if (c == '=') { + encountered_equal = true; + return true; + } + return std::isalnum(c) || c == '-'; + } + }); + } + + // At this point we are not dealing with a long flag. We already checked that + // the first character is alpha-numeric so we've got the case of a single + // short flag covered. This might be a short flag group though and we might + // be tempted to check that each character of the short flag group is + // alpha-numeric. However, you can specify the argument for a short flag + // without a space delimiter (e.g. "-I/usr/local/include") so you can't tell + // if the rest of a short flag group is part of the argument or not unless + // you know what is a defined flag or not. We leave that kind of processing + // to the parser. + return true; +} + + +inline +bool is_valid_flag_definition( + const char* s) +{ + auto len = std::strlen(s); + + // The shortest possible flag has two characters: a hyphen and an + // alpha-numeric character. + if (len < 2) { + return false; + } + + // All flags must start with a hyphen. + if (s[0] != '-') { + return false; + } + + // Shift the name forward by a character to account for the initial hyphen. + // This means if s was originally "-v" then name will be "v". + const char* name = s + 1; + + // Check if we're dealing with a long flag. + bool is_long = false; + if (s[1] == '-') { + is_long = true; + + // Just -- is not a valid flag. + if (len == 2) { + return false; + } + + // Shift the name forward to account for the extra hyphen. This means if s + // was originally "--output" then name will be "output". + name = s + 2; + } + + // The first character of the flag name must be alpha-numeric. This is to + // prevent things like "---a" from being valid flags. + len = std::strlen(name); + if (!std::isalnum(name[0])) { + return false; + } + + // If this is a short flag then it must only have one character. + if (!is_long && len > 1) { + return false; + } + + // The rest of the characters must be alpha-numeric, but long flags are + // allowed to have hyphens too. + return std::all_of(name + 1, name + len, [&](const char& c) { + return std::isalnum(c) || (c == '-' && is_long); + }); +} + + +inline +bool flag_is_short( + const char* s) +{ + return s[0] == '-' && std::isalnum(s[1]); +} + + +inline +bool parser_map::known_short_flag( + const char flag) const +{ + return this->short_map[flag] != nullptr; +} + + +inline +const definition* parser_map::get_definition_for_short_flag( + const char flag) const +{ + return this->short_map[flag]; +} + + +inline +bool parser_map::known_long_flag( + const std::string& flag) const +{ + const auto existing_long_flag = this->long_map.find(flag); + return existing_long_flag != long_map.end(); +} + + +inline +const definition* parser_map::get_definition_for_long_flag( + const std::string& flag) const +{ + const auto existing_long_flag = this->long_map.find(flag); + if (existing_long_flag == long_map.end()) { + return nullptr; + } + return existing_long_flag->second; +} + + +inline +parser_map validate_definitions( + const std::vector& definitions) +{ + std::unordered_map long_map; + parser_map map {{{nullptr}}, std::move(long_map)}; + + for (auto& defn : definitions) { + + if (defn.flags.size() == 0) { + std::ostringstream msg; + msg << "option \"" << defn.name << "\" has no flag definitions"; + throw invalid_flag(msg.str()); + } + + for (auto& flag : defn.flags) { + + if (!is_valid_flag_definition(flag.data())) { + std::ostringstream msg; + msg << "flag \"" << flag << "\" specified for option \"" << defn.name + << "\" is invalid"; + throw invalid_flag(msg.str()); + } + + if (flag_is_short(flag.data())) { + const int short_flag_letter = flag[1]; + const auto existing_short_flag = map.short_map[short_flag_letter]; + bool short_flag_already_exists = (existing_short_flag != nullptr); + if (short_flag_already_exists) { + std::ostringstream msg; + msg << "duplicate short flag \"" << flag + << "\" found, specified by both option \"" << defn.name + << "\" and option \"" << existing_short_flag->name; + throw invalid_flag(msg.str()); + } + map.short_map[short_flag_letter] = &defn; + continue; + } + + // If we're here then this is a valid, long-style flag. + if (map.known_long_flag(flag)) { + const auto existing_long_flag = map.get_definition_for_long_flag(flag); + std::ostringstream msg; + msg << "duplicate long flag \"" << flag + << "\" found, specified by both option \"" << defn.name + << "\" and option \"" << existing_long_flag->name; + throw invalid_flag(msg.str()); + } + map.long_map.insert(std::make_pair(flag, &defn)); + } + } + + return map; +} + + +inline +parser_results parser::parse(int argc, const char** argv) const +{ + // Inspect each definition to see if its valid. You may wonder "why don't + // you do this validation on construction?" I had thought about it but + // realized that since I've made the parser an aggregate type (granted it + // just "aggregates" a single vector) I would need to track any changes to + // the definitions vector and re-run the validity check in order to + // maintain this expected "validity invariant" on the object. That would + // then require hiding the definitions vector as a private entry and then + // turning the parser into a thin interface (by re-exposing setters and + // getters) to the vector methods just so that I can catch when the + // definition has been modified. It seems much simpler to just enforce the + // validity when you actually want to parser because it's at the moment of + // parsing that you know the definitions are complete. + parser_map map = validate_definitions(this->definitions); + + // Initialize the parser results that we'll be returning. Store the program + // name (assumed to be the first command line argument) and initialize + // everything else as empty. + std::unordered_map options {}; + std::vector pos; + parser_results results {argv[0], std::move(options), std::move(pos)}; + + // Add an empty option result for each definition. + for (const auto& defn : this->definitions) { + option_results opt_results {{}}; + results.options.insert( + std::make_pair(defn.name, opt_results)); + } + + // Don't start off ignoring flags. We only ignore flags after a -- shows up + // in the command line arguments. + bool ignore_flags = false; + + // Keep track of any options that are expecting arguments. + const char* last_flag_expecting_args = nullptr; + option_result* last_option_expecting_args = nullptr; + unsigned int num_option_args_to_consume = 0; + + // Get pointers to pointers so we can treat the raw pointer array as an + // iterator for standard library algorithms. This isn't used yet but can be + // used to template this function to work on iterators over strings or + // C-strings. + const char** arg_i = argv + 1; + const char** arg_end = argv + argc; + + while (arg_i != arg_end) { + auto arg_i_cstr = *arg_i; + auto arg_i_len = std::strlen(arg_i_cstr); + + // Some behavior to note: if the previous option is expecting an argument + // then the next entry will be treated as a positional argument even if + // it looks like a flag. + bool treat_as_positional_argument = ( + ignore_flags + || num_option_args_to_consume > 0 + || !cmd_line_arg_is_option_flag(arg_i_cstr) + ); + if (treat_as_positional_argument) { + + // If last option is expecting some specific positive number of + // arguments then give this argument to that option, *regardless of + // whether or not the argument looks like a flag or is the special "--" + // argument*. + if (num_option_args_to_consume > 0) { + last_option_expecting_args->arg = arg_i_cstr; + --num_option_args_to_consume; + ++arg_i; + continue; + } + + // Now we check if this is just "--" which is a special argument that + // causes all following arguments to be treated as non-options and is + // itselve discarded. + if (std::strncmp(arg_i_cstr, "--", 2) == 0 && arg_i_len == 2) { + ignore_flags = true; + ++arg_i; + continue; + } + + // If there are no expectations for option arguments then simply use + // this argument as a positional argument. + results.pos.push_back(arg_i_cstr); + ++arg_i; + continue; + } + + // Reset the "expecting argument" state. + last_flag_expecting_args = nullptr; + last_option_expecting_args = nullptr; + num_option_args_to_consume = 0; + + // If we're at this point then we're definitely dealing with something + // that is flag-like and has hyphen as the first character and has a + // length of at least two characters. How we handle this potential flag + // depends on whether or not it is a long-option so we check that first. + bool is_long_flag = (arg_i_cstr[1] == '-'); + + if (is_long_flag) { + + // Long flags have a complication: their arguments can be specified + // using an '=' character right inside the argument. That means an + // argument like "--output=foobar.txt" is actually an option with flag + // "--output" and argument "foobar.txt". So we look for the first + // instance of the '=' character and keep it in long_flag_arg. If + // long_flag_arg is nullptr then we didn't find '='. We need the + // flag_len to construct long_flag_str below. + auto long_flag_arg = std::strchr(arg_i_cstr, '='); + std::size_t flag_len = arg_i_len; + if (long_flag_arg != nullptr) { + flag_len = long_flag_arg - arg_i_cstr; + } + std::string long_flag_str(arg_i_cstr, flag_len); + + if (!map.known_long_flag(long_flag_str)) { + std::ostringstream msg; + msg << "found unexpected flag: " << long_flag_str; + throw unexpected_option_error(msg.str()); + } + + const auto defn = map.get_definition_for_long_flag(long_flag_str); + + if (long_flag_arg != nullptr && defn->num_args == 0) { + std::ostringstream msg; + msg << "found argument for option not expecting an argument: " + << arg_i_cstr; + throw unexpected_argument_error(msg.str()); + } + + // We've got a legitimate, known long flag option so we add an option + // result. This option result initially has an arg of nullptr, but that + // might change in the following block. + auto& opt_results = results.options[defn->name]; + option_result opt_result {nullptr}; + opt_results.all.push_back(std::move(opt_result)); + + if (defn->requires_arguments()) { + bool there_is_an_equal_delimited_arg = (long_flag_arg != nullptr); + if (there_is_an_equal_delimited_arg) { + // long_flag_arg would be "=foo" in the "--output=foo" case so we + // increment by 1 to get rid of the equal sign. + opt_results.all.back().arg = long_flag_arg + 1; + } else { + last_flag_expecting_args = arg_i_cstr; + last_option_expecting_args = &(opt_results.all.back()); + num_option_args_to_consume = defn->num_args; + } + } + + ++arg_i; + continue; + } + + // If we've made it here then we're looking at either a short flag or a + // group of short flags. Short flags can be grouped together so long as + // they don't require any arguments unless the option that does is the + // last in the group ("-o x -v" is okay, "-vo x" is okay, "-ov x" is + // not). So starting after the dash we're going to process each character + // as if it were a separate flag. Note "sf_idx" stands for "short flag + // index". + for (std::size_t sf_idx = 1; sf_idx < arg_i_len; ++sf_idx) { + const auto short_flag = arg_i_cstr[sf_idx]; + + if (!std::isalnum(short_flag)) { + std::ostringstream msg; + msg << "found non-alphanumeric character '" << arg_i_cstr[sf_idx] + << "' in flag group '" << arg_i_cstr << "'"; + throw std::domain_error(msg.str()); + } + + if (!map.known_short_flag(short_flag)) { + std::ostringstream msg; + msg << "found unexpected flag '" << arg_i_cstr[sf_idx] + << "' in flag group '" << arg_i_cstr << "'"; + throw unexpected_option_error(msg.str()); + } + + auto defn = map.get_definition_for_short_flag(short_flag); + auto& opt_results = results.options[defn->name]; + + // Create an option result with an empty argument (for now) and add it + // to this option's results. + option_result opt_result {nullptr}; + opt_results.all.push_back(std::move(opt_result)); + + if (defn->requires_arguments()) { + + // If this short flag's option requires an argument and we're the + // last flag in the short flag group then just put the parser into + // "expecting argument for last option" state and move onto the next + // command line argument. + bool is_last_short_flag_in_group = (sf_idx == arg_i_len - 1); + if (is_last_short_flag_in_group) { + last_flag_expecting_args = arg_i_cstr; + last_option_expecting_args = &(opt_results.all.back()); + num_option_args_to_consume = defn->num_args; + break; + } + + // If this short flag's option requires an argument and we're NOT the + // last flag in the short flag group then we automatically consume + // the rest of the short flag group as the argument for this flag. + // This is how we get the POSIX behavior of being able to specify a + // flag's arguments without a white space delimiter (e.g. + // "-I/usr/local/include"). + opt_results.all.back().arg = arg_i_cstr + sf_idx + 1; + break; + } + } + + ++arg_i; + continue; + } + + // If we're done with all of the arguments but are still expecting + // arguments for a previous option then we haven't satisfied that option. + // This is an error. + if (num_option_args_to_consume > 0) { + std::ostringstream msg; + msg << "last option \"" << last_flag_expecting_args + << "\" expects an argument but the parser ran out of command line " + << "arguments to parse"; + throw option_lacks_argument_error(msg.str()); + } + + return results; +} + + +inline +parser_results parser::parse(int argc, char** argv) const +{ + return parse(argc, const_cast(argv)); +} + + +namespace convert { + + + /** + * @brief + * Templated function for conversion to T using the @ref std::strtol() + * function. This is used for anything long length or shorter (long, int, + * short, char). + */ + template inline + T long_(const char* arg) + { + char* endptr = nullptr; + errno = 0; + T ret = static_cast(std::strtol(arg, &endptr, 0)); + if (endptr == arg) { + std::ostringstream msg; + msg << "unable to convert argument to integer: \"" << arg << "\""; + throw std::invalid_argument(msg.str()); + } + if (errno == ERANGE) { + throw std::out_of_range("argument numeric value out of range"); + } + return ret; + } + + + /** + * @brief + * Templated function for conversion to T using the @ref std::strtoll() + * function. This is used for anything long long length or shorter (long + * long). + */ + template inline + T long_long_(const char* arg) + { + char* endptr = nullptr; + errno = 0; + T ret = static_cast(std::strtoll(arg, &endptr, 0)); + if (endptr == arg) { + std::ostringstream msg; + msg << "unable to convert argument to integer: \"" << arg << "\""; + throw std::invalid_argument(msg.str()); + } + if (errno == ERANGE) { + throw std::out_of_range("argument numeric value out of range"); + } + return ret; + } + + +#define DEFINE_CONVERSION_FROM_LONG_(TYPE) \ + template <> inline \ + TYPE arg(const char* arg) \ + { \ + return long_(arg); \ + } + + DEFINE_CONVERSION_FROM_LONG_(char) + DEFINE_CONVERSION_FROM_LONG_(unsigned char) + DEFINE_CONVERSION_FROM_LONG_(signed char) + DEFINE_CONVERSION_FROM_LONG_(short) + DEFINE_CONVERSION_FROM_LONG_(unsigned short) + DEFINE_CONVERSION_FROM_LONG_(int) + DEFINE_CONVERSION_FROM_LONG_(unsigned int) + DEFINE_CONVERSION_FROM_LONG_(long) + DEFINE_CONVERSION_FROM_LONG_(unsigned long) + +#undef DEFINE_CONVERSION_FROM_LONG_ + + +#define DEFINE_CONVERSION_FROM_LONG_LONG_(TYPE) \ + template <> inline \ + TYPE arg(const char* arg) \ + { \ + return long_long_(arg); \ + } + + DEFINE_CONVERSION_FROM_LONG_LONG_(long long) + DEFINE_CONVERSION_FROM_LONG_LONG_(unsigned long long) + +#undef DEFINE_CONVERSION_FROM_LONG_LONG_ + + + template <> inline + bool arg(const char* arg) + { + return argagg::convert::arg(arg) != 0; + } + + + template <> inline + float arg(const char* arg) + { + char* endptr = nullptr; + errno = 0; + float ret = std::strtof(arg, &endptr); + if (endptr == arg) { + std::ostringstream msg; + msg << "unable to convert argument to integer: \"" << arg << "\""; + throw std::invalid_argument(msg.str()); + } + if (errno == ERANGE) { + throw std::out_of_range("argument numeric value out of range"); + } + return ret; + } + + + template <> inline + double arg(const char* arg) + { + char* endptr = nullptr; + errno = 0; + double ret = std::strtod(arg, &endptr); + if (endptr == arg) { + std::ostringstream msg; + msg << "unable to convert argument to integer: \"" << arg << "\""; + throw std::invalid_argument(msg.str()); + } + if (errno == ERANGE) { + throw std::out_of_range("argument numeric value out of range"); + } + return ret; + } + + + template <> inline + const char* arg(const char* arg) + { + return arg; + } + + + template <> inline + std::string arg(const char* arg) + { + return std::string(arg); + } + +} + + +inline +fmt_ostream::fmt_ostream(std::ostream& output) +: std::ostringstream(), output(output) +{ +} + + +inline +fmt_ostream::~fmt_ostream() +{ + output << fmt_string(this->str()); +} + + +#ifdef __unix__ + + +inline +std::string fmt_string(const std::string& s) +{ + constexpr int read_end = 0; + constexpr int write_end = 1; + + // TODO (vnguyen): This function overall needs to handle possible error + // returns from the various syscalls. + + int read_pipe[2]; + int write_pipe[2]; + if (pipe(read_pipe) == -1) { + return s; + } + if (pipe(write_pipe) == -1) { + return s; + } + + auto parent_pid = fork(); + bool is_fmt_proc = (parent_pid == 0); + if (is_fmt_proc) { + dup2(write_pipe[read_end], STDIN_FILENO); + dup2(read_pipe[write_end], STDOUT_FILENO); + close(write_pipe[read_end]); + close(write_pipe[write_end]); + close(read_pipe[read_end]); + close(read_pipe[write_end]); + const char* argv[] = {"fmt", NULL}; + execvp(const_cast(argv[0]), const_cast(argv)); + } + + close(write_pipe[read_end]); + close(read_pipe[write_end]); + auto fmt_write_fd = write_pipe[write_end]; + auto write_result = write(fmt_write_fd, s.c_str(), s.length()); + if (write_result != static_cast(s.length())) { + return s; + } + close(fmt_write_fd); + + auto fmt_read_fd = read_pipe[read_end]; + std::ostringstream os; + char buf[64]; + while (true) { + auto read_count = read( + fmt_read_fd, reinterpret_cast(buf), sizeof(buf)); + if (read_count <= 0) { + break; + } + os.write(buf, static_cast(read_count)); + } + close(fmt_read_fd); + + return os.str(); +} + + +#else // #ifdef __unix__ + + +inline +std::string fmt_string(const std::string& s) +{ + return s; +} + + +#endif // #ifdef __unix__ + + +} // namespace argagg + + +inline +std::ostream& operator << (std::ostream& os, const argagg::parser& x) +{ + for (auto& definition : x.definitions) { + os << " "; + for (auto& flag : definition.flags) { + os << flag; + if (flag != definition.flags.back()) { + os << ", "; + } + } + os << std::endl; + os << " " << definition.help << std::endl; + } + return os; +} + + +#endif // ARGAGG_ARGAGG_ARGAGG_HPP diff --git a/thirdparty/Pangolin/include/pangolin/utils/assert.h b/thirdparty/Pangolin/include/pangolin/utils/assert.h new file mode 100644 index 00000000..f0e70978 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/assert.h @@ -0,0 +1,60 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Hauke Strasdat, Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#ifdef __GNUC__ +# define PANGO_FUNCTION __PRETTY_FUNCTION__ +#elif (_MSC_VER >= 1310) +# define PANGO_FUNCTION __FUNCTION__ +#else +# define PANGO_FUNCTION "unknown" +#endif + +namespace pangolin { + +template PANGO_HOST_DEVICE +void abort(const char* function, const char* file, int line, Args&&... args) +{ + std::printf("pangolin::abort() in function '%s', file '%s', line %d.\n", function, file, line); +#ifndef __CUDACC__ + std::cout << FormatString(std::forward(args)...) << std::endl; + std::abort(); +#endif +} + +} + +// Always check, even in debug +#define PANGO_ENSURE(expr, ...) ((expr) ? ((void)0) : pangolin::abort(PANGO_FUNCTION, __FILE__, __LINE__, ##__VA_ARGS__)) + +// May be disabled for optimisation +#define PANGO_ASSERT(expr, ...) ((expr) ? ((void)0) : pangolin::abort(PANGO_FUNCTION, __FILE__, __LINE__, ##__VA_ARGS__)) diff --git a/thirdparty/Pangolin/include/pangolin/utils/compontent_cast.h b/thirdparty/Pangolin/include/pangolin/utils/compontent_cast.h new file mode 100644 index 00000000..9482f235 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/compontent_cast.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +#ifdef HAVE_EIGEN +# include +#endif + +namespace pangolin +{ + +// Scalar / Vector agnostic static_cast-like thing +// +// e.g. Promote float to double: +// ComponentCast::cast(0.14f); +// +// e.g. Promote Eigen::Vector2f to Eigen::Vector2d: +// ComponentCast::cast(Eigen::Vector2f(0.1,0.2); + +template +struct ComponentCast +{ + PANGO_HOST_DEVICE + static To cast(const From& val) + { + return static_cast(val); + } +}; + +#ifdef HAVE_EIGEN +template +struct ComponentCast > +{ + PANGO_HOST_DEVICE + static To cast(const Eigen::MatrixBase& val) + { + return val.template cast(); + } +}; +#endif + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/file_extension.h b/thirdparty/Pangolin/include/pangolin/utils/file_extension.h new file mode 100644 index 00000000..2912fac6 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/file_extension.h @@ -0,0 +1,74 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +enum ImageFileType +{ + ImageFileTypePpm, + ImageFileTypeTga, + ImageFileTypePng, + ImageFileTypeJpg, + ImageFileTypeTiff, + ImageFileTypeGif, + ImageFileTypeExr, + ImageFileTypePango, + ImageFileTypePvn, + ImageFileTypeZstd, + ImageFileTypeLz4, + ImageFileTypeP12b, + ImageFileTypePly, + ImageFileTypeObj, + ImageFileTypeUnknown +}; + + +PANGOLIN_EXPORT +std::string ImageFileTypeToName(ImageFileType); + +PANGOLIN_EXPORT +ImageFileType NameToImageFileType(const std::string&); + +PANGOLIN_EXPORT +std::string FileLowercaseExtention(const std::string& filename); + +PANGOLIN_EXPORT +ImageFileType FileTypeMagic(const unsigned char data[], size_t bytes); + +PANGOLIN_EXPORT +ImageFileType FileTypeExtension(const std::string& ext); + +PANGOLIN_EXPORT +ImageFileType FileType(const std::string& filename); + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/file_utils.h b/thirdparty/Pangolin/include/pangolin/utils/file_utils.h new file mode 100644 index 00000000..16905abf --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/file_utils.h @@ -0,0 +1,151 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace pangolin +{ + +PANGOLIN_EXPORT +std::vector& Split(const std::string& s, char delim, std::vector& elements); + +PANGOLIN_EXPORT +std::vector Split(const std::string &s, char delim); + +PANGOLIN_EXPORT +std::vector Expand(const std::string &s, char open='[', char close=']', char delim=','); + +PANGOLIN_EXPORT +std::string SanitizePath(const std::string& path); + +PANGOLIN_EXPORT +std::string PathParent(const std::string& path, int levels = 1); + +PANGOLIN_EXPORT +bool FileExists(const std::string& filename); + +PANGOLIN_EXPORT +std::string FindPath(const std::string& child_path, const std::string& signature_path); + +PANGOLIN_EXPORT +std::string PathExpand(const std::string& sPath); + +PANGOLIN_EXPORT +bool MatchesWildcard(const std::string& str, const std::string& wildcard); + +// Fill 'file_vec' with the files that match the glob-like 'wildcard_file_path' +// ? can be used to match any single charector +// * can be used to match any sequence of charectors in a directory +// ** can be used to match any directories across any number of levels +// e.g. FilesMatchingWildcard("~/*/code/*.h", vec); +// e.g. FilesMatchingWildcard("~/**/*.png", vec); +PANGOLIN_EXPORT +bool FilesMatchingWildcard(const std::string& wildcard_file_path, std::vector& file_vec); + +PANGOLIN_EXPORT +std::string MakeUniqueFilename(const std::string& filename); + +PANGOLIN_EXPORT +bool IsPipe(const std::string& file); + +PANGOLIN_EXPORT +bool IsPipe(int fd); + +PANGOLIN_EXPORT +int WritablePipeFileDescriptor(const std::string& file); + +/** + * Open the file for reading. Note that it is opened with O_NONBLOCK. The pipe + * open is done in two stages so that the producer knows a reader is waiting + * (but not blocked). The reader then checks PipeHasDataToRead() until it + * returns true. The file can then be opened. Note that the file descriptor + * should be closed after the read stream has been created so that the write + * side of the pipe does not get signaled. + */ +PANGOLIN_EXPORT +int ReadablePipeFileDescriptor(const std::string& file); + +PANGOLIN_EXPORT +bool PipeHasDataToRead(int fd); + +PANGOLIN_EXPORT +void FlushPipe(const std::string& file); + +// TODO: Tidy these inlines up / move them + +inline bool StartsWith(const std::string& str, const std::string& prefix) +{ + return !str.compare(0, prefix.size(), prefix); +} + +inline bool EndsWith(const std::string& str, const std::string& prefix) +{ + return !str.compare(str.size() - prefix.size(), prefix.size(), prefix); +} + +inline std::string Trim(const std::string& str, const std::string& delimiters = " \f\n\r\t\v" ) +{ + const size_t f = str.find_first_not_of( delimiters ); + return f == std::string::npos ? + "" : + str.substr( f, str.find_last_not_of( delimiters ) + 1 ); +} + +inline void ToUpper( std::string& str ) +{ + std::transform(str.begin(), str.end(), str.begin(), ::toupper); +} + +inline void ToLower( std::string& str ) +{ + std::transform(str.begin(), str.end(), str.begin(), ::tolower); +} + +inline std::string ToUpperCopy( const std::string& str ) +{ + std::string out; + out.resize(str.size()); + std::transform(str.begin(), str.end(), out.begin(), ::toupper); + return out; +} + +inline std::string ToLowerCopy( const std::string& str ) +{ + std::string out; + out.resize(str.size()); + std::transform(str.begin(), str.end(), out.begin(), ::tolower); + return out; +} + + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/fix_size_buffer_queue.h b/thirdparty/Pangolin/include/pangolin/utils/fix_size_buffer_queue.h new file mode 100644 index 00000000..ce4d9320 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/fix_size_buffer_queue.h @@ -0,0 +1,153 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace pangolin +{ + +template +class FixSizeBuffersQueue +{ + +public: + FixSizeBuffersQueue() {} + + ~FixSizeBuffersQueue() { + } + + BufPType getNewest() { + std::lock_guard vlock(vMtx); + std::lock_guard elock(eMtx); + if(validBuffers.size() == 0) { + // Empty queue. + return 0; + } else { + // Requeue all but newest buffers. + while(validBuffers.size() > 1) { + emptyBuffers.push_back(std::move(validBuffers.front())); + validBuffers.pop_front(); + } + // Return newest buffer. + BufPType bp = std::move(validBuffers.front()); + validBuffers.pop_front(); + return bp; + } + } + + BufPType getNext() { + std::lock_guard vlock(vMtx); + if(validBuffers.size() == 0) { + // Empty queue. + return 0; + } else { + // Return oldest buffer. + BufPType bp = std::move(validBuffers.front()); + validBuffers.pop_front(); + return bp; + } + } + + BufPType getFreeBuffer() { + std::lock_guard vlock(vMtx); + std::lock_guard elock(eMtx); + if(emptyBuffers.size() > 0) { + // Simply get a free buffer from the free buffers list. + BufPType bp = std::move(emptyBuffers.front()); + emptyBuffers.pop_front(); + return bp; + } else { + if(validBuffers.size() == 0) { + // Queue not yet initialized. + throw std::runtime_error("Queue not yet initialised."); + } else { + std::cerr << "Out of free buffers." << std::endl; + // No free buffers return oldest among the valid buffers. + BufPType bp = std::move(validBuffers.front()); + validBuffers.pop_front(); + return bp; + } + } + } + + void addValidBuffer(BufPType bp) { + // Add buffer to valid buffers queue. + std::lock_guard vlock(vMtx); + validBuffers.push_back(std::move(bp)); + } + + void returnOrAddUsedBuffer(BufPType bp) { + // Add buffer back to empty buffers queue. + std::lock_guard elock(eMtx); + emptyBuffers.push_back(std::move(bp)); + } + + size_t AvailableFrames() const { + std::lock_guard vlock(vMtx); + return validBuffers.size(); + } + + size_t EmptyBuffers() const { + std::lock_guard elock(eMtx); + return emptyBuffers.size(); + } + + bool DropNFrames(size_t n) { + std::lock_guard vlock(vMtx); + if(validBuffers.size() < n) { + return false; + } else { + std::lock_guard elock(eMtx); + // Requeue all but newest buffers. + for(unsigned int i=0; i validBuffers; + std::list emptyBuffers; + mutable std::mutex vMtx; + mutable std::mutex eMtx; +// unsigned int maxNumBuffers; +// unsigned int bufferSizeBytes; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/format_string.h b/thirdparty/Pangolin/include/pangolin/utils/format_string.h new file mode 100644 index 00000000..7b39f9a6 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/format_string.h @@ -0,0 +1,87 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Hauke Strasdat, Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +namespace pangolin { +namespace details { + +// Following: http://stackoverflow.com/a/22759544 +template +class IsStreamable { +private: + template + static auto test(int) -> decltype( (std::declval() << std::declval(), std::true_type()) ); + + template + static auto test(...) -> std::false_type; + +public: + static const bool value = decltype(test(0))::value; +}; + +inline void FormatStream(std::stringstream& stream, const char* text) +{ + stream << text; +} + +// Following: http://en.cppreference.com/w/cpp/language/parameter_pack +template +void FormatStream(std::stringstream& stream, const char* text, T arg, Args... args) +{ + static_assert(IsStreamable::value, + "One of the args has not an ostream overload!"); + for (; *text != '\0'; ++text) { + if (*text == '%') { + stream << arg; + FormatStream(stream, text + 1, args...); + return; + } + stream << *text; + } + stream << "\nFormat-Warning: There are " << sizeof...(Args) + 1 + << " args unused."; +} + +} // namespace details + +template +std::string FormatString(const char* text, Args... args) +{ + std::stringstream stream; + details::FormatStream(stream, text, args...); + return stream.str(); +} + +inline std::string FormatString() +{ + return std::string(); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/log.h b/thirdparty/Pangolin/include/pangolin/utils/log.h new file mode 100644 index 00000000..e9e3536c --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/log.h @@ -0,0 +1,44 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +// TODO: Something a bit more useful here, probably using format_string.h + +#pragma once + +#ifndef _ANDROID_ +# include +# define pango_print_debug(...) printf(__VA_ARGS__) +# define pango_print_info(...) printf(__VA_ARGS__) +# define pango_print_error(...) fprintf(stderr, __VA_ARGS__) +# define pango_print_warn(...) fprintf(stderr, __VA_ARGS__) +#else +# include +# define pango_print_debug(...) __android_log_print(ANDROID_LOG_DEBUG, "pango", __VA_ARGS__ ); +# define pango_print_info(...) __android_log_print(ANDROID_LOG_INFO, "pango", __VA_ARGS__ ); +# define pango_print_error(...) __android_log_print(ANDROID_LOG_ERROR, "pango", __VA_ARGS__ ); +# define pango_print_warn(...) __android_log_print(ANDROID_LOG_ERROR, "pango", __VA_ARGS__ ); +#endif diff --git a/thirdparty/Pangolin/include/pangolin/utils/memstreambuf.h b/thirdparty/Pangolin/include/pangolin/utils/memstreambuf.h new file mode 100644 index 00000000..7cdafb4c --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/memstreambuf.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +namespace pangolin { + +// A simple streambuf wrapper around std::vector for memory buffer use +struct memstreambuf : public std::streambuf +{ +public: + memstreambuf(size_t initial_buffer_size) + { + buffer.reserve(initial_buffer_size); + } + + // Avoiding use of std::streambuf's move constructor, since it is missing for old GCC + memstreambuf(memstreambuf&& o) + : buffer(std::move(o.buffer)) + { + pubseekpos(o.pubseekoff(0, std::ios_base::cur)); + } + + size_t size() const + { + return buffer.size(); + } + + const unsigned char* data() const + { + return buffer.data(); + } + + void clear() + { + buffer.clear(); + } + + std::vector buffer; + +protected: + std::streamsize xsputn(const char_type* __s, std::streamsize __n) override + { + buffer.insert(buffer.end(), __s, __s + __n); + return __n; + } + + int_type overflow(int_type __c) override + { + buffer.push_back( static_cast(__c) ); + return __c; + } +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/params.h b/thirdparty/Pangolin/include/pangolin/utils/params.h new file mode 100644 index 00000000..beebeae8 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/params.h @@ -0,0 +1,80 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT Params +{ +public: + typedef std::vector> ParamMap; + + Params() + { + } + + Params(std::initializer_list> l) + : params(l) + { + } + + bool Contains(const std::string& key) const + { + for(ParamMap::const_iterator it = params.begin(); it!=params.end(); ++it) { + if(it->first == key) return true; + } + return false; + } + + template + T Get(const std::string& key, T default_val) const + { + // Return last value passed to the key. + for(ParamMap::const_reverse_iterator it = params.rbegin(); it!=params.rend(); ++it) { + if(it->first == key) return Convert::Do(it->second); + } + return default_val; + } + + template + void Set(const std::string& key, const T& val) + { + params.push_back(std::pair(key,Convert::Do(val))); + } + + ParamMap params; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/parse.h b/thirdparty/Pangolin/include/pangolin/utils/parse.h new file mode 100644 index 00000000..eedbd351 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/parse.h @@ -0,0 +1,108 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PANGOLIN_PARSE_H +#define PANGOLIN_PARSE_H + +#include +#include + +namespace pangolin +{ + +const unsigned int parse_max_token_size = 1024; + +inline void ConsumeWhitespace(std::istream& is) +{ + while(is.good() && std::isspace(is.peek()) ) { + is.get(); + } +} + +inline bool ConsumeToNewline(std::istream& is) +{ + while(is.good()) { + if(is.get() == '\n') { + return true; + } + } + return false; +} + +template inline +size_t ReadToken(std::istream& is, char buffer[buffer_size]) +{ + size_t r = 0; + while(is.good() && r < buffer_size-1) { + int c = is.peek(); + if( std::isgraph(c) ) { + buffer[r++] = (char)is.get(); + }else{ + break; + } + } + buffer[r] = '\0'; + return r; +} + +inline std::string ReadToken(std::istream &is) +{ + char str_token[parse_max_token_size]; + ReadToken(is, str_token); + return std::string(str_token); +} + +template inline +size_t ConsumeWhitespaceReadToken(std::istream& is, char buffer[buffer_size]) +{ + ConsumeWhitespace(is); + return ReadToken(is, buffer); +} + +inline int ParseToken(const char* token, const char* token_list[], size_t token_list_size) +{ + for(size_t i=0; i < token_list_size; ++i) { + if( strcmp(token, token_list[i]) == 0 ) { + return i; + } + } + return -1; +} + +#define PANGOLIN_DEFINE_PARSE_TOKEN(x) \ + inline x ParseToken##x(const char* token) { \ + return (x)ParseToken(token, x##String, x##Size); \ + } \ + inline x ParseToken##x(std::istream& is) { \ + char str_token[parse_max_token_size]; \ + ReadToken(is, str_token); \ + return ParseToken##x( str_token ); \ + } + +} + +#endif // PANGOLIN_PARSE_H diff --git a/thirdparty/Pangolin/include/pangolin/utils/picojson.h b/thirdparty/Pangolin/include/pangolin/utils/picojson.h new file mode 100644 index 00000000..3791ee6b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/picojson.h @@ -0,0 +1,1414 @@ +/* This is a (butchered) derivative of picojson, incorporated into the + * Pangolin Project (http://github.com/stevenlovegrove/Pangolin) + * + * Modifications Copyright (c) 2014 Steven Lovegrove, + * Original licence applies (below), https://github.com/kazuho/picojson + */ + +/* + * Copyright 2009-2010 Cybozu Labs, Inc. + * Copyright 2011-2014 Kazuho Oku + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef picojson_h +#define picojson_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// Enable INT64 support +#define PICOJSON_USE_INT64 + +// for isnan/isinf +#if __cplusplus>=201103L +# include +#else +extern "C" { +# ifdef _MSC_VER +# include +# elif defined(__INTEL_COMPILER) +# include +# else +# include +# endif +} +#endif + +// experimental support for int64_t (see README.mkdn for detail) +#ifdef PICOJSON_USE_INT64 +# define __STDC_FORMAT_MACROS +# include +# include +#endif // PICOJSON_USE_INT64 + +// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0 +#ifndef PICOJSON_USE_LOCALE +# define PICOJSON_USE_LOCALE 1 +#endif // PICOJSON_USE_LOCALE + +#if PICOJSON_USE_LOCALE +extern "C" { +# include +} +#endif // PICOJSON_USE_LOCALE + +#ifndef PICOJSON_ASSERT +# define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0) +#endif + +#ifdef _MSC_VER +#define SNPRINTF _snprintf_s +#pragma warning(push) +#pragma warning(disable : 4244) // conversion from int to char +#else +#define SNPRINTF snprintf +#endif + +#ifdef _MSC_VER +#define PICOJSON_FALSE_TEMPLATE_TYPE nullptr +#else +#define PICOJSON_FALSE_TEMPLATE_TYPE ((void*)0) +#endif + +namespace picojson { + +enum { + null_type, + boolean_type, + number_type, + string_type, + array_type, + object_type +#ifdef PICOJSON_USE_INT64 + , int64_type +#endif +}; + +enum { + INDENT_WIDTH = 2 +}; + +struct null {}; + +class value { +public: + typedef std::vector array; + typedef std::map object; + + union _storage { + bool boolean_; + double number_; +#ifdef PICOJSON_USE_INT64 + int64_t int64_; +#endif + std::string* string_; + array* array_; + object* object_; + }; +protected: + int type_; + _storage u_; +public: + + + ///////////////////////////// + // Constructors / Destructor + ///////////////////////////// + + ~value(); + value(); + value(int type, bool); + + ///////////////////////////// + // Implicit type constructors + ///////////////////////////// + + value(bool b) : type_(boolean_type) { + u_.boolean_ = b; + } + +#ifdef PICOJSON_USE_INT64 + value(short v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } + value(unsigned short v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } + value(int v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } + value(unsigned int v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } + value(long v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } + value(unsigned long v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } + value(long long v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } + value(unsigned long long v) : type_(int64_type) { + u_.int64_ = static_cast(v); + } +#endif + + value(float n) : type_(number_type) { + if ( + #ifdef _MSC_VER + ! _finite(n) + #elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf)) + std::isnan(n) || std::isinf(n) + #else + isnan(n) || isinf(n) + #endif + ) { + throw std::overflow_error(""); + } + u_.number_ = static_cast(n); + } + + value(double n) : type_(number_type) { + if ( + #ifdef _MSC_VER + ! _finite(n) + #elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf)) + std::isnan(n) || std::isinf(n) + #else + isnan(n) || isinf(n) + #endif + ) { + throw std::overflow_error(""); + } + u_.number_ = n; + } + + value(const array& a); + value(const object& o); + + value(const std::string& s); + value(const char* s); + value(const char* s, size_t len); + + value(const value& x); + value& operator=(const value& x); + + ///////////////////////////// + // Query / get type + ///////////////////////////// + + void swap(value& x); + template bool is() const; + template const T& get() const; + template T& get(); + bool evaluate_as_boolean() const; + size_t size() const; + + ///////////////////////////// + // Usage as array + ///////////////////////////// + + value& operator[](size_t idx); + const value& operator[](size_t idx) const; + bool contains(size_t idx) const; + value& push_back(const value& = value() ); + + ///////////////////////////// + // Usage as object + ///////////////////////////// + + value& operator[](const std::string& key); + const value& operator[](const std::string& key) const; + bool contains(const std::string& key) const; + + template + T get_value(const std::string& key, T default_value) const; + + ///////////////////////////// + // Serialization + ///////////////////////////// + + std::string to_str() const; + template void serialize(Iter os, bool prettify = false) const; + std::string serialize(bool prettify = false) const; +private: + template value(const T*); // intentionally defined to block implicit conversion of pointer to bool + template static void _indent(Iter os, int indent); + template void _serialize(Iter os, int indent) const; + std::string _serialize(int indent) const; +}; + +typedef value::array array; +typedef value::object object; + +inline value::value() : type_(null_type), u_({false}) {} + +inline value::value(int type, bool) : type_(type) { + switch (type) { +#define INIT(p, v) case p##type: u_.p = v; break + INIT(boolean_, false); + INIT(number_, 0.0); +#ifdef PICOJSON_USE_INT64 + INIT(int64_, 0); +#endif + INIT(string_, new std::string()); + INIT(array_, new array()); + INIT(object_, new object()); +#undef INIT + default: break; + } +} + +inline value::value(const std::string& s) : type_(string_type) { + u_.string_ = new std::string(s); +} + +inline value::value(const array& a) : type_(array_type) { + u_.array_ = new array(a); +} + +inline value::value(const object& o) : type_(object_type) { + u_.object_ = new object(o); +} + +inline value::value(const char* s) : type_(string_type) { + u_.string_ = new std::string(s); +} + +inline value::value(const char* s, size_t len) : type_(string_type) { + u_.string_ = new std::string(s, len); +} + +inline value::~value() { + switch (type_) { +#define DEINIT(p) case p##type: delete u_.p; break + DEINIT(string_); + DEINIT(array_); + DEINIT(object_); +#undef DEINIT + default: break; + } +} + +inline value::value(const value& x) : type_(x.type_) { + switch (type_) { +#define INIT(p, v) case p##type: u_.p = v; break + INIT(string_, new std::string(*x.u_.string_)); + INIT(array_, new array(*x.u_.array_)); + INIT(object_, new object(*x.u_.object_)); +#undef INIT + default: + u_ = x.u_; + break; + } +} + +inline value& value::operator=(const value& x) { + if (this != &x) { + this->~value(); + new (this) value(x); + } + return *this; +} + +inline void value::swap(value& x) { + std::swap(type_, x.type_); + std::swap(u_, x.u_); +} + +#define IS(ctype, jtype) \ + template <> inline bool value::is() const { \ + return type_ == jtype##_type; \ +} +IS(null, null) +IS(bool, boolean) +#ifdef PICOJSON_USE_INT64 +IS(int64_t, int64) +#endif +IS(std::string, string) +IS(array, array) +IS(object, object) +#undef IS +template <> inline bool value::is() const { + return type_ == number_type + #ifdef PICOJSON_USE_INT64 + || type_ == int64_type + #endif + ; +} + +#define GET(ctype, var) \ + template <> inline const ctype& value::get() const { \ + PICOJSON_ASSERT("type mismatch! call is() before get()" \ + && is()); \ + return var; \ +} \ + template <> inline ctype& value::get() { \ + PICOJSON_ASSERT("type mismatch! call is() before get()" \ + && is()); \ + return var; \ +} +GET(bool, u_.boolean_) +GET(std::string, *u_.string_) +GET(array, *u_.array_) +GET(object, *u_.object_) +#ifdef PICOJSON_USE_INT64 +GET(double, (type_ == int64_type && (const_cast(this)->type_ = number_type, const_cast(this)->u_.number_ = u_.int64_), u_.number_)) +GET(int64_t, u_.int64_) +#else +GET(double, u_.number_) +#endif +#undef GET + +inline bool value::evaluate_as_boolean() const { + switch (type_) { + case null_type: + return false; + case boolean_type: + return u_.boolean_; + case number_type: + return u_.number_ != 0; + case string_type: + return ! u_.string_->empty(); + default: + return true; + } +} + +inline size_t value::size() const +{ + PICOJSON_ASSERT("Type mismatch! Not array." && is()); + return u_.array_->size(); +} + +inline const value& value::operator[](size_t idx) const { + PICOJSON_ASSERT("Type mismatch! Not array." && is()); + PICOJSON_ASSERT("Out of bounds." && idx < u_.array_->size() ); + return (*u_.array_)[idx]; +} + +inline value& value::operator[](size_t idx) { + if( type_ == null_type ) { + // instantiate as array + type_ = array_type; + u_.array_ = new array(); + } + + PICOJSON_ASSERT("Type mismatch! Not array." && is()); + PICOJSON_ASSERT("Out of bounds." && idx < u_.array_->size() ); + return (*u_.array_)[idx]; +} + +inline bool value::contains(size_t idx) const { + if( type_ == array_type) { + return idx < u_.array_->size(); + }else{ + return false; + } +} + +inline value& value::push_back(const value& val) +{ + if( type_ == null_type ) { + // instantiate as array + type_ = array_type; + u_.array_ = new array(); + } + PICOJSON_ASSERT("Type mismatch! Not array." && is()); + u_.array_->push_back( val ); + return u_.array_->back(); +} + +inline const value& value::operator[](const std::string& key) const { + PICOJSON_ASSERT("Type mismatch! Not object." && is() ); + object::const_iterator i = u_.object_->find(key); + PICOJSON_ASSERT("Key not found." && i != u_.object_->end() ); + return i->second; +} + +inline value& value::operator[](const std::string& key) { + if( type_ == null_type ) { + // instantiate as object + type_ = object_type; + u_.object_ = new object(); + } + PICOJSON_ASSERT("Type mismatch! Not object." && is()); + return u_.object_->operator [](key); +} + +inline bool value::contains(const std::string& key) const { + if( type_ == object_type) { + object::const_iterator i = u_.object_->find(key); + return i != u_.object_->end(); + }else{ + return false; + } +} + +template +inline T value::get_value(const std::string& key, T default_value) const { + if(contains(key)) { + return (*this)[key].get(); + }else{ + return default_value; + } +} + +inline std::string value::to_str() const { + switch (type_) { + case null_type: return "null"; + case boolean_type: return u_.boolean_ ? "true" : "false"; +#ifdef PICOJSON_USE_INT64 + case int64_type: { + char buf[sizeof("-9223372036854775808")]; + SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_); + return buf; + } +#endif + case number_type: { + char buf[256]; + double tmp; + SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_); +#if PICOJSON_USE_LOCALE + char *decimal_point = localeconv()->decimal_point; + if (strcmp(decimal_point, ".") != 0) { + size_t decimal_point_len = strlen(decimal_point); + for (char *p = buf; *p != '\0'; ++p) { + if (strncmp(p, decimal_point, decimal_point_len) == 0) { + return std::string(buf, p) + "." + (p + decimal_point_len); + } + } + } +#endif + return buf; + } + case string_type: return *u_.string_; + case array_type: return "array"; + case object_type: return "object"; + default: PICOJSON_ASSERT("value::to_str() assert failed." && 0); +#ifdef _MSC_VER + __assume(0); +#endif + } +} + +template void copy(const std::string& s, Iter oi) { + std::copy(s.begin(), s.end(), oi); +} + +template void serialize_str(const std::string& s, Iter oi) { + *oi++ = '"'; + for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) { + switch (*i) { +#define MAP(val, sym) case val: copy(sym, oi); break + MAP('"', "\\\""); + MAP('\\', "\\\\"); + MAP('/', "\\/"); + MAP('\b', "\\b"); + MAP('\f', "\\f"); + MAP('\n', "\\n"); + MAP('\r', "\\r"); + MAP('\t', "\\t"); +#undef MAP + default: + if (static_cast(*i) < 0x20 || *i == 0x7f) { + char buf[7]; + SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff); + copy(buf, buf + 6, oi); + } else { + *oi++ = *i; + } + break; + } + } + *oi++ = '"'; +} + +template void value::serialize(Iter oi, bool prettify) const { + return _serialize(oi, prettify ? 0 : -1); +} + +inline std::string value::serialize(bool prettify) const { + return _serialize(prettify ? 0 : -1); +} + +template void value::_indent(Iter oi, int indent) { + *oi++ = '\n'; + for (int i = 0; i < indent * INDENT_WIDTH; ++i) { + *oi++ = ' '; + } +} + +template void value::_serialize(Iter oi, int indent) const { + switch (type_) { + case string_type: + serialize_str(*u_.string_, oi); + break; + case array_type: { + *oi++ = '['; + if (indent != -1) { + ++indent; + } + for (array::const_iterator i = u_.array_->begin(); + i != u_.array_->end(); + ++i) { + if (i != u_.array_->begin()) { + *oi++ = ','; + } + if (indent != -1) { + _indent(oi, indent); + } + i->_serialize(oi, indent); + } + if (indent != -1) { + --indent; + if (! u_.array_->empty()) { + _indent(oi, indent); + } + } + *oi++ = ']'; + break; + } + case object_type: { + *oi++ = '{'; + if (indent != -1) { + ++indent; + } + for (object::const_iterator i = u_.object_->begin(); + i != u_.object_->end(); + ++i) { + if (i != u_.object_->begin()) { + *oi++ = ','; + } + if (indent != -1) { + _indent(oi, indent); + } + serialize_str(i->first, oi); + *oi++ = ':'; + if (indent != -1) { + *oi++ = ' '; + } + i->second._serialize(oi, indent); + } + if (indent != -1) { + --indent; + if (! u_.object_->empty()) { + _indent(oi, indent); + } + } + *oi++ = '}'; + break; + } + default: + copy(to_str(), oi); + break; + } + if (indent == 0) { + *oi++ = '\n'; + } +} + +inline std::string value::_serialize(int indent) const { + std::string s; + _serialize(std::back_inserter(s), indent); + return s; +} + +template class input { +protected: + Iter cur_, end_; + int last_ch_; + bool ungot_; + int line_; +public: + input(const Iter& first, const Iter& last) : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {} + int getc() { + if (ungot_) { + ungot_ = false; + return last_ch_; + } + if (cur_ == end_) { + last_ch_ = -1; + return -1; + } + if (last_ch_ == '\n') { + line_++; + } + last_ch_ = *cur_ & 0xff; + ++cur_; + return last_ch_; + } + void ungetc() { + if (last_ch_ != -1) { + PICOJSON_ASSERT(! ungot_); + ungot_ = true; + } + } + Iter cur() const { return cur_; } + int line() const { return line_; } + void skip_ws() { + while (1) { + int ch = getc(); + if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) { + ungetc(); + break; + } + } + } + bool expect(int expect) { + skip_ws(); + if (getc() != expect) { + ungetc(); + return false; + } + return true; + } + bool match(const std::string& pattern) { + for (std::string::const_iterator pi(pattern.begin()); + pi != pattern.end(); + ++pi) { + if (getc() != *pi) { + ungetc(); + return false; + } + } + return true; + } +}; + +template inline int _parse_quadhex(input &in) { + int uni_ch = 0, hex; + for (int i = 0; i < 4; i++) { + if ((hex = in.getc()) == -1) { + return -1; + } + if ('0' <= hex && hex <= '9') { + hex -= '0'; + } else if ('A' <= hex && hex <= 'F') { + hex -= 'A' - 0xa; + } else if ('a' <= hex && hex <= 'f') { + hex -= 'a' - 0xa; + } else { + in.ungetc(); + return -1; + } + uni_ch = uni_ch * 16 + hex; + } + return uni_ch; +} + +template inline bool _parse_codepoint(String& out, input& in) { + int uni_ch; + if ((uni_ch = _parse_quadhex(in)) == -1) { + return false; + } + if (0xd800 <= uni_ch && uni_ch <= 0xdfff) { + if (0xdc00 <= uni_ch) { + // a second 16-bit of a surrogate pair appeared + return false; + } + // first 16-bit of surrogate pair, get the next one + if (in.getc() != '\\' || in.getc() != 'u') { + in.ungetc(); + return false; + } + int second = _parse_quadhex(in); + if (! (0xdc00 <= second && second <= 0xdfff)) { + return false; + } + uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff); + uni_ch += 0x10000; + } + if (uni_ch < 0x80) { + out.push_back(uni_ch); + } else { + if (uni_ch < 0x800) { + out.push_back(0xc0 | (uni_ch >> 6)); + } else { + if (uni_ch < 0x10000) { + out.push_back(0xe0 | (uni_ch >> 12)); + } else { + out.push_back(0xf0 | (uni_ch >> 18)); + out.push_back(0x80 | ((uni_ch >> 12) & 0x3f)); + } + out.push_back(0x80 | ((uni_ch >> 6) & 0x3f)); + } + out.push_back(0x80 | (uni_ch & 0x3f)); + } + return true; +} + +template inline bool _parse_string(String& out, input& in, int delim='"') { + while (1) { + int ch = in.getc(); + if (ch < ' ') { + in.ungetc(); + return false; + } else if (ch == delim) { + return true; + } else if (ch == '\\') { + if ((ch = in.getc()) == -1) { + return false; + } + switch (ch) { +#define MAP(sym, val) case sym: out.push_back(val); break + MAP('"', '\"'); + MAP('\\', '\\'); + MAP('/', '/'); + MAP('b', '\b'); + MAP('f', '\f'); + MAP('n', '\n'); + MAP('r', '\r'); + MAP('t', '\t'); +#undef MAP + case 'u': + if (! _parse_codepoint(out, in)) { + return false; + } + break; + default: + return false; + } + } else { + out.push_back(ch); + } + } +} + +template inline bool _parse_array(Context& ctx, input& in) { + if (! ctx.parse_array_start()) { + return false; + } + size_t idx = 0; + if (in.expect(']')) { + return ctx.parse_array_stop(idx); + } + do { + if (! ctx.parse_array_item(in, idx)) { + return false; + } + idx++; + } while (in.expect(',')); + return in.expect(']') && ctx.parse_array_stop(idx); +} + +template inline bool _parse_object(Context& ctx, input& in) { + if (! ctx.parse_object_start()) { + return false; + } + if (in.expect('}')) { + return true; + } + do { + std::string key; + // Support " and ' delimited strings + if( in.expect('"') ) { + if( !_parse_string(key, in, '"') ) + return false; + }else if (!in.expect('\'') || !_parse_string(key, in,'\'') ) { + return false; + } + if (!in.expect(':') || !ctx.parse_object_item(in, key)) { + return false; + } + } while (in.expect(',')); + return in.expect('}'); +} + +template inline std::string _parse_number(input& in) { + std::string num_str; + while (1) { + int ch = in.getc(); + if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' + || ch == 'e' || ch == 'E') { + num_str.push_back(ch); + } else if (ch == '.') { +#if PICOJSON_USE_LOCALE + num_str += localeconv()->decimal_point; +#else + num_str.push_back('.'); +#endif + } else { + in.ungetc(); + break; + } + } + return num_str; +} + +template inline bool _parse(Context& ctx, input& in) { + in.skip_ws(); + int ch = in.getc(); + switch (ch) { +#define IS(ch, text, op) case ch: \ + if (in.match(text) && op) { \ + return true; \ + } else { \ + return false; \ + } + IS('n', "ull", ctx.set_null()); + IS('f', "alse", ctx.set_bool(false)); + IS('t', "rue", ctx.set_bool(true)); +#undef IS + case '"': + return ctx.parse_string(in); + case '[': + return _parse_array(ctx, in); + case '{': + return _parse_object(ctx, in); + default: + if (('0' <= ch && ch <= '9') || ch == '-') { + double f; + char *endp; + in.ungetc(); + std::string num_str = _parse_number(in); + if (num_str.empty()) { + return false; + } +#ifdef PICOJSON_USE_INT64 + { + errno = 0; + intmax_t ival = strtoimax(num_str.c_str(), &endp, 10); + if (errno == 0 + && std::numeric_limits::min() <= ival + && ival <= std::numeric_limits::max() + && endp == num_str.c_str() + num_str.size()) { + ctx.set_int64(ival); + return true; + } + } +#endif + f = strtod(num_str.c_str(), &endp); + if (endp == num_str.c_str() + num_str.size()) { + ctx.set_number(f); + return true; + } + return false; + } + break; + } + in.ungetc(); + return false; +} + +class deny_parse_context { +public: + bool set_null() { return false; } + bool set_bool(bool) { return false; } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t) { return false; } +#endif + bool set_number(double) { return false; } + template bool parse_string(input&) { return false; } + bool parse_array_start() { return false; } + template bool parse_array_item(input&, size_t) { + return false; + } + bool parse_array_stop(size_t) { return false; } + bool parse_object_start() { return false; } + template bool parse_object_item(input&, const std::string&) { + return false; + } +}; + +class default_parse_context { +protected: + value* out_; +public: + default_parse_context(value* out) : out_(out) {} + bool set_null() { + *out_ = value(); + return true; + } + bool set_bool(bool b) { + *out_ = value(b); + return true; + } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t i) { + *out_ = value(i); + return true; + } +#endif + bool set_number(double f) { + *out_ = value(f); + return true; + } + template bool parse_string(input& in) { + *out_ = value(string_type, false); + return _parse_string(out_->get(), in); + } + bool parse_array_start() { + *out_ = value(array_type, false); + return true; + } + template bool parse_array_item(input& in, size_t) { + array& a = out_->get(); + a.push_back(value()); + default_parse_context ctx(&a.back()); + return _parse(ctx, in); + } + bool parse_array_stop(size_t) { return true; } + bool parse_object_start() { + *out_ = value(object_type, false); + return true; + } + template bool parse_object_item(input& in, const std::string& key) { + object& o = out_->get(); + default_parse_context ctx(&o[key]); + return _parse(ctx, in); + } +private: + default_parse_context(const default_parse_context&); + default_parse_context& operator=(const default_parse_context&); +}; + +class null_parse_context { +public: + struct dummy_str { + void push_back(int) {} + }; +public: + null_parse_context() {} + bool set_null() { return true; } + bool set_bool(bool) { return true; } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t) { return true; } +#endif + bool set_number(double) { return true; } + template bool parse_string(input& in) { + dummy_str s; + return _parse_string(s, in); + } + bool parse_array_start() { return true; } + template bool parse_array_item(input& in, size_t) { + return _parse(*this, in); + } + bool parse_array_stop(size_t) { return true; } + bool parse_object_start() { return true; } + template bool parse_object_item(input& in, const std::string&) { + return _parse(*this, in); + } +private: + null_parse_context(const null_parse_context&); + null_parse_context& operator=(const null_parse_context&); +}; + +// obsolete, use the version below +template inline std::string parse(value& out, Iter& pos, const Iter& last) { + std::string err; + pos = parse(out, pos, last, &err); + return err; +} + +template inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) { + input in(first, last); + if (! _parse(ctx, in) && err != NULL) { + char buf[64]; + SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line()); + *err = buf; + while (1) { + int ch = in.getc(); + if (ch == -1 || ch == '\n') { + break; + } else if (ch >= ' ') { + err->push_back(ch); + } + } + } + return in.cur(); +} + +template inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) { + default_parse_context ctx(&out); + return _parse(ctx, first, last, err); +} + +inline std::string parse(value &out, const std::string &s) { + std::string err; + parse(out, s.begin(), s.end(), &err); + return err; +} + +inline std::string parse(value& out, std::istream& is) { + std::string err; + parse(out, std::istreambuf_iterator(is.rdbuf()), + std::istreambuf_iterator(), &err); + return err; +} + +template struct last_error_t { + static std::string s; +}; +template std::string last_error_t::s; + +inline void set_last_error(const std::string& s) { + last_error_t::s = s; +} + +inline const std::string& get_last_error() { + return last_error_t::s; +} + +inline bool operator==(const value& x, const value& y) { + if (x.is()) + return y.is(); +#define PICOJSON_CMP(type) \ + if (x.is()) \ + return y.is() && x.get() == y.get() + PICOJSON_CMP(bool); + PICOJSON_CMP(double); + PICOJSON_CMP(std::string); + PICOJSON_CMP(array); + PICOJSON_CMP(object); +#undef PICOJSON_CMP + PICOJSON_ASSERT(0); +#ifdef _MSC_VER + __assume(0); +#endif +} + +inline bool operator!=(const value& x, const value& y) { + return ! (x == y); +} + +} // namespace json + +inline std::istream& operator>>(std::istream& is, picojson::value& x) +{ + picojson::set_last_error(std::string()); + std::string err = picojson::parse(x, is); + if (! err.empty()) { + picojson::set_last_error(err); + is.setstate(std::ios::failbit); + } + return is; +} + +inline std::ostream& operator<<(std::ostream& os, const picojson::value& x) +{ + x.serialize(std::ostream_iterator(os)); + return os; +} +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +#endif // picojson_h + + + + +#ifdef TEST_PICOJSON + +#ifdef _MSC_VER +#pragma warning(disable : 4127) // conditional expression is constant +#endif // _MSC_VER + +using namespace std; + +static bool success = true; +static int test_num = 0; + +static void ok(bool b, const char* name = "") +{ + if (! b) + success = false; + printf("%s %d - %s\n", b ? "ok" : "ng", ++test_num, name); +} + +static void done_testing() +{ + printf("1..%d\n", test_num); +} + +template void is(const T& x, const T& y, const char* name = "") +{ + if (x == y) { + ok(true, name); + } else { + ok(false, name); + } +} + +#include +#include +#include +#include + +int main(void) +{ +#if PICOJSON_USE_LOCALE + setlocale(LC_ALL, ""); +#endif // PICOJSON_USE_LOCALE + + // constructors +#define TEST(expr, expected) \ + is(picojson::value expr .serialize(), string(expected), "picojson::value" #expr) + + TEST( (true), "true"); + TEST( (false), "false"); + TEST( (42.0), "42"); + TEST( (string("hello")), "\"hello\""); + TEST( ("hello"), "\"hello\""); + TEST( ("hello", 4), "\"hell\""); + + { + double a = 1; + for (int i = 0; i < 1024; i++) { + picojson::value vi(a); + std::stringstream ss; + ss << vi; + picojson::value vo; + ss >> vo; + double b = vo.get(); + if ((i < 53 && a != b) || fabs(a - b) / b > 1e-8) { + printf("ng i=%d a=%.18e b=%.18e\n", i, a, b); + } + a *= 2; + } + } + +#undef TEST + +#define TEST(in, type, cmp, serialize_test) { \ + picojson::value v; \ + const char* s = in; \ + string err = picojson::parse(v, s, s + strlen(s)); \ + ok(err.empty(), in " no error"); \ + ok(v.is(), in " check type"); \ + is(v.get(), cmp, in " correct output"); \ + is(*s, '\0', in " read to eof"); \ + if (serialize_test) { \ + is(v.serialize(), string(in), in " serialize"); \ +} \ +} + TEST("false", bool, false, true); + TEST("true", bool, true, true); + TEST("90.5", double, 90.5, false); + TEST("1.7976931348623157e+308", double, DBL_MAX, false); + TEST("\"hello\"", string, string("hello"), true); + TEST("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"", string, string("\"\\/\b\f\n\r\t"), + true); + TEST("\"\\u0061\\u30af\\u30ea\\u30b9\"", string, + string("a\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xb9"), false); + TEST("\"\\ud840\\udc0b\"", string, string("\xf0\xa0\x80\x8b"), false); +#ifdef PICOJSON_USE_INT64 + TEST("0", int64_t, 0, true); + TEST("-9223372036854775808", int64_t, std::numeric_limits::min(), true); + TEST("9223372036854775807", int64_t, std::numeric_limits::max(), true); +#endif // PICOJSON_USE_INT64 + +#undef TEST + +#define TEST(type, expr) { \ + picojson::value v; \ + const char *s = expr; \ + string err = picojson::parse(v, s, s + strlen(s)); \ + ok(err.empty(), "empty " #type " no error"); \ + ok(v.is(), "empty " #type " check type"); \ + ok(v.get().empty(), "check " #type " array size"); \ +} + TEST(array, "[]"); + TEST(object, "{}"); +#undef TEST + + { + picojson::value v; + const char *s = "[1,true,\"hello\"]"; + string err = picojson::parse(v, s, s + strlen(s)); + ok(err.empty(), "array no error"); + ok(v.is(), "array check type"); + is(v.get().size(), size_t(3), "check array size"); + ok(v.contains(0), "check contains array[0]"); + ok(v.get(0).is(), "check array[0] type"); + is(v.get(0).get(), 1.0, "check array[0] value"); + ok(v.contains(1), "check contains array[1]"); + ok(v.get(1).is(), "check array[1] type"); + ok(v.get(1).get(), "check array[1] value"); + ok(v.contains(2), "check contains array[2]"); + ok(v.get(2).is(), "check array[2] type"); + is(v.get(2).get(), string("hello"), "check array[2] value"); + ok(!v.contains(3), "check not contains array[3]"); + } + + { + picojson::value v; + const char *s = "{ \"a\": true }"; + string err = picojson::parse(v, s, s + strlen(s)); + ok(err.empty(), "object no error"); + ok(v.is(), "object check type"); + is(v.get().size(), size_t(1), "check object size"); + ok(v.contains("a"), "check contains property"); + ok(v.get("a").is(), "check bool property exists"); + is(v.get("a").get(), true, "check bool property value"); + is(v.serialize(), string("{\"a\":true}"), "serialize object"); + ok(!v.contains("z"), "check not contains property"); + } + +#define TEST(json, msg) do { \ + picojson::value v; \ + const char *s = json; \ + string err = picojson::parse(v, s, s + strlen(s)); \ + is(err, string("syntax error at line " msg), msg); \ +} while (0) + TEST("falsoa", "1 near: oa"); + TEST("{]", "1 near: ]"); + TEST("\n\bbell", "2 near: bell"); + TEST("\"abc\nd\"", "1 near: "); +#undef TEST + + { + picojson::value v1, v2; + const char *s; + string err; + s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; + err = picojson::parse(v1, s, s + strlen(s)); + s = "{ \"d\": 2.0, \"b\": true, \"a\": [1,2,\"three\"] }"; + err = picojson::parse(v2, s, s + strlen(s)); + ok((v1 == v2), "check == operator in deep comparison"); + } + + { + picojson::value v1, v2; + const char *s; + string err; + s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; + err = picojson::parse(v1, s, s + strlen(s)); + s = "{ \"d\": 2.0, \"a\": [1,\"three\"], \"b\": true }"; + err = picojson::parse(v2, s, s + strlen(s)); + ok((v1 != v2), "check != operator for array in deep comparison"); + } + + { + picojson::value v1, v2; + const char *s; + string err; + s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; + err = picojson::parse(v1, s, s + strlen(s)); + s = "{ \"d\": 2.0, \"a\": [1,2,\"three\"], \"b\": false }"; + err = picojson::parse(v2, s, s + strlen(s)); + ok((v1 != v2), "check != operator for object in deep comparison"); + } + + { + picojson::value v1, v2; + const char *s; + string err; + s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; + err = picojson::parse(v1, s, s + strlen(s)); + picojson::object& o = v1.get(); + o.erase("b"); + picojson::array& a = o["a"].get(); + picojson::array::iterator i; + i = std::remove(a.begin(), a.end(), picojson::value(std::string("three"))); + a.erase(i, a.end()); + s = "{ \"a\": [1,2], \"d\": 2 }"; + err = picojson::parse(v2, s, s + strlen(s)); + ok((v1 == v2), "check erase()"); + } + + ok(picojson::value(3.0).serialize() == "3", + "integral number should be serialized as a integer"); + + { + const char* s = "{ \"a\": [1,2], \"d\": 2 }"; + picojson::null_parse_context ctx; + string err; + picojson::_parse(ctx, s, s + strlen(s), &err); + ok(err.empty(), "null_parse_context"); + } + + { + picojson::value v; + const char *s = "{ \"a\": 1, \"b\": [ 2, { \"b1\": \"abc\" } ], \"c\": {}, \"d\": [] }"; + string err; + err = picojson::parse(v, s, s + strlen(s)); + ok(err.empty(), "parse test data for prettifying output"); + ok(v.serialize() == "{\"a\":1,\"b\":[2,{\"b1\":\"abc\"}],\"c\":{},\"d\":[]}", "non-prettifying output"); + ok(v.serialize(true) == "{\n \"a\": 1,\n \"b\": [\n 2,\n {\n \"b1\": \"abc\"\n }\n ],\n \"c\": {},\n \"d\": []\n}\n", "prettifying output"); + } + + try { + picojson::value v(std::numeric_limits::quiet_NaN()); + ok(false, "should not accept NaN"); + } catch (std::overflow_error e) { + ok(true, "should not accept NaN"); + } + + try { + picojson::value v(std::numeric_limits::infinity()); + ok(false, "should not accept infinity"); + } catch (std::overflow_error e) { + ok(true, "should not accept infinity"); + } + + try { + picojson::value v(123.); + ok(! v.is(), "is() should return false"); + v.get(); + ok(false, "get() should raise an error"); + } catch (std::runtime_error e) { + ok(true, "get() should raise an error"); + } + +#ifdef PICOJSON_USE_INT64 + { + picojson::value v1((int64_t)123); + ok(v1.is(), "is int64_t"); + ok(v1.is(), "is double as well"); + ok(v1.serialize() == "123", "serialize the value"); + ok(v1.get() == 123, "value is correct as int64_t"); + ok(v1.get(), "value is correct as double"); + + ok(! v1.is(), "is no more int64_type once get() is called"); + ok(v1.is(), "and is still a double"); + + const char *s = "-9223372036854775809"; + ok(picojson::parse(v1, s, s + strlen(s)).empty(), "parse underflowing int64_t"); + ok(! v1.is(), "underflowing int is not int64_t"); + ok(v1.is(), "underflowing int is double"); + ok(v1.get() + 9.22337203685478e+18 < 65536, "double value is somewhat correct"); + } +#endif // PICOJSON_USE_INT64 + + done_testing(); + + return success ? 0 : 1; +} + +#endif // TEST_PICOJSON diff --git a/thirdparty/Pangolin/include/pangolin/utils/posix/condition_variable.h b/thirdparty/Pangolin/include/pangolin/utils/posix/condition_variable.h new file mode 100644 index 00000000..77e1b9f0 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/posix/condition_variable.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +#include + +namespace pangolin +{ + +class ConditionVariableInterface +{ +public: + virtual ~ConditionVariableInterface() + { + } + + virtual void wait() = 0; + virtual bool wait(timespec t) = 0; + virtual void signal() = 0; + virtual void broadcast() = 0; +}; + +std::shared_ptr create_named_condition_variable(const + std::string& name); +std::shared_ptr open_named_condition_variable(const + std::string& name); +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/posix/semaphore.h b/thirdparty/Pangolin/include/pangolin/utils/posix/semaphore.h new file mode 100644 index 00000000..8563d2b0 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/posix/semaphore.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include + +namespace pangolin +{ + + class SemaphoreInterface + { + public: + + virtual ~SemaphoreInterface() { + } + + virtual bool tryAcquire() = 0; + virtual void acquire() = 0; + virtual void release() = 0; + }; + + std::shared_ptr create_named_semaphore(const std::string& name, + unsigned int value); + std::shared_ptr open_named_semaphore(const std::string& name); + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/posix/shared_memory_buffer.h b/thirdparty/Pangolin/include/pangolin/utils/posix/shared_memory_buffer.h new file mode 100644 index 00000000..8ece2bb4 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/posix/shared_memory_buffer.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include + +namespace pangolin +{ + class SharedMemoryBufferInterface + { + public: + virtual ~SharedMemoryBufferInterface() { + } + virtual bool tryLock() = 0; + virtual void lock() = 0; + virtual void unlock() = 0; + virtual unsigned char *ptr() = 0; + virtual std::string name() = 0; + }; + + std::shared_ptr create_named_shared_memory_buffer(const + std::string& name, size_t size); + std::shared_ptr open_named_shared_memory_buffer(const + std::string& name, bool readwrite); +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/registration.h b/thirdparty/Pangolin/include/pangolin/utils/registration.h new file mode 100644 index 00000000..70a3cae9 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/registration.h @@ -0,0 +1,64 @@ +#pragma once + +#include + +namespace pangolin { + +template +class Registration +{ +public: + using UnregisterFunc = std::function; + + Registration() + : token() + { + } + + Registration(TokenType token, UnregisterFunc unregister) + : token(token), unregister(unregister) + { + + } + + // No copy constructor + Registration(const Registration&) = delete; + + // Default move constructor + Registration(Registration&& o) + { + *this = std::move(o); + } + + Registration& operator =(Registration&& o) + { + token = o.token; + unregister = std::move(o.unregister); + o.unregister = nullptr; + return *this; + } + + ~Registration() + { + Release(); + } + + void Release() + { + if(unregister) { + unregister(token); + token = TokenType(); + } + } + + const TokenType& Token() + { + return token; + } + +private: + TokenType token; + UnregisterFunc unregister; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/signal_slot.h b/thirdparty/Pangolin/include/pangolin/utils/signal_slot.h new file mode 100644 index 00000000..2d20c39d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/signal_slot.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +#include + +namespace pangolin { + +// Based on http://simmesimme.github.io/tutorials/2015/09/20/signal-slot +template +class Signal +{ +public: + using Id = size_t; + using Reg = Registration; + + Signal() + : current_id_(0) + { + } + + Signal(const Signal&) = delete; + + Signal(Signal&&) = default; + + // connects a std::function to the signal. The returned + // value can be used to disconnect the function again + Reg Connect(const std::function& slot) const { + slots_.insert(std::make_pair(++current_id_, slot)); + return Reg(current_id_, [this](Id id){ Disconnect(id);}); + } + + // disconnects a previously connected function + void Disconnect(Id id) const { + slots_.erase(id); + } + + // disconnects all previously connected functions + void DisconnectAll() const { + slots_.clear(); + } + + // calls all connected functions + void operator()(Args... p) { + for(auto it : slots_) { + it.second(p...); + } + } + +private: + mutable std::map> slots_; + mutable Id current_id_; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/sigstate.h b/thirdparty/Pangolin/include/pangolin/utils/sigstate.h new file mode 100644 index 00000000..0ea68fd8 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/sigstate.h @@ -0,0 +1,75 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#ifndef SIGPIPE +# define SIGPIPE 13 +#endif // !SIGPIPE + +namespace pangolin +{ + +typedef void (*SigCallbackFn)(int); + +struct PANGOLIN_EXPORT SigCallback +{ + SigCallback(const int & sig, SigCallbackFn fn, void* data) + : sig(sig), fn(fn), data(data), value(false) + { + std::signal(sig, fn); + } + + int sig; + SigCallbackFn fn; + void * data; + volatile sig_atomic_t value; +}; + +class PANGOLIN_EXPORT SigState +{ +public: + static SigState& I(); + + SigState(); + ~SigState(); + + void Clear(); + + std::map sig_callbacks; +}; + +PANGOLIN_EXPORT +void RegisterNewSigCallback(SigCallbackFn callback, void* data, const int signal); + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/simple_math.h b/thirdparty/Pangolin/include/pangolin/utils/simple_math.h new file mode 100644 index 00000000..eff7a43f --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/simple_math.h @@ -0,0 +1,446 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace pangolin +{ + +static const double Identity3d[] = {1,0,0, 0,1,0, 0,0,1}; +static const double Zero3d[] = {0,0,0, 0,0,0, 0,0,0}; +static const double Identity4d[] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; +static const double Zero4d[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; + +static const float Identity3f[] = {1,0,0, 0,1,0, 0,0,1}; +static const float Zero3f[] = {0,0,0, 0,0,0, 0,0,0}; +static const float Identity4f[] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; +static const float Zero4f[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; + +template +void MatPrint(const P m[R*C]) +{ + for( int r=0; r < R; ++r) + { + for( int c=0; c < C; ++c ) + std::cout << m[R*c+r] << " "; + std::cout << std::endl; + } + std::cout << std::endl; +} + +template +void MatPrint(const P m[R*C], std::string name) +{ + std::cout << name << " = [" << std::endl; + for( int r=0; r < R; ++r) + { + for( int c=0; c < C; ++c ) + std::cout << m[R*c+r] << " "; + std::cout << std::endl; + } + std::cout << std::endl << "]" << std::endl; +} + +// Set array using varadic arguments +template +void MatSet(P m[R*C], ...) +{ + va_list ap; + va_start(ap,m); + for( int i=0; i< R*C; ++i ) + { + *m = (P)va_arg(ap,double); + ++m; + } +} + +// m = zeroes(N) +template +void SetZero(P m[R*C] ) +{ + std::fill_n(m,R*C,0); +} + +// m = identity(N) +template +void SetIdentity(P m[N*N] ) +{ + std::fill_n(m,N*N,0); + for( int i=0; i< N; ++i ) + m[N*i+i] = 1; +} + +// mo = m1 * m2 +template +void MatMul(P mo[R*C], const P m1[R*M], const P m2[M*C] ) +{ + for( int r=0; r < R; ++r) + for( int c=0; c < C; ++c ) + { + mo[R*c+r] = 0; + for( int m=0; m < M; ++ m) mo[R*c+r] += m1[R*m+r] * m2[M*c+m]; + } +} + +// mo = m1 * m2 * s +template +void MatMul(P mo[R*C], const P m1[R*M], const P m2[M*C], P s ) +{ + for( int r=0; r < R; ++r) + for( int c=0; c < C; ++c ) + { + mo[R*c+r] = 0; + for( int m=0; m < M; ++ m) mo[R*c+r] += m1[R*m+r] * m2[M*c+m] * s; + } +} + +// mo = m1 * transpose(m2) +template +void MatMulTranspose(P mo[R*C], const P m1[R*M], const P m2[C*M] ) +{ + for( int r=0; r < R; ++r) + for( int c=0; c < C; ++c ) + { + mo[R*c+r] = 0; + for( int m=0; m < M; ++ m) mo[R*c+r] += m1[R*m+r] * m2[C*m+c]; + } +} + +// m = m1 + m2 +template +void MatAdd(P m[R*C], const P m1[R*C], const P m2[R*C]) +{ + for( int i=0; i< R*C; ++i ) + m[i] = m1[i] + m2[i]; +} + +// m = m1 - m2 +template +void MatSub(P m[R*C], const P m1[R*C], const P m2[R*C]) +{ + for( int i=0; i< R*C; ++i ) + m[i] = m1[i] - m2[i]; +} + +// m = m1 * scalar +template +void MatMul(P m[R*C], const P m1[R*C], P scalar) +{ + for( int i=0; i< R*C; ++i ) + m[i] = m1[i] * scalar; +} + +// m = m1 + m2 +template +void MatMul(P m[R*C], P scalar) +{ + for( int i=0; i< R*C; ++i ) + m[i] *= scalar; +} + +template +void MatTranspose(P out[N*N], const P in[N*N] ) +{ + for( int c=0; c +void MatTranspose(P m[N*N] ) +{ + for( int c=0; c(m[N*c+r],m[N*r+c]); +} + +// m = a x b +template +void VecCross3(P m[3], const P a[3], const P b[3]) +{ + m[0] = a[1]*b[2] - a[2]*b[1]; + m[1] = a[2]*b[0] - a[0]*b[2]; + m[2] = a[0]*b[1] - a[1]*b[0]; +} + +// s = skewSymetrixMatrix(v) +template +void MatSkew(P s[3*3], const P v[3] ) +{ + s[0] = 0; + s[1] = v[2]; + s[2] = -v[1]; + s[3] = -v[2]; + s[4] = 0; + s[5] = v[0]; + s[6] = v[1]; + s[7] = -v[0]; + s[8] = 0; +} + +template +void MatOrtho( P m[N*N] ) +{ + // http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/index.htm + P Itimes3[N*N]; + SetIdentity(Itimes3); + MatMul(Itimes3,(P)3.0); + + P mmT[N*N]; + MatMulTranspose(mmT,m,m); + + P _c[N*N]; + MatSub(_c,Itimes3,mmT); + P _m[N*N]; + MatMul(_m,m,_c,(P)0.5); + std::copy(_m,_m+(N*N),m); +} + +template +void Rotation(P R[3*3], P x, P y, P z) +{ + P sx = sin(x); + P sy = sin(y); + P sz = sin(z); + P cx = cos(x); + P cy = cos(y); + P cz = cos(z); + // P cx = sqrt( (P)1.0 - sx * sx); + // P cy = sqrt( (P)1.0 - sy * sy); + // P cz = sqrt( (P)1.0 - sz * sz); + R[0] = cy * cz; + R[1] = sx * sy * cz + cx * sz; + R[2] = -cx * sy * cz + sx * sz; + R[3] = -cy * sz; + R[4] = -sx * sy * sz + cx * cz; + R[5] = cx * sy * sz + sx * cz; + R[6] = sy; + R[7] = -sx * cy; + R[8] = cx * cy; +} + +template +void LieSetIdentity(P T_ba[3*4] ) +{ + SetIdentity<3>(T_ba); + std::fill_n(T_ba+(3*3),3,0); +} + +template +void LieSetRotation(P T_ba[3*4], const P R_ba[3*3] ) +{ + std::copy(R_ba,R_ba+(3*3),T_ba); +} + +template +void LieSetTranslation(P T_ba[3*4], const P a_b[3] ) +{ + std::copy(a_b, a_b+3, T_ba+(3*3)); +} + +template +void LieSetSE3(P T_ba[3*4], const P R_ba[3*3], const P a_b[3] ) +{ + LieSetRotation

(T_ba,R_ba); + LieSetTranslation

(T_ba,a_b); +} + +template +void LieGetRotation(P R_ba[3*3], const P T_ba[3*4] ) +{ + std::copy(T_ba,T_ba+(3*3),R_ba); +} + +template +void LieApplySO3( P out[3], const P R_ba[3*3], const P in[3] ) +{ + MatMul<3,3,1,P>(out,R_ba,in); +} + +template +void LieApplySE3vec( P x_b[3], const P T_ba[3*4], const P x_a[3] ) +{ + P rot[3]; + MatMul<3,3,1,P>(rot,T_ba,x_a); + MatAdd<3,1,P>(x_b,rot,T_ba+(3*3)); +} + +template +void LieApplySE34x4vec3( P x_b[3], const P T_ba[4*4], const P x_a[3] ) +{ + x_b[0] = T_ba[0]*x_a[0] + T_ba[4]*x_a[1] + T_ba[8]*x_a[2] + T_ba[12]; + x_b[1] = T_ba[1]*x_a[0] + T_ba[5]*x_a[1] + T_ba[9]*x_a[2] + T_ba[13]; + x_b[2] = T_ba[2]*x_a[0] + T_ba[6]*x_a[1] + T_ba[10]*x_a[2] + T_ba[14]; +} + +template +void LieMulSO3( P R_ca[3*3], const P R_cb[3*3], const P R_ba[3*3] ) +{ + MatMul<3,3,3>(R_ca,R_cb,R_ba); +} + +template +void LieMulSE3( P T_ca[3*4], const P T_cb[3*4], const P T_ba[3*4] ) +{ + LieMulSO3<>(T_ca,T_cb,T_ba); + P R_cb_times_a_b[3]; + LieApplySO3<>(R_cb_times_a_b,T_cb,T_ba+(3*3)); + MatAdd<3,1>(T_ca+(3*3),R_cb_times_a_b,T_cb+(3*3)); +} + +template +void LiePutSE3in4x4(P out[4*4], const P in[3*4] ) +{ + SetIdentity<4>(out); + std::copy(in,in+3, out); + std::copy(in+3,in+6, out+4); + std::copy(in+6,in+9, out+8); + std::copy(in+9,in+12, out+12); +} + +template +void LieSE3from4x4(P out[3*4], const P in[4*4] ) +{ + std::copy(in,in+3, out); + std::copy(in+4,in+7, out+3); + std::copy(in+8,in+11, out+6); + std::copy(in+12,in+15, out+9); +} + +template +void LieMul4x4bySE3( P T_ca[4*4], const P T_cb[3*4], const P T_ba[4*4] ) +{ + // TODO: fast + P T_cb4[4*4]; + LiePutSE3in4x4<>(T_cb4,T_cb); + P res[4*4]; + MatMul<4,4,4>(res,T_cb4,T_ba); + std::copy(res,res+(4*4),T_ca); +} + +template +void LieTransposeSO3( P R_ab[3*3], const P R_ba[3*3] ) +{ + MatTranspose<3,P>(R_ab,R_ba); +} + +template +void LieInverseSE3( P T_ab[3*4], const P T_ba[3*4] ) +{ + LieTransposeSO3

(T_ab,T_ba); + P minus_b_a[3]; + LieApplySO3(minus_b_a, T_ab, T_ba+(3*3)); + MatMul<3,1,P>(T_ab+(3*3),minus_b_a, -1); +} + +// c = a x b +template +void CrossProduct( P c[3], const P a[3], const P b[3] ) +{ + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; +} + +template +P Length( P v[R] ) +{ + P sum_sq = 0; + + for(size_t r = 0; r < R; ++r ) { + sum_sq += v[r] * v[r]; + } + + return sqrt(sum_sq); +} + + +template +void Normalise( P v[R] ) +{ + const P length = Length(v); + + for(size_t r = 0; r < R; ++r ) { + v[r] /= length; + } +} + +template +void EnforceUpT_wc(P T_wc[3*4], const P up_w[3]) +{ + // Copy R_wc + P R_wc[3*3]; + std::copy(T_wc,T_wc+3*3,R_wc); + + // New R_wc should go into T_wc + P* NR_wc = T_wc; + + // // cx_w,cy_w,cz_w are camera axis in world coordinates + // // Calculate new camera coordinates (ncx_w,ncy_w,ncz_w) + + // ncx_w = up_w x cz_w + CrossProduct(NR_wc + 0*3, up_w, R_wc + 2*3); + + // ncy_w = cz_w x ncx_w + CrossProduct(NR_wc + 1*3, R_wc + 2*3, NR_wc + 0*3); + + // ncz_w = cz_w + std::copy(R_wc + 2*3, R_wc + 3*3, NR_wc + 2*3); + + Normalise<3,P>(NR_wc + 0*3); + Normalise<3,P>(NR_wc + 1*3); + Normalise<3,P>(NR_wc + 2*3); +} + +template +void EnforceUpT_cw(P T_cw_4x4[4*4], const P up_w[3]) +{ + // 3x4 from 4x4 + P T_cw[3*4]; + LieSE3from4x4

(T_cw,T_cw_4x4); + + // Invert T_cw + P T_wc[3*4]; + LieInverseSE3

(T_wc, T_cw); + + // Enforce up for T_wc + EnforceUpT_wc

(T_wc, up_w); + + // Invert + LieInverseSE3

(T_cw, T_wc); + + // 4x4 from 3x4 + LiePutSE3in4x4

(T_cw_4x4,T_cw); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/threadedfilebuf.h b/thirdparty/Pangolin/include/pangolin/utils/threadedfilebuf.h new file mode 100644 index 00000000..a8eb2ac9 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/threadedfilebuf.h @@ -0,0 +1,97 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef _LINUX_ +// On linux, using posix file i/o to allow sync writes. +#define USE_POSIX_FILE_IO +#endif + +namespace pangolin +{ + +class PANGOLIN_EXPORT threadedfilebuf : public std::streambuf +{ +public: + ~threadedfilebuf(); + threadedfilebuf(); + threadedfilebuf(const std::string& filename, size_t buffer_size_bytes); + + void open(const std::string& filename, size_t buffer_size_bytes); + void close(); + void force_close(); + + void operator()(); + +protected: + void soft_close(); + + //! Override streambuf::xsputn for asynchronous write + std::streamsize xsputn(const char * s, std::streamsize n) override; + + //! Override streambuf::overflow for asynchronous write + int overflow(int c) override; + + std::streampos seekoff( + std::streamoff off, std::ios_base::seekdir way, + std::ios_base::openmode which = std::ios_base::in | std::ios_base::out + ) override; + +#ifdef USE_POSIX_FILE_IO + int filenum = -1; +#else + std::filebuf file; +#endif + + char* mem_buffer; + std::streamsize mem_size; + std::streamsize mem_max_size; + std::streamsize mem_start; + std::streamsize mem_end; + + std::streampos input_pos; + + std::mutex update_mutex; + std::condition_variable cond_queued; + std::condition_variable cond_dequeued; + std::thread write_thread; + + bool should_run; + bool is_pipe; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/timer.h b/thirdparty/Pangolin/include/pangolin/utils/timer.h new file mode 100644 index 00000000..6b0418b4 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/timer.h @@ -0,0 +1,116 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include + +namespace pangolin +{ + +// These methods exist for backwards compatibility. +// They are deprecated in favour of direct use of std::chrono in C++11 + +using baseclock = std::chrono::steady_clock; +using basetime = baseclock::time_point; +static_assert(baseclock::is_steady, "baseclock must be steady to be robust against system time settings"); + +inline basetime TimeNow() +{ + return baseclock::now(); +} + +inline double Time_s(basetime t) +{ + using namespace std::chrono; + return duration_cast( t.time_since_epoch() ).count(); +} + +inline int64_t Time_us(basetime t) +{ + using namespace std::chrono; + return duration_cast( t.time_since_epoch() ).count(); +} + +inline double TimeDiff_s(basetime start, basetime end) +{ + const baseclock::duration d = end - start; + return Time_s( basetime() + d); +} + +inline int64_t TimeDiff_us(basetime start, basetime end) +{ + const baseclock::duration d = end - start; + return Time_us( basetime() + d); +} + +inline basetime TimeAdd(basetime t1, basetime t2) +{ + + return t1 + t2.time_since_epoch(); +} + +inline double TimeNow_s() +{ + return Time_s(TimeNow()); +} + +inline int64_t TimeNow_us() +{ + return Time_us(TimeNow()); +} + +inline basetime WaitUntil(basetime t) +{ + std::this_thread::sleep_until(t); + return TimeNow(); +} + +struct Timer +{ + Timer() { + Reset(); + } + + void Reset() + { + start = TimeNow(); + } + + double Elapsed_s() + { + basetime currtime = TimeNow(); + return TimeDiff_s(start,currtime); + } + + basetime start; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/transform.h b/thirdparty/Pangolin/include/pangolin/utils/transform.h new file mode 100644 index 00000000..b29c1e9d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/transform.h @@ -0,0 +1,102 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +// Find the open brace preceeded by '$' +inline const char* FirstOpenBrace(const char* str, char token = '$', char open = '{') +{ + bool symbol = false; + + for(; *str != '\0'; ++str ) { + if( *str == token) { + symbol = true; + }else{ + if( symbol ) { + if( *str == open ) { + return str; + } else { + symbol = false; + } + } + } + } + return 0; +} + +// Find the first matching end brace. str includes open brace +inline const char* MatchingEndBrace(const char* str, char open = '{', char close = '}') +{ + int b = 0; + for(; *str != '\0'; ++str ) { + if( *str == open ) { + ++b; + }else if( *str == close ) { + --b; + if( b == 0 ) { + return str; + } + } + } + return 0; +} + +inline std::string Transform(const std::string& val, std::function dictionary, char token = '$', char open = '{', char close = '}') +{ + std::string expanded = val; + + while(true) + { + const char* brace = FirstOpenBrace(expanded.c_str(), token, open); + if(brace) + { + const char* endbrace = MatchingEndBrace(brace); + if( endbrace ) + { + std::ostringstream oss; + oss << std::string(expanded.c_str(), brace-1); + + const std::string inexpand = Transform( std::string(brace+1,endbrace), dictionary, token, open, close ); + oss << dictionary(inexpand); + oss << std::string(endbrace+1, expanded.c_str() + expanded.length() ); + expanded = oss.str(); + continue; + } + } + break; + } + + return expanded; +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/type_convert.h b/thirdparty/Pangolin/include/pangolin/utils/type_convert.h new file mode 100644 index 00000000..93d026f7 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/type_convert.h @@ -0,0 +1,210 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace pangolin +{ +struct BadInputException : std::exception { + char const* what() const throw() { return "Failed to serialise type"; } +}; +} + +namespace std +{ +// Dummy methods to serialise functions / functors / lambdas etc +#ifdef CALLEE_HAS_VARIADIC_TEMPLATES +template +inline std::istream& operator>>(std::istream& /*is*/, std::function& /*f*/) { + throw pangolin::BadInputException(); +} +template +inline std::ostream& operator<<(std::ostream& /*os*/, const std::function& /*f*/) { + throw pangolin::BadInputException(); +} +#else +template +inline std::istream& operator>>(std::istream& /*is*/, std::function& /*f*/) { + throw pangolin::BadInputException(); +} +template +inline std::ostream& operator<<(std::ostream& /*os*/, const std::function& /*f*/) { + throw pangolin::BadInputException(); +} +inline std::istream& operator>>(std::istream& /*is*/, std::function& /*f*/) { + throw pangolin::BadInputException(); +} +inline std::ostream& operator<<(std::ostream& /*os*/, const std::function& /*f*/) { + throw pangolin::BadInputException(); +} +#endif +} + +namespace pangolin +{ + +template +struct Convert; + +// Generic conversion through serialisation from / to string +template +struct Convert { + static T Do(const S& src) + { + std::ostringstream oss; + oss << src; + std::istringstream iss(oss.str()); + T target; + iss >> target; + + if(iss.fail()) + throw BadInputException(); + + return target; + } +}; + +// Between the same types is just a copy +template +struct Convert { + static T Do(const T& src) + { + return src; + } +}; + +// Apply bool alpha IO manipulator for bool types +template<> +struct Convert { + static bool Do(const std::string& src) + { + bool target; + std::istringstream iss(src); + iss >> target; + + if(iss.fail()) + { + std::istringstream iss2(src); + iss2 >> std::boolalpha >> target; + if( iss2.fail()) + throw BadInputException(); + } + + return target; + } +}; + +// From strings +template +struct Convert::value + >::type > { + static T Do(const std::string& src) + { + T target; + std::istringstream iss(src); + iss >> target; + + if(iss.fail()) + throw BadInputException(); + + return target; + } +}; + +// To strings +template +struct Convert::value + >::type > { + static std::string Do(const S& src) + { + std::ostringstream oss; + oss << src; + return oss.str(); + } +}; + +// Between scalars +template +struct Convert::value && !std::is_same::value && + std::is_scalar::value && !std::is_same::value && + !std::is_same::value + >::type > { + static T Do(const S& src) + { + return static_cast(src); + } +}; + +// From Scalars to bool (different than scalar definition to avoid MSVC Warnings) +template +struct Convert::value && + std::is_scalar::value && + !std::is_same::value +>::type > { + static T Do(const S& src) + { + return src != static_cast(0); + } +}; + +// From bool to Scalars (different than scalar definition to avoid MSVC Warnings) +template +struct Convert::value && + std::is_same::value && + !std::is_same::value +>::type > { + static T Do(const S& src) + { + return src ? static_cast(0) : static_cast(1); + } +}; + +template +std::string ToString(const S& src) +{ + return Convert::Do(src); +} + +template +T FromString(const std::string& src) +{ + return Convert::Do(src); +} + + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/uri.h b/thirdparty/Pangolin/include/pangolin/utils/uri.h new file mode 100644 index 00000000..0ea376ed --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/uri.h @@ -0,0 +1,49 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT Uri : public Params +{ +public: + std::string scheme; + std::string url; + std::string full_uri; +}; + +//! Parse string as Video URI +PANGOLIN_EXPORT +Uri ParseUri(const std::string& str_uri); + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/variadic_all.h b/thirdparty/Pangolin/include/pangolin/utils/variadic_all.h new file mode 100644 index 00000000..3cc0681e --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/variadic_all.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +namespace pangolin { + +template +bool all_of(TPred pred, const T& i) +{ + return pred(i); +} + +template +bool all_of(const TPred& pred, const T& i, const Targs& ... ins) +{ + return pred(i) && all_of(pred, ins...); +} + +template +bool any_of(TPred pred, const T& i) +{ + return pred(i); +} + +template +bool any_of(const TPred& pred, const T& i, Targs& ... ins) +{ + return pred(i) || any_of(pred, ins...); +} + +template +bool all_found(const TContainer& c, const Targs& ... its) +{ + using T1 = typename std::tuple_element<0, std::tuple>::type; + return all_of([&c](const T1& it){return it != c.end();}, its...); +} + +template +bool all_equal(const T& v1, const Targs& ... its) +{ + return all_of([v1](const T& o){return v1 == o;}, its...); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/utils/xml/license.txt b/thirdparty/Pangolin/include/pangolin/utils/xml/license.txt new file mode 100755 index 00000000..14098318 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/xml/license.txt @@ -0,0 +1,52 @@ +Use of this software is granted under one of the following two licenses, +to be chosen freely by the user. + +1. Boost Software License - Version 1.0 - August 17th, 2003 +=============================================================================== + +Copyright (c) 2006, 2007 Marcin Kalicinski + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +2. The MIT License +=============================================================================== + +Copyright (c) 2006, 2007 Marcin Kalicinski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml.hpp b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml.hpp new file mode 100755 index 00000000..252e344d --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml.hpp @@ -0,0 +1,2635 @@ +#ifndef RAPIDXML_HPP_INCLUDED +#define RAPIDXML_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation + +// If standard library is disabled, user must provide implementations of required functions and typedefs +#if !defined(RAPIDXML_NO_STDLIB) + #include // For std::size_t + #include // For assert + #include // For placement new + #include // for conversion between types +#endif + +// On MSVC, disable "conditional expression is constant" warning (level 4). +// This warning is almost impossible to avoid with certain types of templated code +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable:4127) // Conditional expression is constant +#endif + +/////////////////////////////////////////////////////////////////////////// +// RAPIDXML_PARSE_ERROR + +#if defined(RAPIDXML_NO_EXCEPTIONS) + +#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); } + +namespace rapidxml +{ + //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, + //! this function is called to notify user about the error. + //! It must be defined by the user. + //!

+ //! This function cannot return. If it does, the results are undefined. + //!

+ //! A very simple definition might look like that: + //!

+    //! void %rapidxml::%parse_error_handler(const char *what, void *where)
+    //! {
+    //!     std::cout << "Parse error: " << what << "\n";
+    //!     std::abort();
+    //! }
+    //! 
+ //! \param what Human readable description of the error. + //! \param where Pointer to character data where error was detected. + void parse_error_handler(const char *what, void *where); +} + +#else + +#include // For std::exception + +#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where) + +namespace rapidxml +{ + + //! Parse error exception. + //! This exception is thrown by the parser when an error occurs. + //! Use what() function to get human-readable error message. + //! Use where() function to get a pointer to position within source text where error was detected. + //!

+ //! If throwing exceptions by the parser is undesirable, + //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included. + //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception. + //! This function must be defined by the user. + //!

+ //! This class derives from std::exception class. + class parse_error: public std::exception + { + + public: + + //! Constructs parse error + parse_error(const char *what, void *where) + : m_what(what) + , m_where(where) + { + } + + //! Gets human readable description of error. + //! \return Pointer to null terminated description of the error. + virtual const char *what() const throw() + { + return m_what; + } + + //! Gets pointer to character data where error happened. + //! Ch should be the same as char type of xml_document that produced the error. + //! \return Pointer to location within the parsed string where error occured. + template + Ch *where() const + { + return reinterpret_cast(m_where); + } + + private: + + const char *m_what; + void *m_where; + + }; +} + +#endif + +/////////////////////////////////////////////////////////////////////////// +// Pool sizes + +#ifndef RAPIDXML_STATIC_POOL_SIZE + // Size of static memory block of memory_pool. + // Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // No dynamic memory allocations are performed by memory_pool until static memory is exhausted. + #define RAPIDXML_STATIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef RAPIDXML_DYNAMIC_POOL_SIZE + // Size of dynamic memory block of memory_pool. + // Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool. + #define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef RAPIDXML_ALIGNMENT + // Memory allocation alignment. + // Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer. + // All memory allocations for nodes, attributes and strings will be aligned to this value. + // This must be a power of 2 and at least 1, otherwise memory_pool will not work. + #define RAPIDXML_ALIGNMENT sizeof(void *) +#endif + +namespace rapidxml +{ + // Forward declarations + template class xml_node; + template class xml_attribute; + template class xml_document; + + //! Enumeration listing all node types produced by the parser. + //! Use xml_node::type() function to query node type. + enum node_type + { + node_document, //!< A document node. Name and value are empty. + node_element, //!< An element node. Name contains element name. Value contains text of first data node. + node_data, //!< A data node. Name is empty. Value contains data text. + node_cdata, //!< A CDATA node. Name is empty. Value contains data text. + node_comment, //!< A comment node. Name is empty. Value contains comment text. + node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes. + node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text. + node_pi //!< A PI node. Name contains target. Value contains instructions. + }; + + /////////////////////////////////////////////////////////////////////// + // Parsing flags + + //! Parse flag instructing the parser to not create data nodes. + //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_data_nodes = 0x1; + + //! Parse flag instructing the parser to not use text of first data node as a value of parent element. + //! Can be combined with other flags by use of | operator. + //! Note that child data nodes of element node take precendence over its value when printing. + //! That is, if element has one or more child data nodes and a value, the value will be ignored. + //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements. + //!

+ //! See xml_document::parse() function. + const int parse_no_element_values = 0x2; + + //! Parse flag instructing the parser to not place zero terminators after strings in the source text. + //! By default zero terminators are placed, modifying source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_string_terminators = 0x4; + + //! Parse flag instructing the parser to not translate entities in the source text. + //! By default entities are translated, modifying source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_entity_translation = 0x8; + + //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters. + //! By default, UTF-8 handling is enabled. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_utf8 = 0x10; + + //! Parse flag instructing the parser to create XML declaration node. + //! By default, declaration node is not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_declaration_node = 0x20; + + //! Parse flag instructing the parser to create comments nodes. + //! By default, comment nodes are not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_comment_nodes = 0x40; + + //! Parse flag instructing the parser to create DOCTYPE node. + //! By default, doctype node is not created. + //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_doctype_node = 0x80; + + //! Parse flag instructing the parser to create PI nodes. + //! By default, PI nodes are not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_pi_nodes = 0x100; + + //! Parse flag instructing the parser to validate closing tag names. + //! If not set, name inside closing tag is irrelevant to the parser. + //! By default, closing tags are not validated. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_validate_closing_tags = 0x200; + + //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes. + //! By default, whitespace is not trimmed. + //! This flag does not cause the parser to modify source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_trim_whitespace = 0x400; + + //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character. + //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag. + //! By default, whitespace is not normalized. + //! If this flag is specified, source text will be modified. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_normalize_whitespace = 0x800; + + // Compound flags + + //! Parse flags which represent default behaviour of the parser. + //! This is always equal to 0, so that all other flags can be simply ored together. + //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values. + //! This also means that meaning of each flag is a negation of the default setting. + //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is enabled by default, + //! and using the flag will disable it. + //!

+ //! See xml_document::parse() function. + const int parse_default = 0; + + //! A combination of parse flags that forbids any modifications of the source text. + //! This also results in faster parsing. However, note that the following will occur: + //!
    + //!
  • names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends
  • + //!
  • entities will not be translated
  • + //!
  • whitespace will not be normalized
  • + //!
+ //! See xml_document::parse() function. + const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation; + + //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data. + //!

+ //! See xml_document::parse() function. + const int parse_fastest = parse_non_destructive | parse_no_data_nodes; + + //! A combination of parse flags resulting in largest amount of data being extracted. + //! This usually results in slowest parsing. + //!

+ //! See xml_document::parse() function. + const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags; + + /////////////////////////////////////////////////////////////////////// + // Command option default defaults + + //! Default case sensitivity when searching for node / attribute names. + const bool default_case_sensitivity = false; + + + /////////////////////////////////////////////////////////////////////// + // Internals + + //! \cond internal + namespace internal + { + + // Struct that contains lookup tables for the parser + // It must be a template to allow correct linking (because it has static data members, which are defined in a header file). + template + struct lookup_tables + { + static const unsigned char lookup_whitespace[256]; // Whitespace table + static const unsigned char lookup_node_name[256]; // Node name table + static const unsigned char lookup_text[256]; // Text table + static const unsigned char lookup_text_pure_no_ws[256]; // Text table + static const unsigned char lookup_text_pure_with_ws[256]; // Text table + static const unsigned char lookup_attribute_name[256]; // Attribute name table + static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote + static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote + static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes + static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes + static const unsigned char lookup_digits[256]; // Digits + static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters + }; + + // Find length of the string + template + inline std::size_t measure(const Ch *p) + { + const Ch *tmp = p; + while (*tmp) + ++tmp; + return tmp - p; + } + + // Compare strings for equality + template + inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive) + { + if (size1 != size2) + return false; + if (case_sensitive) + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (*p1 != *p2) + return false; + } + else + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (lookup_tables<0>::lookup_upcase[static_cast(*p1)] != lookup_tables<0>::lookup_upcase[static_cast(*p2)]) + return false; + } + return true; + } + } + //! \endcond + + /////////////////////////////////////////////////////////////////////// + // Memory pool + + //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation. + //! In most cases, you will not need to use this class directly. + //! However, if you need to create nodes manually or modify names/values of nodes, + //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. + //! Not only is this faster than allocating them by using new operator, + //! but also their lifetime will be tied to the lifetime of document, + //! possibly simplyfing memory management. + //!

+ //! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. + //! You can also call allocate_string() function to allocate strings. + //! Such strings can then be used as names or values of nodes without worrying about their lifetime. + //! Note that there is no free() function -- all allocations are freed at once when clear() function is called, + //! or when the pool is destroyed. + //!

+ //! It is also possible to create a standalone memory_pool, and use it + //! to allocate nodes, whose lifetime will not be tied to any document. + //!

+ //! Pool maintains RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. + //! Until static memory is exhausted, no dynamic memory allocations are done. + //! When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE each, + //! by using global new[] and delete[] operators. + //! This behaviour can be changed by setting custom allocation routines. + //! Use set_allocator() function to set them. + //!

+ //! Allocations for nodes, attributes and strings are aligned at RAPIDXML_ALIGNMENT bytes. + //! This value defaults to the size of pointer on target architecture. + //!

+ //! To obtain absolutely top performance from the parser, + //! it is important that all nodes are allocated from a single, contiguous block of memory. + //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. + //! If required, you can tweak RAPIDXML_STATIC_POOL_SIZE, RAPIDXML_DYNAMIC_POOL_SIZE and RAPIDXML_ALIGNMENT + //! to obtain best wasted memory to performance compromise. + //! To do it, define their values before rapidxml.hpp file is included. + //! \param Ch Character type of created nodes. + template + class memory_pool + { + + public: + + //! \cond internal + typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory + typedef void (free_func)(void *); // Type of user-defined function used to free memory + //! \endcond + + //! Constructs empty pool with default allocator functions. + memory_pool() + : m_alloc_func(0) + , m_free_func(0) + { + init(); + } + + //! Destroys pool and frees all the memory. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Nodes allocated from the pool are no longer valid. + ~memory_pool() + { + clear(); + } + + //! Allocates a new node from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param type Type of node to create. + //! \param name Name to assign to the node, or 0 to assign no name. + //! \param value Value to assign to the node, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated node. This pointer will never be NULL. + xml_node *allocate_node(node_type type, + const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_node)); + xml_node *node = new(memory) xml_node(type); + if (name) + { + if (name_size > 0) + node->name(name, name_size); + else + node->name(name); + } + if (value) + { + if (value_size > 0) + node->value(value, value_size); + else + node->value(value); + } + return node; + } + + //! Allocates a new attribute from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param name Name to assign to the attribute, or 0 to assign no name. + //! \param value Value to assign to the attribute, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated attribute. This pointer will never be NULL. + xml_attribute *allocate_attribute(const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_attribute)); + xml_attribute *attribute = new(memory) xml_attribute; + if (name) + { + if (name_size > 0) + attribute->name(name, name_size); + else + attribute->name(name); + } + if (value) + { + if (value_size > 0) + attribute->value(value, value_size); + else + attribute->value(value); + } + return attribute; + } + + //! Allocates a char array of given size from the pool, and optionally copies a given string to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param source String to initialize the allocated memory with, or 0 to not initialize it. + //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated. + //! \return Pointer to allocated char array. This pointer will never be NULL. + Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) + { + assert(source || size); // Either source or size (or both) must be specified + if (size == 0) + size = internal::measure(source) + 1; + Ch *result = static_cast(allocate_aligned(size * sizeof(Ch))); + if (source) + for (std::size_t i = 0; i < size; ++i) + result[i] = source[i]; + return result; + } + + //! Clones an xml_node and its hierarchy of child nodes and attributes. + //! Nodes and attributes are allocated from this memory pool. + //! Names and values are not cloned, they are shared between the clone and the source. + //! Result node can be optionally specified as a second parameter, + //! in which case its contents will be replaced with cloned source node. + //! This is useful when you want to clone entire document. + //! \param source Node to clone. + //! \param result Node to put results in, or 0 to automatically allocate result node + //! \return Pointer to cloned node. This pointer will never be NULL. + xml_node *clone_node(const xml_node *source, xml_node *result = 0) + { + // Prepare result node + if (result) + { + result->remove_all_attributes(); + result->remove_all_nodes(); + result->type(source->type()); + } + else + result = allocate_node(source->type()); + + // Clone name and value + result->name(source->name(), source->name_size()); + result->value(source->value(), source->value_size()); + + // Clone child nodes and attributes + for (xml_node *child = source->first_node(); child; child = child->next_sibling()) + result->append_node(clone_node(child)); + for (xml_attribute *attr = source->first_attribute(); attr; attr = attr->next_attribute()) + result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size())); + + return result; + } + + //! Clears the pool. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Any nodes or strings allocated from the pool will no longer be valid. + void clear() + { + while (m_begin != m_static_memory) + { + char *previous_begin = reinterpret_cast
(align(m_begin))->previous_begin; + if (m_free_func) + m_free_func(m_begin); + else + delete[] m_begin; + m_begin = previous_begin; + } + init(); + } + + //! Sets or resets the user-defined memory allocation functions for the pool. + //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined. + //! Allocation function must not return invalid pointer on failure. It should either throw, + //! stop the program, or use longjmp() function to pass control to other place of program. + //! If it returns invalid pointer, results are undefined. + //!

+ //! User defined allocation functions must have the following forms: + //!
+ //!
void *allocate(std::size_t size); + //!
void free(void *pointer); + //!

+ //! \param af Allocation function, or 0 to restore default function + //! \param ff Free function, or 0 to restore default function + void set_allocator(alloc_func *af, free_func *ff) + { + assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet + m_alloc_func = af; + m_free_func = ff; + } + + private: + + struct header + { + char *previous_begin; + }; + + void init() + { + m_begin = m_static_memory; + m_ptr = align(m_begin); + m_end = m_static_memory + sizeof(m_static_memory); + } + + char *align(char *ptr) + { + std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) & (RAPIDXML_ALIGNMENT - 1)); + return ptr + alignment; + } + + char *allocate_raw(std::size_t size) + { + // Allocate + void *memory; + if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[] + { + memory = m_alloc_func(size); + assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp + } + else + { + memory = new char[size]; +#ifdef RAPIDXML_NO_EXCEPTIONS + if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc + RAPIDXML_PARSE_ERROR("out of memory", 0); +#endif + } + return static_cast(memory); + } + + void *allocate_aligned(std::size_t size) + { + // Calculate aligned pointer + char *result = align(m_ptr); + + // If not enough memory left in current pool, allocate a new pool + if (result + size > m_end) + { + // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE) + std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE; + if (pool_size < size) + pool_size = size; + + // Allocate + std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation + char *raw_memory = allocate_raw(alloc_size); + + // Setup new pool in allocated memory + char *pool = align(raw_memory); + header *new_header = reinterpret_cast
(pool); + new_header->previous_begin = m_begin; + m_begin = raw_memory; + m_ptr = pool + sizeof(header); + m_end = raw_memory + alloc_size; + + // Calculate aligned pointer again using new pool + result = align(m_ptr); + } + + // Update pool and return aligned pointer + m_ptr = result + size; + return result; + } + + char *m_begin; // Start of raw memory making up current pool + char *m_ptr; // First free byte in current pool + char *m_end; // One past last available byte in current pool + char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory + alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used + free_func *m_free_func; // Free function, or 0 if default is to be used + }; + + /////////////////////////////////////////////////////////////////////////// + // XML base + + //! Base class for xml_node and xml_attribute implementing common functions: + //! name(), name_size(), value(), value_size() and parent(). + //! \param Ch Character type to use + template + class xml_base + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + // Construct a base with empty name, value and parent + xml_base() + : m_name(0) + , m_value(0) + , m_parent(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets name of the node. + //! Interpretation of name depends on type of node. + //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //!

+ //! Use name_size() function to determine length of the name. + //! \return Name of node, or empty string if node has no name. + Ch *name() const + { + return m_name ? m_name : nullstr(); + } + + //! Gets size of node name, not including terminator character. + //! This function works correctly irrespective of whether name is or is not zero terminated. + //! \return Size of node name, in characters. + std::size_t name_size() const + { + return m_name ? m_name_size : 0; + } + + //! Gets value of node. + //! Interpretation of value depends on type of node. + //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //!

+ //! Use value_size() function to determine length of the value. + //! \return Value of node, or empty string if node has no value. + Ch *value() const + { + return m_value ? m_value : nullstr(); + } + + //! Gets size of node value, not including terminator character. + //! This function works correctly irrespective of whether value is or is not zero terminated. + //! \return Size of node value, in characters. + std::size_t value_size() const + { + return m_value ? m_value_size : 0; + } + + //! Gets value of node converted to type T. + //! \return Value of node converted to type T or default_val if no value exists. + //! \throws parse_error iff conversion to type T fails. + template + T valueT(T default_val = T() ) + { + if(m_value) { + std::istringstream ss( std::string(m_value, m_value_size) ); + T ret_val; + ss >> ret_val; + if(ss.fail()) { + RAPIDXML_PARSE_ERROR("error converting value in valueT()", m_value); + } + return ret_val; + } + return default_val; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets name of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //!

+ //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //!

+ //! Size of name must be specified separately, because name does not have to be zero terminated. + //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //! \param name Name of node to set. Does not have to be zero terminated. + //! \param size Size of name, in characters. This does not include zero terminator, if one is present. + void name(const Ch *name, std::size_t size) + { + m_name = const_cast(name); + m_name_size = size; + } + + //! Sets name of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t). + //! \param name Name of node to set. Must be zero terminated. + void name(const Ch *name) + { + this->name(name, internal::measure(name)); + } + + //! Sets value of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //!

+ //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //!

+ //! Size of value must be specified separately, because it does not have to be zero terminated. + //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //!

+ //! If an element has a child node of type node_data, it will take precedence over element value when printing. + //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser. + //! \param value value of node to set. Does not have to be zero terminated. + //! \param size Size of value, in characters. This does not include zero terminator, if one is present. + void value(const Ch *value, std::size_t size) + { + m_value = const_cast(value); + m_value_size = size; + } + + //! Sets value of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t). + //! \param value Vame of node to set. Must be zero terminated. + void value(const Ch *value) + { + this->value(value, internal::measure(value)); + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets node parent. + //! \return Pointer to parent node, or 0 if there is no parent. + xml_node *parent() const + { + return m_parent; + } + + protected: + + // Return empty string + static Ch *nullstr() + { + static Ch zero = Ch('\0'); + return &zero; + } + + Ch *m_name; // Name of node, or 0 if no name + Ch *m_value; // Value of node, or 0 if no value + std::size_t m_name_size; // Length of node name, or undefined of no name + std::size_t m_value_size; // Length of node value, or undefined if no value + xml_node *m_parent; // Pointer to parent node, or 0 if none + + }; + + //! Class representing attribute node of XML document. + //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base). + //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. + //! Thus, this text must persist in memory for the lifetime of attribute. + //! \param Ch Character type to use. + template + class xml_attribute: public xml_base + { + + friend class xml_node; + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty attribute with the specified type. + //! Consider using memory_pool of appropriate xml_document if allocating attributes manually. + xml_attribute() + { + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which attribute is a child. + //! \return Pointer to document that contains this attribute, or 0 if there is no parent document. + xml_document *document() const + { + if (xml_node *node = this->parent()) + { + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast *>(node) : 0; + } + else + return 0; + } + + //! Gets previous attribute, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_prev_attribute : 0; + } + + //! Gets next attribute, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_next_attribute : 0; + } + + private: + + xml_attribute *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero + xml_attribute *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML node + + //! Class representing a node of XML document. + //! Each node may have associated name and value strings, which are available through name() and value() functions. + //! Interpretation of name and value depends on type of the node. + //! Type of node can be determined by using type() function. + //!

+ //! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. + //! Thus, this text must persist in the memory for the lifetime of node. + //! \param Ch Character type to use. + template + class xml_node: public xml_base + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty node with the specified type. + //! Consider using memory_pool of appropriate document to allocate nodes manually. + //! \param type Type of node to construct. + xml_node(node_type type) + : m_type(type) + , m_first_node(0) + , m_first_attribute(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets type of node. + //! \return Type of node. + node_type type() const + { + return m_type; + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which node is a child. + //! \return Pointer to document that contains this node, or 0 if there is no parent document. + xml_document *document() const + { + xml_node *node = const_cast *>(this); + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast *>(node) : 0; + } + + //! Gets first child node, optionally matching node name. + //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node *first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *child = m_first_node; child; child = child->next_sibling()) + if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + return child; + return 0; + } + else + return m_first_node; + } + + //! Gets last child node, optionally matching node name. + //! Behaviour is undefined if node has no children. + //! Use first_node() to test if node has children. + //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node *last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + assert(m_first_node); // Cannot query for last child if node has no children + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *child = m_last_node; child; child = child->previous_sibling()) + if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + return child; + return 0; + } + else + return m_last_node; + } + + //! Gets previous sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node *previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + return sibling; + return 0; + } + else + return m_prev_sibling; + } + + //! Gets next sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node *next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + return sibling; + return 0; + } + else + return m_next_sibling; + } + + //! Gets first attribute of node, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute; + } + + //! Gets last attribute of node, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = default_case_sensitivity) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute ? m_last_attribute : 0; + } + + //! Gets first attribute of node, optionally matching attribute name, converting to type T + //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param default_val value to return if attribute is not found or if it has no value + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Converted value of attribute, or default_val if attribute not found or it has no value + template + T first_attribute_value(const Ch *name = 0, std::size_t name_size = 0, T default_val = T(), bool case_sensitive = default_case_sensitivity ) + { + rapidxml::xml_attribute<>* a = first_attribute( name, name_size, case_sensitive ); + return a ? a->valueT(default_val) : default_val; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets type of node. + //! \param type Type of node to set. + void type(node_type type) + { + m_type = type; + } + + /////////////////////////////////////////////////////////////////////////// + // Node manipulation + + //! Prepends a new child node. + //! The prepended child becomes the first child, and all existing children are moved one position back. + //! \param child Node to prepend. + void prepend_node(xml_node *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_next_sibling = m_first_node; + m_first_node->m_prev_sibling = child; + } + else + { + child->m_next_sibling = 0; + m_last_node = child; + } + m_first_node = child; + child->m_parent = this; + child->m_prev_sibling = 0; + } + + //! Appends a new child node. + //! The appended child becomes the last child. + //! \param child Node to append. + void append_node(xml_node *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_prev_sibling = m_last_node; + m_last_node->m_next_sibling = child; + } + else + { + child->m_prev_sibling = 0; + m_first_node = child; + } + m_last_node = child; + child->m_parent = this; + child->m_next_sibling = 0; + } + + //! Inserts a new child node at specified place inside the node. + //! All children after and including the specified node are moved one position back. + //! \param where Place where to insert the child, or 0 to insert at the back. + //! \param child Node to insert. + void insert_node(xml_node *where, xml_node *child) + { + assert(!where || where->parent() == this); + assert(child && !child->parent() && child->type() != node_document); + if (where == m_first_node) + prepend_node(child); + else if (where == 0) + append_node(child); + else + { + child->m_prev_sibling = where->m_prev_sibling; + child->m_next_sibling = where; + where->m_prev_sibling->m_next_sibling = child; + where->m_prev_sibling = child; + child->m_parent = this; + } + } + + //! Removes first child node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_first_node() + { + assert(first_node()); + xml_node *child = m_first_node; + m_first_node = child->m_next_sibling; + if (child->m_next_sibling) + child->m_next_sibling->m_prev_sibling = 0; + else + m_last_node = 0; + child->m_parent = 0; + } + + //! Removes last child of the node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_last_node() + { + assert(first_node()); + xml_node *child = m_last_node; + if (child->m_prev_sibling) + { + m_last_node = child->m_prev_sibling; + child->m_prev_sibling->m_next_sibling = 0; + } + else + m_first_node = 0; + child->m_parent = 0; + } + + //! Removes specified child from the node + // \param where Pointer to child to be removed. + void remove_node(xml_node *where) + { + assert(where && where->parent() == this); + assert(first_node()); + if (where == m_first_node) + remove_first_node(); + else if (where == m_last_node) + remove_last_node(); + else + { + where->m_prev_sibling->m_next_sibling = where->m_next_sibling; + where->m_next_sibling->m_prev_sibling = where->m_prev_sibling; + where->m_parent = 0; + } + } + + //! Removes all child nodes (but not attributes). + void remove_all_nodes() + { + for (xml_node *node = first_node(); node; node = node->m_next_sibling) + node->m_parent = 0; + m_first_node = 0; + } + + //! Prepends a new attribute to the node. + //! \param attribute Attribute to prepend. + void prepend_attribute(xml_attribute *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_next_attribute = m_first_attribute; + m_first_attribute->m_prev_attribute = attribute; + } + else + { + attribute->m_next_attribute = 0; + m_last_attribute = attribute; + } + m_first_attribute = attribute; + attribute->m_parent = this; + attribute->m_prev_attribute = 0; + } + + //! Appends a new attribute to the node. + //! \param attribute Attribute to append. + void append_attribute(xml_attribute *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_prev_attribute = m_last_attribute; + m_last_attribute->m_next_attribute = attribute; + } + else + { + attribute->m_prev_attribute = 0; + m_first_attribute = attribute; + } + m_last_attribute = attribute; + attribute->m_parent = this; + attribute->m_next_attribute = 0; + } + + //! Inserts a new attribute at specified place inside the node. + //! All attributes after and including the specified attribute are moved one position back. + //! \param where Place where to insert the attribute, or 0 to insert at the back. + //! \param attribute Attribute to insert. + void insert_attribute(xml_attribute *where, xml_attribute *attribute) + { + assert(!where || where->parent() == this); + assert(attribute && !attribute->parent()); + if (where == m_first_attribute) + prepend_attribute(attribute); + else if (where == 0) + append_attribute(attribute); + else + { + attribute->m_prev_attribute = where->m_prev_attribute; + attribute->m_next_attribute = where; + where->m_prev_attribute->m_next_attribute = attribute; + where->m_prev_attribute = attribute; + attribute->m_parent = this; + } + } + + //! Removes first attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_first_attribute() + { + assert(first_attribute()); + xml_attribute *attribute = m_first_attribute; + if (attribute->m_next_attribute) + { + attribute->m_next_attribute->m_prev_attribute = 0; + } + else + m_last_attribute = 0; + attribute->m_parent = 0; + m_first_attribute = attribute->m_next_attribute; + } + + //! Removes last attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_last_attribute() + { + assert(first_attribute()); + xml_attribute *attribute = m_last_attribute; + if (attribute->m_prev_attribute) + { + attribute->m_prev_attribute->m_next_attribute = 0; + m_last_attribute = attribute->m_prev_attribute; + } + else + m_first_attribute = 0; + attribute->m_parent = 0; + } + + //! Removes specified attribute from node. + //! \param where Pointer to attribute to be removed. + void remove_attribute(xml_attribute *where) + { + assert(first_attribute() && where->parent() == this); + if (where == m_first_attribute) + remove_first_attribute(); + else if (where == m_last_attribute) + remove_last_attribute(); + else + { + where->m_prev_attribute->m_next_attribute = where->m_next_attribute; + where->m_next_attribute->m_prev_attribute = where->m_prev_attribute; + where->m_parent = 0; + } + } + + //! Removes all attributes of node. + void remove_all_attributes() + { + for (xml_attribute *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute) + attribute->m_parent = 0; + m_first_attribute = 0; + } + + private: + + /////////////////////////////////////////////////////////////////////////// + // Restrictions + + // No copying + xml_node(const xml_node &); + void operator =(const xml_node &); + + /////////////////////////////////////////////////////////////////////////// + // Data members + + // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0. + // This is required for maximum performance, as it allows the parser to omit initialization of + // unneded/redundant values. + // + // The rules are as follows: + // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively + // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage + // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage + + node_type m_type; // Type of node; always valid + xml_node *m_first_node; // Pointer to first child node, or 0 if none; always valid + xml_node *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero + xml_attribute *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid + xml_attribute *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero + xml_node *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + xml_node *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML document + + //! This class represents root of the DOM hierarchy. + //! It is also an xml_node and a memory_pool through public inheritance. + //! Use parse() function to build a DOM tree from a zero-terminated XML text string. + //! parse() function allocates memory for nodes and attributes by using functions of xml_document, + //! which are inherited from memory_pool. + //! To access root node of the document, use the document itself, as if it was an xml_node. + //! \param Ch Character type to use. + template + class xml_document: public xml_node, public memory_pool + { + + public: + + //! Constructs empty XML document + xml_document() + : xml_node(node_document) + { + } + + //! Parses zero-terminated XML string according to given flags. + //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used. + //! The string must persist for the lifetime of the document. + //! In case of error, rapidxml::parse_error exception will be thrown. + //!

+ //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning. + //! Make sure that data is zero-terminated. + //!

+ //! Document can be parsed into multiple times. + //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool. + //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser. + template + void parse(Ch *text) + { + assert(text); + + // Remove current contents + this->remove_all_nodes(); + this->remove_all_attributes(); + + // Parse BOM, if any + parse_bom(text); + + // Parse children + while (1) + { + // Skip whitespace before node + skip(text); + if (*text == 0) + break; + + // Parse and append new child + if (*text == Ch('<')) + { + ++text; // Skip '<' + if (xml_node *node = parse_node(text)) + this->append_node(node); + } + else + RAPIDXML_PARSE_ERROR("expected <", text); + } + + } + + //! Clears the document by deleting all nodes and clearing the memory pool. + //! All nodes owned by document pool are destroyed. + void clear() + { + this->remove_all_nodes(); + this->remove_all_attributes(); + memory_pool::clear(); + } + + private: + + /////////////////////////////////////////////////////////////////////// + // Internal character utility functions + + // Detect whitespace character + struct whitespace_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_whitespace[static_cast(ch)]; + } + }; + + // Detect node name character + struct node_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_node_name[static_cast(ch)]; + } + }; + + // Detect attribute name character + struct attribute_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_attribute_name[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) + struct text_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_no_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_with_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast(ch)]; + } + }; + + // Detect attribute value character + template + struct attribute_value_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Detect attribute value character + template + struct attribute_value_pure_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Insert coded character, using UTF8 or 8-bit ASCII + template + static void insert_coded_character(Ch *&text, unsigned long code) + { + if (Flags & parse_no_utf8) + { + // Insert 8-bit ASCII character + // Todo: possibly verify that code is less than 256 and use replacement char otherwise? + text[0] = static_cast(code); + text += 1; + } + else + { + // Insert UTF8 sequence + if (code < 0x80) // 1 byte sequence + { + text[0] = static_cast(code); + text += 1; + } + else if (code < 0x800) // 2 byte sequence + { + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xC0); + text += 2; + } + else if (code < 0x10000) // 3 byte sequence + { + text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xE0); + text += 3; + } + else if (code < 0x110000) // 4 byte sequence + { + text[3] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xF0); + text += 4; + } + else // Invalid, only codes up to 0x10FFFF are allowed in Unicode + { + RAPIDXML_PARSE_ERROR("invalid numeric character entity", text); + } + } + } + + // Skip characters until predicate evaluates to true + template + static void skip(Ch *&text) + { + Ch *tmp = text; + while (StopPred::test(*tmp)) + ++tmp; + text = tmp; + } + + // Skip characters until predicate evaluates to true while doing the following: + // - replacing XML character entity references with proper characters (' & " < > &#...;) + // - condensing whitespace sequences to single space character + template + static Ch *skip_and_expand_character_refs(Ch *&text) + { + // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip + if (Flags & parse_no_entity_translation && + !(Flags & parse_normalize_whitespace) && + !(Flags & parse_trim_whitespace)) + { + skip(text); + return text; + } + + // Use simple skip until first modification is detected + skip(text); + + // Use translation skip + Ch *src = text; + Ch *dest = src; + while (StopPred::test(*src)) + { + // If entity translation is enabled + if (!(Flags & parse_no_entity_translation)) + { + // Test if replacement is needed + if (src[0] == Ch('&')) + { + switch (src[1]) + { + + // & ' + case Ch('a'): + if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) + { + *dest = Ch('&'); + ++dest; + src += 5; + continue; + } + if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';')) + { + *dest = Ch('\''); + ++dest; + src += 6; + continue; + } + break; + + // " + case Ch('q'): + if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';')) + { + *dest = Ch('"'); + ++dest; + src += 6; + continue; + } + break; + + // > + case Ch('g'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('>'); + ++dest; + src += 4; + continue; + } + break; + + // < + case Ch('l'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('<'); + ++dest; + src += 4; + continue; + } + break; + + // &#...; - assumes ASCII + case Ch('#'): + if (src[2] == Ch('x')) + { + unsigned long code = 0; + src += 3; // Skip &#x + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; + if (digit == 0xFF) + break; + code = code * 16 + digit; + ++src; + } + insert_coded_character(dest, code); // Put character in output + } + else + { + unsigned long code = 0; + src += 2; // Skip &# + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; + if (digit == 0xFF) + break; + code = code * 10 + digit; + ++src; + } + insert_coded_character(dest, code); // Put character in output + } + if (*src == Ch(';')) + ++src; + else + RAPIDXML_PARSE_ERROR("expected ;", src); + continue; + + // Something else + default: + // Ignore, just copy '&' verbatim + break; + + } + } + } + + // If whitespace condensing is enabled + if (Flags & parse_normalize_whitespace) + { + // Test if condensing is needed + if (whitespace_pred::test(*src)) + { + *dest = Ch(' '); ++dest; // Put single space in dest + ++src; // Skip first whitespace char + // Skip remaining whitespace chars + while (whitespace_pred::test(*src)) + ++src; + continue; + } + } + + // No replacement, only copy character + *dest++ = *src++; + + } + + // Return new end + text = src; + return dest; + + } + + /////////////////////////////////////////////////////////////////////// + // Internal parsing functions + + // Parse BOM, if any + template + void parse_bom(Ch *&text) + { + // UTF-8? + if (static_cast(text[0]) == 0xEF && + static_cast(text[1]) == 0xBB && + static_cast(text[2]) == 0xBF) + { + text += 3; // Skup utf-8 bom + } + } + + // Parse XML declaration ( + xml_node *parse_xml_declaration(Ch *&text) + { + // If parsing of declaration is disabled + if (!(Flags & parse_declaration_node)) + { + // Skip until end of declaration + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + + // Create declaration + xml_node *declaration = this->allocate_node(node_declaration); + + // Skip whitespace before attributes or ?> + skip(text); + + // Parse declaration attributes + parse_node_attributes(text, declaration); + + // Skip ?> + if (text[0] != Ch('?') || text[1] != Ch('>')) + RAPIDXML_PARSE_ERROR("expected ?>", text); + text += 2; + + return declaration; + } + + // Parse XML comment (' + return 0; // Do not produce comment node + } + + // Remember value start + Ch *value = text; + + // Skip until end of comment + while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create comment node + xml_node *comment = this->allocate_node(node_comment); + comment->value(value, text - value); + + // Place zero terminator after comment value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip '-->' + return comment; + } + + // Parse DOCTYPE + template + xml_node *parse_doctype(Ch *&text) + { + // Remember value start + Ch *value = text; + + // Skip to > + while (*text != Ch('>')) + { + // Determine character type + switch (*text) + { + + // If '[' encountered, scan for matching ending ']' using naive algorithm with depth + // This works for all W3C test files except for 2 most wicked + case Ch('['): + { + ++text; // Skip '[' + int depth = 1; + while (depth > 0) + { + switch (*text) + { + case Ch('['): ++depth; break; + case Ch(']'): --depth; break; + case 0: RAPIDXML_PARSE_ERROR("unexpected end of data", text); + } + ++text; + } + break; + } + + // Error on end of text + case Ch('\0'): + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Other character, skip it + default: + ++text; + + } + } + + // If DOCTYPE nodes enabled + if (Flags & parse_doctype_node) + { + // Create a new doctype node + xml_node *doctype = this->allocate_node(node_doctype); + doctype->value(value, text - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 1; // skip '>' + return doctype; + } + else + { + text += 1; // skip '>' + return 0; + } + + } + + // Parse PI + template + xml_node *parse_pi(Ch *&text) + { + // If creation of PI nodes is enabled + if (Flags & parse_pi_nodes) + { + // Create pi node + xml_node *pi = this->allocate_node(node_pi); + + // Extract PI target name + Ch *name = text; + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected PI target", text); + pi->name(name, text - name); + + // Skip whitespace between pi target and pi + skip(text); + + // Remember start of pi + Ch *value = text; + + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Set pi value (verbatim, no entity expansion or whitespace normalization) + pi->value(value, text - value); + + // Place zero terminator after name and value + if (!(Flags & parse_no_string_terminators)) + { + pi->name()[pi->name_size()] = Ch('\0'); + pi->value()[pi->value_size()] = Ch('\0'); + } + + text += 2; // Skip '?>' + return pi; + } + else + { + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + } + + // Parse and append data + // Return character that ends data. + // This is necessary because this character might have been overwritten by a terminating 0 + template + Ch parse_and_append_data(xml_node *node, Ch *&text, Ch *contents_start) + { + // Backup to contents start if whitespace trimming is disabled + if (!(Flags & parse_trim_whitespace)) + text = contents_start; + + // Skip until end of data + Ch *value = text, *end; + if (Flags & parse_normalize_whitespace) + end = skip_and_expand_character_refs(text); + else + end = skip_and_expand_character_refs(text); + + // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after > + if (Flags & parse_trim_whitespace) + { + if (Flags & parse_normalize_whitespace) + { + // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end + if (*(end - 1) == Ch(' ')) + --end; + } + else + { + // Backup until non-whitespace character is found + while (whitespace_pred::test(*(end - 1))) + --end; + } + } + + // If characters are still left between end and value (this test is only necessary if normalization is enabled) + // Create new data node + if (!(Flags & parse_no_data_nodes)) + { + xml_node *data = this->allocate_node(node_data); + data->value(value, end - value); + node->append_node(data); + } + + // Add data to parent node if no data exists yet + if (!(Flags & parse_no_element_values)) + if (*node->value() == Ch('\0')) + node->value(value, end - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + { + Ch ch = *text; + *end = Ch('\0'); + return ch; // Return character that ends data; this is required because zero terminator overwritten it + } + + // Return character that ends data + return *text; + } + + // Parse CDATA + template + xml_node *parse_cdata(Ch *&text) + { + // If CDATA is disabled + if (Flags & parse_no_data_nodes) + { + // Skip until end of cdata + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 3; // Skip ]]> + return 0; // Do not produce CDATA node + } + + // Skip until end of cdata + Ch *value = text; + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create new cdata node + xml_node *cdata = this->allocate_node(node_cdata); + cdata->value(value, text - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip ]]> + return cdata; + } + + // Parse element node + template + xml_node *parse_element(Ch *&text) + { + // Create element node + xml_node *element = this->allocate_node(node_element); + + // Extract element name + Ch *name = text; + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected element name", text); + element->name(name, text - name); + + // Skip whitespace between element name and attributes or > + skip(text); + + // Parse attributes, if any + parse_node_attributes(text, element); + + // Determine ending type + if (*text == Ch('>')) + { + ++text; + parse_node_contents(text, element); + } + else if (*text == Ch('/')) + { + ++text; + if (*text != Ch('>')) + RAPIDXML_PARSE_ERROR("expected >", text); + ++text; + } + else + RAPIDXML_PARSE_ERROR("expected >", text); + + // Place zero terminator after name + if (!(Flags & parse_no_string_terminators)) + element->name()[element->name_size()] = Ch('\0'); + + // Return parsed element + return element; + } + + // Determine node type, and parse it + template + xml_node *parse_node(Ch *&text) + { + // Parse proper node type + switch (text[0]) + { + + // <... + default: + // Parse and append element node + return parse_element(text); + + // (text); + } + else + { + // Parse PI + return parse_pi(text); + } + + // (text); + } + break; + + // (text); + } + break; + + // (text); + } + + } // switch + + // Attempt to skip other, unrecognized node types starting with ')) + { + if (*text == 0) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + ++text; // Skip '>' + return 0; // No node recognized + + } + } + + // Parse contents of the node - children, data etc. + template + void parse_node_contents(Ch *&text, xml_node *node) + { + // For all children and text + while (1) + { + // Skip whitespace between > and node contents + Ch *contents_start = text; // Store start of node contents before whitespace is skipped + skip(text); + Ch next_char = *text; + + // After data nodes, instead of continuing the loop, control jumps here. + // This is because zero termination inside parse_and_append_data() function + // would wreak havoc with the above code. + // Also, skipping whitespace after data nodes is unnecessary. + after_data_node: + + // Determine what comes next: node closing, child node, data node, or 0? + switch (next_char) + { + + // Node closing or child node + case Ch('<'): + if (text[1] == Ch('/')) + { + // Node closing + text += 2; // Skip '(text); + if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true)) + RAPIDXML_PARSE_ERROR("invalid closing tag name", text); + } + else + { + // No validation, just skip name + skip(text); + } + // Skip remaining whitespace after node name + skip(text); + if (*text != Ch('>')) + RAPIDXML_PARSE_ERROR("expected >", text); + ++text; // Skip '>' + return; // Node closed, finished parsing contents + } + else + { + // Child node + ++text; // Skip '<' + if (xml_node *child = parse_node(text)) + node->append_node(child); + } + break; + + // End of data - error + case Ch('\0'): + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Data node + default: + next_char = parse_and_append_data(node, text, contents_start); + goto after_data_node; // Bypass regular processing after data nodes + + } + } + } + + // Parse XML attributes of the node + template + void parse_node_attributes(Ch *&text, xml_node *node) + { + // For all attributes + while (attribute_name_pred::test(*text)) + { + // Extract attribute name + Ch *name = text; + ++text; // Skip first character of attribute name + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected attribute name", name); + + // Create new attribute + xml_attribute *attribute = this->allocate_attribute(); + attribute->name(name, text - name); + node->append_attribute(attribute); + + // Skip whitespace after attribute name + skip(text); + + // Skip = + if (*text != Ch('=')) + RAPIDXML_PARSE_ERROR("expected =", text); + ++text; + + // Add terminating zero after name + if (!(Flags & parse_no_string_terminators)) + attribute->name()[attribute->name_size()] = 0; + + // Skip whitespace after = + skip(text); + + // Skip quote and remember if it was ' or " + Ch quote = *text; + if (quote != Ch('\'') && quote != Ch('"')) + RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; + + // Extract attribute value and expand char refs in it + Ch *value = text, *end; + const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes + if (quote == Ch('\'')) + end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); + else + end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); + + // Set attribute value + attribute->value(value, end - value); + + // Make sure that end quote is present + if (*text != quote) + RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; // Skip quote + + // Add terminating zero after value + if (!(Flags & parse_no_string_terminators)) + attribute->value()[attribute->value_size()] = 0; + + // Skip whitespace after attribute value + skip(text); + } + } + + }; + + //! \cond internal + namespace internal + { + + // Whitespace (space \n \r \t) + template + const unsigned char lookup_tables::lookup_whitespace[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F + }; + + // Node name (anything but space \n \r \t / > ? \0) + template + const unsigned char lookup_tables::lookup_node_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) (anything but < \0) + template + const unsigned char lookup_tables::lookup_text[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled + // (anything but < \0 &) + template + const unsigned char lookup_tables::lookup_text_pure_no_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled + // (anything but < \0 & space \n \r \t) + template + const unsigned char lookup_tables::lookup_text_pure_with_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute name (anything but space \n \r \t / < > = ? ! \0) + template + const unsigned char lookup_tables::lookup_attribute_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote (anything but ' \0) + template + const unsigned char lookup_tables::lookup_attribute_data_1[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote that does not require processing (anything but ' \0 &) + template + const unsigned char lookup_tables::lookup_attribute_data_1_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote (anything but " \0) + template + const unsigned char lookup_tables::lookup_attribute_data_2[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote that does not require processing (anything but " \0 &) + template + const unsigned char lookup_tables::lookup_attribute_data_2_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Digits (dec and hex, 255 denotes end of numeric character reference) + template + const unsigned char lookup_tables::lookup_digits[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3 + 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5 + 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F + }; + + // Upper case conversion + template + const unsigned char lookup_tables::lookup_upcase[256] = + { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A B C D E F + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 + 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 6 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127, // 7 + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8 + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9 + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C + 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D + 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F + }; + } + //! \endcond + +} + +// Undefine internal macros +#undef RAPIDXML_PARSE_ERROR + +// On MSVC, restore warnings state +#ifdef _MSC_VER + #pragma warning(pop) +#endif + +#endif diff --git a/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_iterators.hpp b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_iterators.hpp new file mode 100755 index 00000000..52ebc298 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_iterators.hpp @@ -0,0 +1,174 @@ +#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED +#define RAPIDXML_ITERATORS_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_iterators.hpp This file contains rapidxml iterators + +#include "rapidxml.hpp" + +namespace rapidxml +{ + + //! Iterator of child nodes of xml_node + template + class node_iterator + { + + public: + + typedef typename xml_node value_type; + typedef typename xml_node &reference; + typedef typename xml_node *pointer; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + node_iterator() + : m_node(0) + { + } + + node_iterator(xml_node *node) + : m_node(node->first_node()) + { + } + + reference operator *() const + { + assert(m_node); + return *m_node; + } + + pointer operator->() const + { + assert(m_node); + return m_node; + } + + node_iterator& operator++() + { + assert(m_node); + m_node = m_node->next_sibling(); + return *this; + } + + node_iterator operator++(int) + { + node_iterator tmp = *this; + ++this; + return tmp; + } + + node_iterator& operator--() + { + assert(m_node && m_node->previous_sibling()); + m_node = m_node->previous_sibling(); + return *this; + } + + node_iterator operator--(int) + { + node_iterator tmp = *this; + ++this; + return tmp; + } + + bool operator ==(const node_iterator &rhs) + { + return m_node == rhs.m_node; + } + + bool operator !=(const node_iterator &rhs) + { + return m_node != rhs.m_node; + } + + private: + + xml_node *m_node; + + }; + + //! Iterator of child attributes of xml_node + template + class attribute_iterator + { + + public: + + typedef typename xml_attribute value_type; + typedef typename xml_attribute &reference; + typedef typename xml_attribute *pointer; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + attribute_iterator() + : m_attribute(0) + { + } + + attribute_iterator(xml_node *node) + : m_attribute(node->first_attribute()) + { + } + + reference operator *() const + { + assert(m_attribute); + return *m_attribute; + } + + pointer operator->() const + { + assert(m_attribute); + return m_attribute; + } + + attribute_iterator& operator++() + { + assert(m_attribute); + m_attribute = m_attribute->next_attribute(); + return *this; + } + + attribute_iterator operator++(int) + { + attribute_iterator tmp = *this; + ++this; + return tmp; + } + + attribute_iterator& operator--() + { + assert(m_attribute && m_attribute->previous_attribute()); + m_attribute = m_attribute->previous_attribute(); + return *this; + } + + attribute_iterator operator--(int) + { + attribute_iterator tmp = *this; + ++this; + return tmp; + } + + bool operator ==(const attribute_iterator &rhs) + { + return m_attribute == rhs.m_attribute; + } + + bool operator !=(const attribute_iterator &rhs) + { + return m_attribute != rhs.m_attribute; + } + + private: + + xml_attribute *m_attribute; + + }; + +} + +#endif diff --git a/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_print.hpp b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_print.hpp new file mode 100755 index 00000000..0ae2b14f --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_print.hpp @@ -0,0 +1,421 @@ +#ifndef RAPIDXML_PRINT_HPP_INCLUDED +#define RAPIDXML_PRINT_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_print.hpp This file contains rapidxml printer implementation + +#include "rapidxml.hpp" + +// Only include streams if not disabled +#ifndef RAPIDXML_NO_STREAMS + #include + #include +#endif + +namespace rapidxml +{ + + /////////////////////////////////////////////////////////////////////// + // Printing flags + + const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function. + + /////////////////////////////////////////////////////////////////////// + // Internal + + //! \cond internal + namespace internal + { + + /////////////////////////////////////////////////////////////////////////// + // Internal character operations + + // Copy characters from given range to given output iterator + template + inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) + { + while (begin != end) + *out++ = *begin++; + return out; + } + + // Copy characters from given range to given output iterator and expand + // characters into references (< > ' " &) + template + inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out) + { + while (begin != end) + { + if (*begin == noexpand) + { + *out++ = *begin; // No expansion, copy character + } + else + { + switch (*begin) + { + case Ch('<'): + *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('>'): + *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('\''): + *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';'); + break; + case Ch('"'): + *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('&'): + *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); + break; + default: + *out++ = *begin; // No expansion, copy character + } + } + ++begin; // Step to next character + } + return out; + } + + // Fill given output iterator with repetitions of the same character + template + inline OutIt fill_chars(OutIt out, int n, Ch ch) + { + for (int i = 0; i < n; ++i) + *out++ = ch; + return out; + } + + // Find character + template + inline bool find_char(const Ch *begin, const Ch *end) + { + while (begin != end) + if (*begin++ == ch) + return true; + return false; + } + + /////////////////////////////////////////////////////////////////////////// + // Internal printing operations + + // Print node + template + inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent) + { + // Print proper node type + switch (node->type()) + { + + // Document + case node_document: + out = print_children(out, node, flags, indent); + break; + + // Element + case node_element: + out = print_element_node(out, node, flags, indent); + break; + + // Data + case node_data: + out = print_data_node(out, node, flags, indent); + break; + + // CDATA + case node_cdata: + out = print_cdata_node(out, node, flags, indent); + break; + + // Declaration + case node_declaration: + out = print_declaration_node(out, node, flags, indent); + break; + + // Comment + case node_comment: + out = print_comment_node(out, node, flags, indent); + break; + + // Doctype + case node_doctype: + out = print_doctype_node(out, node, flags, indent); + break; + + // Pi + case node_pi: + out = print_pi_node(out, node, flags, indent); + break; + + // Unknown + default: + assert(0); + break; + } + + // If indenting not disabled, add line break after node + if (!(flags & print_no_indenting)) + *out = Ch('\n'), ++out; + + // Return modified iterator + return out; + } + + // Print children of the node + template + inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent) + { + for (xml_node *child = node->first_node(); child; child = child->next_sibling()) + out = print_node(out, child, flags, indent); + return out; + } + + // Print attributes of the node + template + inline OutIt print_attributes(OutIt out, const xml_node *node, int flags) + { + for (xml_attribute *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + if (attribute->name() && attribute->value()) + { + // Print attribute name + *out = Ch(' '), ++out; + out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out); + *out = Ch('='), ++out; + // Print attribute value using appropriate quote type + if (find_char(attribute->value(), attribute->value() + attribute->value_size())) + { + *out = Ch('\''), ++out; + out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out); + *out = Ch('\''), ++out; + } + else + { + *out = Ch('"'), ++out; + out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out); + *out = Ch('"'), ++out; + } + } + } + return out; + } + + // Print data node + template + inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_data); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); + return out; + } + + // Print data node + template + inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_cdata); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'); ++out; + *out = Ch('!'); ++out; + *out = Ch('['); ++out; + *out = Ch('C'); ++out; + *out = Ch('D'); ++out; + *out = Ch('A'); ++out; + *out = Ch('T'); ++out; + *out = Ch('A'); ++out; + *out = Ch('['); ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch(']'); ++out; + *out = Ch(']'); ++out; + *out = Ch('>'); ++out; + return out; + } + + // Print element node + template + inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_element); + + // Print element name and attributes, if any + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + out = print_attributes(out, node, flags); + + // If node is childless + if (node->value_size() == 0 && !node->first_node()) + { + // Print childless node tag ending + *out = Ch('/'), ++out; + *out = Ch('>'), ++out; + } + else + { + // Print normal node tag ending + *out = Ch('>'), ++out; + + // Test if node contains a single data node only (and no other nodes) + xml_node *child = node->first_node(); + if (!child) + { + // If node has no children, only print its value without indenting + out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); + } + else if (child->next_sibling() == 0 && child->type() == node_data) + { + // If node has a sole data child, only print its value without indenting + out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out); + } + else + { + // Print all children with full indenting + if (!(flags & print_no_indenting)) + *out = Ch('\n'), ++out; + out = print_children(out, node, flags, indent + 1); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + } + + // Print node end + *out = Ch('<'), ++out; + *out = Ch('/'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + *out = Ch('>'), ++out; + } + return out; + } + + // Print declaration node + template + inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent) + { + // Print declaration start + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('?'), ++out; + *out = Ch('x'), ++out; + *out = Ch('m'), ++out; + *out = Ch('l'), ++out; + + // Print attributes + out = print_attributes(out, node, flags); + + // Print declaration end + *out = Ch('?'), ++out; + *out = Ch('>'), ++out; + + return out; + } + + // Print comment node + template + inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_comment); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('!'), ++out; + *out = Ch('-'), ++out; + *out = Ch('-'), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('-'), ++out; + *out = Ch('-'), ++out; + *out = Ch('>'), ++out; + return out; + } + + // Print doctype node + template + inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_doctype); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('!'), ++out; + *out = Ch('D'), ++out; + *out = Ch('O'), ++out; + *out = Ch('C'), ++out; + *out = Ch('T'), ++out; + *out = Ch('Y'), ++out; + *out = Ch('P'), ++out; + *out = Ch('E'), ++out; + *out = Ch(' '), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('>'), ++out; + return out; + } + + // Print pi node + template + inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_pi); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('?'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + *out = Ch(' '), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('?'), ++out; + *out = Ch('>'), ++out; + return out; + } + + } + //! \endcond + + /////////////////////////////////////////////////////////////////////////// + // Printing + + //! Prints XML to given output iterator. + //! \param out Output iterator to print to. + //! \param node Node to be printed. Pass xml_document to print entire document. + //! \param flags Flags controlling how XML is printed. + //! \return Output iterator pointing to position immediately after last character of printed text. + template + inline OutIt print(OutIt out, const xml_node &node, int flags = 0) + { + return internal::print_node(out, &node, flags, 0); + } + +#ifndef RAPIDXML_NO_STREAMS + + //! Prints XML to given output stream. + //! \param out Output stream to print to. + //! \param node Node to be printed. Pass xml_document to print entire document. + //! \param flags Flags controlling how XML is printed. + //! \return Output stream. + template + inline std::basic_ostream &print(std::basic_ostream &out, const xml_node &node, int flags = 0) + { + print(std::ostream_iterator(out), node, flags); + return out; + } + + //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process. + //! \param out Output stream to print to. + //! \param node Node to be printed. + //! \return Output stream. + template + inline std::basic_ostream &operator <<(std::basic_ostream &out, const xml_node &node) + { + return print(out, node); + } + +#endif + +} + +#endif diff --git a/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_utils.hpp b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_utils.hpp new file mode 100755 index 00000000..4de07638 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/utils/xml/rapidxml_utils.hpp @@ -0,0 +1,122 @@ +#ifndef RAPIDXML_UTILS_HPP_INCLUDED +#define RAPIDXML_UTILS_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful +//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective. + +#include "rapidxml.hpp" +#include +#include +#include +#include + +namespace rapidxml +{ + + //! Represents data loaded from a file + template + class file + { + + public: + + //! Loads file into the memory. Data will be automatically destroyed by the destructor. + //! \param filename Filename to load. + file(const char *filename) + { + using namespace std; + + // Open stream + basic_ifstream stream(filename, ios::binary); + if (!stream) + throw runtime_error(string("cannot open file ") + filename); + stream.unsetf(ios::skipws); + + // Determine stream size + stream.seekg(0, ios::end); + size_t size = (size_t)stream.tellg(); + stream.seekg(0); + + // Load data and add terminating 0 + m_data.resize(size + 1); + stream.read(&m_data.front(), static_cast(size)); + m_data[size] = 0; + } + + //! Loads file into the memory. Data will be automatically destroyed by the destructor + //! \param stream Stream to load from + file(std::basic_istream &stream) + { + using namespace std; + + // Load data and add terminating 0 + stream.unsetf(ios::skipws); + m_data.assign(istreambuf_iterator(stream), istreambuf_iterator()); + if (stream.fail() || stream.bad()) + throw runtime_error("error reading stream"); + m_data.push_back(0); + } + + //! Gets file data. + //! \return Pointer to data of file. + Ch *data() + { + return &m_data.front(); + } + + //! Gets file data. + //! \return Pointer to data of file. + const Ch *data() const + { + return &m_data.front(); + } + + //! Gets file data size. + //! \return Size of file data, in characters. + std::size_t size() const + { + return m_data.size(); + } + + private: + + std::vector m_data; // File data + + }; + + //! Counts children of node. Time complexity is O(n). + //! \return Number of children of node + template + inline std::size_t count_children(xml_node *node) + { + xml_node *child = node->first_node(); + std::size_t count = 0; + while (child) + { + ++count; + child = child->next_sibling(); + } + return count; + } + + //! Counts attributes of node. Time complexity is O(n). + //! \return Number of attributes of node + template + inline std::size_t count_attributes(xml_node *node) + { + xml_attribute *attr = node->first_attribute(); + std::size_t count = 0; + while (attr) + { + ++count; + attr = attr->next_attribute(); + } + return count; + } + +} + +#endif diff --git a/thirdparty/Pangolin/include/pangolin/var/input_record_repeat.h b/thirdparty/Pangolin/include/pangolin/var/input_record_repeat.h new file mode 100644 index 00000000..b8df0c51 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/input_record_repeat.h @@ -0,0 +1,86 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace pangolin +{ + +struct FrameInput +{ + int index; + std::string var; + std::string val; +}; + +struct PANGOLIN_EXPORT InputRecordRepeat +{ + InputRecordRepeat(const std::string& var_record_prefix); + ~InputRecordRepeat(); + + void SetIndex(int id); + + void Record(); + void Stop(); + + void LoadBuffer(const std::string& filename); + void SaveBuffer(const std::string& filename); + void ClearBuffer(); + + void PlayBuffer(); + void PlayBuffer(size_t start, size_t end); + + void UpdateVariable(const std::string& name ); + + template + inline void UpdateVariable(const Var& var ) { + GuiVarChanged((void*)this, var.var->Meta().full_name, *var.var); + } + + size_t Size(); + +protected: + bool record; + bool play; + + int index; + std::ofstream file; + std::string filename; + + std::list play_queue; + std::list record_queue; + + static void GuiVarChanged(void* data, const std::string& name, VarValueGeneric& var); +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/var/var.h b/thirdparty/Pangolin/include/pangolin/var/var.h new file mode 100644 index 00000000..b3fd894f --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/var.h @@ -0,0 +1,340 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace pangolin +{ + +template +inline void InitialiseNewVarMetaGeneric( + VarValue& v, const std::string& name +) { + // Initialise meta parameters + const std::vector parts = pangolin::Split(name,'.'); + v.Meta().full_name = name; + v.Meta().friendly = parts.size() > 0 ? parts[parts.size()-1] : ""; + v.Meta().range[0] = 0.0; + v.Meta().range[1] = 0.0; + v.Meta().increment = 0.0; + v.Meta().flags = META_FLAG_NONE; + v.Meta().logscale = false; + v.Meta().generic = true; + + VarState::I().NotifyNewVar(name, v); +} + +template +inline void InitialiseNewVarMeta( + VarValue& v, const std::string& name, + double min = 0, double max = 0, int flags = META_FLAG_TOGGLE, + bool logscale = false +) { + // Initialise meta parameters + const std::vector parts = pangolin::Split(name,'.'); + v.Meta().full_name = name; + v.Meta().friendly = parts.size() > 0 ? parts[parts.size()-1] : ""; + v.Meta().range[0] = min; + v.Meta().range[1] = max; + if (std::is_integral::value) { + v.Meta().increment = 1.0; + } else { + v.Meta().increment = (max - min) / 100.0; + } + v.Meta().flags = flags; + v.Meta().logscale = logscale; + v.Meta().generic = false; + + VarState::I().NotifyNewVar(name, v); +} + +template +class Var +{ +public: + static T& Attach( + const std::string& name, T& variable, + double min, double max, bool logscale = false + ) { + // Find name in VarStore + VarValueGeneric*& v = VarState::I()[name]; + if(v) { + throw std::runtime_error("Var with that name already exists."); + }else{ + // new VarRef (owned by VarStore) + VarValue* nv = new VarValue(variable); + v = nv; + if(logscale) { + if (min <= 0 || max <= 0) { + throw std::runtime_error("LogScale: range of numbers must be positive!"); + } + InitialiseNewVarMeta(*nv, name, std::log(min), std::log(max), META_FLAG_TOGGLE, logscale); + }else{ + InitialiseNewVarMeta(*nv, name, min, max, META_FLAG_TOGGLE, logscale); + } + } + return variable; + } + + static T& Attach( + const std::string& name, T& variable, int flags = META_FLAG_NONE + ) { + // Find name in VarStore + VarValueGeneric*& v = VarState::I()[name]; + if (v) { + throw std::runtime_error("Var with that name already exists."); + } + else{ + // new VarRef (owned by VarStore) + VarValue* nv = new VarValue(variable); + v = nv; + InitialiseNewVarMeta(*nv, name, 0.0, 0.0, flags); + } + return variable; + } + + static T& Attach( + const std::string& name, T& variable, bool toggle + ) { + return Attach(name, variable, toggle ? META_FLAG_TOGGLE : META_FLAG_NONE); + } + + ~Var() + { + delete ptr; + } + + Var( VarValueGeneric& v ) + : ptr(0) + { + InitialiseFromGeneric(&v); + } + + + Var( const std::string& name ) + : ptr(0) + { + // Find name in VarStore + VarValueGeneric*& v = VarState::I()[name]; + if(v && !v->Meta().generic) { + InitialiseFromGeneric(v); + }else{ + // new VarValue (owned by VarStore) + VarValue* nv; + if(v) { + // Specialise generic variable + nv = new VarValue( Convert::Do( v->str->Get() ) ); + delete v; + }else{ + nv = new VarValue( T() ); + } + v = nv; + var = nv; + InitialiseNewVarMeta(*nv, name); + } + } + + Var(const std::string& name, const T& value, int flags = META_FLAG_NONE) + : ptr(0) + { + // Find name in VarStore + VarValueGeneric*& v = VarState::I()[name]; + if(v && !v->Meta().generic) { + InitialiseFromGeneric(v); + }else{ + // new VarValue (owned by VarStore) + VarValue* nv; + if(v) { + // Specialise generic variable + nv = new VarValue( Convert::Do( v->str->Get() ) ); + delete v; + }else{ + nv = new VarValue(value); + } + v = nv; + var = nv; + InitialiseNewVarMeta(*nv, name, 0, 1, flags); + } + } + + Var(const std::string& name, const T& value, bool toggle) + : Var(name, value, toggle ? META_FLAG_TOGGLE : META_FLAG_NONE) + { + } + + Var( + const std::string& name, const T& value, + double min, double max, bool logscale = false + ) : ptr(0) + { + // Find name in VarStore + VarValueGeneric*& v = VarState::I()[name]; + if(v && !v->Meta().generic) { + InitialiseFromGeneric(v); + }else{ + // new VarValue (owned by VarStore) + VarValue* nv; + if(v) { + // Specialise generic variable + nv = new VarValue( Convert::Do( v->str->Get() ) ); + delete v; + }else{ + nv = new VarValue(value); + } + var = nv; + v = nv; + if(logscale) { + if (min <= 0 || max <= 0) { + throw std::runtime_error("LogScale: range of numbers must be positive!"); + } + InitialiseNewVarMeta(*nv, name, std::log(min), std::log(max), META_FLAG_TOGGLE, true); + }else{ + InitialiseNewVarMeta(*nv, name, min, max); + } + } + } + + void Reset() + { + var->Reset(); + } + + const T& Get() const + { + try{ + return var->Get(); + }catch(const BadInputException&) + { + const_cast *>(this)->Reset(); + return var->Get(); + } + } + + operator const T& () const + { + return Get(); + } + + const T* operator->() + { + try{ + return &(var->Get()); + }catch(const BadInputException&) + { + Reset(); + return &(var->Get()); + } + } + + void operator=(const T& val) + { + var->Set(val); + } + + void operator=(const Var& v) + { + var->Set(v.var->Get()); + } + + VarMeta& Meta() + { + return var->Meta(); + } + + bool GuiChanged() + { + if(var->Meta().gui_changed) { + var->Meta().gui_changed = false; + return true; + } + return false; + } + + VarValueT& Ref() + { + return *var; + } + +protected: + // Initialise from existing variable, obtain data / accessor + void InitialiseFromGeneric(VarValueGeneric* v) + { + if( !strcmp(v->TypeId(), typeid(T).name()) ) { + // Same type + var = (VarValueT*)(v); + }else if( std::is_same::value ) { + // Use types string accessor + var = (VarValueT*)(v->str); + }else if( !strcmp(v->TypeId(), typeid(bool).name() ) ) { + // Wrapper, owned by this object + ptr = new VarWrapper( *(VarValueT*)v ); + var = ptr; + }else if( !strcmp(v->TypeId(), typeid(short).name() ) ) { + // Wrapper, owned by this object + ptr = new VarWrapper( *(VarValueT*)v ); + var = ptr; + }else if( !strcmp(v->TypeId(), typeid(int).name() ) ) { + // Wrapper, owned by this object + ptr = new VarWrapper( *(VarValueT*)v ); + var = ptr; + }else if( !strcmp(v->TypeId(), typeid(long).name() ) ) { + // Wrapper, owned by this object + ptr = new VarWrapper( *(VarValueT*)v ); + var = ptr; + }else if( !strcmp(v->TypeId(), typeid(float).name() ) ) { + // Wrapper, owned by this object + ptr = new VarWrapper( *(VarValueT*)v ); + var = ptr; + }else if( !strcmp(v->TypeId(), typeid(double).name() ) ) { + // Wrapper, owned by this object + ptr = new VarWrapper( *(VarValueT*)v ); + var = ptr; + }else{ + // other types: have to go via string + // Wrapper, owned by this object + ptr = new VarWrapper( *(v->str) ); + var = ptr; + } + } + + // Holds reference to stored variable object + // N.B. mutable because it is a cached value and Get() is advertised as const. + mutable VarValueT* var; + + // ptr is non-zero if this object owns the object variable (a wrapper) + VarValueT* ptr; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/var/varextra.h b/thirdparty/Pangolin/include/pangolin/var/varextra.h new file mode 100644 index 00000000..63882623 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/varextra.h @@ -0,0 +1,92 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +namespace pangolin +{ + +PANGOLIN_EXPORT +void ParseVarsFile(const std::string& filename); + +PANGOLIN_EXPORT +void LoadJsonFile(const std::string& filename, const std::string& prefix=""); + +PANGOLIN_EXPORT +void SaveJsonFile(const std::string& filename, const std::string& prefix=""); + +PANGOLIN_EXPORT +void ProcessHistoricCallbacks(NewVarCallbackFn callback, void* data, const std::string& filter = ""); + +PANGOLIN_EXPORT +void RegisterNewVarCallback(NewVarCallbackFn callback, void* data, const std::string& filter = ""); + +PANGOLIN_EXPORT +void RegisterGuiVarChangedCallback(GuiVarChangedCallbackFn callback, void* data, const std::string& filter = ""); + +template +struct SetVarFunctor +{ + SetVarFunctor(const std::string& name, T val) : varName(name), setVal(val) {} + void operator()() { Var(varName).Ref().Set(setVal); } + std::string varName; + T setVal; +}; + +struct ToggleVarFunctor +{ + ToggleVarFunctor(const std::string& name) : varName(name) {} + void operator()() { Var val(varName,false); val = !val; } + std::string varName; +}; + +inline bool Pushed(Var& button) +{ + bool val = button; + button = false; + return val; +} + +inline bool Pushed(bool& button) +{ + bool val = button; + button = false; + return val; +} + +template +inline std::ostream& operator<<(std::ostream& s, Var& rhs) +{ + s << rhs.operator const T &(); + return s; +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/var/varstate.h b/thirdparty/Pangolin/include/pangolin/var/varstate.h new file mode 100644 index 00000000..90d7e2cd --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/varstate.h @@ -0,0 +1,130 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace pangolin +{ + +typedef void (*NewVarCallbackFn)(void* data, const std::string& name, VarValueGeneric& var, bool brand_new); +typedef void (*GuiVarChangedCallbackFn)(void* data, const std::string& name, VarValueGeneric& var); + +struct PANGOLIN_EXPORT NewVarCallback +{ + NewVarCallback(const std::string& filter, NewVarCallbackFn fn, void* data) + :filter(filter),fn(fn),data(data) {} + std::string filter; + NewVarCallbackFn fn; + void* data; +}; + +struct PANGOLIN_EXPORT GuiVarChangedCallback +{ + GuiVarChangedCallback(const std::string& filter, GuiVarChangedCallbackFn fn, void* data) + :filter(filter),fn(fn),data(data) {} + std::string filter; + GuiVarChangedCallbackFn fn; + void* data; +}; + +class PANGOLIN_EXPORT VarState +{ +public: + static VarState& I(); + + VarState(); + ~VarState(); + + void Clear(); + + template + void NotifyNewVar(const std::string& name, VarValue& var ) + { + var_adds.push_back(name); + + // notify those watching new variables + for(std::vector::iterator invc = new_var_callbacks.begin(); invc != new_var_callbacks.end(); ++invc) { + if( StartsWith(name,invc->filter) ) { + invc->fn( invc->data, name, var, true); + } + } + } + + VarValueGeneric*& operator[](const std::string& str) + { + VarStoreContainer::iterator it = vars.find(str); + if (it == vars.end()) { + vars[str] = nullptr; + } + return vars[str]; + } + + bool Exists(const std::string& str) const + { + return vars.find(str) != vars.end(); + } + + void FlagVarChanged() + { + varHasChanged = true; + } + + bool VarHasChanged() + { + const bool has_changed = varHasChanged; + varHasChanged = false; + return has_changed; + } + +//protected: + typedef std::map VarStoreContainer; + typedef std::vector VarStoreAdditions; + + VarStoreContainer vars; + VarStoreAdditions var_adds; + + std::vector new_var_callbacks; + std::vector gui_var_changed_callbacks; + + bool varHasChanged; +}; + +inline bool GuiVarHasChanged() { + return VarState::I().VarHasChanged(); +} + +inline void FlagVarChanged() { + VarState::I().FlagVarChanged(); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/var/varvalue.h b/thirdparty/Pangolin/include/pangolin/var/varvalue.h new file mode 100644 index 00000000..ee3193dc --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/varvalue.h @@ -0,0 +1,114 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +template +class VarValue : public VarValueT::type> +{ +public: + typedef typename std::remove_reference::type VarT; + + ~VarValue() + { + delete str_ptr; + } + + VarValue() + { + Init(); + } + + VarValue(const T& value) + : value(value), default_value(value) + { + Init(); + } + + VarValue(const T& value, const VarT& default_value) + : value(value), default_value(default_value) + { + Init(); + } + + const char* TypeId() const + { + return typeid(VarT).name(); + } + + void Reset() + { + value = default_value; + } + + VarMeta& Meta() + { + return meta; + } + + const VarT& Get() const + { + return value; + } + + VarT& Get() + { + return value; + } + + void Set(const VarT& val) + { + value = val; + } + +protected: + void Init() + { + if(std::is_same::value) { + str_ptr = 0; + this->str = (VarValueT*)this; + }else{ + str_ptr = new VarWrapper(*this); + this->str = str_ptr; + } + } + + // If non-zero, this class owns this str pointer in the base-class. + VarValueT* str_ptr; + + T value; + VarT default_value; + VarMeta meta; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/var/varvaluegeneric.h b/thirdparty/Pangolin/include/pangolin/var/varvaluegeneric.h new file mode 100644 index 00000000..fe814029 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/varvaluegeneric.h @@ -0,0 +1,87 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +namespace pangolin +{ +constexpr int META_FLAG_NONE = 0x0000; +constexpr int META_FLAG_TOGGLE = 0x0001; +constexpr int META_FLAG_READONLY = 0x0002; + +struct VarMeta +{ + VarMeta() : + increment(0.), + flags(META_FLAG_NONE), + gui_changed(false), + logscale(false), + generic(false) + { + range[0] = 0.; + range[1] = 0.; + } + + std::string full_name; + std::string friendly; + double range[2]; + double increment; + int flags; + bool gui_changed; + bool logscale; + bool generic; +}; + +// Forward declaration +template +class VarValueT; + +//! Abstract base class for named Pangolin variables +class VarValueGeneric +{ +public: + VarValueGeneric() + : str(0) + { + } + + virtual ~VarValueGeneric() + { + } + + virtual const char* TypeId() const = 0; + virtual void Reset() = 0; + virtual VarMeta& Meta() = 0; + +//protected: + // String serialisation object. + VarValueT* str; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/var/varvaluet.h b/thirdparty/Pangolin/include/pangolin/var/varvaluet.h new file mode 100644 index 00000000..5b7a45c5 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/varvaluet.h @@ -0,0 +1,46 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +template +class VarValueT : public VarValueGeneric +{ +public: + typedef typename std::remove_reference::type VarT; + + virtual const VarT& Get() const = 0; + virtual void Set(const VarT& val) = 0; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/var/varwrapper.h b/thirdparty/Pangolin/include/pangolin/var/varwrapper.h new file mode 100644 index 00000000..02faacd3 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/var/varwrapper.h @@ -0,0 +1,91 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +namespace pangolin +{ + +template +class VarWrapper : public VarValueT +{ +public: + typedef typename std::remove_reference::type VarS; + + VarWrapper(VarValueT& src) + : src(src) + { + this->str = src.str; + } + + const char* TypeId() const + { + return typeid(T).name(); + } + + void Reset() + { + src.Reset(); + + // If reset throws, it will go up to the user, since there is nothing + // more we can do + cache = Convert::Do(src.Get()); + } + + VarMeta& Meta() + { + return src.Meta(); + } + + const T& Get() const + { + // This might throw, but we can't reset because this is a const method + cache = Convert::Do(src.Get()); + return cache; + } + + void Set(const T& val) + { + cache = val; + try { + src.Set( Convert::Do(val) ); + }catch(const BadInputException&) { + pango_print_warn("Unable to set variable with type %s from %s. Resetting.", typeid(VarS).name(), typeid(T).name() ); + Reset(); + } + } + +protected: + mutable T cache; + VarValueT& src; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/debayer.h b/thirdparty/Pangolin/include/pangolin/video/drivers/debayer.h new file mode 100644 index 00000000..4d4d9bfc --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/debayer.h @@ -0,0 +1,116 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +// Enum to match libdc1394's dc1394_bayer_method_t +typedef enum { + BAYER_METHOD_NEAREST = 0, + BAYER_METHOD_SIMPLE, + BAYER_METHOD_BILINEAR, + BAYER_METHOD_HQLINEAR, + BAYER_METHOD_DOWNSAMPLE_, + BAYER_METHOD_EDGESENSE, + BAYER_METHOD_VNG, + BAYER_METHOD_AHD, + + // Pangolin custom defines + BAYER_METHOD_NONE = 512, + BAYER_METHOD_DOWNSAMPLE, + BAYER_METHOD_DOWNSAMPLE_MONO +} bayer_method_t; + +// Enum to match libdc1394's dc1394_color_filter_t +typedef enum { + DC1394_COLOR_FILTER_RGGB = 512, + DC1394_COLOR_FILTER_GBRG, + DC1394_COLOR_FILTER_GRBG, + DC1394_COLOR_FILTER_BGGR +} color_filter_t; + +// Video class that debayers its video input using the given method. +class PANGOLIN_EXPORT DebayerVideo : + public VideoInterface, + public VideoFilterInterface, + public BufferAwareVideoInterface +{ +public: + DebayerVideo(std::unique_ptr& videoin, const std::vector &method, color_filter_t tile); + ~DebayerVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + std::vector& InputStreams(); + + static color_filter_t ColorFilterFromString(std::string str); + + static bayer_method_t BayerMethodFromString(std::string str); + + uint32_t AvailableFrames() const; + + bool DropNFrames(uint32_t n); + +protected: + void ProcessStreams(unsigned char* out, const unsigned char* in); + + std::unique_ptr src; + std::vector videoin; + std::vector streams; + + size_t size_bytes; + std::unique_ptr buffer; + + std::vector methods; + color_filter_t tile; + + picojson::value device_properties; + picojson::value frame_properties; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/deinterlace.h b/thirdparty/Pangolin/include/pangolin/video/drivers/deinterlace.h new file mode 100644 index 00000000..4098ef34 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/deinterlace.h @@ -0,0 +1,62 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT DeinterlaceVideo + : public VideoInterface +{ +public: + DeinterlaceVideo(std::unique_ptr& videoin); + ~DeinterlaceVideo(); + + size_t SizeBytes() const; + + const std::vector& Streams() const; + + void Start(); + + void Stop(); + + bool GrabNext( unsigned char* image, bool wait = true ); + + bool GrabNewest( unsigned char* image, bool wait = true ); + +protected: + std::unique_ptr videoin; + std::vector streams; + unsigned char* buffer; +}; + + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/depthsense.h b/thirdparty/Pangolin/include/pangolin/video/drivers/depthsense.h new file mode 100644 index 00000000..13a90c97 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/depthsense.h @@ -0,0 +1,171 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +// DepthSense SDK for SoftKinetic cameras from Creative +#include + +namespace pangolin +{ + +enum DepthSenseSensorType +{ + DepthSenseUnassigned = -1, + DepthSenseRgb = 0, + DepthSenseDepth +}; + +// Video class that outputs test video signal. +class PANGOLIN_EXPORT DepthSenseVideo : + public VideoInterface, public VideoPropertiesInterface +{ +public: + DepthSenseVideo(DepthSense::Device device, DepthSenseSensorType s1, DepthSenseSensorType s2, ImageDim dim1, ImageDim dim2, unsigned int fps1, unsigned int fps2, const Uri& uri); + ~DepthSenseVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::DeviceProperties() + const picojson::value& DeviceProperties() const { + return device_properties; + } + + //! Implement VideoInput::DeviceProperties() + const picojson::value& FrameProperties() const { + return frame_properties; + } +protected: + void onNewColorSample(DepthSense::ColorNode node, DepthSense::ColorNode::NewSampleReceivedData data); + void onNewDepthSample(DepthSense::DepthNode node, DepthSense::DepthNode::NewSampleReceivedData data); + + struct SensorConfig + { + DepthSenseSensorType type; + ImageDim dim; + unsigned int fps; + }; + + void UpdateParameters(const DepthSense::Node& node, const Uri& uri); + void ConfigureNodes(const Uri& uri); + void ConfigureDepthNode(const SensorConfig& sensorConfig, const Uri& uri); + void ConfigureColorNode(const SensorConfig& sensorConfig, const Uri& uri); + + double GetDeltaTime() const; + + std::vector streams; + picojson::value device_properties; + picojson::value frame_properties; + picojson::value* streams_properties; + + + DepthSense::Device device; + DepthSense::DepthNode g_dnode; + DepthSense::ColorNode g_cnode; + + unsigned char* fill_image; + + int depthmap_stream; + int rgb_stream; + + int gotDepth; + int gotColor; + std::mutex update_mutex; + std::condition_variable cond_image_filled; + std::condition_variable cond_image_requested; + + SensorConfig sensorConfig[2]; + + bool enableDepth; + bool enableColor; + double depthTs; + double colorTs; + + size_t size_bytes; +}; + +class DepthSenseContext +{ + friend class DepthSenseVideo; + +public: + // Singleton Instance + static DepthSenseContext& I(); + + DepthSenseVideo* GetDepthSenseVideo(size_t device_num, DepthSenseSensorType s1, DepthSenseSensorType s2, ImageDim dim1, ImageDim dim2, unsigned int fps1, unsigned int fps2, const Uri& uri); + +protected: + // Protected Constructor + DepthSenseContext(); + ~DepthSenseContext(); + + DepthSense::Context& Context(); + + void NewDeviceRunning(); + void DeviceClosing(); + + void StartNodes(); + void StopNodes(); + + void EventLoop(); + + void onDeviceConnected(DepthSense::Context context, DepthSense::Context::DeviceAddedData data); + void onDeviceDisconnected(DepthSense::Context context, DepthSense::Context::DeviceRemovedData data); + + DepthSense::Context g_context; + + std::thread event_thread; + bool is_running; + + int running_devices; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/ffmpeg.h b/thirdparty/Pangolin/include/pangolin/video/drivers/ffmpeg.h new file mode 100644 index 00000000..aeb0cf94 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/ffmpeg.h @@ -0,0 +1,207 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +extern "C" +{ + +// HACK for some versions of FFMPEG +#ifndef INT64_C +#define INT64_C(c) (c ## LL) +#define UINT64_C(c) (c ## ULL) +#endif + +#include +#include +#include +#include +} + +#ifndef HAVE_FFMPEG_AVPIXELFORMAT +# define AVPixelFormat PixelFormat +#endif + +namespace pangolin +{ + +class PANGOLIN_EXPORT FfmpegVideo : public VideoInterface +{ +public: + FfmpegVideo(const std::string filename, const std::string fmtout = "RGB24", const std::string codec_hint = "", bool dump_info = false, int user_video_stream = -1, ImageDim size = ImageDim(0,0)); + ~FfmpegVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + +protected: + void InitUrl(const std::string filename, const std::string fmtout = "RGB24", const std::string codec_hint = "", bool dump_info = false , int user_video_stream = -1, ImageDim size= ImageDim(0,0)); + + std::vector streams; + + SwsContext *img_convert_ctx; + AVFormatContext *pFormatCtx; + int videoStream; + int audioStream; + AVCodecContext *pVidCodecCtx; + AVCodecContext *pAudCodecCtx; + AVCodec *pVidCodec; + AVCodec *pAudCodec; + AVFrame *pFrame; + AVFrame *pFrameOut; + AVPacket packet; + int numBytesOut; + uint8_t *buffer; + AVPixelFormat fmtout; +}; + +enum FfmpegMethod +{ + FFMPEG_FAST_BILINEAR = 1, + FFMPEG_BILINEAR = 2, + FFMPEG_BICUBIC = 4, + FFMPEG_X = 8, + FFMPEG_POINT = 0x10, + FFMPEG_AREA = 0x20, + FFMPEG_BICUBLIN = 0x40, + FFMPEG_GAUSS = 0x80, + FFMPEG_SINC =0x100, + FFMPEG_LANCZOS =0x200, + FFMPEG_SPLINE =0x400 +}; + +class PANGOLIN_EXPORT FfmpegConverter : public VideoInterface +{ +public: + FfmpegConverter(std::unique_ptr& videoin, const std::string pixelfmtout = "RGB24", FfmpegMethod method = FFMPEG_POINT); + ~FfmpegConverter(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + +protected: + std::vector streams; + + struct ConvertContext + { + SwsContext* img_convert_ctx; + AVPixelFormat fmtsrc; + AVPixelFormat fmtdst; + AVFrame* avsrc; + AVFrame* avdst; + size_t w,h; + size_t src_buffer_offset; + size_t dst_buffer_offset; + + void convert(const unsigned char * src, unsigned char* dst); + + }; + + std::unique_ptr videoin; + std::unique_ptr input_buffer; + + std::vector converters; + //size_t src_buffer_size; + size_t dst_buffer_size; +}; + +#if (LIBAVFORMAT_VERSION_MAJOR > 55) || ((LIBAVFORMAT_VERSION_MAJOR == 55) && (LIBAVFORMAT_VERSION_MINOR >= 7)) +typedef AVCodecID CodecID; +#endif + +// Forward declaration +class FfmpegVideoOutputStream; + +class PANGOLIN_EXPORT FfmpegVideoOutput + : public VideoOutputInterface +{ + friend class FfmpegVideoOutputStream; +public: + FfmpegVideoOutput( const std::string& filename, int base_frame_rate, int bit_rate, bool flip = false ); + ~FfmpegVideoOutput(); + + const std::vector& Streams() const override; + + void SetStreams(const std::vector& streams, const std::string& uri, const picojson::value& properties) override; + + int WriteStreams(const unsigned char* data, const picojson::value& frame_properties) override; + + bool IsPipe() const override; + +protected: + void Initialise(std::string filename); + void StartStream(); + void Close(); + + std::string filename; + bool started; + AVFormatContext *oc; + std::vector streams; + std::vector strs; + + int frame_count; + + int base_frame_rate; + int bit_rate; + bool is_pipe; + bool flip; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/firewire.h b/thirdparty/Pangolin/include/pangolin/video/drivers/firewire.h new file mode 100644 index 00000000..a631a220 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/firewire.h @@ -0,0 +1,254 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include + +#ifndef _WIN32 +#include +#endif + + + +namespace pangolin +{ + +PANGOLIN_EXPORT +std::string Dc1394ColorCodingToString(dc1394color_coding_t coding); + +PANGOLIN_EXPORT +dc1394color_coding_t Dc1394ColorCodingFromString(std::string coding); + +PANGOLIN_EXPORT +void Dc1394ModeDetails(dc1394video_mode_t mode, unsigned& w, unsigned& h, std::string& format ); + +class PANGOLIN_EXPORT FirewireFrame +{ + friend class FirewireVideo; +public: + bool isValid() { return frame; } + unsigned char* Image() { return frame ? frame->image : 0; } + unsigned Width() const { return frame ? frame->size[0] : 0; } + unsigned Height() const { return frame ? frame->size[1] : 0; } + unsigned ImageBytes() const { return frame ? frame->image_bytes : 0; } + int FramesBehind() const { return frame ? frame->frames_behind : -1; } + unsigned Timestamp() const { return frame ? frame->timestamp : 0; } + int Id() const { return frame ? frame->id : -1; } +protected: + FirewireFrame(dc1394video_frame_t* frame) : frame(frame) {} + dc1394video_frame_t *frame; +}; + +struct PANGOLIN_EXPORT Guid +{ + Guid(uint64_t guid):guid(guid){} + uint64_t guid; +}; + +class PANGOLIN_EXPORT FirewireVideo : public VideoInterface +{ +public: + const static int MAX_FR = -1; + const static int EXT_TRIG = -1; + const static uint32_t GPIO_CTRL_PIN0 = 0x1110; + const static uint32_t GPIO_CTRL_PIN1 = 0x1120; + const static uint32_t GPIO_CTRL_PIN2 = 0x1130; + const static uint32_t GPIO_CTRL_PIN3 = 0x1140; + + FirewireVideo( + unsigned deviceid = 0, + dc1394video_mode_t video_mode = DC1394_VIDEO_MODE_640x480_RGB8, + dc1394framerate_t framerate = DC1394_FRAMERATE_30, + dc1394speed_t iso_speed = DC1394_ISO_SPEED_400, + int dma_buffers = 10 + ); + + FirewireVideo( + Guid guid, + dc1394video_mode_t video_mode = DC1394_VIDEO_MODE_640x480_RGB8, + dc1394framerate_t framerate = DC1394_FRAMERATE_30, + dc1394speed_t iso_speed = DC1394_ISO_SPEED_400, + int dma_buffers = 10 + ); + + FirewireVideo( + Guid guid, + dc1394video_mode_t video_mode, + float framerate, + uint32_t width, uint32_t height, + uint32_t left, uint32_t top, + dc1394speed_t iso_speed, + int dma_buffers, bool reset_at_boot=false + ); + + FirewireVideo( + unsigned deviceid, + dc1394video_mode_t video_mode, + float framerate, + uint32_t width, uint32_t height, + uint32_t left, uint32_t top, + dc1394speed_t iso_speed, + int dma_buffers, bool reset_at_boot=false + ); + + ~FirewireVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + //! (deprecated: use Streams[i].Width()) + //! Return image width + unsigned Width() const { return width; } + + //! (deprecated: use Streams[i].Height()) + //! Return image height + unsigned Height() const { return height; } + + //! Return object containing reference to image data within + //! DMA buffer. The FirewireFrame must be returned to + //! signal that it can be reused with a corresponding PutFrame() + FirewireFrame GetNext(bool wait = true); + + //! Return object containing reference to newest image data within + //! DMA buffer discarding old images. The FirewireFrame must be + //! returned to signal that it can be reused with a corresponding PutFrame() + FirewireFrame GetNewest(bool wait = true); + + //! Return FirewireFrame object. Data held by FirewireFrame is + //! invalidated on return. + void PutFrame(FirewireFrame& frame); + + //! return absolute shutter value + float GetShutterTime() const; + + //! set absolute shutter value + void SetShutterTime(float val); + + //! set auto shutter value + void SetAutoShutterTime(); + + //! return absolute gain value + float GetGain() const; + + //! set absolute gain value + void SetGain(float val); + + //! set auto gain value + void SetAutoGain(); + + //! return absolute brightness value + float GetBrightness() const; + + //! set absolute brightness value + void SetBrightness(float val); + + //! set auto brightness + void SetAutoBrightness(); + + //! return absolute gamma value + float GetGamma() const; + + //! return quantised shutter value + void SetShutterTimeQuant(int shutter); + + //! set the trigger to internal, i.e. determined by video mode + void SetInternalTrigger(); + + //! set the trigger to external + void SetExternalTrigger( + dc1394trigger_mode_t mode=DC1394_TRIGGER_MODE_0, + dc1394trigger_polarity_t polarity=DC1394_TRIGGER_ACTIVE_HIGH, + dc1394trigger_source_t source=DC1394_TRIGGER_SOURCE_0 + ); + + //! set a camera register + void SetRegister(uint64_t offset, uint32_t value); + + //! read camera register + uint32_t GetRegister(uint64_t offset); + + //! set a camera control register + void SetControlRegister(uint64_t offset, uint32_t value); + + //! read camera control register + uint32_t GetControlRegister(uint64_t offset); + +protected: + void init_stream_info(); + + void init_camera( + uint64_t guid, int dma_frames, + dc1394speed_t iso_speed, + dc1394video_mode_t video_mode, + dc1394framerate_t framerate + ); + + void init_format7_camera( + uint64_t guid, int dma_frames, + dc1394speed_t iso_speed, + dc1394video_mode_t video_mode, + float framerate, + uint32_t width, uint32_t height, + uint32_t left, uint32_t top, bool reset_at_boot + ); + + static int nearest_value(int value, int step, int min, int max); + static double bus_period_from_iso_speed(dc1394speed_t iso_speed); + + size_t frame_size_bytes; + std::vector streams; + + bool running; + dc1394camera_t *camera; + unsigned width, height, top, left; + //dc1394featureset_t features; + dc1394_t * d; + dc1394camera_list_t * list; + mutable dc1394error_t err; + +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/images.h b/thirdparty/Pangolin/include/pangolin/video/drivers/images.h new file mode 100644 index 00000000..2ba4e0ef --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/images.h @@ -0,0 +1,121 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include +#include + +namespace pangolin +{ + +// Video class that outputs test video signal. +class PANGOLIN_EXPORT ImagesVideo : public VideoInterface, public VideoPlaybackInterface, public VideoPropertiesInterface +{ +public: + ImagesVideo(const std::string& wildcard_path); + ImagesVideo(const std::string& wildcard_path, const PixelFormat& raw_fmt, size_t raw_width, size_t raw_height); + + // Explicitly delete copy ctor and assignment operator. + // See http://stackoverflow.com/questions/29565299/how-to-use-a-vector-of-unique-pointers-in-a-dll-exported-class-with-visual-studi + // >> It appears adding __declspec(dllexport) forces the compiler to define the implicitly-declared copy constructor and copy assignment operator + ImagesVideo(const ImagesVideo&) = delete; + ImagesVideo& operator=(const ImagesVideo&) = delete; + + ~ImagesVideo(); + + /////////////////////////////////// + // Implement VideoInterface + + void Start() override; + + void Stop() override; + + size_t SizeBytes() const override; + + const std::vector& Streams() const override; + + bool GrabNext( unsigned char* image, bool wait = true ) override; + + bool GrabNewest( unsigned char* image, bool wait = true ) override; + + /////////////////////////////////// + // Implement VideoPlaybackInterface + + size_t GetCurrentFrameId() const override; + + size_t GetTotalFrames() const override; + + size_t Seek(size_t frameid) override; + + /////////////////////////////////// + // Implement VideoPropertiesInterface + + const picojson::value& DeviceProperties() const override; + + const picojson::value& FrameProperties() const override; + +protected: + typedef std::vector Frame; + + const std::string& Filename(size_t frameNum, size_t channelNum) { + return filenames[channelNum][frameNum]; + } + + void PopulateFilenames(const std::string& wildcard_path); + + void PopulateFilenamesFromJson(const std::string& filename); + + bool LoadFrame(size_t i); + + void ConfigureStreamSizes(); + + std::vector streams; + size_t size_bytes; + + size_t num_files; + size_t num_channels; + size_t next_frame_id; + std::vector > filenames; + std::vector loaded; + + bool unknowns_are_raw; + PixelFormat raw_fmt; + size_t raw_width; + size_t raw_height; + + // Load any json properties if they are defined + picojson::value device_properties; + picojson::value json_frames; + picojson::value null_props; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/images_out.h b/thirdparty/Pangolin/include/pangolin/video/drivers/images_out.h new file mode 100644 index 00000000..ad6f662b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/images_out.h @@ -0,0 +1,60 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT ImagesVideoOutput : public VideoOutputInterface +{ +public: + ImagesVideoOutput(const std::string& image_folder, const std::string& json_file_out, const std::string &image_file_extension); + ~ImagesVideoOutput(); + + const std::vector& Streams() const override; + void SetStreams(const std::vector& streams, const std::string& uri, const picojson::value& device_properties) override; + int WriteStreams(const unsigned char* data, const picojson::value& frame_properties) override; + bool IsPipe() const override; + +protected: + std::vector streams; + std::string input_uri; + picojson::value device_properties; + picojson::value json_frames; + + size_t image_index; + std::string image_folder; + std::string image_file_extension; + std::ofstream file; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/join.h b/thirdparty/Pangolin/include/pangolin/video/drivers/join.h new file mode 100644 index 00000000..8eb383da --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/join.h @@ -0,0 +1,78 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT JoinVideo + : public VideoInterface, public VideoFilterInterface +{ +public: + JoinVideo(std::vector> &src); + + ~JoinVideo(); + + // Explicitly delete copy ctor and assignment operator. + // See http://stackoverflow.com/questions/29565299/how-to-use-a-vector-of-unique-pointers-in-a-dll-exported-class-with-visual-studi + // >> It appears adding __declspec(dllexport) forces the compiler to define the implicitly-declared copy constructor and copy assignment operator + JoinVideo(const JoinVideo&) = delete; + JoinVideo& operator=(const JoinVideo&) = delete; + + size_t SizeBytes() const; + + const std::vector& Streams() const; + + void Start(); + + void Stop(); + + bool Sync(int64_t tolerance_us, double transfer_bandwidth_gbps = 0); + + bool GrabNext( unsigned char* image, bool wait = true ); + + bool GrabNewest( unsigned char* image, bool wait = true ); + + std::vector& InputStreams(); + +protected: + int64_t GetAdjustedCaptureTime(size_t src_index); + + std::vector> storage; + std::vector src; + std::vector streams; + size_t size_bytes; + + int64_t sync_tolerance_us; + int64_t transfer_bandwidth_bytes_per_us; +}; + + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/merge.h b/thirdparty/Pangolin/include/pangolin/video/drivers/merge.h new file mode 100644 index 00000000..fd3cc071 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/merge.h @@ -0,0 +1,70 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +namespace pangolin +{ + +// Take N streams, and place them into one big buffer. +class PANGOLIN_EXPORT MergeVideo : public VideoInterface, public VideoFilterInterface +{ +public: + MergeVideo(std::unique_ptr& src, const std::vector& stream_pos, size_t w, size_t h); + ~MergeVideo(); + + void Start() override; + + void Stop() override; + + size_t SizeBytes() const override; + + const std::vector& Streams() const override; + + bool GrabNext( unsigned char* image, bool wait = true ) override; + + bool GrabNewest( unsigned char* image, bool wait = true ) override; + + std::vector& InputStreams() override; + +protected: + void CopyBuffer(unsigned char* dst_bytes, unsigned char* src_bytes); + + std::unique_ptr src; + std::vector videoin; + std::unique_ptr buffer; + std::vector stream_pos; + + std::vector streams; + size_t size_bytes; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/mirror.h b/thirdparty/Pangolin/include/pangolin/video/drivers/mirror.h new file mode 100644 index 00000000..5d040546 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/mirror.h @@ -0,0 +1,96 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +enum MirrorOptions +{ + MirrorOptionsNone = 0, + MirrorOptionsFlipX, + MirrorOptionsFlipY, + MirrorOptionsFlipXY, + MirrorOptionsTranspose, + MirrorOptionsRotateCW, + MirrorOptionsRotateCCW, +}; + +// Video class that debayers its video input using the given method. +class PANGOLIN_EXPORT MirrorVideo : + public VideoInterface, + public VideoFilterInterface, + public BufferAwareVideoInterface +{ +public: + MirrorVideo(std::unique_ptr& videoin, const std::vector& flips); + ~MirrorVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + //! Implement VideoFilterInterface method + std::vector& InputStreams(); + + uint32_t AvailableFrames() const; + + bool DropNFrames(uint32_t n); + +protected: + void Process(unsigned char* image, const unsigned char* buffer); + + std::unique_ptr videoin; + std::vector inputs; + std::vector streams; + std::vector flips; + size_t size_bytes; + unsigned char* buffer; + + picojson::value device_properties; + picojson::value frame_properties; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/openni.h b/thirdparty/Pangolin/include/pangolin/video/drivers/openni.h new file mode 100644 index 00000000..195f1d9b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/openni.h @@ -0,0 +1,72 @@ +#pragma once + +#include + +#include +#include + +// Workaround poor OpenNI Platform test on Linux before including XnCppWrapper.h +// See https://github.com/dennishamester/OpenNI/commit/ca99f6181234c682bba42a6ba +#ifdef _LINUX_ +#define linux 1 +#endif // _LINUX_ + +// OpenNI generates SO MANY warnings, we'll just disable all for this header(!) +// GCC and clang will listen to this pramga. +#ifndef _MSVC_ +#pragma GCC system_header +#endif +#include + +namespace pangolin +{ + +//! Interface to video capture sources +struct PANGOLIN_EXPORT OpenNiVideo : public VideoInterface +{ +public: + OpenNiVideo(OpenNiSensorType s1, OpenNiSensorType s2, ImageDim dim = ImageDim(640,480), int fps = 30); + ~OpenNiVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + void SetAutoExposure(bool enabled) + { +#if XN_MINOR_VERSION > 5 || (XN_MINOR_VERSION == 5 && XN_BUILD_VERSION >= 7) + if(imageNode.IsValid()) { + imageNode.GetAutoExposureCap().Set(enabled ? 1 : 0); + } +#else + throw pangolin::VideoException("SetAutoExposure Not supported for this version of OpenNI."); +#endif + } + +protected: + std::vector streams; + OpenNiSensorType sensor_type[2]; + + xn::Context context; + xn::DepthGenerator depthNode; + xn::ImageGenerator imageNode; + xn::IRGenerator irNode; + + size_t sizeBytes; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/openni2.h b/thirdparty/Pangolin/include/pangolin/video/drivers/openni2.h new file mode 100644 index 00000000..d3874aa8 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/openni2.h @@ -0,0 +1,147 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Richard Newcombe + * 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +#include +#include + +#include + +namespace pangolin +{ +const int MAX_OPENNI2_STREAMS = 2 * ONI_MAX_SENSORS; + +//! Interface to video capture sources +struct OpenNi2Video : public VideoInterface, public VideoPropertiesInterface, public VideoPlaybackInterface +{ +public: + + // Open all RGB and Depth streams from all devices + OpenNi2Video(ImageDim dim=ImageDim(640,480), ImageRoi roi=ImageRoi(0,0,0,0), int fps=30); + + // Open streams specified + OpenNi2Video(std::vector& stream_modes); + + // Open openni file + OpenNi2Video(const std::string& filename); + + // Open openni file with certain params + OpenNi2Video(const std::string& filename, std::vector& stream_modes); + + void UpdateProperties(); + + void SetMirroring(bool enable); + void SetAutoExposure(bool enable); + void SetAutoWhiteBalance(bool enable); + void SetDepthCloseRange(bool enable); + void SetDepthHoleFilter(bool enable); + void SetDepthColorSyncEnabled(bool enable); + void SetFastCrop(bool enable); + void SetRegisterDepthToImage(bool enable); + void SetPlaybackSpeed(float speed); + void SetPlaybackRepeat(bool enabled); + + ~OpenNi2Video(); + + //! Implement VideoInput::Start() + void Start() override; + + //! Implement VideoInput::Stop() + void Stop() override; + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const override; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const override; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ) override; + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ) override; + + //! Implement VideoPropertiesInterface::Properties() + const picojson::value& DeviceProperties() const override{ + return device_properties; + } + + //! Implement VideoPropertiesInterface::Properties() + const picojson::value& FrameProperties() const override{ + return frame_properties; + } + + //! Implement VideoPlaybackInterface::GetCurrentFrameId + size_t GetCurrentFrameId() const override; + + //! Implement VideoPlaybackInterface::GetTotalFrames + size_t GetTotalFrames() const override; + + //! Implement VideoPlaybackInterface::Seek + size_t Seek(size_t frameid) override; + + openni::VideoStream* GetVideoStream(int stream); + +protected: + void InitialiseOpenNI(); + int AddDevice(const std::string& device_uri); + void AddStream(const OpenNiStreamMode& mode); + void SetupStreamModes(); + void PrintOpenNI2Modes(openni::SensorType sensorType); + openni::VideoMode FindOpenNI2Mode(openni::Device &device, openni::SensorType sensorType, int width, int height, int fps, openni::PixelFormat fmt ); + + size_t numDevices; + size_t numStreams; + + openni::Device devices[ONI_MAX_SENSORS]; + OpenNiStreamMode sensor_type[ONI_MAX_SENSORS]; + + openni::VideoStream video_stream[ONI_MAX_SENSORS]; + openni::VideoFrameRef video_frame[ONI_MAX_SENSORS]; + + std::vector streams; + size_t sizeBytes; + + picojson::value device_properties; + picojson::value frame_properties; + picojson::value* streams_properties; + + bool use_depth; + bool use_ir; + bool use_rgb; + bool depth_to_color; + bool use_ir_and_rgb; + + size_t current_frame_index; + size_t total_frames; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/openni_common.h b/thirdparty/Pangolin/include/pangolin/video/drivers/openni_common.h new file mode 100644 index 00000000..c93183ee --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/openni_common.h @@ -0,0 +1,153 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * 2015 Richard Newcombe + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + +namespace pangolin +{ + +enum OpenNiSensorType +{ + OpenNiUnassigned = -1, + OpenNiRgb = 0, + OpenNiIr, + OpenNiDepth_1mm, + OpenNiDepth_1mm_Registered, + OpenNiDepth_100um, + OpenNiIr8bit, + OpenNiIr24bit, + OpenNiIrProj, + OpenNiIr8bitProj, + OpenNiGrey +}; + +struct PANGOLIN_EXPORT OpenNiStreamMode +{ + OpenNiStreamMode( + OpenNiSensorType sensor_type=OpenNiUnassigned, + ImageDim dim=ImageDim(640,480), ImageRoi roi=ImageRoi(0,0,0,0), int fps=30, int device=0 + ) + : sensor_type(sensor_type), dim(dim), roi(roi), fps(fps), device(device) + { + + } + + OpenNiSensorType sensor_type; + ImageDim dim; + ImageRoi roi; + int fps; + int device; +}; + +inline OpenNiSensorType openni_sensor(const std::string& str) +{ + if( !str.compare("grey") || !str.compare("gray") ) { + return OpenNiGrey; + }else if( !str.compare("rgb") ) { + return OpenNiRgb; + }else if( !str.compare("ir") ) { + return OpenNiIr; + }else if( !str.compare("depth1mm") || !str.compare("depth") ) { + return OpenNiDepth_1mm; + }else if( !str.compare("depth100um") ) { + return OpenNiDepth_100um; + }else if( !str.compare("depth_reg") || !str.compare("reg_depth")) { + return OpenNiDepth_1mm_Registered; + }else if( !str.compare("ir8") ) { + return OpenNiIr8bit; + }else if( !str.compare("ir24") ) { + return OpenNiIr24bit; + }else if( !str.compare("ir+") ) { + return OpenNiIrProj; + }else if( !str.compare("ir8+") ) { + return OpenNiIr8bitProj; + }else if( str.empty() ) { + return OpenNiUnassigned; + }else{ + throw pangolin::VideoException("Unknown OpenNi sensor", str ); + } +} + +// Find prefix character key +// Given arguments "depth!5:320x240@15", "!:@", would return map +// \0->"depth", !->"5", :->"320x240", @->"15" +inline std::map GetTokenSplits(const std::string& str, const std::string& tokens) +{ + std::map splits; + + char last_token = 0; + size_t last_start = 0; + for(unsigned int i=0; i> (std::istream &is, OpenNiStreamMode& fmt) +{ + std::string str; + is >> str; + + std::map splits = GetTokenSplits(str, "!:@#"); + + if(splits.count(0)) { + fmt.sensor_type = openni_sensor(splits[0]); + } + + if(splits.count('@')) { + fmt.fps = pangolin::Convert::Do(splits['@']); + } + + if(splits.count(':')) { + fmt.dim = pangolin::Convert::Do(splits[':']); + } + + if(splits.count('!')) { + fmt.device = pangolin::Convert::Do(splits['!']); + } + + if(splits.count('#')) { + fmt.roi = pangolin::Convert::Do(splits['#']); + } + + return is; +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/pack.h b/thirdparty/Pangolin/include/pangolin/video/drivers/pack.h new file mode 100644 index 00000000..3bfb1f87 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/pack.h @@ -0,0 +1,84 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +// Video class that packs its video input using the given method. +class PANGOLIN_EXPORT PackVideo : + public VideoInterface, + public VideoFilterInterface, + public BufferAwareVideoInterface +{ +public: + PackVideo(std::unique_ptr& videoin, PixelFormat new_fmt); + ~PackVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + //! Implement VideoFilterInterface method + std::vector& InputStreams(); + + uint32_t AvailableFrames() const; + + bool DropNFrames(uint32_t n); + +protected: + void Process(unsigned char* image, const unsigned char* buffer); + + std::unique_ptr src; + std::vector videoin; + std::vector streams; + size_t size_bytes; + unsigned char* buffer; + + picojson::value device_properties; + picojson::value frame_properties; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/pango.h b/thirdparty/Pangolin/include/pangolin/video/drivers/pango.h new file mode 100644 index 00000000..f6fecbe9 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/pango.h @@ -0,0 +1,104 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT PangoVideo + : public VideoInterface, public VideoPropertiesInterface, public VideoPlaybackInterface +{ +public: + PangoVideo(const std::string& filename, std::shared_ptr playback_session); + ~PangoVideo(); + + // Implement VideoInterface + + size_t SizeBytes() const override; + + const std::vector& Streams() const override; + + void Start() override; + + void Stop() override; + + bool GrabNext( unsigned char* image, bool wait = true ) override; + + bool GrabNewest( unsigned char* image, bool wait = true ) override; + + // Implement VideoPropertiesInterface + const picojson::value& DeviceProperties() const override { + if (-1 == _src_id) throw std::runtime_error("Not initialised"); + return _device_properties; + } + + const picojson::value& FrameProperties() const override { + return _frame_properties; + } + + // Implement VideoPlaybackInterface + + size_t GetCurrentFrameId() const override; + + size_t GetTotalFrames() const override; + + size_t Seek(size_t frameid) override; + + std::string GetSourceUri(); + +private: + void HandlePipeClosed(); + +protected: + int FindPacketStreamSource(); + void SetupStreams(const PacketStreamSource& src); + + const std::string _filename; + std::shared_ptr _playback_session; + std::shared_ptr _reader; + SyncTimeEventPromise _event_promise; + int _src_id; + const PacketStreamSource* _source; + + size_t _size_bytes; + bool _fixed_size; + std::vector _streams; + std::vector stream_decoder; + picojson::value _device_properties; + picojson::value _frame_properties; + std::string _source_uri; + + Registration session_seek; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/pango_video_output.h b/thirdparty/Pangolin/include/pangolin/video/drivers/pango_video_output.h new file mode 100644 index 00000000..a986a70b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/pango_video_output.h @@ -0,0 +1,70 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include + +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT PangoVideoOutput : public VideoOutputInterface +{ +public: + PangoVideoOutput(const std::string& filename, size_t buffer_size_bytes, const std::map &stream_encoder_uris); + ~PangoVideoOutput(); + + const std::vector& Streams() const override; + void SetStreams(const std::vector& streams, const std::string& uri, const picojson::value& device_properties) override; + int WriteStreams(const unsigned char* data, const picojson::value& frame_properties) override; + bool IsPipe() const override; + +protected: +// void WriteHeader(); + + std::vector streams; + std::string input_uri; + const std::string filename; + picojson::value device_properties; + + PacketStreamWriter packetstream; + size_t packetstream_buffer_size_bytes; + int packetstreamsrcid; + size_t total_frame_size; + bool is_pipe; + + bool fixed_size; + std::map stream_encoder_uris; + std::vector stream_encoders; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/pleora.h b/thirdparty/Pangolin/include/pangolin/video/drivers/pleora.h new file mode 100644 index 00000000..4b457441 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/pleora.h @@ -0,0 +1,196 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2015 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace pangolin +{ + +struct GrabbedBuffer { + + inline GrabbedBuffer(PvBuffer* b,PvResult r,bool v) + : buff(b), res(r), valid(v) + { + } + + PvBuffer* buff; + PvResult res; + bool valid; + +}; + +typedef std::list GrabbedBufferList; + +typedef std::list BufferList; + +class PANGOLIN_EXPORT PleoraVideo : public VideoInterface, public VideoPropertiesInterface, + public BufferAwareVideoInterface, public GenicamVideoInterface +{ +public: + + static const size_t DEFAULT_BUFFER_COUNT = 30; + + PleoraVideo(const Params& p); + + ~PleoraVideo(); + + void Start(); + + void Stop(); + + size_t SizeBytes() const; + + const std::vector& Streams() const; + + bool GrabNext( unsigned char* image, bool wait = true ); + + bool GrabNewest( unsigned char* image, bool wait = true ); + + std::string GetParameter(const std::string& name); + + void SetParameter(const std::string& name, const std::string& value); + + void SetGain(int64_t val); + + int64_t GetGain(); + + void SetAnalogBlackLevel(int64_t val); + + int64_t GetAnalogBlackLevel(); + + void SetExposure(double val); + + double GetExposure(); + + void SetGamma(double val); + + double GetGamma(); + + + + void SetupTrigger(bool triggerActive, int64_t triggerSource, int64_t acquisitionMode); + + const picojson::value& DeviceProperties() const { + return device_properties; + } + + const picojson::value& FrameProperties() const { + return frame_properties; + } + + uint32_t AvailableFrames() const; + + bool DropNFrames(uint32_t n); + +protected: + + void InitDevice(const char *model_name, const char *serial_num, size_t index); + + void DeinitDevice(); + + void SetDeviceParams(Params& p); + + void InitStream(); + + void DeinitStream(); + + void InitPangoStreams(); + + void InitPangoDeviceProperties(); + + void InitBuffers(size_t buffer_count); + + void DeinitBuffers(); + + template + T DeviceParam(const char* name); + + template + bool SetDeviceParam(const char* name, T val); + + template + T StreamParam(const char* name); + + template + bool SetStreamParam(const char* name, T val); + + bool ParseBuffer(PvBuffer* lBuffer, unsigned char* image); + + void RetriveAllAvailableBuffers(uint32_t timeout); + + std::vector streams; + picojson::value device_properties; + picojson::value frame_properties; + + size_t size_bytes; + + // Pleora handles + PvSystem* lPvSystem; + const PvDeviceInfo* lDeviceInfo; + PvDevice* lDevice; + PvStream* lStream; + + // Genicam device parameters + PvGenParameterArray* lDeviceParams; + PvGenCommand* lStart; + PvGenCommand* lStop; + + PvGenInteger* lAnalogGain; + PvGenInteger* lAnalogBlackLevel; + PvGenFloat* lExposure; + PvGenFloat* lGamma; + PvGenEnum* lAquisitionMode; + PvGenEnum* lTriggerSource; + PvGenEnum* lTriggerMode; + PvGenFloat* lTemperatureCelcius; + bool getTemp; + + // Genicam stream parameters + PvGenParameterArray* lStreamParams; + + BufferList lBufferList; + GrabbedBufferList lGrabbedBuffList; + uint32_t validGrabbedBuffers; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/pvn.h b/thirdparty/Pangolin/include/pangolin/video/drivers/pvn.h new file mode 100644 index 00000000..8e47e546 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/pvn.h @@ -0,0 +1,77 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT PvnVideo : public VideoInterface +{ +public: + PvnVideo(const std::string& filename, bool realtime = false); + ~PvnVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + +protected: + int frames; + std::ifstream file; + + std::vector streams; + size_t frame_size_bytes; + + bool realtime; + pangolin::basetime frame_interval; + pangolin::basetime last_frame; + + void ReadFileHeader(); +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/realsense.h b/thirdparty/Pangolin/include/pangolin/video/drivers/realsense.h new file mode 100644 index 00000000..064bc7a4 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/realsense.h @@ -0,0 +1,87 @@ +#pragma once + +#include + +#include + +#include + +namespace rs { +class context; +class device; +} + +namespace pangolin +{ + +//! Interface to video capture sources +struct RealSenseVideo : public VideoInterface, public VideoPropertiesInterface, public VideoPlaybackInterface +{ +public: + + // Open all RGB and Depth streams from all devices + RealSenseVideo(ImageDim dim=ImageDim(640,480), int fps=30); + + // Open streams specified + // TODO + //RealSenseVideo(std::vector& stream_modes); + + ~RealSenseVideo(); + + //! Implement VideoInput::Start() + void Start() override; + + //! Implement VideoInput::Stop() + void Stop() override; + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const override; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const override; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ) override; + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ) override; + + //! Implement VideoPropertiesInterface::Properties() + const picojson::value& DeviceProperties() const override { + return device_properties; + } + + //! Implement VideoPropertiesInterface::Properties() + const picojson::value& FrameProperties() const override { + return frame_properties; + } + + //! Implement VideoPlaybackInterface::GetCurrentFrameId + size_t GetCurrentFrameId() const override; + + //! Implement VideoPlaybackInterface::GetTotalFrames + size_t GetTotalFrames() const override; + + //! Implement VideoPlaybackInterface::Seek + size_t Seek(size_t frameid) override; + +protected: + size_t sizeBytes; + + std::vector streams; + + picojson::value device_properties; + picojson::value frame_properties; + picojson::value* streams_properties; + + size_t current_frame_index; + size_t total_frames; + + rs::context* ctx_; + std::vector devs_; + + ImageDim dim_; + size_t fps_; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/realsense2.h b/thirdparty/Pangolin/include/pangolin/video/drivers/realsense2.h new file mode 100644 index 00000000..589f73cb --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/realsense2.h @@ -0,0 +1,87 @@ +#pragma once + +#include + +#include + +#include + +namespace rs2 { +class pipeline; +class config; +} + +namespace pangolin +{ + +//! Interface to video capture sources +struct RealSense2Video : public VideoInterface, public VideoPropertiesInterface, public VideoPlaybackInterface +{ +public: + + // Open all RGB and Depth streams from all devices + RealSense2Video(ImageDim dim=ImageDim(640,480), int fps=30); + + // Open streams specified + // TODO + //RealSense2Video(std::vector& stream_modes); + + ~RealSense2Video(); + + //! Implement VideoInput::Start() + void Start() override; + + //! Implement VideoInput::Stop() + void Stop() override; + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const override; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const override; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ) override; + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ) override; + + //! Implement VideoPropertiesInterface::Properties() + const picojson::value& DeviceProperties() const override { + return device_properties; + } + + //! Implement VideoPropertiesInterface::Properties() + const picojson::value& FrameProperties() const override { + return frame_properties; + } + + //! Implement VideoPlaybackInterface::GetCurrentFrameId + size_t GetCurrentFrameId() const override; + + //! Implement VideoPlaybackInterface::GetTotalFrames + size_t GetTotalFrames() const override; + + //! Implement VideoPlaybackInterface::Seek + size_t Seek(size_t frameid) override; + +protected: + size_t sizeBytes; + + std::vector streams; + + picojson::value device_properties; + picojson::value frame_properties; + picojson::value* streams_properties; + + size_t current_frame_index; + size_t total_frames; + + rs2::pipeline* pipe; + rs2::config* cfg; + + ImageDim dim_; + size_t fps_; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/shared_memory.h b/thirdparty/Pangolin/include/pangolin/video/drivers/shared_memory.h new file mode 100644 index 00000000..66f27dcc --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/shared_memory.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace pangolin +{ + +class SharedMemoryVideo : public VideoInterface +{ +public: + SharedMemoryVideo(size_t w, size_t h, std::string pix_fmt, + const std::shared_ptr& shared_memory, + const std::shared_ptr& buffer_full); + ~SharedMemoryVideo(); + + size_t SizeBytes() const; + const std::vector& Streams() const; + void Start(); + void Stop(); + bool GrabNext(unsigned char *image, bool wait); + bool GrabNewest(unsigned char *image, bool wait); + +private: + PixelFormat _fmt; + size_t _frame_size; + std::vector _streams; + std::shared_ptr _shared_memory; + std::shared_ptr _buffer_full; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/shift.h b/thirdparty/Pangolin/include/pangolin/video/drivers/shift.h new file mode 100644 index 00000000..ed7f5104 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/shift.h @@ -0,0 +1,73 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +// Video class that debayers its video input using the given method. +class PANGOLIN_EXPORT ShiftVideo : public VideoInterface, public VideoFilterInterface +{ +public: + ShiftVideo(std::unique_ptr& videoin, PixelFormat new_fmt, int shift_right_bits = 0, unsigned int mask = 0xFFFF); + ~ShiftVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + std::vector& InputStreams(); + +protected: + std::unique_ptr src; + std::vector videoin; + std::vector streams; + size_t size_bytes; + unsigned char* buffer; + int shift_right_bits; + unsigned int mask; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/split.h b/thirdparty/Pangolin/include/pangolin/video/drivers/split.h new file mode 100644 index 00000000..a5674580 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/split.h @@ -0,0 +1,65 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT SplitVideo + : public VideoInterface, public VideoFilterInterface +{ +public: + SplitVideo(std::unique_ptr& videoin, const std::vector& streams); + + ~SplitVideo(); + + size_t SizeBytes() const; + + const std::vector& Streams() const; + + void Start(); + + void Stop(); + + bool GrabNext( unsigned char* image, bool wait = true ); + + bool GrabNewest( unsigned char* image, bool wait = true ); + + std::vector& InputStreams(); + +protected: + std::unique_ptr src; + std::vector videoin; + std::vector streams; +}; + + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/teli.h b/thirdparty/Pangolin/include/pangolin/video/drivers/teli.h new file mode 100644 index 00000000..e0f851d0 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/teli.h @@ -0,0 +1,118 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2015 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#include + +namespace pangolin +{ + +// Video class that outputs test video signal. +class PANGOLIN_EXPORT TeliVideo : public VideoInterface, public VideoPropertiesInterface, + public BufferAwareVideoInterface, public GenicamVideoInterface +{ +public: + TeliVideo(const Params &p); + ~TeliVideo(); + + Params OpenCameraAndGetRemainingParameters(Params ¶ms); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + inline Teli::CAM_HANDLE GetCameraHandle() { + return cam; + } + + inline Teli::CAM_STRM_HANDLE GetCameraStreamHandle() { + return strm; + } + + bool GetParameter(const std::string& name, std::string& result); + + bool SetParameter(const std::string& name, const std::string& value); + + //! Returns number of available frames + uint32_t AvailableFrames() const; + + //! Drops N frames in the queue starting from the oldest + //! returns false if less than n frames arae available + bool DropNFrames(uint32_t n); + + //! Access JSON properties of device + const picojson::value& DeviceProperties() const; + + //! Access JSON properties of most recently captured frame + const picojson::value& FrameProperties() const; + + void PopulateEstimatedCenterCaptureTime(pangolin::basetime host_reception_time); + +protected: + void Initialise(); + void InitPangoDeviceProperties(); + void SetDeviceParams(const Params &p); + void SetNodeValStr(Teli::CAM_HANDLE cam, Teli::CAM_NODE_HANDLE node, std::string node_str, std::string val_str); + + std::vector streams; + size_t size_bytes; + + Teli::CAM_HANDLE cam; + Teli::CAM_STRM_HANDLE strm; + +#ifdef _WIN_ + HANDLE hStrmCmpEvt; +#endif +#ifdef _LINUX_ + Teli::SIGNAL_HANDLE hStrmCmpEvt; +#endif + double transfer_bandwidth_gbps; + int exposure_us; + picojson::value device_properties; + picojson::value frame_properties; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/test.h b/thirdparty/Pangolin/include/pangolin/video/drivers/test.h new file mode 100644 index 00000000..02646f6b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/test.h @@ -0,0 +1,66 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +// Video class that outputs test video signal. +class PANGOLIN_EXPORT TestVideo : public VideoInterface +{ +public: + TestVideo(size_t w, size_t h, size_t n, std::string pix_fmt); + ~TestVideo(); + + //! Implement VideoInput::Start() + void Start() override; + + //! Implement VideoInput::Stop() + void Stop() override; + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const override; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const override; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ) override; + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ) override; + +protected: + std::vector streams; + size_t size_bytes; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/thread.h b/thirdparty/Pangolin/include/pangolin/video/drivers/thread.h new file mode 100644 index 00000000..ddd02421 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/thread.h @@ -0,0 +1,112 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace pangolin +{ + + +// Video class that creates a thread that keeps pulling frames and processing from its children. +class PANGOLIN_EXPORT ThreadVideo : public VideoInterface, public VideoPropertiesInterface, + public BufferAwareVideoInterface, public VideoFilterInterface +{ +public: + ThreadVideo(std::unique_ptr& videoin, size_t num_buffers); + ~ThreadVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + const picojson::value& DeviceProperties() const; + + const picojson::value& FrameProperties() const; + + uint32_t AvailableFrames() const; + + bool DropNFrames(uint32_t n); + + void operator()(); + + std::vector& InputStreams(); + +protected: + struct GrabResult + { + GrabResult(const size_t buffer_size) + : return_status(false), + buffer(new unsigned char[buffer_size]) + { + } + + // No copy constructor. + GrabResult(const GrabResult& o) = delete; + + // Default move constructor + GrabResult(GrabResult&& o) = default; + + bool return_status; + std::unique_ptr buffer; + picojson::value frame_properties; + }; + + std::unique_ptr src; + std::vector videoin; + + bool quit_grab_thread; + FixSizeBuffersQueue queue; + + std::condition_variable cv; + std::mutex cvMtx; + std::thread grab_thread; + + mutable picojson::value device_properties; + picojson::value frame_properties; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/truncate.h b/thirdparty/Pangolin/include/pangolin/video/drivers/truncate.h new file mode 100644 index 00000000..cfdd3c0a --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/truncate.h @@ -0,0 +1,71 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT TruncateVideo + : public VideoInterface, public VideoFilterInterface +{ +public: + TruncateVideo(std::unique_ptr& videoin, size_t begin, size_t end); + + ~TruncateVideo(); + + size_t SizeBytes() const; + + const std::vector& Streams() const; + + void Start(); + + void Stop(); + + bool GrabNext( unsigned char* image, bool wait = true ); + + bool GrabNewest( unsigned char* image, bool wait = true ); + + std::vector& InputStreams(); + +protected: + std::unique_ptr src; + std::vector videoin; + std::vector streams; + + size_t begin; + size_t end; + size_t next_frame_to_grab; + + inline VideoPlaybackInterface* GetVideoPlaybackInterface(){ return dynamic_cast(src.get()); } +}; + + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/unpack.h b/thirdparty/Pangolin/include/pangolin/video/drivers/unpack.h new file mode 100644 index 00000000..4f0826c4 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/unpack.h @@ -0,0 +1,84 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2014 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +// Video class that debayers its video input using the given method. +class PANGOLIN_EXPORT UnpackVideo : + public VideoInterface, + public VideoFilterInterface, + public BufferAwareVideoInterface +{ +public: + UnpackVideo(std::unique_ptr& videoin, PixelFormat new_fmt); + ~UnpackVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + //! Implement VideoFilterInterface method + std::vector& InputStreams(); + + uint32_t AvailableFrames() const; + + bool DropNFrames(uint32_t n); + +protected: + void Process(unsigned char* image, const unsigned char* buffer); + + std::unique_ptr src; + std::vector videoin; + std::vector streams; + size_t size_bytes; + unsigned char* buffer; + + picojson::value device_properties; + picojson::value frame_properties; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/uvc.h b/thirdparty/Pangolin/include/pangolin/video/drivers/uvc.h new file mode 100755 index 00000000..148a6f7a --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/uvc.h @@ -0,0 +1,115 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include + +#ifdef _MSC_VER +// Define missing timeval struct +typedef struct timeval { + long tv_sec; + long tv_usec; +} timeval; +#endif // _MSC_VER + +#include + +namespace pangolin +{ + +class PANGOLIN_EXPORT UvcVideo : public VideoInterface, public VideoUvcInterface, public VideoPropertiesInterface +{ +public: + UvcVideo(int vendor_id, int product_id, const char* sn, int deviceid, int width, int height, int fps); + ~UvcVideo(); + + void InitDevice(int vid, int pid, const char* sn, int deviceid, int width, int height, int fps); + void DeinitDevice(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + //! Implement VideoUvcInterface::GetCtrl() + int IoCtrl(uint8_t unit, uint8_t ctrl, unsigned char* data, int len, UvcRequestCode req_code); + + //! Implement VideoUvcInterface::GetExposure() + bool GetExposure(int& exp_us); + + //! Implement VideoUvcInterface::SetExposure() + bool SetExposure(int exp_us); + + //! Implement VideoUvcInterface::GetGain() + bool GetGain(float& gain); + + //! Implement VideoUvcInterface::SetGain() + bool SetGain(float gain); + + //! Access JSON properties of device + const picojson::value& DeviceProperties() const; + + //! Access JSON properties of most recently captured frame + const picojson::value& FrameProperties() const; + +protected: + void InitPangoDeviceProperties(); + static uvc_error_t FindDevice( + uvc_context_t *ctx, uvc_device_t **dev, + int vid, int pid, const char *sn, int device_id); + + std::vector streams; + size_t size_bytes; + + uvc_context* ctx_; + uvc_device* dev_; + uvc_device_handle* devh_; + uvc_stream_handle* strm_; + uvc_stream_ctrl_t ctrl_; + uvc_frame_t* frame_; + picojson::value device_properties; + picojson::value frame_properties; + bool is_streaming; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/uvc_mediafoundation.h b/thirdparty/Pangolin/include/pangolin/video/drivers/uvc_mediafoundation.h new file mode 100644 index 00000000..dfa6f126 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/uvc_mediafoundation.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include + +struct IMFActivate; +struct IMFMediaSource; +struct IMFSourceReader; +struct IBaseFilter; +struct IKsControl; + +namespace pangolin +{ + +class PANGOLIN_EXPORT UvcMediaFoundationVideo + : public pangolin::VideoInterface, public pangolin::VideoUvcInterface, public pangolin::VideoPropertiesInterface +{ + public: + UvcMediaFoundationVideo(int vendorId, int productId, int deviceId, size_t width, size_t height, int fps); + ~UvcMediaFoundationVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext(unsigned char* image, bool wait = true); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest(unsigned char* image, bool wait = true); + + //! Implement VideoUvcInterface::GetCtrl() + int IoCtrl(uint8_t unit, uint8_t ctrl, unsigned char* data, int len, pangolin::UvcRequestCode req_code); + + //! Implement VideoUvcInterface::GetExposure() + bool GetExposure(int& exp_us); + + //! Implement VideoUvcInterface::SetExposure() + bool SetExposure(int exp_us); + + //! Implement VideoUvcInterface::GetGain() + bool GetGain(float& gain); + + //! Implement VideoUvcInterface::SetGain() + bool SetGain(float gain); + + //! Access JSON properties of device + const picojson::value& DeviceProperties() const; + + //! Access JSON properties of most recently captured frame + const picojson::value& FrameProperties() const; + + protected: + bool FindDevice(int vendorId, int productId, int deviceId); + void InitDevice(size_t width, size_t height, int fps); + void DeinitDevice(); + + static bool DeviceMatches(const std::wstring& symLink, int vendorId, int productId); + static bool SymLinkIDMatches(const std::wstring& symLink, const wchar_t* idStr, int id); + + std::vector streams; + size_t size_bytes; + + IMFMediaSource* mediaSource; + IMFSourceReader* sourceReader; + IBaseFilter* baseFilter; + IKsControl* ksControl; + DWORD ksControlNodeId; + + picojson::value device_properties; + picojson::value frame_properties; +}; +} diff --git a/thirdparty/Pangolin/include/pangolin/video/drivers/v4l.h b/thirdparty/Pangolin/include/pangolin/video/drivers/v4l.h new file mode 100755 index 00000000..a2ed55a2 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/drivers/v4l.h @@ -0,0 +1,128 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace pangolin +{ + +typedef enum { + IO_METHOD_READ, + IO_METHOD_MMAP, + IO_METHOD_USERPTR, +} io_method; + +struct buffer { + void* start; + size_t length; +}; + +class PANGOLIN_EXPORT V4lVideo : public VideoInterface, public VideoUvcInterface, public VideoPropertiesInterface +{ +public: + V4lVideo(const char* dev_name, io_method io = IO_METHOD_MMAP, unsigned iwidth=0, unsigned iheight=0); + ~V4lVideo(); + + //! Implement VideoInput::Start() + void Start(); + + //! Implement VideoInput::Stop() + void Stop(); + + //! Implement VideoInput::SizeBytes() + size_t SizeBytes() const; + + //! Implement VideoInput::Streams() + const std::vector& Streams() const; + + //! Implement VideoInput::GrabNext() + bool GrabNext( unsigned char* image, bool wait = true ); + + //! Implement VideoInput::GrabNewest() + bool GrabNewest( unsigned char* image, bool wait = true ); + + //! Implement VideoUvcInterface::IoCtrl() + int IoCtrl(uint8_t unit, uint8_t ctrl, unsigned char* data, int len, UvcRequestCode req_code); + + bool GetExposure(int& exp_us); + + bool SetExposure(int exp_us); + + bool GetGain(float& gain); + + bool SetGain(float gain); + + int GetFileDescriptor() const{ + return fd; + } + + //! Access JSON properties of device + const picojson::value& DeviceProperties() const; + + //! Access JSON properties of most recently captured frame + const picojson::value& FrameProperties() const; + +protected: + void InitPangoDeviceProperties(); + + + int ReadFrame(unsigned char* image); + void Mainloop(); + + void init_read(unsigned int buffer_size); + void init_mmap(const char* dev_name); + void init_userp(const char* dev_name, unsigned int buffer_size); + + void init_device(const char* dev_name, unsigned iwidth, unsigned iheight, unsigned ifps, unsigned v4l_format = V4L2_PIX_FMT_YUYV, v4l2_field field = V4L2_FIELD_INTERLACED); + void uninit_device(); + + void open_device(const char* dev_name); + void close_device(); + + std::vector streams; + + io_method io; + int fd; + buffer* buffers; + unsigned int n_buffers; + bool running; + unsigned width; + unsigned height; + float fps; + size_t image_size; + + picojson::value device_properties; + picojson::value frame_properties; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/iostream_operators.h b/thirdparty/Pangolin/include/pangolin/video/iostream_operators.h new file mode 100644 index 00000000..600e06e1 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/iostream_operators.h @@ -0,0 +1,132 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2015 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace pangolin +{ + +struct PANGOLIN_EXPORT Point +{ + inline Point() : x(0), y(0) {} + inline Point(size_t x, size_t y) : x(x), y(y) {} + size_t x; + size_t y; +}; + +typedef Point ImageDim; + +struct PANGOLIN_EXPORT ImageRoi +{ + inline ImageRoi() : x(0), y(0), w(0), h(0) {} + inline ImageRoi(size_t x, size_t y, size_t w, size_t h) : x(x), y(y), w(w), h(h) {} + size_t x; size_t y; + size_t w; size_t h; +}; + +inline std::istream& operator>> (std::istream &is, ImageDim &dim) +{ + if(std::isdigit(is.peek()) ) { + // Expect 640x480, 640*480, ... + is >> dim.x; is.get(); is >> dim.y; + }else{ + // Expect 'VGA', 'QVGA', etc + std::string sdim; + is >> sdim; + ToUpper(sdim); + + if( !sdim.compare("QQVGA") ) { + dim = ImageDim(160,120); + }else if( !sdim.compare("HQVGA") ) { + dim = ImageDim(240,160); + }else if( !sdim.compare("QVGA") ) { + dim = ImageDim(320,240); + }else if( !sdim.compare("WQVGA") ) { + dim = ImageDim(360,240); + }else if( !sdim.compare("HVGA") ) { + dim = ImageDim(480,320); + }else if( !sdim.compare("VGA") ) { + dim = ImageDim(640,480); + }else if( !sdim.compare("WVGA") ) { + dim = ImageDim(720,480); + }else if( !sdim.compare("SVGA") ) { + dim = ImageDim(800,600); + }else if( !sdim.compare("DVGA") ) { + dim = ImageDim(960,640); + }else if( !sdim.compare("WSVGA") ) { + dim = ImageDim(1024,600); + }else{ + throw VideoException("Unrecognised image-size string."); + } + } + return is; +} + +inline std::istream& operator>> (std::istream &is, ImageRoi &roi) +{ + is >> roi.x; is.get(); is >> roi.y; is.get(); + is >> roi.w; is.get(); is >> roi.h; + return is; +} + +inline std::istream& operator>> (std::istream &is, PixelFormat& fmt) +{ + std::string sfmt; + is >> sfmt; + fmt = PixelFormatFromString(sfmt); + return is; +} + +inline std::istream& operator>> (std::istream &is, Image& img) +{ + size_t offset; + is >> offset; is.get(); + img.ptr = (unsigned char*)(offset); + is >> img.w; is.get(); + is >> img.h; is.get(); + is >> img.pitch; + return is; +} + +inline std::istream& operator>> (std::istream &is, StreamInfo &stream) +{ + PixelFormat fmt; + Image img_offset; + is >> img_offset; is.get(); + is >> fmt; + stream = StreamInfo(fmt, img_offset); + return is; +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/stream_encoder_factory.h b/thirdparty/Pangolin/include/pangolin/video/stream_encoder_factory.h new file mode 100644 index 00000000..b6f7efe8 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/stream_encoder_factory.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include + +namespace pangolin { + +using ImageEncoderFunc = std::function&)>; +using ImageDecoderFunc = std::function; + +class StreamEncoderFactory +{ +public: + static StreamEncoderFactory& I(); + + ImageEncoderFunc GetEncoder(const std::string& encoder_spec, const PixelFormat& fmt); + + ImageDecoderFunc GetDecoder(const std::string& encoder_spec, const PixelFormat& fmt); +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/stream_info.h b/thirdparty/Pangolin/include/pangolin/video/stream_info.h new file mode 100644 index 00000000..d141d7a4 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/stream_info.h @@ -0,0 +1,100 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin { + +class PANGOLIN_EXPORT StreamInfo +{ +public: + inline StreamInfo() + : fmt(PixelFormatFromString("GRAY8")) {} + + inline StreamInfo(PixelFormat fmt, const Image img_offset ) + : fmt(fmt), img_offset(img_offset) {} + + inline StreamInfo(PixelFormat fmt, size_t w, size_t h, size_t pitch, unsigned char* offset = 0) + : fmt(fmt), img_offset(offset,w,h,pitch) {} + + //! Format representing how image is laid out in memory + inline const PixelFormat &PixFormat() const { return fmt; } + + //! Image width in pixels + inline size_t Width() const { return img_offset.w; } + + //! Image height in pixels + inline size_t Height() const { return img_offset.h; } + + inline double Aspect() const { return (double)Width() / (double)Height(); } + + //! Pitch: Number of bytes between one image row and the next + inline size_t Pitch() const { return img_offset.pitch; } + + //! Number of contiguous bytes in memory that the image occupies + inline size_t RowBytes() const { + // Row size without padding + return (fmt.bpp*img_offset.w)/8; + } + + //! Returns true iff image contains padding or stridded access + //! This implies that the image data is not contiguous in memory. + inline bool IsPitched() const { + return Pitch() != RowBytes(); + } + + //! Number of contiguous bytes in memory that the image occupies + inline size_t SizeBytes() const { + return (img_offset.h-1) * img_offset.pitch + RowBytes(); + } + + //! Offset in bytes relative to start of frame buffer + inline unsigned char* Offset() const { return img_offset.ptr; } + + //! Return Image wrapper around raw base pointer + inline Image StreamImage(unsigned char* base_ptr) const { + Image img = img_offset; + img.ptr += (size_t)base_ptr; + return img; + } + + //! Return Image wrapper around raw base pointer + inline const Image StreamImage(const unsigned char* base_ptr) const { + Image img = img_offset; + img.ptr += (size_t)base_ptr; + return img; + } + +protected: + PixelFormat fmt; + Image img_offset; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/video.h b/thirdparty/Pangolin/include/pangolin/video/video.h new file mode 100644 index 00000000..46e982dd --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/video.h @@ -0,0 +1,261 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +// Pangolin video supports various cameras and file formats through +// different 3rd party libraries. +// +// Video URI's take the following form: +// scheme:[param1=value1,param2=value2,...]//device +// +// scheme = file | files | pango | shmem | dc1394 | uvc | v4l | openni2 | +// openni | depthsense | pleora | teli | mjpeg | test | +// thread | convert | debayer | split | join | shift | mirror | unpack +// +// file/files - read one or more streams from image file(s) / video +// e.g. "files://~/data/dataset/img_*.jpg" +// e.g. "files://~/data/dataset/img_[left,right]_*.pgm" +// e.g. "files:///home/user/sequence/foo%03d.jpeg" +// +// e.g. "file:[fmt=GRAY8,size=640x480]///home/user/raw_image.bin" +// e.g. "file:[realtime=1]///home/user/video/movie.pango" +// e.g. "file:[stream=1]///home/user/video/movie.avi" +// +// dc1394 - capture video through a firewire camera +// e.g. "dc1394:[fmt=RGB24,size=640x480,fps=30,iso=400,dma=10]//0" +// e.g. "dc1394:[fmt=FORMAT7_1,size=640x480,pos=2+2,iso=400,dma=10]//0" +// e.g. "dc1394:[fmt=FORMAT7_3,deinterlace=1]//0" +// +// v4l - capture video from a Video4Linux (USB) camera (normally YUVY422 format) +// method=mmap|read|userptr +// e.g. "v4l:///dev/video0" +// e.g. "v4l[method=mmap]:///dev/video0" +// +// openni2 - capture video / depth from OpenNI2 SDK (Kinect / Xtrion etc) +// imgN=grey|rgb|ir|ir8|ir24|depth|reg_depth +// e.g. "openni2://' +// e.g. "openni2:[img1=rgb,img2=depth,coloursync=true]//" +// e.g. "openni2:[img1=depth,close=closerange,holefilter=true]//" +// e.g. "openni2:[size=320x240,fps=60,img1=ir]//" +// +// openni - capture video / depth from OpenNI 1.0 SDK (Kinect / Xtrion etc) +// Sensor modes containing '8' will truncate to 8-bits. +// Sensor modes containing '+' explicitly enable IR illuminator +// imgN=rgb|ir|ir8|ir+|ir8+|depth|reg_depth +// autoexposure=true|false +// e.g. "openni://' +// e.g. "openni:[img1=rgb,img2=depth]//" +// e.g. "openni:[size=320x240,fps=60,img1=ir]//" +// +// depthsense - capture video / depth from DepthSense SDK. +// DepthSenseViewer can be used to alter capture settings. +// imgN=depth|rgb +// sizeN=QVGA|320x240|... +// fpsN=25|30|60|... +// e.g. "depthsense://" +// e.g. "depthsense:[img1=depth,img2=rgb]//" +// +// pleora - USB 3 vision cameras accepts any option in the same format reported by eBUSPlayer +// e.g. for lightwise cameras: "pleora:[size=512x256,pos=712x512,sn=00000274,ExposureTime=10000,PixelFormat=Mono12p,AcquisitionMode=SingleFrame,TriggerSource=Line0,TriggerMode=On]//" +// e.g. for toshiba cameras: "pleora:[size=512x256,pos=712x512,sn=0300056,PixelSize=Bpp12,ExposureTime=10000,ImageFormatSelector=Format1,BinningHorizontal=2,BinningVertical=2]//" +// e.g. toshiba alternated "pleora:[UserSetSelector=UserSet1,ExposureTime=10000,PixelSize=Bpp12,Width=1400,OffsetX=0,Height=1800,OffsetY=124,LineSelector=Line1,LineSource=ExposureActive,LineSelector=Line2,LineSource=Off,LineModeAll=6,LineInverterAll=6,UserSetSave=Execute, +// UserSetSelector=UserSet2,PixelSize=Bpp12,Width=1400,OffsetX=1048,Height=1800,OffsetY=124,ExposureTime=10000,LineSelector=Line1,LineSource=Off,LineSelector=Line2,LineSource=ExposureActive,LineModeAll=6,LineInverterAll=6,UserSetSave=Execute, +// SequentialShutterIndex=1,SequentialShutterEntry=1,SequentialShutterIndex=2,SequentialShutterEntry=2,SequentialShutterTerminateAt=2,SequentialShutterEnable=On,,AcquisitionFrameRateControl=Manual,AcquisitionFrameRate=70]//" +// +// thread - thread that continuously pulls from the child streams so that data in, unpacking, debayering etc can be decoupled from the main application thread +// e.g. thread://pleora:// +// e.g. thread://unpack://pleora:[PixelFormat=Mono12p]// +// +// convert - use FFMPEG to convert between video pixel formats +// e.g. "convert:[fmt=RGB24]//v4l:///dev/video0" +// e.g. "convert:[fmt=GRAY8]//v4l:///dev/video0" +// +// mjpeg - capture from (possibly networked) motion jpeg stream using FFMPEG +// e.g. "mjpeg://http://127.0.0.1/?action=stream" +// +// debayer - debayer an input video stream +// e.g. "debayer:[tile="BGGR",method="downsample"]//v4l:///dev/video0 +// +// split - split an input video into a one or more streams based on Region of Interest / memory specification +// roiN=X+Y+WxH +// memN=Offset:WxH:PitchBytes:Format +// e.g. "split:[roi1=0+0+640x480,roi2=640+0+640x480]//files:///home/user/sequence/foo%03d.jpeg" +// e.g. "split:[mem1=307200:640x480:1280:GRAY8,roi2=640+0+640x480]//files:///home/user/sequence/foo%03d.jpeg" +// e.g. "split:[stream1=2,stream2=1]//pango://video.pango" +// +// truncate - select a subregion of a video based on start and end (last index+1) index +// e.g. Generate 30 random frames: "truncate:[end=30]//test://" +// e.g. "truncate:[begin=100,end=120]" +// +// join - join streams +// e.g. "join:[sync_tolerance_us=100, sync_continuously=true]//{pleora:[sn=00000274]//}{pleora:[sn=00000275]//}" +// +// test - output test video sequence +// e.g. "test://" +// e.g. "test:[size=640x480,fmt=RGB24]//" + +#include +#include +#include +#include + +namespace pangolin +{ + +//! Open Video Interface from string specification (as described in this files header) +PANGOLIN_EXPORT +std::unique_ptr OpenVideo(const std::string& uri); + +//! Open Video Interface from Uri specification +PANGOLIN_EXPORT +std::unique_ptr OpenVideo(const Uri& uri); + +//! Open VideoOutput Interface from string specification (as described in this files header) +PANGOLIN_EXPORT +std::unique_ptr OpenVideoOutput(const std::string& str_uri); + +//! Open VideoOutput Interface from Uri specification +PANGOLIN_EXPORT +std::unique_ptr OpenVideoOutput(const Uri& uri); + +//! Create vector of matching interfaces either through direct cast or filter interface. +template +std::vector FindMatchingVideoInterfaces( VideoInterface& video ) +{ + std::vector matches; + + T* vid = dynamic_cast(&video); + if(vid) { + matches.push_back(vid); + } + + VideoFilterInterface* vidf = dynamic_cast(&video); + if(vidf) { + std::vector fmatches = vidf->FindMatchingStreams(); + matches.insert(matches.begin(), fmatches.begin(), fmatches.end()); + } + + return matches; +} + +template +T* FindFirstMatchingVideoInterface( VideoInterface& video ) +{ + T* vid = dynamic_cast(&video); + if(vid) { + return vid; + } + + VideoFilterInterface* vidf = dynamic_cast(&video); + if(vidf) { + std::vector fmatches = vidf->FindMatchingStreams(); + if(fmatches.size()) { + return fmatches[0]; + } + } + + return 0; +} + +inline +picojson::value GetVideoFrameProperties(VideoInterface* video) +{ + VideoPropertiesInterface* pi = dynamic_cast(video); + VideoFilterInterface* fi = dynamic_cast(video); + + if(pi) { + return pi->FrameProperties(); + }else if(fi){ + if(fi->InputStreams().size() == 1) { + return GetVideoFrameProperties(fi->InputStreams()[0]); + }else if(fi->InputStreams().size() > 0){ + picojson::value streams; + + for(size_t i=0; i< fi->InputStreams().size(); ++i) { + const picojson::value dev_props = GetVideoFrameProperties(fi->InputStreams()[i]); + if(dev_props.contains("streams")) { + const picojson::value& dev_streams = dev_props["streams"]; + for(size_t j=0; j < dev_streams.size(); ++j) { + streams.push_back(dev_streams[j]); + } + }else{ + streams.push_back(dev_props); + } + } + + if(streams.size() > 1) { + picojson::value json = streams[0]; + json["streams"] = streams; + return json; + }else{ + return streams[0]; + } + } + } + return picojson::value(); +} + +inline +picojson::value GetVideoDeviceProperties(VideoInterface* video) +{ + VideoPropertiesInterface* pi = dynamic_cast(video); + VideoFilterInterface* fi = dynamic_cast(video); + + if(pi) { + return pi->DeviceProperties(); + }else if(fi){ + if(fi->InputStreams().size() == 1) { + return GetVideoDeviceProperties(fi->InputStreams()[0]); + }else if(fi->InputStreams().size() > 0){ + picojson::value streams; + + for(size_t i=0; i< fi->InputStreams().size(); ++i) { + const picojson::value dev_props = GetVideoDeviceProperties(fi->InputStreams()[i]); + if(dev_props.contains("streams")) { + const picojson::value& dev_streams = dev_props["streams"]; + for(size_t j=0; j < dev_streams.size(); ++j) { + streams.push_back(dev_streams[j]); + } + }else{ + streams.push_back(dev_props); + } + } + + if(streams.size() > 1) { + picojson::value json = streams[0]; + json["streams"] = streams; + return json; + }else{ + return streams[0]; + } + } + } + return picojson::value(); +} + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/video_exception.h b/thirdparty/Pangolin/include/pangolin/video/video_exception.h new file mode 100644 index 00000000..60208c28 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/video_exception.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +namespace pangolin { + +struct PANGOLIN_EXPORT VideoException : std::exception +{ + VideoException(std::string str) : desc(str) {} + VideoException(std::string str, std::string detail) { + desc = str + "\n\t" + detail; + } + ~VideoException() throw() {} + const char* what() const throw() { return desc.c_str(); } + std::string desc; +}; + +struct PANGOLIN_EXPORT VideoExceptionNoKnownHandler : public VideoException +{ + VideoExceptionNoKnownHandler(const std::string& scheme) + : VideoException("No known video handler for URI '" + scheme + "'") + { + } +}; + +} + diff --git a/thirdparty/Pangolin/include/pangolin/video/video_input.h b/thirdparty/Pangolin/include/pangolin/video/video_input.h new file mode 100644 index 00000000..11f9ee4f --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/video_input.h @@ -0,0 +1,140 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +namespace pangolin +{ + +struct PANGOLIN_EXPORT VideoInput + : public VideoInterface, + public VideoFilterInterface +{ + ///////////////////////////////////////////////////////////// + // VideoInterface Methods + ///////////////////////////////////////////////////////////// + + size_t SizeBytes() const override; + const std::vector& Streams() const override; + void Start() override; + void Stop() override; + bool GrabNext( unsigned char* image, bool wait = true ) override; + bool GrabNewest( unsigned char* image, bool wait = true ) override; + + ///////////////////////////////////////////////////////////// + // VideoFilterInterface Methods + ///////////////////////////////////////////////////////////// + + std::vector& InputStreams() override + { + return videos; + } + + ///////////////////////////////////////////////////////////// + // VideoInput Methods + ///////////////////////////////////////////////////////////// + + VideoInput(); + VideoInput(VideoInput&& other) = default; + VideoInput(const std::string &input_uri, const std::string &output_uri = "pango:[buffer_size_mb=100]//video_log.pango"); + ~VideoInput(); + + void Open(const std::string &input_uri, const std::string &output_uri = "pango:[buffer_size_mb=100]//video_log.pango"); + void Close(); + + // experimental - not stable + bool Grab( unsigned char* buffer, std::vector >& images, bool wait = true, bool newest = false); + + // Return details of first stream + unsigned int Width() const { + return (unsigned int)Streams()[0].Width(); + } + unsigned int Height() const { + return (unsigned int)Streams()[0].Height(); + } + PixelFormat PixFormat() const { + return Streams()[0].PixFormat(); + } + const Uri& VideoUri() const { + return uri_input; + } + + void Reset() { + Close(); + Open(uri_input.full_uri, uri_output.full_uri); + } + + // Return pointer to inner video class as VideoType + template + VideoType* Cast() { + return dynamic_cast(video_src.get()); + } + + const std::string& LogFilename() const; + std::string& LogFilename(); + + // Switch to live video and record output to file + void Record(); + + // Switch to live video and record a single frame + void RecordOneFrame(); + + // Specify that one in n frames are logged to file. Default is 1. + void SetTimelapse(size_t one_in_n_frames); + + // True iff grabbed live frames are being logged to file + bool IsRecording() const; + +protected: + void InitialiseRecorder(); + + Uri uri_input; + Uri uri_output; + + std::unique_ptr video_src; + std::unique_ptr video_recorder; + + // Use to store either video_src or video_file for VideoFilterInterface, + // depending on which is active + std::vector videos; + + int buffer_size_bytes; + + int frame_num; + size_t record_frame_skip; + + bool record_once; + bool record_continuous; +}; + +// VideoInput subsumes the previous VideoRecordRepeat class. +typedef VideoInput VideoRecordRepeat; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/video_interface.h b/thirdparty/Pangolin/include/pangolin/video/video_interface.h new file mode 100755 index 00000000..f37302d7 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/video_interface.h @@ -0,0 +1,183 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +#define PANGO_HAS_TIMING_DATA "has_timing_data" +#define PANGO_HOST_RECEPTION_TIME_US "host_reception_time_us" +#define PANGO_CAPTURE_TIME_US "capture_time_us" +#define PANGO_EXPOSURE_US "exposure_us" +#define PANGO_GAMMA "gamma" +// analog gain is in linear scale and not dB +#define PANGO_ANALOG_GAIN "analog_gain" +#define PANGO_ANALOG_BLACK_LEVEL "analog_black_level" +#define PANGO_SENSOR_TEMPERATURE_C "sensor_temperature_C" +#define PANGO_ESTIMATED_CENTER_CAPTURE_TIME_US "estimated_center_capture_time_us" +#define PANGO_JOIN_OFFSET_US "join_offset_us" +#define PANGO_FRAME_COUNTER "frame_counter" + +namespace pangolin { + +//! Interface to video capture sources +struct PANGOLIN_EXPORT VideoInterface +{ + virtual ~VideoInterface() {} + + //! Required buffer size to store all frames + virtual size_t SizeBytes() const = 0; + + //! Get format and dimensions of all video streams + virtual const std::vector& Streams() const = 0; + + //! Start Video device + virtual void Start() = 0; + + //! Stop Video device + virtual void Stop() = 0; + + //! Copy the next frame from the camera to image. + //! Optionally wait for a frame if one isn't ready + //! Returns true iff image was copied + virtual bool GrabNext( unsigned char* image, bool wait = true ) = 0; + + //! Copy the newest frame from the camera to image + //! discarding all older frames. + //! Optionally wait for a frame if one isn't ready + //! Returns true iff image was copied + virtual bool GrabNewest( unsigned char* image, bool wait = true ) = 0; +}; + +//! Interface to GENICAM video capture sources +struct PANGOLIN_EXPORT GenicamVideoInterface +{ + virtual ~GenicamVideoInterface() {} + + virtual bool GetParameter(const std::string& name, std::string& result) = 0; + + virtual bool SetParameter(const std::string& name, const std::string& value) = 0; + + virtual size_t CameraCount() const + { + return 1; + } +}; + +struct PANGOLIN_EXPORT BufferAwareVideoInterface +{ + virtual ~BufferAwareVideoInterface() {} + + //! Returns number of available frames + virtual uint32_t AvailableFrames() const = 0; + + //! Drops N frames in the queue starting from the oldest + //! returns false if less than n frames arae available + virtual bool DropNFrames(uint32_t n) = 0; +}; + +struct PANGOLIN_EXPORT VideoPropertiesInterface +{ + virtual ~VideoPropertiesInterface() {} + + //! Access JSON properties of device + virtual const picojson::value& DeviceProperties() const = 0; + + //! Access JSON properties of most recently captured frame + virtual const picojson::value& FrameProperties() const = 0; +}; + +enum UvcRequestCode { + UVC_RC_UNDEFINED = 0x00, + UVC_SET_CUR = 0x01, + UVC_GET_CUR = 0x81, + UVC_GET_MIN = 0x82, + UVC_GET_MAX = 0x83, + UVC_GET_RES = 0x84, + UVC_GET_LEN = 0x85, + UVC_GET_INFO = 0x86, + UVC_GET_DEF = 0x87 +}; + +struct PANGOLIN_EXPORT VideoFilterInterface +{ + virtual ~VideoFilterInterface() {} + + template + std::vector FindMatchingStreams() + { + std::vector matches; + std::vector children = InputStreams(); + for(size_t c=0; c < children.size(); ++c) { + T* concrete_video = dynamic_cast(children[c]); + if(concrete_video) { + matches.push_back(concrete_video); + }else{ + VideoFilterInterface* filter_video = dynamic_cast(children[c]); + if(filter_video) { + std::vector child_matches = filter_video->FindMatchingStreams(); + matches.insert(matches.end(), child_matches.begin(), child_matches.end()); + } + } + } + return matches; + } + + virtual std::vector& InputStreams() = 0; +}; + +struct PANGOLIN_EXPORT VideoUvcInterface +{ + virtual ~VideoUvcInterface() {} + virtual int IoCtrl(uint8_t unit, uint8_t ctrl, unsigned char* data, int len, UvcRequestCode req_code) = 0; + virtual bool GetExposure(int& exp_us) = 0; + virtual bool SetExposure(int exp_us) = 0; + virtual bool GetGain(float& gain) = 0; + virtual bool SetGain(float gain) = 0; +}; + +struct PANGOLIN_EXPORT VideoPlaybackInterface +{ + virtual ~VideoPlaybackInterface() {} + + /// Return monotonic id of current frame + /// The 'current frame' is the frame returned from the last successful call to Grab + virtual size_t GetCurrentFrameId() const = 0; + + /// Return total number of frames to be captured from device, + /// or 0 if unknown. + virtual size_t GetTotalFrames() const = 0; + + /// Return frameid on success, or next frame on failure + virtual size_t Seek(size_t frameid) = 0; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/video_output.h b/thirdparty/Pangolin/include/pangolin/video/video_output.h new file mode 100644 index 00000000..04c79e7b --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/video_output.h @@ -0,0 +1,93 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011-2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +// Pangolin video output supports various formats using +// different 3rd party libraries. (Only one right now) +// +// VideoOutput URI's take the following form: +// scheme:[param1=value1,param2=value2,...]//device +// +// scheme = ffmpeg +// +// ffmpeg - encode to compressed file using ffmpeg +// fps : fps to embed in encoded file. +// bps : bits per second +// unique_filename : append unique suffix if file already exists +// +// e.g. ffmpeg://output_file.avi +// e.g. ffmpeg:[fps=30,bps=1000000,unique_filename]//output_file.avi + +#include +#include +#include + +namespace pangolin +{ + +//! VideoOutput wrap to generically construct instances of VideoOutputInterface. +class PANGOLIN_EXPORT VideoOutput : public VideoOutputInterface +{ +public: + VideoOutput(); + VideoOutput(VideoOutput&& other) = default; + VideoOutput(const std::string& uri); + ~VideoOutput(); + + bool IsOpen() const; + void Open(const std::string& uri); + void Close(); + + const std::vector& Streams() const override; + + void SetStreams(const std::vector& streams, const std::string& uri = "", const picojson::value& properties = picojson::value() ) override; + + int WriteStreams(const unsigned char* data, const picojson::value& frame_properties = picojson::value() ) override; + + bool IsPipe() const override; + + void AddStream(const PixelFormat& pf, size_t w,size_t h,size_t pitch); + + void AddStream(const PixelFormat& pf, size_t w,size_t h); + + void SetStreams(const std::string& uri = "", const picojson::value& properties = picojson::value() ); + + size_t SizeBytes(void) const ; + + std::vector> GetOutputImages(unsigned char* buffer) const ; + + std::vector> GetOutputImages(std::vector& buffer) const ; + + +protected: + std::vector streams; + Uri uri; + std::unique_ptr recorder; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/video_output_interface.h b/thirdparty/Pangolin/include/pangolin/video/video_output_interface.h new file mode 100644 index 00000000..efbec4d1 --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/video_output_interface.h @@ -0,0 +1,52 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011-2013 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include + +namespace pangolin { + +//! Interface to video recording destinations +struct PANGOLIN_EXPORT VideoOutputInterface +{ + virtual ~VideoOutputInterface() {} + + //! Get format and dimensions of all video streams + virtual const std::vector& Streams() const = 0; + + virtual void SetStreams(const std::vector& streams, const std::string& uri ="", const picojson::value& properties = picojson::value() ) = 0; + + virtual int WriteStreams(const unsigned char* data, const picojson::value& frame_properties = picojson::value() ) = 0; + + virtual bool IsPipe() const = 0; +}; + +} diff --git a/thirdparty/Pangolin/include/pangolin/video/video_record_repeat.h b/thirdparty/Pangolin/include/pangolin/video/video_record_repeat.h new file mode 100644 index 00000000..79e8571c --- /dev/null +++ b/thirdparty/Pangolin/include/pangolin/video/video_record_repeat.h @@ -0,0 +1,31 @@ +/* This file is part of the Pangolin Project. + * http://github.com/stevenlovegrove/Pangolin + * + * Copyright (c) 2011 Steven Lovegrove + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +// VideoInput subsumes the previous VideoRecordRepeat class. +#include diff --git a/thirdparty/Pangolin/include/tinyobj/tiny_obj_loader.h b/thirdparty/Pangolin/include/tinyobj/tiny_obj_loader.h new file mode 100644 index 00000000..d19040c0 --- /dev/null +++ b/thirdparty/Pangolin/include/tinyobj/tiny_obj_loader.h @@ -0,0 +1,2547 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-2018 Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 1.3.1 : Make ParseTextureNameAndOption API public +// version 1.3.0 : Separate warning and error message(breaking API of LoadObj) +// version 1.2.3 : Added color space extension('-colorspace') to tex opts. +// version 1.2.2 : Parse multiple group names. +// version 1.2.1 : Added initial support for line('l') primitive(PR #178) +// version 1.2.0 : Hardened implementation(#175) +// version 1.1.1 : Support smoothing groups(#162) +// version 1.1.0 : Support parsing vertex color(#144) +// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138) +// version 1.0.7 : Support multiple tex options(#126) +// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124) +// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43) +// version 1.0.4 : Support multiple filenames for 'mtllib'(#112) +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include +#include +#include + +namespace tinyobj { + +#ifdef __clang__ +#pragma clang diagnostic push +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#pragma clang diagnostic ignored "-Wpadded" + +#endif + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost real_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right +// +// TinyObjLoader extension. +// +// -colorspace SPACE # Color space of the texture. e.g. +// 'sRGB` or 'linear' +// + +#ifdef TINYOBJLOADER_USE_DOUBLE +//#pragma message "using double" +typedef double real_t; +#else +//#pragma message "using float" +typedef float real_t; +#endif + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +typedef struct { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + real_t sharpness; // -boost (default 1.0?) + real_t brightness; // base_value in -mm option (default 0) + real_t contrast; // gain_value in -mm option (default 1) + real_t origin_offset[3]; // -o u [v [w]] (default 0 0 0) + real_t scale[3]; // -s u [v [w]] (default 1 1 1) + real_t turbulence[3]; // -t u [v [w]] (default 0 0 0) + // int texture_resolution; // -texres resolution (default = ?) TODO + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + real_t bump_multiplier; // -bm (for bump maps only, default 1.0) + + // extension + std::string colorspace; // Explicitly specify color space of stored value. + // Usually `sRGB` or `linear` (default empty). +} texture_option_t; + +typedef struct { + std::string name; + + real_t ambient[3]; + real_t diffuse[3]; + real_t specular[3]; + real_t transmittance[3]; + real_t emission[3]; + real_t shininess; + real_t ior; // index of refraction + real_t dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, map_Bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + std::string reflection_texname; // refl + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + texture_option_t reflection_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + real_t roughness; // [0, 1] default 0 + real_t metallic; // [0, 1] default 0 + real_t sheen; // [0, 1] default 0 + real_t clearcoat_thickness; // [0, 1] default 0 + real_t clearcoat_roughness; // [0, 1] default 0 + real_t anisotropy; // aniso. [0, 1] default 0 + real_t anisotropy_rotation; // anisor. [0, 1] default 0 + real_t pad0; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map unknown_parameter; +} material_t; + +typedef struct { + std::string name; + + std::vector intValues; + std::vector floatValues; + std::vector stringValues; +} tag_t; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +typedef struct { + int vertex_index; + int normal_index; + int texcoord_index; +} index_t; + +typedef struct { + std::vector indices; + std::vector num_face_vertices; // The number of vertices per + // face. 3 = polygon, 4 = quad, + // ... Up to 255. + std::vector material_ids; // per-face material ID + std::vector smoothing_group_ids; // per-face smoothing group + // ID(0 = off. positive value + // = group id) + std::vector tags; // SubD tag +} mesh_t; + +typedef struct { + std::vector indices; // pairs of indices for lines +} path_t; + +typedef struct { + std::string name; + mesh_t mesh; + path_t path; +} shape_t; + +// Vertex attributes +typedef struct { + std::vector vertices; // 'v' + std::vector normals; // 'vn' + std::vector texcoords; // 'vt' + std::vector colors; // extension: vertex colors +} attrib_t; + +typedef struct callback_t_ { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, real_t x, real_t y, real_t z, real_t w); + void (*normal_cb)(void *user_data, real_t x, real_t y, real_t z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, real_t x, real_t y, real_t z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t_() + : vertex_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +} callback_t; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err) = 0; +}; + +class MaterialFileReader : public MaterialReader { + public: + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err); + + private: + std::string m_mtlBaseDir; +}; + +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err); + + private: + std::istream &m_inStream; +}; + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning message into `warn`, and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working +/// directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +/// Option 'default_vcols_fallback' specifies whether vertex colors should +/// always be defined, even if no colors are given (fallback to white). +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, const char *filename, + const char *mtl_basedir = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning message into `warn`, and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *warn = NULL, std::string *err = NULL); + +/// Loads object from a std::istream, uses GetMtlIStreamFn to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads materials into std::map +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning, std::string *err); + +/// +/// Parse texture name and texture option for custom texture parameter through material::unknown_parameter +/// +/// @param[out] texname Parsed texture name +/// @param[out] texopt Parsed texopt +/// @param[in] linebuf Input string +/// @param[in] is_bump Is this texture bump/normal? +/// +bool ParseTextureNameAndOption(std::string *texname, + texture_option_t *texopt, + const char *linebuf, + const bool is_bump); +} // namespace tinyobj + +#endif // TINY_OBJ_LOADER_H_ + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +struct vertex_index_t { + int v_idx, vt_idx, vn_idx; + vertex_index_t() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index_t(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index_t(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +// Internal data structure for face representation +// index + smoothing group. +struct face_t { + unsigned int + smoothing_group_id; // smoothing group id. 0 = smoothing groupd is off. + int pad_; + std::vector vertex_indices; // face vertex indices. + + face_t() : smoothing_group_id(0) {} +}; + +struct line_t { + int idx0; + int idx1; +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {} + int num_ints; + int num_reals; + int num_strings; +}; + +struct obj_shape { + std::vector v; + std::vector vn; + std::vector vt; +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +static std::istream &safeGetline(std::istream &is, std::string &t) { + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf *sb = is.rdbuf(); + + if (se) { + for (;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if (sb->sgetc() == '\n') sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if (t.empty()) is.setstate(std::ios::eofbit); + return is; + default: + t += static_cast(c); + } + } + } + + return is; +} + +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast((x) - '0') < static_cast(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +// Make index zero-base, and also support relative index. +static inline bool fixIndex(int idx, int n, int *ret) { + if (!ret) { + return false; + } + + if (idx > 0) { + (*ret) = idx - 1; + return true; + } + + if (idx == 0) { + // zero is not allowed according to the spec. + return false; + } + + if (idx < 0) { + (*ret) = n + idx; // negative value = relative + return true; + } + + return false; // never reach here. +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : std::pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + exponent *= 10; + exponent += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = (sign == '+' ? 1 : -1) * + (exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent) + : mantissa); + return true; +fail: + return false; +} + +static inline real_t parseReal(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + real_t f = static_cast(val); + (*token) = end; + return f; +} + +static inline bool parseReal(const char **token, real_t *out) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val; + bool ret = tryParseDouble((*token), end, &val); + if (ret) { + real_t f = static_cast(val); + (*out) = f; + } + (*token) = end; + return ret; +} + +static inline void parseReal2(real_t *x, real_t *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); +} + +static inline void parseReal3(real_t *x, real_t *y, real_t *z, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); +} + +static inline void parseV(real_t *x, real_t *y, real_t *z, real_t *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + (*w) = parseReal(token, default_w); +} + +// Extension: parse vertex with colors(6 items) +static inline bool parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + const char **token, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + + const bool found_color = + parseReal(token, r) && parseReal(token, g) && parseReal(token, b); + + if (!found_color) { + (*r) = (*g) = (*b) = 1.0; + } + + return found_color; +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + (*token) += strspn((*token), " \t"); + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + + (*token)++; // Skip '/' + + (*token) += strspn((*token), " \t"); + ts.num_reals = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; // Skip '/' + + ts.num_strings = parseInt(token); + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize, + vertex_index_t *ret) { + if (!ret) { + return false; + } + + vertex_index_t vi(-1); + + if (!fixIndex(atoi((*token)), vsize, &(vi.v_idx))) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + if (!fixIndex(atoi((*token)), vnsize, &(vi.vn_idx))) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + (*ret) = vi; + return true; + } + + // i/j/k or i/j + if (!fixIndex(atoi((*token)), vtsize, &(vi.vt_idx))) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + + // i/j/k + (*token)++; // skip '/' + if (!fixIndex(atoi((*token)), vnsize, &(vi.vn_idx))) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + + (*ret) = vi; + + return true; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index_t parseRawTriple(const char **token) { + vertex_index_t vi(static_cast(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +bool ParseTextureNameAndOption(std::string *texname, + texture_option_t *texopt, + const char *linebuf, const bool is_bump) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + // Fill with default value for texopt. + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = static_cast(1.0); + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = static_cast(1.0); + texopt->brightness = static_cast(0.0); + texopt->contrast = static_cast(1.0); + texopt->origin_offset[0] = static_cast(0.0); + texopt->origin_offset[1] = static_cast(0.0); + texopt->origin_offset[2] = static_cast(0.0); + texopt->scale[0] = static_cast(1.0); + texopt->scale[1] = static_cast(1.0); + texopt->scale[2] = static_cast(1.0); + texopt->turbulence[0] = static_cast(0.0); + texopt->turbulence[1] = static_cast(0.0); + texopt->turbulence[2] = static_cast(0.0); + texopt->type = TEXTURE_TYPE_NONE; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + token += strspn(token, " \t"); // skip space + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseReal2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else if ((0 == strncmp(token, "-colorspace", 11)) && + IS_SPACE((token[11]))) { + token += 12; + texopt->colorspace = parseString(&token); + } else { +// Assume texture filename +#if 0 + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space +#else + // Read filename until line end to parse filename containing whitespace + // TODO(syoyo): Support parsing texture option flag after the filename. + texture_name = std::string(token); + token += texture_name.length(); +#endif + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitMaterial(material_t *material) { + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->reflection_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = static_cast(0.0); + material->diffuse[i] = static_cast(0.0); + material->specular[i] = static_cast(0.0); + material->transmittance[i] = static_cast(0.0); + material->emission[i] = static_cast(0.0); + } + material->illum = 0; + material->dissolve = static_cast(1.0); + material->shininess = static_cast(1.0); + material->ior = static_cast(1.0); + + material->roughness = static_cast(0.0); + material->metallic = static_cast(0.0); + material->sheen = static_cast(0.0); + material->clearcoat_thickness = static_cast(0.0); + material->clearcoat_roughness = static_cast(0.0); + material->anisotropy_rotation = static_cast(0.0); + material->anisotropy = static_cast(0.0); + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +// code from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html +template +static int pnpoly(int nvert, T *vertx, T *verty, T testx, T testy) { + int i, j, c = 0; + for (i = 0, j = nvert - 1; i < nvert; j = i++) { + if (((verty[i] > testy) != (verty[j] > testy)) && + (testx < + (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + + vertx[i])) + c = !c; + } + return c; +} + +// TODO(syoyo): refactor function. +static bool exportGroupsToShape(shape_t *shape, + const std::vector &faceGroup, + std::vector &lineGroup, + const std::vector &tags, + const int material_id, const std::string &name, + bool triangulate, + const std::vector &v) { + if (faceGroup.empty() && lineGroup.empty()) { + return false; + } + + if (!faceGroup.empty()) { + // Flatten vertices and indices + for (size_t i = 0; i < faceGroup.size(); i++) { + const face_t &face = faceGroup[i]; + + size_t npolys = face.vertex_indices.size(); + + if (npolys < 3) { + // Face must have 3+ vertices. + continue; + } + + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i1(-1); + vertex_index_t i2 = face.vertex_indices[1]; + + if (triangulate) { + // find the two axes to work in + size_t axes[2] = {1, 2}; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[(k + 0) % npolys]; + i1 = face.vertex_indices[(k + 1) % npolys]; + i2 = face.vertex_indices[(k + 2) % npolys]; + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + + if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) || + ((3 * vi2 + 2) >= v.size())) { + // Invalid triangle. + // FIXME(syoyo): Is it ok to simply skip this invalid triangle? + continue; + } + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + real_t v1x = v[vi1 * 3 + 0]; + real_t v1y = v[vi1 * 3 + 1]; + real_t v1z = v[vi1 * 3 + 2]; + real_t v2x = v[vi2 * 3 + 0]; + real_t v2y = v[vi2 * 3 + 1]; + real_t v2z = v[vi2 * 3 + 2]; + real_t e0x = v1x - v0x; + real_t e0y = v1y - v0y; + real_t e0z = v1z - v0z; + real_t e1x = v2x - v1x; + real_t e1y = v2y - v1y; + real_t e1z = v2z - v1z; + real_t cx = std::fabs(e0y * e1z - e0z * e1y); + real_t cy = std::fabs(e0z * e1x - e0x * e1z); + real_t cz = std::fabs(e0x * e1y - e0y * e1x); + const real_t epsilon = std::numeric_limits::epsilon(); + if (cx > epsilon || cy > epsilon || cz > epsilon) { + // found a corner + if (cx > cy && cx > cz) { + } else { + axes[0] = 0; + if (cz > cx && cz > cy) axes[1] = 1; + } + break; + } + } + + real_t area = 0; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[(k + 0) % npolys]; + i1 = face.vertex_indices[(k + 1) % npolys]; + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + if (((vi0 * 3 + axes[0]) >= v.size()) || + ((vi0 * 3 + axes[1]) >= v.size()) || + ((vi1 * 3 + axes[0]) >= v.size()) || + ((vi1 * 3 + axes[1]) >= v.size())) { + // Invalid index. + continue; + } + real_t v0x = v[vi0 * 3 + axes[0]]; + real_t v0y = v[vi0 * 3 + axes[1]]; + real_t v1x = v[vi1 * 3 + axes[0]]; + real_t v1y = v[vi1 * 3 + axes[1]]; + area += (v0x * v1y - v0y * v1x) * static_cast(0.5); + } + + int maxRounds = 10; // arbitrary max loop count to protect against + // unexpected errors + + face_t remainingFace = face; // copy + size_t guess_vert = 0; + vertex_index_t ind[3]; + real_t vx[3]; + real_t vy[3]; + while (remainingFace.vertex_indices.size() > 3 && maxRounds > 0) { + npolys = remainingFace.vertex_indices.size(); + if (guess_vert >= npolys) { + maxRounds -= 1; + guess_vert -= npolys; + } + for (size_t k = 0; k < 3; k++) { + ind[k] = remainingFace.vertex_indices[(guess_vert + k) % npolys]; + size_t vi = size_t(ind[k].v_idx); + if (((vi * 3 + axes[0]) >= v.size()) || + ((vi * 3 + axes[1]) >= v.size())) { + // ??? + vx[k] = static_cast(0.0); + vy[k] = static_cast(0.0); + } else { + vx[k] = v[vi * 3 + axes[0]]; + vy[k] = v[vi * 3 + axes[1]]; + } + } + real_t e0x = vx[1] - vx[0]; + real_t e0y = vy[1] - vy[0]; + real_t e1x = vx[2] - vx[1]; + real_t e1y = vy[2] - vy[1]; + real_t cross = e0x * e1y - e0y * e1x; + // if an internal angle + if (cross * area < static_cast(0.0)) { + guess_vert += 1; + continue; + } + + // check all other verts in case they are inside this triangle + bool overlap = false; + for (size_t otherVert = 3; otherVert < npolys; ++otherVert) { + size_t idx = (guess_vert + otherVert) % npolys; + + if (idx >= remainingFace.vertex_indices.size()) { + // ??? + continue; + } + + size_t ovi = size_t(remainingFace.vertex_indices[idx].v_idx); + + if (((ovi * 3 + axes[0]) >= v.size()) || + ((ovi * 3 + axes[1]) >= v.size())) { + // ??? + continue; + } + real_t tx = v[ovi * 3 + axes[0]]; + real_t ty = v[ovi * 3 + axes[1]]; + if (pnpoly(3, vx, vy, tx, ty)) { + overlap = true; + break; + } + } + + if (overlap) { + guess_vert += 1; + continue; + } + + // this triangle is an ear + { + index_t idx0, idx1, idx2; + idx0.vertex_index = ind[0].v_idx; + idx0.normal_index = ind[0].vn_idx; + idx0.texcoord_index = ind[0].vt_idx; + idx1.vertex_index = ind[1].v_idx; + idx1.normal_index = ind[1].vn_idx; + idx1.texcoord_index = ind[1].vt_idx; + idx2.vertex_index = ind[2].v_idx; + idx2.normal_index = ind[2].vn_idx; + idx2.texcoord_index = ind[2].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + } + + // remove v1 from the list + size_t removed_vert_index = (guess_vert + 1) % npolys; + while (removed_vert_index + 1 < npolys) { + remainingFace.vertex_indices[removed_vert_index] = + remainingFace.vertex_indices[removed_vert_index + 1]; + removed_vert_index += 1; + } + remainingFace.vertex_indices.pop_back(); + } + + if (remainingFace.vertex_indices.size() == 3) { + i0 = remainingFace.vertex_indices[0]; + i1 = remainingFace.vertex_indices[1]; + i2 = remainingFace.vertex_indices[2]; + { + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + } + } + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face.vertex_indices[k].v_idx; + idx.normal_index = face.vertex_indices[k].vn_idx; + idx.texcoord_index = face.vertex_indices[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); // per face + } + } + + shape->name = name; + shape->mesh.tags = tags; + } + + if (!lineGroup.empty()) { + shape->path.indices.swap(lineGroup); + } + + return true; +} + +// Split a string with specified delimiter character. +// http://stackoverflow.com/questions/236129/split-a-string-in-c +static void SplitString(const std::string &s, char delim, + std::vector &elems) { + std::stringstream ss; + ss.str(s); + std::string item; + while (std::getline(ss, item, delim)) { + elems.push_back(item); + } +} + +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning, std::string *err) { + (void)err; + + // Create a default material anyway. + material_t material; + InitMaterial(&material); + + // Issue 43. `d` wins against `Tr` since `Tr` is not in the MTL specification. + bool has_d = false; + bool has_tr = false; + + std::stringstream warn_ss; + + size_t line_no = 0; + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + line_no++; + + // Trim trailing whitespace. + if (linebuf.size() > 0) { + linebuf = linebuf.substr(0, linebuf.find_last_not_of(" \t") + 1); + } + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // new mtl + if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + // initial temporary material + InitMaterial(&material); + + has_d = false; + has_tr = false; + + // set new mtl name + token += 7; + { + std::stringstream sstr; + sstr << token; + material.name = sstr.str(); + } + continue; + } + + // ambient + if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + continue; + } + + // diffuse + if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + continue; + } + + // specular + if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + continue; + } + + // transmittance + if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) || + (token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + continue; + } + + // ior(index of refraction) + if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) { + token += 2; + material.ior = parseReal(&token); + continue; + } + + // emission + if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + continue; + } + + // shininess + if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.shininess = parseReal(&token); + continue; + } + + // illum model + if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) { + token += 6; + material.illum = parseInt(&token); + continue; + } + + // dissolve + if ((token[0] == 'd' && IS_SPACE(token[1]))) { + token += 1; + material.dissolve = parseReal(&token); + + if (has_tr) { + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name << "\". Use the value of `d` for dissolve (line " + << line_no << " in .mtl.)" + << std::endl; + } + has_d = true; + continue; + } + if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + if (has_d) { + // `d` wins. Ignore `Tr` value. + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name << "\". Use the value of `d` for dissolve (line " + << line_no << " in .mtl.)" + << std::endl; + } else { + // We invert value of Tr(assume Tr is in range [0, 1]) + // NOTE: Interpretation of Tr is application(exporter) dependent. For + // some application(e.g. 3ds max obj exporter), Tr = d(Issue 43) + material.dissolve = static_cast(1.0) - parseReal(&token); + } + has_tr = true; + continue; + } + + // PBR: roughness + if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + material.roughness = parseReal(&token); + continue; + } + + // PBR: metallic + if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) { + token += 2; + material.metallic = parseReal(&token); + continue; + } + + // PBR: sheen + if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.sheen = parseReal(&token); + continue; + } + + // PBR: clearcoat thickness + if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) { + token += 2; + material.clearcoat_thickness = parseReal(&token); + continue; + } + + // PBR: clearcoat roughness + if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) { + token += 4; + material.clearcoat_roughness = parseReal(&token); + continue; + } + + // PBR: anisotropy + if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) { + token += 6; + material.anisotropy = parseReal(&token); + continue; + } + + // PBR: anisotropy rotation + if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) { + token += 7; + material.anisotropy_rotation = parseReal(&token); + continue; + } + + // ambient texture + if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), token, + /* is_bump */ false); + continue; + } + + // diffuse texture + if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), token, + /* is_bump */ false); + continue; + } + + // specular texture + if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), token, + /* is_bump */ false); + continue; + } + + // specular highlight texture + if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), token, + /* is_bump */ false); + continue; + } + + // bump texture + if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // bump texture + if ((0 == strncmp(token, "map_Bump", 8)) && IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // bump texture + if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // alpha texture + if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) { + token += 6; + material.alpha_texname = token; + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), token, + /* is_bump */ false); + continue; + } + + // displacement texture + if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), token, + /* is_bump */ false); + continue; + } + + // reflection map + if ((0 == strncmp(token, "refl", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.reflection_texname), + &(material.reflection_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: roughness texture + if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: metallic texture + if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: sheen texture + if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: emissive texture + if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: normal map texture + if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption( + &(material.normal_texname), &(material.normal_texopt), token, + /* is_bump */ false); // @fixme { is_bump will be true? } + continue; + } + + // unknown parameter + const char *_space = strchr(token, ' '); + if (!_space) { + _space = strchr(token, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - token; + std::string key(token, static_cast(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair(key, value)); + } + } + // flush last material. + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + + if (warning) { + (*warning) = warn_ss.str(); + } +} + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *warn, std::string *err) { + std::string filepath; + + if (!m_mtlBaseDir.empty()) { + filepath = std::string(m_mtlBaseDir) + matId; + } else { + filepath = matId; + } + + std::ifstream matIStream(filepath.c_str()); + if (!matIStream) { + std::stringstream ss; + ss << "Material file [ " << filepath << " ] not found." << std::endl; + if (warn) { + (*warn) += ss.str(); + } + return false; + } + + LoadMtl(matMap, materials, &matIStream, warn, err); + + return true; +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *warn, std::string *err) { + (void)err; + (void)matId; + if (!m_inStream) { + std::stringstream ss; + ss << "Material stream in error state. " << std::endl; + if (warn) { + (*warn) += ss.str(); + } + return false; + } + + LoadMtl(matMap, materials, &m_inStream, warn, err); + + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, const char *filename, const char *mtl_basedir, + bool trianglulate, bool default_vcols_fallback) { + attrib->vertices.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + attrib->colors.clear(); + shapes->clear(); + + std::stringstream errss; + + std::ifstream ifs(filename); + if (!ifs) { + errss << "Cannot open file [" << filename << "]" << std::endl; + if (err) { + (*err) = errss.str(); + } + return false; + } + + std::string baseDir = mtl_basedir ? mtl_basedir : ""; + if (!baseDir.empty()) { +#ifndef _WIN32 + const char dirsep = '/'; +#else + const char dirsep = '\\'; +#endif + if (baseDir[baseDir.length() - 1] != dirsep) baseDir += dirsep; + } + MaterialFileReader matFileReader(baseDir); + + return LoadObj(attrib, shapes, materials, warn, err, &ifs, &matFileReader, + trianglulate, default_vcols_fallback); +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn /*= NULL*/, bool triangulate, + bool default_vcols_fallback) { + std::stringstream errss; + + std::vector v; + std::vector vn; + std::vector vt; + std::vector vc; + std::vector tags; + std::vector faceGroup; + std::vector lineGroup; + std::string name; + + // material + std::map material_map; + int material = -1; + + // smoothing group id + unsigned int current_smoothing_id = + 0; // Initial value. 0 means no smoothing. + + int greatest_v_idx = -1; + int greatest_vn_idx = -1; + int greatest_vt_idx = -1; + + shape_t shape; + + bool found_all_colors = true; + + size_t line_num = 0; + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + line_num++; + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + real_t x, y, z; + real_t r, g, b; + + found_all_colors &= parseVertexWithColor(&x, &y, &z, &r, &g, &b, &token); + + v.push_back(x); + v.push_back(y); + v.push_back(z); + + if (found_all_colors || default_vcols_fallback) { + vc.push_back(r); + vc.push_back(g); + vc.push_back(b); + } + + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; + parseReal3(&x, &y, &z, &token); + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y; + parseReal2(&x, &y, &token); + vt.push_back(x); + vt.push_back(y); + continue; + } + + // line + if (token[0] == 'l' && IS_SPACE((token[1]))) { + token += 2; + + line_t line_cache; + bool end_line_bit = 0; + while (!IS_NEW_LINE(token[0])) { + // get index from string + int idx = 0; + fixIndex(parseInt(&token), 0, &idx); + + size_t n = strspn(token, " \t\r"); + token += n; + + if (!end_line_bit) { + line_cache.idx0 = idx; + } else { + line_cache.idx1 = idx; + lineGroup.push_back(line_cache.idx0); + lineGroup.push_back(line_cache.idx1); + line_cache = line_t(); + } + end_line_bit = !end_line_bit; + } + + continue; + } + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + face_t face; + + face.smoothing_group_id = current_smoothing_id; + face.vertex_indices.reserve(3); + + while (!IS_NEW_LINE(token[0])) { + vertex_index_t vi; + if (!parseTriple(&token, static_cast(v.size() / 3), + static_cast(vn.size() / 3), + static_cast(vt.size() / 2), &vi)) { + if (err) { + std::stringstream ss; + ss << "Failed parse `f' line(e.g. zero value for face index. line " << line_num << ".)\n"; + (*err) += ss.str(); + } + return false; + } + + greatest_v_idx = greatest_v_idx > vi.v_idx ? greatest_v_idx : vi.v_idx; + greatest_vn_idx = + greatest_vn_idx > vi.vn_idx ? greatest_vn_idx : vi.vn_idx; + greatest_vt_idx = + greatest_vt_idx > vi.vt_idx ? greatest_vt_idx : vi.vt_idx; + + face.vertex_indices.push_back(vi); + size_t n = strspn(token, " \t\r"); + token += n; + } + + // replace with emplace_back + std::move on C++11 + faceGroup.push_back(face); + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + token += 7; + std::stringstream ss; + ss << token; + std::string namebuf = ss.str(); + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material) { + // Create per-face material. Thus we don't add `shape` to `shapes` at + // this time. + // just clear `faceGroup` after `exportGroupsToShape()` call. + exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name, + triangulate, v); + faceGroup.clear(); + material = newMaterialId; + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + token += 7; + + std::vector filenames; + SplitString(std::string(token), ' ', filenames); + + if (filenames.empty()) { + if (warn) { + std::stringstream ss; + ss << "Looks like empty filename for mtllib. Use default " + "material (line " << line_num << ".)\n"; + + (*warn) += ss.str(); + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + std::string warn_mtl; + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), materials, + &material_map, &warn_mtl, &err_mtl); + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + if (ok) { + found = true; + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, + material, name, triangulate, v); + (void)ret; // return value not used. + + if (shape.mesh.indices.size() > 0) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + faceGroup.clear(); + + std::vector names; + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + // names[0] must be 'g' + + if (names.size() < 2) { + // 'g' with empty names + if (warn) { + std::stringstream ss; + ss << "Empty group name. line: " << line_num << "\n"; + (*warn) += ss.str(); + name = ""; + } + } else { + std::stringstream ss; + ss << names[1]; + + // tinyobjloader does not support multiple groups for a primitive. + // Currently we concatinate multiple group names with a space to get + // single group name. + + for (size_t i = 2; i < names.size(); i++) { + ss << " " << names[i]; + } + + name = ss.str(); + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, + material, name, triangulate, v); + if (ret) { + shapes->push_back(shape); + } + + // material = -1; + faceGroup.clear(); + shape = shape_t(); + + // @todo { multiple object name? } + token += 2; + std::stringstream ss; + ss << token; + name = ss.str(); + + continue; + } + + if (token[0] == 't' && IS_SPACE(token[1])) { + const int max_tag_nums = 8192; // FIXME(syoyo): Parameterize. + tag_t tag; + + token += 2; + + tag.name = parseString(&token); + + tag_sizes ts = parseTagTriple(&token); + + if (ts.num_ints < 0) { + ts.num_ints = 0; + } + if (ts.num_ints > max_tag_nums) { + ts.num_ints = max_tag_nums; + } + + if (ts.num_reals < 0) { + ts.num_reals = 0; + } + if (ts.num_reals > max_tag_nums) { + ts.num_reals = max_tag_nums; + } + + if (ts.num_strings < 0) { + ts.num_strings = 0; + } + if (ts.num_strings > max_tag_nums) { + ts.num_strings = max_tag_nums; + } + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = parseInt(&token); + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = parseReal(&token); + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + tag.stringValues[i] = parseString(&token); + } + + tags.push_back(tag); + + continue; + } + + if (token[0] == 's' && IS_SPACE(token[1])) { + // smoothing group id + token += 2; + + // skip space. + token += strspn(token, " \t"); // skip space + + if (token[0] == '\0') { + continue; + } + + if (token[0] == '\r' || token[1] == '\n') { + continue; + } + + if (strlen(token) >= 3) { + if (token[0] == 'o' && token[1] == 'f' && token[2] == 'f') { + current_smoothing_id = 0; + } + } else { + // assume number + int smGroupId = parseInt(&token); + if (smGroupId < 0) { + // parse error. force set to 0. + // FIXME(syoyo): Report warning. + current_smoothing_id = 0; + } else { + current_smoothing_id = static_cast(smGroupId); + } + } + + continue; + } // smoothing group id + + // Ignore unknown command. + } + + // not all vertices have colors, no default colors desired? -> clear colors + if (!found_all_colors && !default_vcols_fallback) { + vc.clear(); + } + + if (greatest_v_idx >= static_cast(v.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex indices out of bounds (line " << line_num << ".)\n" << std::endl; + (*warn) += ss.str(); + } + } + if (greatest_vn_idx >= static_cast(vn.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex normal indices out of bounds (line " << line_num << ".)\n" << std::endl; + (*warn) += ss.str(); + } + } + if (greatest_vt_idx >= static_cast(vt.size() / 2)) { + if (warn) { + std::stringstream ss; + ss << "Vertex texcoord indices out of bounds (line " << line_num << ".)\n" << std::endl; + (*warn) += ss.str(); + } + } + + bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, + name, triangulate, v); + // exportGroupsToShape return false when `usemtl` is called in the last + // line. + // we also add `shape` to `shapes` when `shape.mesh` has already some + // faces(indices) + if (ret || shape.mesh.indices.size()) { + shapes->push_back(shape); + } + faceGroup.clear(); // for safety + + if (err) { + (*err) += errss.str(); + } + + attrib->vertices.swap(v); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + attrib->colors.swap(vc); + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *warn, /* = NULL*/ + std::string *err /*= NULL*/) { + std::stringstream errss; + + // material + std::map material_map; + int material_id = -1; // -1 = invalid + + std::vector indices; + std::vector materials; + std::vector names; + names.reserve(2); + std::vector names_out; + + std::string linebuf; + while (inStream.peek() != -1) { + safeGetline(inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + // TODO(syoyo): Support parsing vertex color extension. + real_t x, y, z, w; // w is optional. default = 1.0 + parseV(&x, &y, &z, &w, &token); + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, w); + } + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; + parseReal3(&x, &y, &z, &token); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; // y and z are optional. default = 0.0 + parseReal3(&x, &y, &z, &token); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + indices.clear(); + while (!IS_NEW_LINE(token[0])) { + vertex_index_t vi = parseRawTriple(&token); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + size_t n = strspn(token, " \t\r"); + token += n; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast(indices.size())); + } + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + token += 7; + std::stringstream ss; + ss << token; + std::string namebuf = ss.str(); + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf.c_str(), material_id); + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + token += 7; + + std::vector filenames; + SplitString(std::string(token), ' ', filenames); + + if (filenames.empty()) { + if (warn) { + (*warn) += + "Looks like empty filename for mtllib. Use default " + "material. \n"; + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + std::string warn_mtl; + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), &materials, + &material_map, &warn_mtl, &err_mtl); + + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; // This should be warn message. + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + if (ok) { + found = true; + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } else { + if (callback.mtllib_cb) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast(materials.size())); + } + } + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + names.clear(); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + if (callback.group_cb) { + if (names.size() > 1) { + // create const char* array. + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // @todo { multiple object name? } + token += 2; + + std::stringstream ss; + ss << token; + std::string object_name = ss.str(); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + continue; + } + +#if 0 // @todo + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + token += 2; + std::stringstream ss; + ss << token; + tag.name = ss.str(); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = parseReal(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + std::stringstream ss; + ss << token; + tag.stringValues[i] = ss.str(); + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + } + + if (err) { + (*err) += errss.str(); + } + + return true; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} // namespace tinyobj + +#endif diff --git a/thirdparty/Pangolin/package.xml b/thirdparty/Pangolin/package.xml new file mode 100644 index 00000000..8e936d17 --- /dev/null +++ b/thirdparty/Pangolin/package.xml @@ -0,0 +1,16 @@ + + + pangolin + 0.5.0 + pangolin + Steven Lovegrove + Steven Lovegrove + MIT + cmake + libglew-dev + cmake + python + + cmake + + diff --git a/thirdparty/Pangolin/pyexamples/SimpleDisplay.py b/thirdparty/Pangolin/pyexamples/SimpleDisplay.py new file mode 100644 index 00000000..8a1155da --- /dev/null +++ b/thirdparty/Pangolin/pyexamples/SimpleDisplay.py @@ -0,0 +1,48 @@ +import sys +sys.path.append('../build/src') + +import pypangolin as pango +from OpenGL.GL import * + +def a_callback(): + print("a pressed") + +def main(): + win = pango.CreateWindowAndBind("pySimpleDisplay", 640, 480) + glEnable(GL_DEPTH_TEST) + + pm = pango.ProjectionMatrix(640,480,420,420,320,240,0.1,1000); + mv = pango.ModelViewLookAt(-0, 0.5, -3, 0, 0, 0, pango.AxisY) + s_cam = pango.OpenGlRenderState(pm, mv) + + ui_width = 180 + + handler=pango.Handler3D(s_cam) + d_cam = pango.CreateDisplay().SetBounds(pango.Attach(0), + pango.Attach(1), + pango.Attach.Pix(ui_width), + pango.Attach(1), + -640.0/480.0).SetHandler(handler) + + pango.CreatePanel("ui").SetBounds( pango.Attach(0), + pango.Attach(1), + pango.Attach(0), + pango.Attach.Pix(ui_width)) + var_ui=pango.Var("ui") + var_ui.A_Button=False + var_ui.B_Button=True + var_ui.B_Double=1 + var_ui.B_Str="sss" + + ctrl=-96 + pango.RegisterKeyPressCallback(ctrl+ord('a'), a_callback) + + while not pango.ShouldQuit(): + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + d_cam.Activate(s_cam) + pango.glDrawColouredCube() + pango.FinishFrame() + + +if __name__ == "__main__": + main() diff --git a/thirdparty/Pangolin/pyexamples/SimplePlot.py b/thirdparty/Pangolin/pyexamples/SimplePlot.py new file mode 100644 index 00000000..a168988d --- /dev/null +++ b/thirdparty/Pangolin/pyexamples/SimplePlot.py @@ -0,0 +1,35 @@ +import sys +sys.path.append('../build/src') + +from OpenGL.GL import * +import pypangolin as pango +import math + +def main(): + win = pango.CreateWindowAndBind("main py_pangolin", 640, 480) + log = pango.DataLog() + log.SetLabels(["sin(t)", "cos(t)", "sin(t)+cos(t)"]) + + t=0; + tinc=0.01 + + plotter = pango.Plotter(log,0,4*math.pi/tinc,-2,2,math.pi/(4*tinc),0.5); + plotter.Track("$i") + plotter.AddMarker(pango.Marker.Vertical, -1000, pango.Marker.LessThan, pango.Colour.Blue().WithAlpha(0.2)) + plotter.AddMarker(pango.Marker.Horizontal, 100, pango.Marker.GreaterThan, pango.Colour.Red().WithAlpha(0.2)) + plotter.AddMarker(pango.Marker.Horizontal, 10, pango.Marker.Equal, pango.Colour.Green().WithAlpha(0.2)) + plotter.SetBounds(pango.Attach(0), pango.Attach(1), + pango.Attach(0), pango.Attach(1)) + + pango.DisplayBase().AddDisplay(plotter) + + while not pango.ShouldQuit(): + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + + log.Log(math.sin(t), math.cos(t), math.sin(t)+math.cos(t)) + t+=tinc + + pango.FinishFrame() + +if __name__ == "__main__": + main() diff --git a/thirdparty/Pangolin/pyexamples/SimpleVideo.py b/thirdparty/Pangolin/pyexamples/SimpleVideo.py new file mode 100644 index 00000000..5e7ceb8a --- /dev/null +++ b/thirdparty/Pangolin/pyexamples/SimpleVideo.py @@ -0,0 +1,57 @@ +import sys +import os +import argparse +import numpy as np +import time +import json + +# If this example doesn't work, it's probably because this path is wrong... +sys.path.append('../build/src') + +import pypangolin as pango + +def main(flags): + vid_uri = flags.pango + vout_uri = flags.pangoOut + + vid = pango.VideoInput(vid_uri) + vout = pango.VideoOutput(vout_uri) if vout_uri else None + + device_properties = vid.DeviceProperties() + + # print metadata + print("Opened video uri: '{}' with {} x {} dimensions".format( vid_uri,vid.Width(),vid.Height())) + + # user specified initial frame + vid.Seek(flags.startFrame) + + # show each frame + streamsBitDepth = vid.GetStreamsBitDepth() + + for frame in vid: + if vout: + vout.WriteStreams(frame, streamsBitDepth, vid.FrameProperties(), device_properties); + + # frame is a list of Images! One per stream + # process(frame) + + # printing + sys.stdout.write('\rframe: {} / {}'.format(vid.GetCurrentFrameId(), vid.GetTotalFrames())) + + print('\nDONE') + +if __name__ == "__main__": + # input flags + parser = argparse.ArgumentParser('Read a .pango file frame by frame. Optionally stream to another video output.') + parser.add_argument( + '--pango', type=str, + help='path to the input pango file.') + parser.add_argument( + '--startFrame', type=int, default=0, + help='index of the start frame (inclusive)') + parser.add_argument( + '--pangoOut', type=str, default=None, + help='path to the output pango file.') + + # main function + main(parser.parse_args()) diff --git a/thirdparty/Pangolin/src/CMakeLists.txt b/thirdparty/Pangolin/src/CMakeLists.txt new file mode 100644 index 00000000..26b188ec --- /dev/null +++ b/thirdparty/Pangolin/src/CMakeLists.txt @@ -0,0 +1,770 @@ +####################################################### +## Library sources + +macro( append_glob list glob ) + file(GLOB files ${glob}) + set(${list} "${${list}};${files}") +endmacro() + +## Header only includes / core headers +set( INCDIR "../include/pangolin" ) +set( HEADERS + ${INCDIR}/pangolin.h + ${INCDIR}/platform.h +) +append_glob(HEADERS ${INCDIR}/utils/*.h*) +append_glob(HEADERS ${INCDIR}/image/*.h*) +append_glob(HEADERS ${INCDIR}/log/*.h*) +append_glob(HEADERS ${INCDIR}/geometry/*.h*) + +### Store list of source files +append_glob(SOURCES utils/*.cpp) +append_glob(SOURCES image/*.cpp) +append_glob(SOURCES log/*.cpp) +append_glob(SOURCES geometry/*.cpp) + +### Store list of Video factory registery methods to call for init. +include(CreateMethodCallFile) +set( VIDEO_FACTORY_REG "" ) +set( WINDOW_FACTORY_REG "" ) + +####################################################### +## User build options + +option(BUILD_PANGOLIN_GUI "Build support for Pangolin GUI" ON) +if(BUILD_PANGOLIN_GUI) + append_glob(HEADERS ${INCDIR}/gl/*.h*) + append_glob(HEADERS ${INCDIR}/display/*.h*) + append_glob(HEADERS ${INCDIR}/handler/*.h*) + + append_glob(SOURCES gl/*.cpp) + append_glob(SOURCES display/*.cpp) + append_glob(SOURCES handler/*.cpp) + + if(NOT HAVE_GLES OR HAVE_GLES_2) + append_glob(HEADERS ${INCDIR}/plot/*.h*) + append_glob(SOURCES plot/*.cpp) + endif() + +endif() + +option(BUILD_PANGOLIN_VARS "Build support for Pangolin Vars" ON) +if(BUILD_PANGOLIN_VARS) + append_glob(HEADERS ${INCDIR}/var/*.h*) + append_glob(SOURCES var/*.cpp) + + if(BUILD_PANGOLIN_GUI) + list(APPEND HEADERS ${INCDIR}/display/widgets/widgets.h ) + list(APPEND SOURCES display/widgets/widgets.cpp ) + endif() +endif() + +option(BUILD_PANGOLIN_VIDEO "Build support for Pangolin Video Utilities" ON) +if(BUILD_PANGOLIN_VIDEO) + # Generic video includes + append_glob(HEADERS ${INCDIR}/video/*.h*) + append_glob(SOURCES video/*.cpp) + + # Generic video drivers + list(APPEND HEADERS + ${INCDIR}/video/drivers/test.h + ${INCDIR}/video/drivers/images.h + ${INCDIR}/video/drivers/images_out.h + ${INCDIR}/video/drivers/split.h + ${INCDIR}/video/drivers/truncate.h + ${INCDIR}/video/drivers/pvn.h + ${INCDIR}/video/drivers/pango.h + ${INCDIR}/video/drivers/pango_video_output.h + ${INCDIR}/video/drivers/debayer.h + ${INCDIR}/video/drivers/shift.h + ${INCDIR}/video/drivers/mirror.h + ${INCDIR}/video/drivers/unpack.h + ${INCDIR}/video/drivers/pack.h + ${INCDIR}/video/drivers/join.h + ${INCDIR}/video/drivers/merge.h + ${INCDIR}/video/drivers/thread.h + ) + list(APPEND SOURCES + video/drivers/test.cpp + video/drivers/images.cpp + video/drivers/images_out.cpp + video/drivers/split.cpp + video/drivers/truncate.cpp + video/drivers/pvn.cpp + video/drivers/pango.cpp + video/drivers/pango_video_output.cpp + video/drivers/debayer.cpp + video/drivers/shift.cpp + video/drivers/mirror.cpp + video/drivers/unpack.cpp + video/drivers/pack.cpp + video/drivers/join.cpp + video/drivers/merge.cpp + video/drivers/json.cpp + video/drivers/thread.cpp + ) + + list(APPEND VIDEO_FACTORY_REG + RegisterTestVideoFactory + RegisterImagesVideoFactory + RegisterImagesVideoOutputFactory + RegisterSplitVideoFactory + RegisterTruncateVideoFactory + RegisterPvnVideoFactory + RegisterPangoVideoFactory + RegisterPangoVideoOutputFactory + RegisterDebayerVideoFactory + RegisterShiftVideoFactory + RegisterMirrorVideoFactory + RegisterUnpackVideoFactory + RegisterPackVideoFactory + RegisterJoinVideoFactory + RegisterMergeVideoFactory + RegisterJsonVideoFactory + RegisterThreadVideoFactory + ) + + if(LINUX) + list(APPEND HEADERS ${INCDIR}/video/drivers/shared_memory.h) + list(APPEND SOURCES video/drivers/shared_memory.cpp) + # Required for shared memory API using some versions of glibc + list(APPEND LINK_LIBS rt pthread) + endif() + +endif() + +if(BUILD_PANGOLIN_GUI AND BUILD_PANGOLIN_VARS AND BUILD_PANGOLIN_VIDEO ) + list(APPEND HEADERS ${INCDIR}/tools/video_viewer.h) + list(APPEND SOURCES tools/video_viewer.cpp) +endif() + +####################################################### +## Setup required includes / link info + +option(DISPLAY_X11 "X11 Window Interface" ON) +option(DISPLAY_WAYLAND "Wayland Window Interface" OFF) + +if(BUILD_PANGOLIN_GUI) + if( ANDROID ) + # Android specific display code + list(APPEND HEADERS ${INCDIR}/display/device/display_android.h ) + list(APPEND SOURCES display/device/display_android.cpp ) + list(APPEND WINDOW_FACTORY_REG RegisterAndroidWindowFactory) + + if(HAVE_GLES_2) + list(APPEND LINK_LIBS "-lEGL;-lGLESv2" ) + else() + list(APPEND LINK_LIBS "-lEGL;-lGLESv1_CM" ) + endif() + elseif( IOS ) + list(APPEND LINK_LIBS "-framework OpenGLES" ) + list(APPEND HEADERS "${INCDIR}/ios/PangolinAppDelegate.h" "${INCDIR}/ios/PangolinViewController.h" ) + list(APPEND SOURCES "ios/PangolinAppDelegate.mm" "ios/PangolinViewController.mm" ) + list(APPEND WINDOW_FACTORY_REG RegisterIosWindowFactory) + else() + find_package(OpenGL REQUIRED) + list(APPEND USER_INC ${OPENGL_INCLUDE_DIR}) + list(APPEND LINK_LIBS ${OPENGL_LIBRARIES}) + + if(NOT BUILD_EXTERN_GLEW) + find_package(GLEW REQUIRED) + endif() + list(APPEND USER_INC ${GLEW_INCLUDE_DIR}) + list(APPEND LINK_LIBS ${GLEW_LIBRARY}) + endif() + + if( HAVE_GLES_2 ) + # Add Pangolins backwards compat layer. + list(APPEND HEADERS ${INCDIR}/gl2engine.h ) + list(APPEND SOURCES gl2engine.cpp) + endif() + + # headless offscreen rendering via EGL + find_package(OpenGL QUIET COMPONENTS EGL) + if(OpenGL_EGL_FOUND) + list(APPEND WINDOW_FACTORY_REG RegisterNoneWindowFactory) + list(APPEND SOURCES display/device/display_headless.cpp) + list(APPEND LINK_LIBS ${OPENGL_egl_LIBRARY} ) + endif() +endif() + +####################################################### +## Find optional dependencies + +if(ANDROID) + # Fix issue with thread local storage on android. + add_definitions(-fno-data-sections) + list(APPEND LINK_LIBS android log) +elseif(IOS) + # Nothing specific in here yet. +else() + if(BUILD_PANGOLIN_GUI) + if(_WIN_) + list(APPEND WINDOW_FACTORY_REG RegisterWinWindowFactory) + list(APPEND SOURCES display/device/display_win.cpp ) + elseif(_OSX_) + list(APPEND WINDOW_FACTORY_REG RegisterOsxWindowFactory) + list(APPEND SOURCES display/device/display_osx.mm display/device/PangolinNSApplication.mm display/device/PangolinNSGLView.mm ) + list(APPEND LINK_LIBS "-framework Cocoa" ) + elseif(_LINUX_) + # Wayland + find_package(Wayland QUIET) + if(DISPLAY_WAYLAND OR WAYLAND_CLIENT_FOUND) + find_package(Wayland REQUIRED) + find_package(PkgConfig) + pkg_check_modules(xkbcommon REQUIRED xkbcommon) + pkg_check_modules(egl QUIET egl) + + # find Wayland protocols + pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir) + + # generate header for protocol 'xdg_shell' + set(XDG_PROT_DEF "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml") + if(EXISTS ${XDG_PROT_DEF}) + # use the 'xdg_shell' protocol + add_definitions(-DUSE_WL_XDG=1) + + # find 'wayland-scanner' executable + pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner) + + # generate protocol implementation + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.h + COMMAND ${WAYLAND_SCANNER} client-header ${XDG_PROT_DEF} xdg-shell-client-protocol.h) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-protocol.c + COMMAND ${WAYLAND_SCANNER} private-code ${XDG_PROT_DEF} xdg-shell-protocol.c + DEPENDS xdg-shell-client-protocol.h) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + list(APPEND SOURCES xdg-shell-protocol.c) + + else() + # use deprecated 'wl_shell' interface + add_definitions(-DUSE_WL_XDG=0) + endif() + + list(APPEND WINDOW_FACTORY_REG RegisterWaylandWindowFactory) + list(APPEND SOURCES display/device/display_wayland.cpp) + list(APPEND LINK_LIBS + ${WAYLAND_CLIENT_LIBRARIES} + ${WAYLAND_EGL_LIBRARIES} + ${WAYLAND_CURSOR_LIBRARIES} + ${egl_LIBRARIES} + ${xkbcommon_LIBRARIES} + ) + list(APPEND INTERNAL_INC + ${WAYLAND_CLIENT_INCLUDE_DIR} + ${WAYLAND_EGL_INCLUDE_DIR} + ${WAYLAND_CURSOR_INCLUDE_DIR} + ${egl_INCLUDE_DIRS} + ${xkbcommon_INCLUDE_DIRS} + ) + endif() + + # X11 + find_package(X11 QUIET) + if(DISPLAY_X11 AND X11_FOUND) + list(APPEND WINDOW_FACTORY_REG RegisterX11WindowFactory) + list(APPEND USER_INC ${X11_INCLUDE_DIR}) + list(APPEND SOURCES display/device/display_x11.cpp ) + list(APPEND LINK_LIBS ${X11_LIBRARIES} ) + endif() + endif() + endif() +endif() + +if(UNIX) + append_glob(HEADERS ${INCDIR}/utils/posix/*.h*) + append_glob(SOURCES utils/posix/*.cpp) + if(_LINUX_) + # Required for shared memory API using some versions of glibc + list(APPEND LINK_LIBS rt pthread) + endif() +endif() + +option(BUILD_PANGOLIN_PYTHON "Build support for Pangolin Interactive Console" ON) +if(BUILD_PANGOLIN_PYTHON AND BUILD_PANGOLIN_GUI AND BUILD_PANGOLIN_VARS AND NOT _WIN_) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../external/pybind11/CMakeLists.txt") + add_subdirectory("../external/pybind11" "${CMAKE_CURRENT_BINARY_DIR}/external/pybind11") + set( pybind11_FOUND true) + else() + find_package(pybind11 QUIET) + endif() + + if(pybind11_FOUND) + set(HAVE_PYTHON 1) + + file(GLOB pypangolin_SRC "python/pypangolin/*.cpp" ) + file(GLOB pypangolin_HDR "python/pypangolin/*.hpp" ) + list(APPEND HEADERS + ${INCDIR}/console/ConsoleInterpreter.h + ${INCDIR}/console/ConsoleView.h + ${INCDIR}/python/pyinterpreter.h + ${INCDIR}/python/pypangolin_init.h + ${INCDIR}/python/pyuniqueobj.h + ${INCDIR}/python/pyvar.h + ${INCDIR}/python/pypangoio.h + ${pypangolin_HDR} + ) + list(APPEND SOURCES + console/ConsoleView.cpp + python/pyinterpreter.cpp + python/pypangolin_init.cpp + ${pypangolin_SRC} + ) + + # pybind11 stuff + list(APPEND INTERNAL_INC ${PYBIND11_INCLUDE_DIR}) + list(APPEND LINK_LIBS PRIVATE ${pybind11_LIBRARIES}) + + if(_GCC_) + set_source_files_properties(python/PyInterpreter.cpp PROPERTIES COMPILE_FLAGS "-Wno-missing-field-initializers") + set_source_files_properties(python/PyModulePangolin.cpp PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing -Wno-missing-field-initializers") + endif() + list(APPEND INTERNAL_INC ${PYTHON_INCLUDE_DIRS}) + list(APPEND LINK_LIBS ${PYTHON_LIBRARIES}) + message(STATUS "Python Found and Enabled (with pybind11)") + endif() +endif() + +option(BUILD_PANGOLIN_EIGEN "Build support for Eigen matrix types" ON) +if(BUILD_PANGOLIN_EIGEN) + find_package(Eigen QUIET) + if(EIGEN_FOUND) + set(HAVE_EIGEN 1) + list(APPEND USER_INC ${EIGEN_INCLUDE_DIR} ) + if(_CLANG_) + # Eigen causes many of these errors. Suppress. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register") + endif() + message(STATUS "Eigen Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_TOON "Build support for TooN matrix types" ON) +if(BUILD_PANGOLIN_TOON) + find_package(TooN QUIET) + if(TooN_FOUND) + set(HAVE_TOON 1) + list(APPEND USER_INC ${TooN_INCLUDE_DIR} ) + message(STATUS "TooN Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LIBDC1394 "Build support for libdc1394 video input" ON) +if(BUILD_PANGOLIN_LIBDC1394 AND BUILD_PANGOLIN_VIDEO) + find_package(DC1394 QUIET) + if(DC1394_FOUND) + set(HAVE_DC1394 1) + list(APPEND INTERNAL_INC ${DC1394_INCLUDE_DIR} ) + list(APPEND LINK_LIBS ${DC1394_LIBRARY} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/firewire.h ${INCDIR}/video/drivers/deinterlace.h ) + list(APPEND SOURCES video/drivers/firewire.cpp video/drivers/deinterlace.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterFirewireVideoFactory ) + message(STATUS "libdc1394 Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_V4L "Build support for V4L video input" ON) +if(BUILD_PANGOLIN_V4L AND BUILD_PANGOLIN_VIDEO AND _LINUX_) + set(HAVE_V4L 1) + list(APPEND HEADERS ${INCDIR}/video/drivers/v4l.h) + list(APPEND SOURCES video/drivers/v4l.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterV4lVideoFactory ) + message(STATUS "V4L Found and Enabled") +endif() + +option(BUILD_PANGOLIN_FFMPEG "Build support for ffmpeg video input" ON) +if(BUILD_PANGOLIN_FFMPEG AND BUILD_PANGOLIN_VIDEO) + find_package(FFMPEG QUIET) + if(FFMPEG_FOUND) + set(HAVE_FFMPEG 1) + list(APPEND INTERNAL_INC ${FFMPEG_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${FFMPEG_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/ffmpeg.h) + list(APPEND SOURCES video/drivers/ffmpeg.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterFfmpegVideoFactory ) + list(APPEND VIDEO_FACTORY_REG RegisterFfmpegVideoOutputFactory ) + + if(_GCC_) + # FFMPEG is a real pain for deprecating the API. + set_source_files_properties(video/drivers/ffmpeg.cpp PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations") + endif() + message(STATUS "ffmpeg Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LIBREALSENSE "Build support for LibRealSense video input" ON) +if(BUILD_PANGOLIN_LIBREALSENSE AND BUILD_PANGOLIN_VIDEO) + find_package(LibRealSense QUIET) + if(LIBREALSENSE_FOUND) + set(HAVE_LIBREALSENSE 1) + list(APPEND INTERNAL_INC ${LIBREALSENSE_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${LIBREALSENSE_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/realsense.h ) + list(APPEND SOURCES video/drivers/realsense.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterRealSenseVideoFactory ) + message(STATUS "LibRealSense Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LIBREALSENSE2 "Build support for LibRealSense2 video input" ON) +if(BUILD_PANGOLIN_LIBREALSENSE2 AND BUILD_PANGOLIN_VIDEO) + find_package(LibRealSense2 QUIET) + if(LIBREALSENSE2_FOUND) + set(HAVE_LIBREALSENSE2 1) + list(APPEND INTERNAL_INC ${LIBREALSENSE2_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${LIBREALSENSE2_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/realsense2.h ) + list(APPEND SOURCES video/drivers/realsense2.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterRealSense2VideoFactory ) + message(STATUS "LibRealSense2 Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_OPENNI "Build support for OpenNI video input" ON) +if(BUILD_PANGOLIN_OPENNI AND BUILD_PANGOLIN_VIDEO) + find_package(OpenNI QUIET) + if(OPENNI_FOUND) + set(HAVE_OPENNI 1) + if(_LINUX_) + add_definitions(-Dlinux=1) + endif() + list(APPEND INTERNAL_INC ${OPENNI_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${OPENNI_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/openni.h ) + list(APPEND SOURCES video/drivers/openni.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterOpenNiVideoFactory ) + message(STATUS "OpenNI Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_OPENNI2 "Build support for OpenNI2 video input" ON) +if(BUILD_PANGOLIN_OPENNI2 AND BUILD_PANGOLIN_VIDEO) + find_package(OpenNI2 QUIET) + if(OPENNI2_FOUND) + set(HAVE_OPENNI2 1) + if(_LINUX_) + add_definitions(-Dlinux=1) + endif() + list(APPEND INTERNAL_INC ${OPENNI2_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${OPENNI2_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/openni2.h ) + list(APPEND SOURCES video/drivers/openni2.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterOpenNi2VideoFactory ) + message(STATUS "OpenNI2 Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LIBUVC "Build support for libuvc video input" ON) +if(BUILD_PANGOLIN_LIBUVC AND BUILD_PANGOLIN_VIDEO) + find_package(uvc QUIET) + if(uvc_FOUND) + set(HAVE_UVC 1) + list(APPEND INTERNAL_INC ${uvc_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${uvc_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/uvc.h ) + list(APPEND SOURCES video/drivers/uvc.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterUvcVideoFactory ) + if(_WIN_) + find_package(pthread REQUIRED QUIET) + list(APPEND LINK_LIBS ${pthread_LIBRARIES} ) + + find_package(libusb1 REQUIRED QUIET) + list(APPEND LINK_LIBS ${libusb1_LIBRARIES} ) + endif() + message(STATUS "libuvc Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_UVC_MEDIAFOUNDATION "Build support for MediaFoundation UVC input" ON) +if (BUILD_PANGOLIN_UVC_MEDIAFOUNDATION AND BUILD_PANGOLIN_VIDEO) + find_package(MediaFoundation QUIET) + if (MediaFoundation_FOUND) + list(APPEND LINK_LIBS ${MediaFoundation_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/uvc_mediafoundation.h ) + list(APPEND SOURCES video/drivers/uvc_mediafoundation.cpp ) + list(APPEND VIDEO_FACTORY_REG RegisterUvcMediaFoundationVideoFactory ) + message(STATUS "MediaFoundation Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_DEPTHSENSE "Build support for DepthSense video input" ON) +if(BUILD_PANGOLIN_DEPTHSENSE AND BUILD_PANGOLIN_VIDEO) + find_package(DepthSense QUIET) + if(DepthSense_FOUND) + set(HAVE_DEPTHSENSE 1) + list(APPEND INTERNAL_INC ${DepthSense_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${DepthSense_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/depthsense.h ) + list(APPEND SOURCES video/drivers/depthsense.cpp) + list(APPEND VIDEO_FACTORY_REG RegisterDepthSenseVideoFactory ) + message(STATUS "DepthSense Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_TELICAM "Build support for TeliCam video input" ON) +if(BUILD_PANGOLIN_TELICAM AND BUILD_PANGOLIN_VIDEO) + find_package(TeliCam QUIET) + if(TeliCam_FOUND) + set(HAVE_TELICAM 1) + list(APPEND INTERNAL_INC ${TeliCam_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${TeliCam_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/teli.h ) + list(APPEND SOURCES video/drivers/teli.cpp ) + list(APPEND VIDEO_FACTORY_REG RegisterTeliVideoFactory ) + + message(STATUS "TeliCam Found and Enabled" ) + endif() +endif() + +option(BUILD_PANGOLIN_PLEORA "Build support for Pleora video input" ON) +if(BUILD_PANGOLIN_PLEORA AND BUILD_PANGOLIN_VIDEO) + find_package(Pleora QUIET) + if(Pleora_FOUND) + set(HAVE_PLEORA 1) + list(APPEND INTERNAL_INC ${Pleora_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${Pleora_LIBRARIES} ) + list(APPEND HEADERS ${INCDIR}/video/drivers/pleora.h ) + list(APPEND SOURCES video/drivers/pleora.cpp ) + list(APPEND VIDEO_FACTORY_REG RegisterPleoraVideoFactory ) + + if(_GCC_) + # Suppress warnings generated from Pleora SDK. + set_source_files_properties(video/drivers/pleora.cpp PROPERTIES COMPILE_FLAGS -Wno-unknown-pragmas) + set_source_files_properties(video/video.cpp PROPERTIES COMPILE_FLAGS -Wno-unknown-pragmas) + endif() + message(STATUS "Pleora Found and Enabled" ) + endif() +endif() + +option(BUILD_PANGOLIN_LIBPNG "Build support for libpng image input" ON) +if(BUILD_PANGOLIN_LIBPNG) + if(NOT BUILD_EXTERN_LIBPNG) + find_package(PNG QUIET) + endif() + if(PNG_FOUND) + # (ZLIB is also found by FindPNG.cmake as its dependency) + set(HAVE_PNG 1) + list(APPEND INTERNAL_INC ${PNG_INCLUDE_DIR} ) + list(APPEND LINK_LIBS ${PNG_LIBRARY} ${ZLIB_LIBRARY} ) + message(STATUS "libpng Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LIBJPEG "Build support for libjpeg image input" ON) +if(BUILD_PANGOLIN_LIBJPEG) + if(NOT BUILD_EXTERN_LIBJPEG) + find_package(JPEG QUIET) + endif() + if(JPEG_FOUND) + set(HAVE_JPEG 1) + list(APPEND INTERNAL_INC ${JPEG_INCLUDE_DIR} ) + list(APPEND LINK_LIBS ${JPEG_LIBRARY} ) + message(STATUS "libjpeg Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LIBTIFF "Build support for libtiff image input" ON) +if(BUILD_PANGOLIN_LIBTIFF) + find_package(TIFF QUIET) + if(TIFF_FOUND) + set(HAVE_TIFF 1) + list(APPEND INTERNAL_INC ${TIFF_INCLUDE_DIR} ) + list(APPEND LINK_LIBS ${TIFF_LIBRARY} ) + message(STATUS "libtiff Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LIBOPENEXR "Build support for libopenexr image input" ON) +if(BUILD_PANGOLIN_LIBOPENEXR) + find_package(OpenEXR QUIET) + if(OpenEXR_FOUND) + set(HAVE_OPENEXR 1) + list(APPEND INTERNAL_INC ${OpenEXR_INCLUDE_DIR} ) + list(APPEND LINK_LIBS ${OpenEXR_LIBRARY} ) + message(STATUS "libopenexr Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_ZSTD "Build support for libzstd compression" ON) +if(BUILD_PANGOLIN_ZSTD) + find_package(zstd QUIET) + if(zstd_FOUND) + set(HAVE_ZSTD 1) + list(APPEND INTERNAL_INC ${zstd_INCLUDE_DIR} ) + list(APPEND LINK_LIBS ${zstd_LIBRARY} ) + message(STATUS "libzstd Found and Enabled") + endif() +endif() + +option(BUILD_PANGOLIN_LZ4 "Build support for liblz4 compression" ON) +if(BUILD_PANGOLIN_LZ4) + find_package(Lz4 QUIET) + if(Lz4_FOUND) + set(HAVE_LZ4 1) + list(APPEND INTERNAL_INC ${Lz4_INCLUDE_DIRS} ) + list(APPEND LINK_LIBS ${Lz4_LIBRARIES} ) + message(STATUS "liblz4 Found and Enabled") + endif() +endif() + +####################################################### +## Embed resource binary files + +include(EmbedBinaryFiles) + +if(BUILD_PANGOLIN_GUI) + embed_binary_files( "_embed_/fonts/*.ttf" "${CMAKE_CURRENT_BINARY_DIR}/fonts.cpp" ) + list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/fonts.cpp" ) +endif() + +####################################################### +## Add Libraries / Include Directories / Link directories + +set(INSTALL_INCLUDE_DIR "include") + +add_library(${LIBRARY_NAME} ${SOURCES} ${HEADERS}) +# 'System' includes shield us from warnings in those includes. +target_include_directories(${LIBRARY_NAME} SYSTEM PUBLIC ${USER_INC} PRIVATE ${INTERNAL_INC}) +target_include_directories(${LIBRARY_NAME} PUBLIC $ + $ + $) +target_link_libraries(${LIBRARY_NAME} PUBLIC ${LINK_LIBS}) + +## Generate symbol export helper header on MSVC +IF(MSVC) + string(TOUPPER ${LIBRARY_NAME} LIBRARY_NAME_CAPS) + include(GenerateExportHeader) + GENERATE_EXPORT_HEADER( ${LIBRARY_NAME} + BASE_NAME ${LIBRARY_NAME_CAPS} + EXPORT_MACRO_NAME ${LIBRARY_NAME_CAPS}_EXPORT + EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/${LIBRARY_NAME}/${LIBRARY_NAME}_export.h" + STATIC_DEFINE ${LIBRARY_NAME_CAPS}_BUILT_AS_STATIC + ) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/${LIBRARY_NAME}/${LIBRARY_NAME}_export.h" + DESTINATION ${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}/${LIBRARY_NAME} + ) +ENDIF() + +## Set Special Compiler flags +if(MSVC) + set(CMAKE_CXX_FLAGS "/EHs ${CMAKE_CXX_FLAGS}") +elseif(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "-Wall -Wno-error=deprecated-declarations ${CMAKE_CXX_FLAGS}") +endif() + +####################################################### +## Create config.h file for inclusion in library + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/include/${LIBRARY_NAME}/config.h" +) + +####################################################### +## Create video_drivers.h file for inclusion in library +## This loads video driver factories based on cmake configuration + +CreateMethodCallFile( + "${CMAKE_CURRENT_BINARY_DIR}/include/${LIBRARY_NAME}/video_drivers.h" + "pangolin" "LoadBuiltInVideoDrivers" "${VIDEO_FACTORY_REG}" +) + +####################################################### +## Create window_frameworks.h file for inclusion in library +## This loads windowing framwork factories based on cmake configuration + +CreateMethodCallFile( + "${CMAKE_CURRENT_BINARY_DIR}/include/${LIBRARY_NAME}/window_frameworks.h" + "pangolin" "LoadBuiltInWindowFrameworks" "${WINDOW_FACTORY_REG}" +) + +####################################################### +## Python wrapper + +option(BUILD_PYPANGOLIN_MODULE "Python wrapper for Pangolin" ON) +if(BUILD_PYPANGOLIN_MODULE AND HAVE_PYTHON ) + file(GLOB pypangolin_SRC "python/pypangolin/*.hpp" "python/pypangolin/*.cpp" "python/pypangolin_module.cpp") + pybind11_add_module(pypangolin ${pypangolin_SRC}) + target_link_libraries(pypangolin PRIVATE ${LIBRARY_NAME}) + target_include_directories(pypangolin PRIVATE "${USER_INC}") +endif() + +####################################################### +## Generate Doxygen documentation target (make pangolin_doc) +find_package(Doxygen) +if(DOXYGEN_FOUND) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../doc ) + add_custom_target(pangolin_doc + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../doc + COMMENT "Generating API documentation with Doxygen" VERBATIM + ) +endif() + +####################################################### + +# This relative path allows installed files to be relocatable. +set( CMAKECONFIG_INSTALL_DIR lib/cmake/${PROJECT_NAME} ) +file( RELATIVE_PATH REL_INCLUDE_DIR + "${CMAKE_INSTALL_PREFIX}/${CMAKECONFIG_INSTALL_DIR}" + "${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}" +) + +# Export library for easy inclusion from other cmake projects. APPEND allows +# call to function even as subdirectory of larger project. +FILE(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") +export( TARGETS ${LIBRARY_NAME} + APPEND FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake" ) + +# Version information +configure_file(${PROJECT_NAME}ConfigVersion.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" @ONLY) + +# Build tree config +set( EXPORT_LIB_INC_DIR "${PROJECT_SOURCE_DIR}/include;${CMAKE_CURRENT_BINARY_DIR}/include" ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY IMMEDIATE ) + +# Install tree config +set( EXPORT_LIB_INC_DIR "\${PROJECT_CMAKE_DIR}/${REL_INCLUDE_DIR}" ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake @ONLY ) + +# Add package to CMake package registery for use from the build tree +option( EXPORT_${PROJECT_NAME} + "Should the ${PROJECT_NAME} package be exported for use by other software" ON ) + +if( EXPORT_${PROJECT_NAME} ) + export( PACKAGE ${PROJECT_NAME} ) +endif() + +####################################################### +## Install headers / targets + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/${LIBRARY_NAME}/config.h" + DESTINATION ${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}/${LIBRARY_NAME} +) +install(DIRECTORY ${INCDIR} + DESTINATION ${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR} +) +install(TARGETS ${LIBRARY_NAME} + EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib +) + +####################################################### +## Install CMake config + +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION ${CMAKECONFIG_INSTALL_DIR} +) +install( + EXPORT ${PROJECT_NAME}Targets DESTINATION ${CMAKECONFIG_INSTALL_DIR} +) diff --git a/thirdparty/Pangolin/src/Doxyfile.in b/thirdparty/Pangolin/src/Doxyfile.in new file mode 100644 index 00000000..8146355e --- /dev/null +++ b/thirdparty/Pangolin/src/Doxyfile.in @@ -0,0 +1,2281 @@ +# Doxyfile 1.8.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Pangolin" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Pangolin is a lightweight rapid development library for managing OpenGL display / interaction and video input" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- +# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, +# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. Do not use file names with spaces, bibtex cannot handle them. See +# also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../include +INPUT += @CMAKE_CURRENT_SOURCE_DIR@/../README.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.h *.md + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = *internal* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = android_app android_poll_source PangolinAppDelegate + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- +# defined cascading style sheet that is included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet file to the output directory. For an example +# see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /