Compare commits

...

No commits in common. "d2dc1bf17f803ecf0b36d1f33cc80396ea120cd3" and "561541b10f03895b21eb31d5dca6ce17f6f6c825" have entirely different histories.

132 changed files with 6228 additions and 33431 deletions

View file

@ -1,19 +0,0 @@
FROM mcr.microsoft.com/devcontainers/cpp:1-ubuntu-24.04
ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="none"
# Optionally install the cmake for vcpkg
COPY ./reinstall-cmake.sh /tmp/
RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \
chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \
fi \
&& rm -f /tmp/reinstall-cmake.sh
# [Optional] Uncomment this section to install additional vcpkg ports.
# RUN su vscode -c "${VCPKG_ROOT}/vcpkg install <your-port-name-here>"
# [Optional] Uncomment this section to install additional packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends \
libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libgl1-mesa-dev mesa-utils

View file

@ -1,35 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/cpp
{
"name": "C++",
"build": {
"dockerfile": "Dockerfile"
},
"containerEnv": {
"DISPLAY": "${localEnv:DISPLAY}",
},
"remoteEnv": {
"DOCKER_BUILDKIT": "0",
},
"runArgs": [
"--volume=/tmp/.X11-unix:/tmp/.X11-unix",
"--network", "host"
],
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "gcc -v",
// Configure tool-specific properties.
"customizations": {
"jetbrains": {
"backend": "CLion"
}
},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
"remoteUser": "root"
}

View file

@ -1,59 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
set -e
CMAKE_VERSION=${1:-"none"}
if [ "${CMAKE_VERSION}" = "none" ]; then
echo "No CMake version specified, skipping CMake reinstallation"
exit 0
fi
# Cleanup temporary directory and associated files when exiting the script.
cleanup() {
EXIT_CODE=$?
set +e
if [[ -n "${TMP_DIR}" ]]; then
echo "Executing cleanup of tmp files"
rm -Rf "${TMP_DIR}"
fi
exit $EXIT_CODE
}
trap cleanup EXIT
echo "Installing CMake..."
apt-get -y purge --auto-remove cmake
mkdir -p /opt/cmake
architecture=$(dpkg --print-architecture)
case "${architecture}" in
arm64)
ARCH=aarch64 ;;
amd64)
ARCH=x86_64 ;;
*)
echo "Unsupported architecture ${architecture}."
exit 1
;;
esac
CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh"
CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt"
TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX)
echo "${TMP_DIR}"
cd "${TMP_DIR}"
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O
sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}"
sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license
ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
ln -s /opt/cmake/bin/ctest /usr/local/bin/ctest

View file

@ -1,56 +0,0 @@
name: CMake
on: [push]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: [self-hosted,Windows]
outputsuffix: win
archive_type: zip
archive_extension: zip
outputfile1: Release/normals.exe
outputfile2: Release/obj.exe
outputfile3: Release/quad_subdivision.exe
- os: [self-hosted,Linux]
outputsuffix: ux
archive_type: zip
archive_extension: zip
outputfile1: normals
outputfile2: obj
outputfile3: quad_subdivision
steps:
- uses: actions/checkout@v3
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
# Build your program with the given configuration
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.2
with:
# Artifact name
name: CG_${{ matrix.outputsuffix }}_${{env.BUILD_TYPE}}
# A file, directory or wildcard pattern that describes what to upload
path: |
${{github.workspace}}/build/${{matrix.outputfile1}}
${{github.workspace}}/build/${{matrix.outputfile2}}
${{github.workspace}}/build/${{matrix.outputfile3}}

6
.gitmodules vendored Normal file
View file

@ -0,0 +1,6 @@
[submodule "lib/glfw"]
path = lib/glfw
url = https://github.com/glfw/glfw.git
[submodule "lib/eigen"]
path = lib/eigen
url = https://github.com/eigenteam/eigen-git-mirror

73
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,73 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "setup",
"type": "shell",
"command": "cmake -S . -B build -D GLFW_BUILD_WAYLAND=OFF -D GLFW_BUILD_X11=ON"
},
{
"label": "build",
"type": "shell",
"command": "make -C build",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
"dependsOn": [
"setup"
]
},
{
"label": "Task 0: Check if OpenGL works",
"type": "shell",
"command": "./build/shaderpipeline 0",
"problemMatcher": []
},
{
"label": "Task 1: basic model, view, projection",
"type": "shell",
"command": "./build/shaderpipeline 1",
"problemMatcher": []
},
{
"label": "Task 2: subdivide the mesh",
"type": "shell",
"command": "./build/shaderpipeline 2",
"problemMatcher": []
},
{
"label": "Task 3: make the mesh round",
"type": "shell",
"command": "./build/shaderpipeline 3",
"problemMatcher": []
},
{
"label": "Task 4: light",
"type": "shell",
"command": "./build/shaderpipeline 4",
"problemMatcher": []
},
{
"label": "Task 5: procedural color",
"type": "shell",
"command": "./build/shaderpipeline 5",
"problemMatcher": []
},
{
"label": "Task 6: procedural bump",
"type": "shell",
"command": "./build/shaderpipeline 6",
"problemMatcher": []
},
{
"label": "Task 7: get creative",
"type": "shell",
"command": "./build/shaderpipeline 7",
"problemMatcher": []
}
]
}

View file

@ -1,34 +1,61 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.6)
project(meshes)
# Set project name
project(shaderpipeline)
set(CMAKE_CXX_STANDARD 11)
# Check for C++17 support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17)
if(COMPILER_SUPPORTS_CXX17)
set(CMAKE_CXX_STANDARD 17)
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.")
endif()
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Add headers
include_directories("include/")
# Libigl
include(libigl)
# OpenGL library
find_package(OpenGL REQUIRED)
# Enable the target igl::glfw and igl::stb
igl_include(glfw)
igl_include(stb)
# Add Glad
add_library(glad "glad.c")
include_directories(include)
# include the header files
include_directories(include/)
# Check if GLFW and Eigen are not empty
file(GLOB GLFW_DIR lib/glfw/*)
list(LENGTH GLFW_DIR NR_FILES_IN_GLFW_DIR)
if(NR_FILES_IN_GLFW_DIR LESS_EQUAL 1)
message(WARNING "Did you forget git submodule update --init --recursive ?")
endif()
# add the source files
file(GLOB SRCFILES src/*.cpp)
# Add GLFW as a submodule
add_subdirectory(lib/glfw)
include_directories(lib/glfw/include)
# create 1 library "core" (from the SRCFILES) and 3 projects/executables ("normals", "quad_subdivision", "obj")
# Add Eigen as a submodule
add_subdirectory(lib/eigen)
include_directories(lib/eigen)
add_library(core ${SRCFILES})
target_link_libraries(core PUBLIC igl::glfw)
# Define the glsl files
# Note: ${RESOURCEFILES} is not used, since it is not part of the C++ compilation step.
# If you use an extension to your IDE that provides syntax highlighting etc for OpenGL,
# you might need to add ${RESOURCEFILES} in add_executable().
file(GLOB RESOURCEFILES "src/*" "glsl/*")
add_executable(normals "normals.cpp")
target_link_libraries(normals PUBLIC core igl::glfw )
# Add c++ files
set(SOURCES main.cpp glHelper.h)
add_executable(quad_subdivision "quad_subdivision.cpp")
target_link_libraries(quad_subdivision PUBLIC core igl::glfw )
add_executable(${PROJECT_NAME} ${SOURCES})
#add_executable(${PROJECT_NAME} ${SOURCES} ${RESOURCEFILES}) # in case you need the glsl files for an IDE extension
add_executable(obj "obj.cpp")
target_link_libraries(obj PUBLIC core igl::glfw igl::stb)
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${OPENGL_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} glfw ${OPENGL_gl_LIBRARY} glad)
# make the current path available to the source code
target_compile_definitions(${PROJECT_NAME} PUBLIC CMAKELISTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
# if using Visual Studio, set the startup project
if(MSVC)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
endif()

555
README.md
View file

@ -1,368 +1,315 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/Po9MPlbW)
# Computer Graphics Lab3 Meshes
**Deadline: Nov. 15 2024, 22:00**
# Computer Graphics Lab5 - Shader Pipeline
## Building using CMake
**Deadline:** Dec. 13 2024, 22:00
### Windows
If your CMake version < 3.16.0, you might see an error pop up while using CMake, saying that Libigl requires a version >= 3.16.0. If you don't want to update your CMake, simply go to the line throwing that error and change the version:
## Building with CMake
This project depends on Eigen and GLFW, which are added as submodules in the `lib/` folder. After cloning the repository, you need to `cd` into it and run:
```
# on my machine the error is thrown in
# "out/build/x64-Debug/_deps/libigl-src/CMakeLists.txt" on line 12:
set(REQUIRED_CMAKE_VERSION "3.16.0")
# change this to a version <= your version, for example:
set(REQUIRED_CMAKE_VERSION "3.0.0")
git submodule update --init --recursive
```
### Linux
If CMake succeeds without errors, great. However, if not, then you will have to resolve the thrown exceptions. We follow [libigl's example project](https://github.com/libigl/libigl-example-project) in this assignment, which they claim should work on Ubuntu out of the box. It can be however that CMake throws exceptions that look like:
OpenGL is already setup by default on most systems. For example, Windows includes the `opengl32.dll` library by default in `C:/Windows/System32`. Drivers for OpenGL are automatically included in most graphics drivers.
1. `"Could not find X11 (missing: X11_X11_LIB ...)"`
2. `"... headers not found; ... install ... development package"`
3. `"Could NOT find OpenGL (missing: OPENGL_opengl_LIBRARY ...)"`
**Linux:** if this was not already installed, run:
To solve errors like this, install the missing packages (you might need to search around on the web if the following command does not suffice):
```
sudo apt install libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libgl1-mesa-dev
sudo apt install libgl1-mesa-dev
sudo apt install freeglut3-dev
```
### WSL (Windows)
Follow the Linux instructions above. Warning: the assignment uses OpenGL and GLFW to create a window, which might not work with WSL. We will not be able to help you here.
### MacOS
We follow [libigl's example project](https://github.com/libigl/libigl-example-project) in this assignment, which they claim should work on MacOS out of the box. If you experience CMake errors that you cannot solve with some help online, please contact us.
-----
## Background
### Read Section 12.1 of _Fundamentals of Computer Graphics (4th Edition)_.
**Review chapters 6, 7 and sections 8.18.2 of Fundamentals of Computer Graphics (4th Edition).**
**Read Sections 11.411.5 and Chapter 17 of Fundamentals of Computer Graphics (4th Edition)**
### Skim read Chapter 11 of _Fundamentals of Computer Graphics (4th Edition)_.
In this assignment, we will use the “real-time rendering” shader pipeline of **OpenGL**. In this assignment, you will build on this workflow to **procedurally render** a planet. You will be combining knowledge from all the previous assignments: ray tracing, normals, mesh subdivision and perlin noise.
There are many ways to store a triangle (or polygonal) mesh on the computer. The
data-structures have very different complexities in terms of code, memory, and
access performance. At the heart of these structures, is the problem of storing
the two types of information defining a mesh: the _geometry_ (where are points
on the surface located in space) and the _connectivity_ (which points are
connected to each other). The connectivity is also sometimes referred to as the
[topology](https://en.wikipedia.org/wiki/Topology) of the mesh.
![](css/earth.gif)
The [graphics pipeline](https://en.wikipedia.org/wiki/Graphics_pipeline) works
on a per-triangle and per-vertex basis. So the simplest way to store geometry is
a 3D position <img src="/markdown/ec6276257da0cb44caa5ae4b07afb40e.svg?invert_in_darkmode&sanitize=true" align=middle width=56.27160494999998pt height=26.76175259999998pt/> for each <img src="/markdown/77a3b857d53fb44e33b53e4c8b68351a.svg?invert_in_darkmode&sanitize=true" align=middle width=5.663225699999989pt height=21.68300969999999pt/>-th vertex of the mesh. And to store
triangle connectivity as an ordered triplet of indices referencing vertices:
<img src="/markdown/567132d8a883ab35cbb45db628ebb96e.svg?invert_in_darkmode&sanitize=true" align=middle width=36.147533399999986pt height=22.831056599999986pt/> defines a triangle with corners at vertices <img src="/markdown/5474c8baa2bc6feabb0eac4237772aab.svg?invert_in_darkmode&sanitize=true" align=middle width=14.628015599999989pt height=14.611878600000017pt/>, <img src="/markdown/4e86697c693f7bd2ebcf1bf515fbba2f.svg?invert_in_darkmode&sanitize=true" align=middle width=16.08162434999999pt height=14.611878600000017pt/> and <img src="/markdown/fac5b28b95f69ccc2e9d37b26c68864f.svg?invert_in_darkmode&sanitize=true" align=middle width=17.24314514999999pt height=14.611878600000017pt/>.
Thus, the geometry is stored as a list of <img src="/markdown/55a049b8f161ae7cfeb0197d75aff967.svg?invert_in_darkmode&sanitize=true" align=middle width=9.86687624999999pt height=14.15524440000002pt/> 3D vectors: efficiently, we can
put these vectors in the rows of a real-valued matrix <img src="/markdown/907f9d3f474ec1dea25687fb39c395a7.svg?invert_in_darkmode&sanitize=true" align=middle width=73.77646979999999pt height=26.76175259999998pt/>. Likewise,
the connectivity is stored as a list of <img src="/markdown/0e51a2dede42189d77627c4d742822c3.svg?invert_in_darkmode&sanitize=true" align=middle width=14.433101099999991pt height=14.15524440000002pt/> triplets: efficiently, we can put
these triplets in the rows of an integer-valued matrix <img src="/markdown/c7299835acc0beb6d4c78f128f1d90cd.svg?invert_in_darkmode&sanitize=true" align=middle width=123.31228469999999pt height=26.76175259999998pt/>.
## The building blocks of an OpenGL application
> **Question:** What if we want to store a (pure-)quad mesh?
### 1. Shaders written in GLSL
### Texture Mapping
Just like OpenCL had the `.cl` file with a specific C-style language, OpenGL has the  [OpenGL shading language (glsl)](https://en.wikipedia.org/wiki/OpenGL_Shading_Language). The extensions are commonly `.glsl, .vs, .fs, .tcs` The programs in these files are called shaders.
[Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping) is a process
for mapping image information (e.g., colors) onto a surface (e.g., triangle
mesh). The standard way to define a texture mapping is to augment the 3D
geometric information of a mesh with additional 2D _parametrization_
information: where do we find each point on the texture image plane? Typically,
parameterization coordinates are bound to the unit square.
In many ways, glsl code looks like C++ code. However, there are many builtin linear algebra types (e.g., `vec3` is a 3D-vector type) and geometric functions (e.g., `dot(a,b)` computes the [dot product](https://en.wikipedia.org/wiki/Dot_product) between vectors `a` and `b`. Since vectors are often used to represent spatial coordinates *or* colors. We can index the coordinates of a vector (`vec3 a`) using `a.r`, `a.g`, `a.b` or `a.x`, `a.y`, `a.z`. When working with [perspective projection](https://en.wikipedia.org/wiki/3D_projection#Perspective_projection) its often useful to employ 4D [homogeneous coordinates](https://en.wikipedia.org/wiki/Homogeneous_coordinates) vectors: `vec4` in glsl. Glsl has many builtin ways to work with differently sized vectors and matrices. For example, if we have `vec4 h` then we can write `vec3 p = h.xyz;` to grab the first three coordinates. Similarly, we could write: `vec4 h = vec4(p,1.0)` to convert a 3D Cartesian point to a 4D homogeneous point.
Mapping a 3D flat polygon to 2D is rather straightforward. The problem of
finding a good mapping from a 3D surface to 2D becomes much harder if our
surface is not flat (e.g., like a
[hemisphere](https://en.wikipedia.org/wiki/Hemisphere)), if the surface does not
have exact one boundary (e.g., like a sphere) or if the surface has "holes"
(e.g., like a [torus/doughnut](https://en.wikipedia.org/wiki/Torus)).
Fortunately, there are many online resources and googling a glsl-related question often returns helpful answers.
Curved surfaces must get _distorted_ when flattened onto the plane. This is why
[Greenland looks bigger than
Africa](https://www.youtube.com/watch?v=vVX-PrBRtTY) on a common map of the
Earth.
### 2. On the CPU side
The lack or presence of too many boundaries or the presence of "doughnut holes"
in surfaces implies that we need to "cut" the surface to lay out it on the
plane so all parts of the surface are "face up". _Think about trying to flatten
a deflated basketball on the ground._
The shaders you write in this assignment will run on the [GPU](https://en.wikipedia.org/wiki/Graphics_processing_unit). Lets briefly describe whats happening on the [CPU](https://en.wikipedia.org/wiki/Central_processing_unit) side.
### Normals
For a smooth surface, knowing the surface geometry (i.e., position in space)
near a point fully determines the [normal
vector](https://en.wikipedia.org/wiki/Normal_(geometry)) at that point.
For a discrete mesh, the normal is only well-defined in the middle of planar
faces (e.g., inside the triangles of a triangle mesh, but not along the edges or
at vertices). Furthermore, if we use these normals for rendering, the surface
will have a faceted appearance. This appearance is mathematically correct, but
not necessarily desired if we wish to display a smooth looking surface.
[Phong](https://en.wikipedia.org/wiki/Bui_Tuong_Phong) realized that [linearly
interpolating](https://en.wikipedia.org/wiki/Linear_interpolation) normals
stored at the corners of each triangle leads to a [smooth
appearance](https://en.wikipedia.org/wiki/Phong_shading#Phong_interpolation).
This raises the question: what normals should we put at vertices or corners of
our mesh?
For a faceted surface (e.g., a cube), all corners of a planar face <img src="/markdown/190083ef7a1625fbc75f243cffb9c96d.svg?invert_in_darkmode&sanitize=true" align=middle width=9.81741584999999pt height=22.831056599999986pt/> should
share the face's normal <img src="/markdown/aa0f607fb8a0f302675de85aeabededc.svg?invert_in_darkmode&sanitize=true" align=middle width=59.845697999999985pt height=26.76175259999998pt/> .
For a smooth surface (e.g., a sphere), corners of triangles located at the same
vertex should share the same normal vector. This way the rendering is continuous
across the vertex. A common way to define per-vertex normals is to take a
weighted average of normals from incident faces. Different weighting schemes are
possible: uniform average (easy, but sensitive to irregular triangulations),
angle-weighted (geometrically well motivated, but not robust near zero-area
triangles), area-weighted (geometrically reasonable, well behaved). In this
assignment, we'll compute area-weighted per-vertex normals:
<p align="center"><img src="/markdown/599fe3b222b5898bd240d6ac12d5c5b5.svg?invert_in_darkmode&sanitize=true" align=middle width=161.40208425pt height=41.4976122pt/></p>
where <img src="/markdown/f947b3c602ca948910b99f1601e5abed.svg?invert_in_darkmode&sanitize=true" align=middle width=36.34324319999999pt height=24.65753399999998pt/> is the set of faces neighboring the <img src="/markdown/6c4adbc36120d62b98deef2a20d5d303.svg?invert_in_darkmode&sanitize=true" align=middle width=8.55786029999999pt height=14.15524440000002pt/>-th vertex.
![Unique triangle normals (orange) are well-defined. We can define a notion of a
normal for each vertex (purple) by taking a (weighted) average of normals from
incident triangles.](markdown/per-vertex-normal.png)
For surfaces with a mixture of smooth-looking parts and creases, it is useful to
define normals independently for each triangle corner (as opposed to each mesh
vertex). For each corner, we'll again compute an area-weighted average of normals
triangles incident on the shared vertex at this corner, but we'll ignore
triangle's whose normal is too different from the corner's face's normal:
<p align="center"><img src="/markdown/cc96dd182e07003c6232739259df10ec.svg?invert_in_darkmode&sanitize=true" align=middle width=245.6981736pt height=42.4291164pt/></p>
where <img src="/markdown/1926c401973f24b4db4f35dca2eb381d.svg?invert_in_darkmode&sanitize=true" align=middle width=6.672392099999992pt height=14.15524440000002pt/> is the minimum dot product between two face normals before we declare
there is a crease between them.
![`./normals` should open a viewing window. Toggling `1`,`2`,`3` should switch
between normal types. Notice that per-face has sharp corners, but a faceted
appearance in the curved regions; the per-vertex has nice smooth regions but
ugly corners where averaging acts up; and per-corner is the best of both
worlds.](markdown/fandisk-normals.png)
### .obj File Format
A common file format to save meshes is the [.obj file format](https://en.wikipedia.org/wiki/Wavefront_.obj_file), which contains a _face_-based representation. The connectivity/topological data is stored implicitly by a list of faces made out of vertices. Per vertex, three main types of geometric information can be stored:
- 3D position information of a vertex (denoted as `v` in the file, and `V` in the src code)
- 3D normal vector information of a vertex (`vn`, or `NV` in src code)
- 2D parameterization information (e.g. texture coordinate) of a vertex (`vt`, or `UV` in the src code)
Take a cube for example. You could construct a mesh with 6 faces, each having 1 normal vector, and 4 vertices per face. You could make it so that each vertex has a 2D texture coordinate.
![cube.png](markdown/cube.png)
In an .obj file, a face is defined as a list of indices pointing towards certain lines of `v`, `vt` and/or `vn`. For example :
```
v 0.0 0.0 0.0 # 3D position 1
v 2.0 0.0 0.0 # 2
v 1.0 2.0 0.0 # 3
vt 0.0 0.0 # 2D texture coordinate 1
vt 1.0 0.0 # 2
vt 0.5 1.0 # 3
vn 0.0 0.0 1.0 # 3D normal vector 1
# some examples faces that can be made:
f 1 2 3 # face 1: a face made of 3 vertices, with 3D positions 1,2,3
f 1/1 2/2 3/3 # face 2: same as face 1, but with 2D texture coordinates 1,2,3 respectively
f 1//1 2//1 3//1 # face 3: same as face 1, but with normal vector 1 for each vertex
f 1/1/1 2/2/1 3/3/1 # face 4: each vertex has a position, texture coordinate and normal vector
```
> **Warning:** In an .obj file, indexing always starts at `1`, not `0`!
This is just an example of course. Faces can have more than 3 vertices, can have vertices with different normal vectors, and the order of faces does not matter.
### Subdivision Surfaces
A [subdivision surface](https://en.wikipedia.org/wiki/Subdivision_surface) is a
natural generalization of a [spline
curve](https://en.wikipedia.org/wiki/Spline_(mathematics)). A smooth spline can
be defined as the [limit](https://en.wikipedia.org/wiki/Limit_(mathematics)) of
a [recursive
process](https://en.wikipedia.org/wiki/Recursion_(computer_science)) applied to
a polygon: each edge of the polygon is split with a new vertex and the vertices
are smoothed toward eachother. If you've drawn smooth curves using Adobe
Illustrator, PowerPoint or Inkscape, then you've used splines.
At a high-level, subdivision surfaces work the same way. We start with a
polyhedral mesh and subdivide each face. This adds new vertices on the faces
and/or edges of the mesh. Then we smooth vertices toward each other.
The first and still (most) popular subdivision scheme was invented by
[Catmull](https://en.wikipedia.org/wiki/Edwin_Catmull) (who went on to co-found
[Pixar](https://en.wikipedia.org/wiki/Pixar)) and
[Clark](https://en.wikipedia.org/wiki/James_H._Clark) (founder of
[Silicon Graphics](https://en.wikipedia.org/wiki/Silicon_Graphics) and
[Netscape](https://en.wikipedia.org/wiki/Netscape)). [Catmull-Clark
subdivision](https://en.wikipedia.org/wiki/CatmullClark_subdivision_surface) is
defined for inputs meshes with arbitrary polygonal faces (triangles, quads,
pentagons, etc.) but always produces a pure-quad mesh as output (i.e., all faces
have 4 sides).
To keep things simple, in this assignment we'll assume the input is also a
pure-quad mesh.
![Running `./quad_subdivision` and repeated pressing _space_ will show this
[Bob](http://www.cs.cmu.edu/~kmcrane/Projects/ModelRepository/#bob) converging
toward a smooth surface.](markdown/bob-subdivision.gif)
## Mesh Viewers
(Optional) In this assignment, you will create meshes that you can save to an .obj file thanks to `write_obj.cpp`. If you would like to view these meshes in something other than the `libigl` viewer we provide, you can open the .obj files in:
1. [Mesh Lab](http://www.meshlab.net) free, open-source. **_Warning_:** Mesh Lab does not appear
to respect user-provided normals in .obj files.
2. [Blender](https://www.blender.org/download/): free, open-source. If you want to see the texture, you will have to make a shader with an image texture.
3. [Autodesk Maya](https://en.wikipedia.org/wiki/Autodesk_Maya) is a commericial 3D
modeling and animation software. They often have [free student versions](https://www.autodesk.com/education/free-software/maya).
## Almost ready to start implementing
### Eigen Matrices
This assignment use the Eigen library. This section contains some useful syntax:
A pseudo-code version of `main.cpp` might look like:
```
Eigen::MatrixXi A; // creates a 0x0 matrix of integers
A.resize(10, 3); // resizes the matrix to 10x3 (meaning 10 rows, 3 columns)
Eigen::MatrixXd B; // creates a 0x0 matrix of doubles
B.resize(10, 3); // important, always use resize() !
Eigen::MatrixXd C = Eigen::MatrixXd::Zero(10, 3); // here C.resize() is not necessary
C.row(0) = Eigen::RowVector3d(0, 0, 1); // overwrite the first row of C
C.row(5); // gives the 5th row of C, as an Eigen::RowVectorXd
C(5,0); // gives the element on row=5 and column=0 of C
main()
initialize window
copy mesh vertex positions V and face indices F to GPU
while window is open
if shaders have not been compiled or files have changed
compile shaders and send to GPU
send "uniform" data to GPU
set all pixels to background color
tell GPU to draw mesh
sleep a few milliseconds
```
### White list
### 3. Window
You're encouraged to use `#include <Eigen/Geometry>` to compute the [cross
product](https://en.wikipedia.org/wiki/Cross_product) of two 3D vectors
`.cross`.
Creating a window is clearly something that will depend on the operating system (e.g., Mac OS X, Linux, Windows). This assignment, like many small scale graphics programs or games, uses an open source windowing toolkit called [glfw](https://en.wikipedia.org/wiki/GLFW). It works on all major operating systems. Once the window is open we have access to its contents as an RGB image. The job of our programs are to fill in all the pixels of this image with colors. The windowing toolkit also handles interactions with the mouse and keyboard as well as window resizing.
### Black list
## OpenGL shaders
This assignment uses [libigl](http://libigl.github.io) for mesh viewing. libigl
has many mesh processing functions implemented in C++, including some of the
functions assigned here. Do not copy or look at the following implementations:
Shaders are compiled *at runtime*. Compilation errors (usually syntax errors) will be output from the main program and the window will turn black (background color).
`igl::per_vertex_normals`
`igl::per_face_normals`
`igl::per_corner_normals`
`igl::double_area`
`igl::vertex_triangle_adjacency`
`igl::writeOBJ`
In this project, you will also be using 4 types of shaders. Each time `glDrawElements()` is called on the CPU, the shaders are executed in the following order:
# Tasks
1. vertex shader
2. tessellation control shader
3. tessellation evaluation shader
4. fragment shader
## Part 1: Understanding the .OBJ File Format
Once you have implemented the files below, run
```
Linux: ./obj ../data/rubiks-cube.png ../data/earth-square.png
Windows: obj.exe ../../../data/rubiks-cube.png ../../../data/earth-square.png
```
to open a window showing your cube being rendered. If you press 'Escape', it will close and the second window displaying your sphere will pop up. They should look like this:
Below is a simplified example of a **vertex shader**, which is called once per vertex. In this project, the 3D position `pos_vs_in` of each vertex is passed to OpenGL in `GlHelper::createVAO()`. This is indicated through the keyword `in`. This data is considered an “attribute” of each vertex. Constants (or `uniform`s) like `project` have the same value over all shaders. Uniform data is usually changed once per draw frame, or per "object". Variables that need to be passed to the next shader are indicated by `out`. The goal of the vertex shader is to write the _screen space_ position of the vertex to `gl_Position`.
![Running `./obj` will first pop up a viewer with your generated cube textured
with a [Rubik's
cube](https://en.wikipedia.org/wiki/Rubik%27s_Cube)](markdown/rubiks-cube.gif)
```cpp
#version 410 core // alway necessary as first line
![After closing that window, another viewer will pop up with your generated sphere textured
with the earth.](markdown/earth.gif)
uniform mat4 project; // perspective projection matrix
> Tip: look at the **header file** of each function to implement.
in vec3 pos_vs_in; // 3D position of mesh vertex
### `src/write_obj.cpp`
The input is a mesh with
1. 3D vertex positions (`V`)
2. 2D parametrization positions (`UV`)
3. 3D normal vectors (`NV`)
4. the vertices making up the faces (`F`), denoted as indices of `V`
5. the uvs of the faces (`UF`), denoted as indices of `UV`
5. the normal vectors of the faces (`UF`), denoted as indices of `NV`
The goal is to write the mesh to an `.obj` file.
> **Note:** This assignment covers only a small subset of meshes and mesh-data that the `.obj` file format supports.
### `src/cube.cpp`
Construct the **quad** mesh of a cube including parameterization and per-face
normals.
> **Hint:** Draw out on paper and _label_ with indices the 3D cube, the 2D
> parameterized cube, and the normals.
### `src/sphere.cpp` (optional, not included in rating)
Construct a **quad** mesh of a sphere with `num_faces_u` × `num_faces_v` faces. Take a look at UV spheres or [equirectangular projection/mapping](https://www.youtube.com/watch?v=15dVTZg0rhE).
The equirectangular projection basically defines how a 3D vertex `(x,y,z)` on the sphere is mapped to a 2D texture coordinate `(u,v)`, and vice versa. To go from `(u,v)` to `(x,y,z)` (although some flipping of axes might be necessary):
out vec3 pos_fs_in; // passed to next shader
void main() {
pos_fs_in = pos_vs_in;
gl_Position = project * vec4(pos_vs_in, 1);
}
```
φ = 2π - 2πu # φ is horizontal and should go from 2π to 0 as u goes from 0 to 1
θ = π - πv # θ is vertical and should go from π to 0 as v goes from 0 to 1
After rasterization, the **fragment shader** is called for each pixel, to determine the value (`color`) of that pixel. For example:
x = sin(θ)cos(φ)
y = cos(θ)
z = sin(θ)sin(φ)
```cpp
#version 410 core // alway necessary as first line
in vec3 pos_fs_in; // passed from previous shader
out vec3 color; // OpenGL will write this to the screen
void main() {
color = 0.5+0.5*pos_fs_in;
}
```
> **Note**: The `v` axis of the texture coordinate is always upwards
Say that we draw a triangle to the screen. The vertex shader is called 3 times, so `pos_fs_in` has 3 different values ($A, B, C$ in the image below). Note however that after the triangle is rasterized, it can cover many pixels on the screen, hundreds to thousands. So what is the value of `pos_fs_in` ($P$) in the fragment shader (which is called once per pixel)? Answer: the value of `pos_fs_in` ($P$) for a pixel is linearly interpolated between the 3 `pos_fs_in` values ($A,B,C$) of the vertices of the triangle. The weights for the linear interpolation are the **barycentric coordinates** ($u,v,w$) of the pixel in the triangle. OpenGL takes care of this interpolation for you.
![](https://www.scratchapixel.com/images/ray-triangle/barycentriccolor.png?)
## Part 2: Calculating normal vectors
You may assume that the input .obj files will all contain faces with 3 vertices (triangles), like `fandisk.obj`. Once you have implemented the functions below, run
### Tessellation control shader
The tessellation control shader determines how to subdivide each input “patch” (i.e., triangle). Unlike the subdivision we saw with [subdivision surfaces](https://en.wikipedia.org/wiki/Subdivision_surface), the subdivision is determined independently for each triangle and *not* called recursively. The exact pattern of the resulting triangulation is left largely to implementation. As the shader programmer, you have control over:
- the number of new edges each input should split into (`gl_TessLevelOuter[1] = 5` means the edge across from vertex `1` (i.e., the edge between vertices `0` and `2`) should be split into 5 edges); and
- the number of edges to place toward the center of the patch (`gl_TessLevelInner[0] = 5` would be a good choice if `gl_TessLevelOuter[...] = 5` and a regular tessellation was desired).
To get a better understanding of tessellation, [please read this Stackoverflow post](https://stackoverflow.com/questions/24083656/tessellation-shader-opengl):
![](css/tessellation_levels.png)
Unlike the vertex or fragment shader, the tessellation control shader has access to attribute information at *all* of the vertices of a triangle. The main responsibility of this shader is setting the `gl_TessLevelOuter` and `gl_TessLevelInner` variables.
### Tesselation evaluation shader
The tessellation *evaluation* shader takes the result of the tessellation that the tessellation *control* shader has specified. This shader is called once for every vertex output during tessellation (including original corners). It has access to the attribute information of the original corners (e.g., in our code `in vec3 pos_es_in[]`) and a special variable `gl_TessCoord` containing the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) of the current vertex. Using this information, it is possible to interpolate information stored at the original corners onto the current vertex: for example, the 3D position. Like the vertex and tessellation control shader, this shader can change the 3D position of a vertex. This is the *last opportunity* to do that, since the fragment shader cannot.
## Bump mapping
#### Intuition
[Bump mapping](https://en.wikipedia.org/wiki/Bump_mapping) a technique to make a **lit** surface look like it has a lot of surface detail. However, unlike [displacement mapping](https://en.wikipedia.org/wiki/Displacement_mapping), the vertices of the mesh are not actually modified/displaced. As you can see on the image below, the geometry of the base model is unaltered by the bump map, while the displacement map moves the vertices.
<img title="" src="https://spiderlilystudio.files.wordpress.com/2020/03/maps.jpg" alt="" width="563">
Bump mapping happens in the fragment shader. Conceptually, a bump map assigns an imaginary height offset ("bump") $`h(p)`$ to each point (pixel) $`p`$ on the mesh, along the surface normal $`n̂(p)`$ at that point. If you recalculate the normal vector for that pixel, now keeping in mind the bumpy surface, you get a new normal vector $`ñ`$. If you use the new normal during the lighting calculation, e.g. Blinn Phong shading, you will get the bumpy surface look. So compared to [normal mapping](https://en.wikipedia.org/wiki/Normal_mapping), where the new normal vector is already known for each pixel, in bump mapping the new vector needs to be calculated.
#### Calculating $`ñ`$
In a mathematical sense, a normal map is non-sense. A point on a surface has a specific normal completely determined by its local geometry. The normal is the direction that goes in the *most outward* direction from the surface. That is, the normal is perpendicular to the surface. Since a surface is two dimensional, the directions that *stay on* the surface are spanned by a two dimensional *tangent plane*.
Normal mapping is useful in computer graphics because we can drape the appearance of a complex surface on top a low resolution and simple one. To create a consistent and believable looking normal map, we can first generate a plausible bump map. Each point $`p∈³`$ on the surface is moved to a new position $`p̃∈³`$ :
$$p̃(p):=p+h(p) \hat{n}(p)$$
where $`h: ℝ³ → `$ is the bump height amount function (could be negative) and $`n̂(p): ℝ³ → ℝ³`$ is the *mathematically* correct normal at $`p`$.
If our bump height $`h`$ is a smooth function over the surface, we can compute the *perceived* normal vector $`ñ`$ by taking a small [finite difference](https://en.wikipedia.org/wiki/Finite_difference) of the 3D position:
$$ñ=\frac{∂p}{∂T} × \frac{∂p}{∂B} ≈ (\frac{p̃(p+εT)p̃(p)}{ε})×(\frac{p̃(p+εB)p̃(p)}{ε})$$
where $`T,B ∈ ℝ³`$ are orthogonal [tangent and bi-tangent vectors](https://en.wikipedia.org/wiki/Tangent_vector) in the tangent plane at $`p`$ and $`ε`$ is a small number (e.g., `0.0001`). By abuse of notation, well make sure that this approximate perceived normal is unit length by dividing by its length:
$$ñ←\frac{ñ}{∥ñ∥}$$
## Before you start implementing
### How come I cant use `#include` in the GLSL shader files?
Our glsl shader programs are not compiled beforehand from files. Instead the CPU-side program must read the file contents into memory as strings and provide the raw strings to the shader compiler. Unfortunately, this means there is no `#include` preprocessor directive and sharing code across different shaders is a burden. In this assignment, it is hard coded which glsl files are read in and compiled, take a look at `path_glsl_files.h`. The used glsl files will also always be printed to the command line.
### How to debug a shader program?
Debugging shader programs must be done _visually_. Since we only see the result of *all* computation, we can use the shader pipelines ability to set screen colors to debug *all* computation simultaneously. For example, when debugging the fragment shader we can check all values at once by setting the pixel color to a value we expect (or dont expect) depending on the computation. A few useful commands come in handy:
```cpp
color = 0.5 + 0.5 * n; // will set the color based on the normal n.
// green = points up, blue = points left, red = points right
```
Linux: ./normals ../data/fandisk.obj
Windows: normals.exe ../../../data/fandisk.obj
<img src="css/normal-debug.png" title="" alt="" width="593">
```cpp
color = vec3(0.5,0.5,0) + vec3(0.5,0.5,0) * view_pos_fs_in.xyz; // will set the color based on the view position.
```
to open a window showing the fandisk being rendered using the normals calculated by you. Type '1', '2' or '3' (above qwerty/azerty on the keyboard) to switch between per-face, per-vertex and per-corner normals. The difference between per-face and per-corner is only visible when zoomed in.
![fandisk.gif](markdown/fandisk.gif)
<img src="css/position-debug.png" title="" alt="" width="593">
> Tip: look at the **header file** of each function to implement.
```cpp
color = -view_pos_fs_in.z /15 *vec3(1,1,1); // will set the color based on the distance to the camera in the z-direction.
```
### `src/triangle_area_normal.cpp`
Compute the normal vector of a 3D triangle given its corner locations. The
output vector should have length equal to the area of the triangle.
<img src="css/distance-debug.png" title="" alt="" width="599">
**Important**: this the only time where you are allowed to return normal vectors that do not have unit length (i.e. that have not been normalized).
```cpp
color = vec3(float(is_moon),1,0); // will set the color to yellow or green based on a boolean value (in this case is_moon).
```
### `src/per_face_normals.cpp`
Compute per-face normals for a triangle mesh. In other words: for each face, compute the normal vector **of unit length**.
<img src="css/bool-debug.png" title="" alt="" width="605">
### `src/per_vertex_normals.cpp`
Compute per-vertex normals for a triangle mesh. In other words: for each vertex, compute the normal vector **of unit length**, by taking a area-weighted average over the normals of all the faces with that vertex as a corner.
### Homogeneous coordinates, `vec4` vs. `vec3`
### `src/vertex_triangle_adjacency.cpp`
Compute a vertex-triangle adjacency list. For each vertex store a list of all incident faces. Tip: `emplace_back()`.
In computer graphics applications, 3D points are often stored as a `vec4 point = vec4(x,y,z,w) = vec4(x,y,z,1)` with `w = 1`. For our purposes, this makes it easy to transform the position of a vertex through multiplication with 4x4 matrices (`mat4` ). Notably a translation matrix uses the fourth column to translate the point. Most projection matrices also use the fourth column and row.
### `src/per_corner_normals.cpp`
Compute per-corner normals for a triangle mesh. The goal is to compute a **unit** normal vector for each corner C of each face F. This is done by taking the area-weighted average of normals of faces connected to C. However, an incident face's normals is only included in the area-weighted average if the angle between that face normal and that of F is smaller than a threshold (`corner_threshold` (= 20 degrees)).
However, **some vectors purely represent a direction, for example a normal vector. For such vectors, `w` needs to be zero!** For example, multiplying a normal vector with a translation `mat4` should not alter the normal vector, since the direction should stay the same. This is achieved by setting `w = 0`, so `vec4 normal = vec4(x,y,z,0)`.
## Part 3: Implementing a mesh subdivision method
-------------
### `src/catmull_clark.cpp`
## Tasks
Conduct `num_iters` iterations of [Catmull-Clark
subdivision](https://en.wikipedia.org/wiki/CatmullClark_subdivision_surface) on
a **pure quad** mesh (`V`,`F`).
You will be implementing the glsl files in the `src/` folder. This assignment works best if you implement the following tasks *in order*.
Once this is implemented, run `./quad_subdivision` (or `quad_subdivision.exe`) on your `cube.obj` or `bob.obj` (shown earlier). Press 'spacebar' to subdivide once. It should look nicely smooth and uniform from all sides:
> **Note:** the `glsl/` folder contains helper methods, for example `PI.glsl`. The glsl files in `src/` that you will implement will contain "Hints" as to which existing methods you can (and should) use.
![subdivide_cube.gif](markdown/subdivide_cube.gif)
> **Note:** we implemented the project so that **you can alter the glsl files while the `shaderpipeline` executable is running**, and the program will automatically detect the changed code, recompile the shader and use it to render the image in the window.
> Tip: First get cube.obj working before moving onto bob.obj.
**Whitelist**: `mix, normalize, length, clamp, sin, cos, abs, pow, ...`
> Tip: I think the step-by-step explanation on [Wikipedia (under "Recursive evaluation")](https://en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface) is quite clear.
**Blacklist**: `noise1, noise2, noise3, noise4`
> Tip: **perform the Catmull-Clark algorithm on paper first**, i.e. draw the cube from cube.obj on a piece of paper and manually calculate each `face point`, `edge point` and `new vertex point`. Check if these values are the same as your implementation.
The `correct results` for each task are included in this readme file; their original gifs can be found in the `css/` folder (unordered).
**Task 0: check if OpenGL works.** Run:
```
./shaderpipeline 0 (Unix)
shaderpipeline.exe 0 (Windows)
```
You should see a window pop up that looks like the image below. If you see a completely black window, something went wrong. Feel free to contact us with info about your setup.
<img src="css/test-01.png" title="" alt="" width="270">
**Task 1: basic model, view, projection.** What you see above is actually two [icosahedrons](https://en.wikipedia.org/wiki/Regular_icosahedron) being rendered to the screen, one is supposed to be a planet and the other a moon. You need to implement the transformation to project the vertices (in object space) to the screen (in screen space):
1. `1_identity.glsl`
2. `1_uniform_scale.glsl`
3. `1_translate.glsl`
4. `1_rotate_about_y.glsl`
5. `1_model.glsl`
6. `1_model_view_projection.vs`: the vertex shader, which uses the methods above to project a vertex from `object -> world -> eye -> screen` space.
7. `1_blue_and_gray.fs`: the fragment shader, which gives each pixel a color.
These should be implemented so that when you run `./shaderpipeline 1`, you get an animation of a gray moon orbiting a blue planet:
<img title="" src="css/test-02.gif" alt="" width="508">
If you press `L` this should switch to a wireframe rendering:
![](css/test-02-wireframe.gif)
**Task 2: subdivide the mesh.** Our icosahedrons are rather low poly. To subdivide each face, implement:
1. `2_tessellate_5.tcs`
Running `./shaderpipeline 2` and pressing `L` should now show that the planet and moon are subdivided, i.e. have more triangles.
![](css/test-03-wireframe.gif)
**Task 3: make the mesh round.** Make the mesh vertices sit on a sphere by implementing:
1. `3_snap_to_sphere.tes` : the tessellation evaluation shader, executed right after `2_tessellate_5.tcs`.
Running `./shaderpipeline 3` should look like:
![](css/test-04.gif)
**Task 4: light.** Our scenario is looking quite flat, let's add a point light and implement Blinn Phong shading to show the roundness of the planet and moon:
1. `4_blinn_phong.glsl`
2. `4_lit.fs`
Running `./shaderpipeline 4` should look like:
![](css/test-05.gif)
**Task 5: procedural color.** As promised, perlin noise (along with random_direction and smooth_step) returns, in this case to build the color texture of the planet and moon. **Important:** the input is now a `vec3`, so implement 3D perlin noise instead of 2D! **Important:** do not normalize the perlin noise, let it keep its inherint (negative) minimum and (positive) maximum value.
1. `5_random_direction.glsl`
2. `5_smooth_step.glsl`: use the improved version, discussed in the epilogue of the previous assignment.
3. `5_perlin_noise.glsl`
4. `5_procedural_color.glsl`
Running `./shaderpipeline 5` should look like (feel free to zoom in using the scroll wheel):
![](css/test-06.gif)
**Task 6: procedural bump.** Your perlin noise method can also be used to vary the height of the planet's and moon's surface:
1. `6_bump_position.glsl`
2. `6_tangent.glsl`
3. `6_bump.fs` : use what you learned about bump mapping earlier in this document to recalculate the normals to create a bumpy looking surface.
Running `./shaderpipeline 6` should look like:
![](css/test-07.gif)
**Task 7: get creative.** Play around in `7_planet.fs` to build your own visualization, using everything you've implemented so far. You can visualize it by running `./shaderpipeline 7`. Here is an example, but fun variations on this are also welcome:
![](css/test-08.gif)
-----
## Epilogue
This section is dedicated to the enthousiasts that want to delve deeper into OpenGL as a hobby to create their own applications. The best resource to quickly learn OpenGL is [learnopengl.com](https://learnopengl.com/). You will draw and light your own meshes in no time, while mastering the fundamentals of computer graphics.
This marks the end of the practicals. Thank you for following the Computer Graphics course. We hope that you now have a better understanding of how the graphics on your screen are created and are inspired to develop your own visualizations.
Good luck on your journey!
- Julie and Bert

View file

@ -1,11 +0,0 @@
if(TARGET igl::core)
return()
endif()
include(FetchContent)
FetchContent_Declare(
libigl
GIT_REPOSITORY https://github.com/libigl/libigl.git
GIT_TAG v2.5.0
)
FetchContent_MakeAvailable(libigl)

BIN
css/bool-debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
css/distance-debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
css/earth.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
css/normal-debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

BIN
css/position-debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
css/tessellation_levels.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
css/test-01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

BIN
css/test-02-wireframe.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
css/test-02.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
css/test-03-wireframe.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
css/test-04.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
css/test-05.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 KiB

BIN
css/test-06.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 KiB

BIN
css/test-07.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 KiB

BIN
css/test-08.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 839 KiB

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View file

@ -1,50 +0,0 @@
# This file uses centimeters as units for non-parametric coordinates.
v -2.000000 0.000000 0.000000
v -3.000000 0.000000 -1.000000
v -4.000000 0.000000 -0.000001
v -3.000000 0.000000 1.000000
v -1.000000 -1.732050 0.000000
v -1.500000 -2.598080 -1.000000
v -2.000000 -3.464100 -0.000001
v -1.500000 -2.598080 1.000000
v 1.000000 -1.732050 0.000000
v 1.500000 -2.598080 -1.000000
v 2.000000 -3.464100 -0.000001
v 1.500000 -2.598080 1.000000
v 2.000000 0.000000 0.000000
v 3.000000 0.000000 -1.000000
v 4.000000 0.000000 -0.000001
v 3.000000 0.000000 1.000000
v 1.000000 1.732050 0.000000
v 1.500000 2.598080 -1.000000
v 2.000000 3.464100 -0.000001
v 1.500000 2.598080 1.000000
v -1.000000 1.732050 0.000000
v -1.500000 2.598080 -1.000000
v -2.000000 3.464100 -0.000001
v -1.500000 2.598080 1.000000
f 6 2 1 5
f 7 3 2 6
f 8 4 3 7
f 5 1 4 8
f 10 6 5 9
f 11 7 6 10
f 12 8 7 11
f 9 5 8 12
f 14 10 9 13
f 15 11 10 14
f 16 12 11 15
f 13 9 12 16
f 18 14 13 17
f 19 15 14 18
f 20 16 15 19
f 17 13 16 20
f 22 18 17 21
f 23 19 18 22
f 24 20 19 23
f 21 17 20 24
f 2 22 21 1
f 3 23 22 2
f 4 24 23 3
f 1 21 24 4

265
glHelper.h Normal file
View file

@ -0,0 +1,265 @@
#ifndef GLHELPERS_H
#define GLHELPERS_H
#include "path_glsl_files.h"
class GlHelper {
public:
GLFWwindow* window;
std::vector<std::string> all_paths;
std::vector<std::string> vertex_shader_paths;
std::vector<std::string> tess_control_shader_paths;
std::vector<std::string> tess_evaluation_shader_paths;
std::vector<std::string> fragment_shader_paths;
double time_of_last_shader_compilation = 0;
bool isFirstCompilation = true;
GlHelper(int task) {
last_time = get_seconds();
setShaderPaths(task, all_paths, vertex_shader_paths, tess_control_shader_paths, tess_evaluation_shader_paths, fragment_shader_paths);
}
// Use GLFW and GLAD to create a window
GLFWwindow* createWindow() {
// Initialize GLFW
if (!glfwInit()) {
std::cerr << "Failed to initialize GLFW" << std::endl;
return NULL;
}
// Set GLFW to create an OpenGL context (version 440 core)
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(width, height, "shader-pipeline", NULL, NULL);
if (!window) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return NULL;
}
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Initialize GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cerr << "Failed to initialized GLAD" << std::endl;
glfwTerminate();
return NULL;
}
this->window = window;
return window;
}
// Handle window rescaling and update the projection matrix accordingly
void setPerspectiveMatrixBasedOnWindowScale() {
const auto& reshape = [](
GLFWwindow* window,
int _width,
int _height)
{
::width = _width, ::height = _height;
// windows can't handle variables named near and far.
float nearVal = 0.01f;
float farVal = 100.0f;
float top = static_cast<float>(tan(35. / 360. * M_PI)) * nearVal;
float right = top * (float)::width / (float)::height;
float left = -right;
float bottom = -top;
proj.setConstant(4, 4, 0.);
proj(0, 0) = (2.0f * nearVal) / (right - left);
proj(1, 1) = (2.0f * nearVal) / (top - bottom);
proj(0, 2) = (right + left) / (right - left);
proj(1, 2) = (top + bottom) / (top - bottom);
proj(2, 2) = -(farVal + nearVal) / (farVal - nearVal);
proj(3, 2) = -1.0f;
proj(2, 3) = -(2.0f * farVal * nearVal) / (farVal - nearVal);
};
// Set up window resizing
glfwSetWindowSizeCallback(window, reshape);
{
int width_window, height_window;
glfwGetWindowSize(window, &width_window, &height_window);
reshape(window, width_window, height_window);
}
}
// Setup a VAO from a mesh
void createVAO() {
icosahedron(V, F);
mesh_to_vao(V, F, VAO);
igl::opengl::report_gl_error("mesh_to_vao");
}
// Make GLFW listen for keyboard and mouse inputs
// and change the user input state accordingly
void setKeyboardAndMouseCallbacks() {
std::cout << R"(
Usage:
[] the window can be rescaled
[Click and drag] to orbit view
[Scroll] to translate view in and out
A,a toggle animation
L,l toggle wireframe rending
Z,z reset view to look along z-axis
)";
// Close the window if user presses ESC or CTRL+C
glfwSetKeyCallback(
window,
[](GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == 256 || (key == 67 && (mods & GLFW_MOD_CONTROL)))
{
glfwSetWindowShouldClose(window, true);
}
});
// Listen to keypresses on A, L and Z
glfwSetCharModsCallback(
window,
[](GLFWwindow* window, unsigned int codepoint, int modifier)
{
switch (codepoint)
{
case 'A':
case 'a':
is_animating ^= 1;
if (is_animating)
{
last_time = get_seconds();
}
break;
case 'L':
case 'l':
wire_frame ^= 1;
if (wire_frame) {
glDisable(GL_CULL_FACE);
}
else {
glEnable(GL_CULL_FACE);
}
break;
case 'Z':
case 'z':
view.matrix().block(0, 0, 3, 3).setIdentity();
break;
default:
std::cout << "Unrecognized key: " << (unsigned char)codepoint << std::endl;
break;
}
});
glfwSetMouseButtonCallback(
window,
[](GLFWwindow* window, int button, int action, int mods)
{
mouse_down = action == GLFW_PRESS;
});
glfwSetCursorPosCallback(
window,
[](GLFWwindow* window, double x, double y)
{
static double mouse_last_x = x;
static double mouse_last_y = y;
float dx = static_cast<float>(x - mouse_last_x);
float dy = static_cast<float>(y - mouse_last_y);
if (mouse_down)
{
// Two axis valuator with fixed up
float factor = std::abs(view.matrix()(2, 3));
view.rotate(
Eigen::AngleAxisf(
dx * factor / float(width),
Eigen::Vector3f(0, 1, 0)));
view.rotate(
Eigen::AngleAxisf(
dy * factor / float(height),
view.matrix().topLeftCorner(3, 3).inverse() * Eigen::Vector3f(1, 0, 0)));
}
mouse_last_x = x;
mouse_last_y = y;
});
glfwSetScrollCallback(window,
[](GLFWwindow* window, double xoffset, double yoffset)
{
view.matrix()(2, 3) =
std::min(std::max(view.matrix()(2, 3) + (float)yoffset, -100.0f), -2.0f);
});
}
bool glslFileChanged() {
for (std::string& path : all_paths)
{
if (last_modification_time(path) > time_of_last_shader_compilation)
{
if (isFirstCompilation) {
isFirstCompilation = false;
}
else {
std::cout << path << " has changed since last compilation attempt." << std::endl;
}
return true;
}
}
return false;
}
bool compileShaderIfChanged() {
if (glslFileChanged()) {
time_of_last_shader_compilation = get_seconds();
// (re)compile shader
if (!create_shader_program_from_files(
vertex_shader_paths,
tess_control_shader_paths,
tess_evaluation_shader_paths,
fragment_shader_paths,
prog_id)) {
// failed to compile shader
glDeleteProgram(prog_id);
prog_id = 0;
return false;
}
}
return true;
}
// Update the uniforms used in the GLSL shaders
void updateShaderUniforms() {
// select program
glUseProgram(prog_id);
// Attach uniforms
{
if (is_animating)
{
double now = get_seconds();
animation_seconds += now - last_time;
last_time = now;
}
glUniform1f(glGetUniformLocation(prog_id, "animation_seconds"), static_cast<GLfloat>(animation_seconds));
}
glUniformMatrix4fv(
glGetUniformLocation(prog_id, "proj"), 1, false, proj.data());
glUniformMatrix4fv(
glGetUniformLocation(prog_id, "view"), 1, false, view.matrix().data());
// Draw mesh as wireframe
if (wire_frame)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
};
#endif

1239
glad.c Normal file

File diff suppressed because it is too large Load diff

2
glsl/PI.glsl Normal file
View file

@ -0,0 +1,2 @@
// Half the circumference of a unit circle
#define M_PI 3.1415926535897932384626433

27
glsl/bump_height.glsl Normal file
View file

@ -0,0 +1,27 @@
// Create a bumpy surface by using procedural noise to generate a height (
// displacement in normal direction).
//
// Inputs:
// is_moon whether we're looking at the moon or centre planet
// s 3D position of seed for noise generation
// Returns elevation adjust along normal (values between -0.1 and 0.1 are
// reasonable.
float bump_height( bool is_moon, vec3 s)
{
float b =
+0.05*(0.5+0.5*smooth_heaviside(perlin_noise( 1.0*s),10)*2-1)
+(0.5 + 0.44*float(!is_moon))*(0.5+0.5*smooth_heaviside((
+(0.6+0.14*float(is_moon))*perlin_noise( 2.0*s)
+(0.2-0.04*float(is_moon))*perlin_noise( 4.0*s)
+(0.2-0.1*float(is_moon))*perlin_noise( 8.0*s)
-0.005*perlin_noise( 64.0*s)
-0.001*perlin_noise( 128.0*s)
),8-float(is_moon)*-s.x*7)*2-1)
+0.01*(0.5+0.5*smooth_heaviside((
+0.1*perlin_noise( 16.0*s)
+0.8*perlin_noise( 32.0*s)
+0.1*perlin_noise( 64.0*s)
),4)*2-1)
-.5;
return 0.06*b+0.07;
}

16
glsl/interpolate.glsl Normal file
View file

@ -0,0 +1,16 @@
// Using gl_TessCoord interpolate between values stored at three corners of a
// triangle.
//
// Inputs:
// v0 value at corner 0
// v1 value at corner 1
// v2 value at corner 2
// Return linearly interpolated value based on gl_TessCoord.
vec3 interpolate(vec3 bary, vec3 v0, vec3 v1, vec3 v2)
{
return bary.x * v0 + bary.y * v1 + bary.z * v2;
}
vec4 interpolate(vec3 bary, vec4 v0, vec4 v1, vec4 v2)
{
return bary.x * v0 + bary.y * v1 + bary.z * v2;
}

8
glsl/pass-through.fs Normal file
View file

@ -0,0 +1,8 @@
in vec4 pos_fs_in;
out vec3 color;
void main()
{
// Set color to screen position to show something
color = 0.5+0.5*pos_fs_in.xyz;
}

18
glsl/pass-through.tcs Normal file
View file

@ -0,0 +1,18 @@
layout (vertices = 3) out;
in vec4 pos_cs_in[];
out vec4 pos_es_in[];
void main()
{
// Calculate the tess levels
if(gl_InvocationID == 0)
{
gl_TessLevelOuter[0] = 1;
gl_TessLevelOuter[1] = 1;
gl_TessLevelOuter[2] = 1;
gl_TessLevelInner[0] = 1;
}
pos_es_in[gl_InvocationID] = pos_cs_in[gl_InvocationID];
}

10
glsl/pass-through.tes Normal file
View file

@ -0,0 +1,10 @@
layout(triangles, equal_spacing, ccw) in;
in vec4 pos_es_in[];
out vec4 pos_fs_in;
// expects: interpolate
void main()
{
pos_fs_in = interpolate(gl_TessCoord,pos_es_in[0], pos_es_in[1], pos_es_in[2]);
gl_Position = pos_fs_in;
}

6
glsl/pass-through.vs Normal file
View file

@ -0,0 +1,6 @@
in vec4 pos_vs_in;
out vec4 pos_cs_in;
void main()
{
pos_cs_in = pos_vs_in;
}

21
glsl/random2.glsl Normal file
View file

@ -0,0 +1,21 @@
// Generate a pseudorandom 2D vector based on a 2D or 3D seed.
//
// https://thebookofshaders.com/edit.php#11/2d-gnoise.frag
//
// Inputs:
// st 2D seed
// Returns 2D random point in [0,1]²
vec2 random2(vec2 st){
st = vec2( dot(st,vec2(127.1,311.7)),
dot(st,vec2(269.5,183.3)) );
return fract(sin(st)*43758.5453123);
}
// Inputs:
// st 3D seed
// Returns 2D random point in [0,1]²
vec2 random2(vec3 st){
vec2 S = vec2( dot(st,vec3(127.1,311.7,783.089)),
dot(st,vec3(269.5,183.3,173.542)) );
return fract(sin(S)*43758.5453123);
}

View file

@ -0,0 +1,13 @@
// A useful filter, behaves like a smoothly parameterized smooth Heaviside
// function.
//
// Inputs:
// x input scalar (-inf, inf)
// t control steepness of step function: --> 0 more linear, --> inf more like
// Heaviside function (piecewise constant function x<0--> -1 , x>0 --> 1)
// Returns scalar value
float smooth_heaviside( float x, float t)
{
return (1./(1.+exp(-2.*t*(x)))-1./2.)/(1./(1.+exp(-2.*t*1.))-1./2.);
}

3
glsl/version410.glsl Normal file
View file

@ -0,0 +1,3 @@
#version 410 core
// We're using version 4.10. This should always be the first file listed and no
// other files should attempt to specify a version.

282
include/KHR/khrplatform.h Normal file
View file

@ -0,0 +1,282 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

View file

@ -1,141 +0,0 @@
#ifndef QUADVIEWER_H
#define QUADVIEWER_H
#include <igl/opengl/glfw/Viewer.h>
#include <Eigen/Core>
#include <cassert>
#include <string>
class QuadViewer
{
public:
igl::opengl::glfw::Viewer viewer;
std::function<bool(igl::opengl::glfw::Viewer& viewer, unsigned int key, int modifiers)> callback_key_pressed;
bool show_lines;
public:
QuadViewer():show_lines(true),
// Important to initialize function
callback_key_pressed([](igl::opengl::glfw::Viewer& viewer, unsigned int key, int modifiers)->bool{return false;})
{
std::cout<<R"(QuadViewer usage:
F,f [disabled]
L,l Show/hide quad eges
U,u Show/hide texture
)";
viewer.data().show_lines = false;
viewer.callback_key_pressed = [this](
igl::opengl::glfw::Viewer & /*viewer*/,
unsigned int key,
int modifier)->bool
{
if(!callback_key_pressed(viewer,key,modifier))
{
switch(key)
{
default:
return false;
case 'F':
case 'f':
// Disable Toggling "face based" since we want control of quad-mesh
// appearance
break;
case 'L':
case 'l':
// Usurp the Toggling "show lines" and map to showing overlay instead
show_lines = !show_lines;
viewer.data().show_overlay = show_lines;
break;
case 'U':
case 'u':
viewer.data().show_texture = !viewer.data().show_texture;
break;
}
}
return true;
};
}
// Set the mesh of .data() to be an exploded version of the given quad mesh
//
// Inputs:
// V #V by 3 mesh vertex positions
// F #F by 4 quad indices into V
void set_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXd & UV,
const Eigen::MatrixXd & NV,
const Eigen::MatrixXi & F)
{
assert((UV.rows() == 0 || V.rows() == UV.rows()) && "V and UV should have same #rows");
assert((NV.rows() == 0 || V.rows() == NV.rows()) && "V and NV should have same #rows");
// libigl Viewer does not handle quad meshes well by default
// Explode the quad mesh into quad soup. Then each quad can have smooth
// normals: faceted-quad appearance
Eigen::MatrixXd FV(F.rows()*4,V.cols());
Eigen::MatrixXd FUV,FNV;
if(UV.rows() != 0) FUV.resize(F.rows()*4,UV.cols());
if(NV.rows() != 0) FNV.resize(F.rows()*4,NV.cols());
Eigen::MatrixXi FF(F.rows(),4);
for(int f = 0;f<F.rows();f++)
{
for(int c = 0;c<4;c++)
{
FF(f,c) = c+f*4;
FV.row(FF(f,c)) = V.row(F(f,c));
if(UV.rows() != 0) FUV.row(FF(f,c)) = UV.row(F(f,c));
if(NV.rows() != 0) FNV.row(FF(f,c)) = NV.row(F(f,c));
}
}
Eigen::MatrixXi T(FF.rows()*2,3);
T<<
FF.col(0), FF.col(1), FF.col(2),
FF.col(0), FF.col(2), FF.col(3);
viewer.data().clear();
viewer.data().set_mesh(FV,T);
if(NV.rows() != 0) viewer.data().set_normals(FNV);
if(UV.rows() != 0) viewer.data().set_uv(FUV);
viewer.data().set_face_based(false);
Eigen::MatrixXi E(FF.rows()*4,2);
E<<
FF.col(0), FF.col(1),
FF.col(1), FF.col(2),
FF.col(2), FF.col(3),
FF.col(3), FF.col(0);
viewer.data().set_edges(FV,E,Eigen::RowVector3d(0,0,0));
}
// Wrapper without UV and NV
void set_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F)
{
return set_mesh(V,Eigen::MatrixXd(),Eigen::MatrixXd(),F);
}
// Explode all data to be per-corner so libigl viewer can handle it.
void set_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & UV,
const Eigen::MatrixXi & UF,
const Eigen::MatrixXd & NV,
const Eigen::MatrixXi & NF)
{
Eigen::MatrixXd vV(F.rows()*F.cols(),V.cols());
Eigen::MatrixXd vUV(F.rows()*F.cols(),UV.cols());
Eigen::MatrixXd vNV(F.rows()*F.cols(),NV.cols());
Eigen::MatrixXi vF(F.rows(),F.cols());
for(int f = 0;f<F.rows();f++)
{
for(int c = 0;c<F.cols();c++)
{
const int vi = f*F.cols()+c;
vV.row(vi) = V.row(F(f,c));
vUV.row(vi) = UV.row(UF(f,c));
vNV.row(vi) = NV.row(NF(f,c));
vF(f,c) = vi;
}
}
set_mesh(vV,vUV,vNV,vF);
}
// Pass through to igl::opengl::glfw::Viewer::launch
int launch(bool fullscreen = false)
{ return viewer.launch(fullscreen); }
};
#endif

57
include/REDRUM.h Normal file
View file

@ -0,0 +1,57 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_REDRUM_H
#define IGL_REDRUM_H
// Q: These should probably be inside the igl namespace. What's the correct
// way to do that?
// A: I guess the right way is to not use a macro but a proper function with
// streams as input and output.
// ANSI color codes for formatting iostream style output
#ifdef WIN32
// Bold Red, etc.
#define NORUM(X) X
#define BOLD(X) X
#define REDRUM(X) X
#define GREENRUM(X) X
#define YELLOWRUM(X) X
#define BLUERUM(X) X
#define MAGENTARUM(X) X
#define CYANRUM(X) X
// Regular Red, etc.
#define REDGIN(X) X
#define GREENGIN(X) X
#define YELLOWGIN(X) X
#define BLUEGIN(X) X
#define MAGENTAGIN(X) X
#define CYANGIN(X) X
#else
// Bold Red, etc.
#define NORUM(X) ""<<X<<""
#define REDRUM(X) "\e[1m\e[31m"<<X<<"\e[m"
#define GREENRUM(X) "\e[1m\e[32m"<<X<<"\e[m"
#define YELLOWRUM(X) "\e[1m\e[33m"<<X<<"\e[m"
#define BLUERUM(X) "\e[1m\e[34m"<<X<<"\e[m"
#define MAGENTARUM(X) "\e[1m\e[35m"<<X<<"\e[m"
#define CYANRUM(X) "\e[1m\e[36m"<<X<<"\e[m"
// Regular Red, etc.
#define REDGIN(X) "\e[31m"<<X<<"\e[m"
#define GREENGIN(X) "\e[32m"<<X<<"\e[m"
#define YELLOWGIN(X) "\e[33m"<<X<<"\e[m"
#define BLUEGIN(X) "\e[34m"<<X<<"\e[m"
#define MAGENTAGIN(X) "\e[35m"<<X<<"\e[m"
#define CYANGIN(X) "\e[36m"<<X<<"\e[m"
#define BOLD(X) "\e[1m"<<X<<"\e[m"
#endif
#endif

18
include/STR.h Normal file
View file

@ -0,0 +1,18 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_STR_H
#define IGL_STR_H
// http://stackoverflow.com/a/2433143/148668
#include <string>
#include <sstream>
// Suppose you have a function:
// void func(std::string c);
// Then you can write:
// func(STR("foo"<<1<<"bar"));
#define STR(X) static_cast<std::ostringstream&>(std::ostringstream().flush() << X).str()
#endif

View file

@ -1,22 +0,0 @@
#ifndef CATMULL_CLARK_H
#define CATMULL_CLARK_H
#include <Eigen/Core>
// Conduct num_iters iterations of Catmull-Clark subdivision on a **pure quad**
// mesh (V,F).
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 4 list of quad mesh indices into V
// num_iters number of iterations
// Outputs:
// SV #SV by 3 list of vertex positions
// SF #SF by 4 list of quad mesh indices into SV
//
void catmull_clark(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const int num_iters,
Eigen::MatrixXd & SV,
Eigen::MatrixXi & SF);
#endif

View file

@ -0,0 +1,153 @@
#ifndef CREATE_SHADER_PROGRAM_FROM_FILES_H
#define CREATE_SHADER_PROGRAM_FROM_FILES_H
#include <string>
#include <vector>
// Create a GLSL shader program given a list of paths containing shader code for
// each shader in the vertex-tessellation-fragment shader pipeline. Prints error
// messages on failure.
//
// Inputs:
// vertex_shader_paths ordered list of paths to files containing glsl vertex
// shader code.
// tess_control_shader_paths ordered list of paths to files containing glsl
// tessellation control shader code.
// tess_evaluation_shader_paths ordered list of paths to files containing glsl
// tessellation evaluation shader code.
// fragment_shader_paths ordered list of paths to files containing glsl fragment
// shader code.
// Outputs:
// id identifier of compiled shader program
// Returns true iff success
inline bool create_shader_program_from_files(
const std::vector<std::string> & vertex_shader_paths,
const std::vector<std::string> & tess_control_shader_paths,
const std::vector<std::string> & tess_evaluation_shader_paths,
const std::vector<std::string> & fragment_shader_paths,
GLuint & id);
// Implementation
#include <iostream>
#include <fstream>
#include "REDRUM.h"
#include "STR.h"
#include "print_shader_info_log.h"
#include "print_program_info_log.h"
inline bool create_shader_program_from_files(
const std::vector<std::string> & vertex_shader_paths,
const std::vector<std::string> & tess_control_shader_paths,
const std::vector<std::string> & tess_evaluation_shader_paths,
const std::vector<std::string> & fragment_shader_paths,
GLuint & id)
{
const auto create_compile_attach = [](
const std::vector<std::string> & paths,
const GLenum type,
const GLuint prog_id,
GLuint & s) -> bool
{
const std::string type_str =
(type == GL_VERTEX_SHADER ? STR(BOLD("vertex shader")) :
(type == GL_FRAGMENT_SHADER ? STR(BOLD("fragment shader")) :
(type == GL_TESS_CONTROL_SHADER ? STR(BOLD("tessellation control shader")) :
(type == GL_TESS_EVALUATION_SHADER ? STR(BOLD("tessellation evaluation shader")) :
"unknown shader"))));
int total_length = 0;
std::vector<std::string> strs;
{
for(int p = 0;p<paths.size();p++)
{
const auto & path = paths[p];
std::ifstream t(path);
if(t.fail())
{
std::cerr<<REDRUM("ERROR")<<": failed to open "<<path<<std::endl;
return false;
}
std::stringstream buffer;
buffer << t.rdbuf();
if(p!=0)
{
strs.push_back(STR(std::endl<<"#line 1 "<<p<<std::endl));
}
strs.push_back(buffer.str());
total_length += static_cast<int>(buffer.str().length());
}
}
std::vector<const char *> cstrs;
for(const auto & str : strs)
{
cstrs.emplace_back(str.c_str());
}
if(total_length == 0)
{
std::cerr<<YELLOWRUM("WARNING")<<": "<<type_str<<" is empty..."<<std::endl;;
s = 0;
return false;
}
s = glCreateShader(type);
if(s == 0)
{
std::cerr<<"failed to create "<<type_str<<std::endl;
return false;
}
{
glShaderSource(s,(GLsizei)cstrs.size(),&cstrs[0],NULL);
}
glCompileShader(s);
print_shader_info_log(type_str,s,paths);
if(!glIsShader(s))
{
std::cerr<<type_str<<" failed to compile."<<std::endl;
return false;
}
glAttachShader(prog_id,s);
return true;
};
// create program
id = glCreateProgram();
if(id == 0)
{
std::cerr<<REDRUM("ERROR")<<": could not create shader program."<<std::endl;
return false;
}
// create shaders
GLuint v=0,tc=0,te=0,f=0;
create_compile_attach(vertex_shader_paths,GL_VERTEX_SHADER,id,v);
create_compile_attach(tess_control_shader_paths,GL_TESS_CONTROL_SHADER,id,tc);
create_compile_attach(tess_evaluation_shader_paths,GL_TESS_EVALUATION_SHADER,id,te);
create_compile_attach(fragment_shader_paths,GL_FRAGMENT_SHADER,id,f);
// Link program
glLinkProgram(id);
const auto & detach = [&id](const GLuint shader)
{
if(shader)
{
glDetachShader(id,shader);
glDeleteShader(shader);
}
};
detach(f);
detach(v);
// print log if any
print_program_info_log(id);
GLint status;
glGetProgramiv(id,GL_LINK_STATUS,&status);
if(status != GL_TRUE)
{
std::cerr<<REDRUM("ERROR")<<": Failed to link shader program"<<std::endl;
return false;
}
std::cout<<GREENRUM("shader compilation successful.")<<std::endl;
return true;
}
#endif

View file

@ -1,22 +0,0 @@
#ifndef CUBE_H
#define CUBE_H
#include <Eigen/Core>
// Construct the quad mesh of a cube.
//
// Outputs:
// V 8 by 3 list of 3D corner vertex positions
// F 6 by 4 list of quad face indices into rows of V
// UV 14 by 2 list of corner parameterization positions
// UF 6 by 4 list of quad face indices into rows of UV
// NV 6 by 3 list of 3D unit normal vectors
// NF 6 by 4 list of quad face indices into rows of NV
void cube(
Eigen::MatrixXd & V,
Eigen::MatrixXi & F,
Eigen::MatrixXd & UV,
Eigen::MatrixXi & UF,
Eigen::MatrixXd & NV,
Eigen::MatrixXi & NF);
#endif

14
include/get_seconds.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef GET_SECONDS_H
#define GET_SECONDS_H
// Return current epoch time in seconds
double get_seconds();
// Implementation
#include <chrono>
double get_seconds()
{
return
std::chrono::duration<double>(
std::chrono::system_clock::now().time_since_epoch()).count();
}
#endif

2401
include/glad/glad.h Normal file

File diff suppressed because it is too large Load diff

63
include/icosahedron.h Normal file
View file

@ -0,0 +1,63 @@
#ifndef ICOSAHEDRON_H
#define ICOSAHEDRON_H
#include <Eigen/Core>
// Construct a triangle mesh of an icosahedron.
//
// Outputs:
// V 12 by 3 list of 3D mesh vertex positions
// F 20 by 3 list of triangle indices into V
template <
typename DerivedV,
typename DerivedF
>
inline void icosahedron(
Eigen::PlainObjectBase<DerivedV> & V,
Eigen::PlainObjectBase<DerivedF> & F);
// Implementation
template <
typename DerivedV,
typename DerivedF
>
inline void icosahedron(
Eigen::PlainObjectBase<DerivedV> & V,
Eigen::PlainObjectBase<DerivedF> & F)
{
V = (DerivedV(12,3) <<
0,0,1,
0.72360679774997894,-0.52573111211913359,0.44721359549995793,
0.72360679774997894,0.52573111211913359,0.44721359549995793,
-0.27639320225002095,0.85065080835203999,0.44721359549995793,
-0.89442719099991586,1.0953573965284052e-16,0.44721359549995793,
-0.27639320225002112,-0.85065080835203988,0.44721359549995793,
0.89442719099991586,0,-0.44721359549995793,
0.27639320225002106,0.85065080835203988,-0.44721359549995793,
-0.72360679774997883,0.5257311121191337,-0.44721359549995793,
-0.72360679774997894,-0.52573111211913348,-0.44721359549995793,
0.27639320225002084,-0.85065080835203999,-0.44721359549995793,
0,0,-1).finished();
F = (DerivedF(20,3)<<
0,1,2,
0,2,3,
0,3,4,
0,4,5,
0,5,1,
1,6,2,
2,7,3,
3,8,4,
4,9,5,
5,10,1,
6,7,2,
7,8,3,
8,9,4,
9,10,5,
10,6,1,
6,11,7,
7,11,8,
8,11,9,
9,11,10,
10,11,6).finished();
}
#endif

View file

@ -0,0 +1,64 @@
#ifndef LAST_MODIFICATION_TIME_H
#define LAST_MODIFICATION_TIME_H
#include <string>
// Inputs:
// path path to file in question
// Returns the last time this file has been modified in seconds.
double last_modification_time(const std::string & path);
// Implementation
#if WIN32
// Shot in the dark... I don't even know if this compiles
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <cassert>
double last_modification_time(const std::string & path)
{
// https://www.rosettacode.org/wiki/File_modification_time#Windows
FILETIME modtime;
//SYSTEMTIME st;
HANDLE fh;
std::wstring w_path = std::wstring(path.begin(), path.end());
fh = CreateFileW(w_path.c_str(), GENERIC_READ | FILE_WRITE_ATTRIBUTES,
0, NULL, OPEN_EXISTING, 0, NULL);
if(fh == INVALID_HANDLE_VALUE)
{
return -1;
}
if(GetFileTime(fh, NULL, NULL, &modtime) == 0)
{
return -1;
}
CloseHandle(fh);
// https://stackoverflow.com/a/19709740/148668
__int64* val = (__int64*) &modtime;
return static_cast<double>(*val) / 10000000.0 - 11644473600.0;
}
#else
#include <sys/stat.h>
#include <sys/time.h>
#include <ctime>
#include <fcntl.h>
double last_modification_time(const std::string & path)
{
struct stat s;
struct timespec t = {0,0};
if (stat(path.c_str(), &s) < 0) { return -1; }
#ifdef __APPLE__
t = s.st_mtimespec;
#else // Linux?
t = s.st_mtim;
#endif
return double(t.tv_sec) + double(t.tv_nsec)*1e-9;
}
#endif
#endif

38
include/load_shader.h Normal file
View file

@ -0,0 +1,38 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL_LOAD_SHADER_H
#define IGL_OPENGL_LOAD_SHADER_H
#include "../igl_inline.h"
#include "gl.h"
#include <string>
namespace igl
{
namespace opengl
{
// Creates and compiles a shader from a given string
//
// Inputs:
// src string containing GLSL shader code
// type GLSL type of shader, one of:
// GL_VERTEX_SHADER
// GL_FRAGMENT_SHADER
// GL_GEOMETRY_SHADER
// Returns index id of the newly created shader, 0 on error
//
// Will immediately return 0 if src is empty.
IGL_INLINE GLuint load_shader(
const std::string & src,const GLenum type);
}
}
// Implementation
#endif

40
include/mesh_to_vao.h Normal file
View file

@ -0,0 +1,40 @@
#ifndef MESH_TO_VAO_H
#define MESH_TO_VAO_H
#include <Eigen/Core>
// Send a triangle mesh to the GPU using a vertex array object.
//
// Inputs:
// V #V by 3 list of 3D mesh vertex positions
// F #F by 3 list of triangle indices into V
// Outputs:
// VAO identifier of compiled vertex array object.
inline void mesh_to_vao(
const Eigen::Matrix< float,Eigen::Dynamic,3,Eigen::RowMajor> & V,
const Eigen::Matrix<GLuint,Eigen::Dynamic,3,Eigen::RowMajor> & F,
GLuint & VAO);
// Implementation
inline void mesh_to_vao(
const Eigen::Matrix< float,Eigen::Dynamic,3,Eigen::RowMajor> & V,
const Eigen::Matrix<GLuint,Eigen::Dynamic,3,Eigen::RowMajor> & F,
GLuint & VAO)
{
// Generate and attach buffers to vertex array
glGenVertexArrays(1, &VAO);
GLuint VBO, EBO;
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*V.size(), V.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*F.size(), F.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
#endif

269
include/path_glsl_files.h Normal file
View file

@ -0,0 +1,269 @@
#ifndef PATH_GLSL_FILES_H
#define PATH_GLSL_FILES_H
static void setShaderPaths(int task,
std::vector<std::string>& all_paths,
std::vector<std::string>& vertex_shader_paths,
std::vector<std::string>& tess_control_shader_paths,
std::vector<std::string>& tess_evaluation_shader_paths,
std::vector<std::string>& fragment_shader_paths) {
if (task == 0) {
vertex_shader_paths = {
"/glsl/pass-through.vs"
};
tess_control_shader_paths = {
"/glsl/pass-through.tcs"
};
tess_evaluation_shader_paths = {
"/glsl/interpolate.glsl",
"/glsl/pass-through.tes"
};
fragment_shader_paths = {
"/glsl/pass-through.fs"
};
}
else if (task == 1) {
vertex_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/src/1_model.glsl",
"/src/1_model_view_projection.vs",
};
tess_control_shader_paths = {
"/glsl/pass-through.tcs",
};
tess_evaluation_shader_paths = {
"/glsl/interpolate.glsl",
"/glsl/pass-through.tes",
};
fragment_shader_paths = {
"/src/1_blue_and_gray.fs",
};
}
else if (task == 2) {
vertex_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/src/1_model.glsl",
"/src/1_model_view_projection.vs",
};
tess_control_shader_paths = {
"/src/2_tessellate_5.tcs",
};
tess_evaluation_shader_paths = {
"/glsl/interpolate.glsl",
"/glsl/pass-through.tes",
};
fragment_shader_paths = {
"/src/1_blue_and_gray.fs",
};
}
else if (task == 3) {
vertex_shader_paths = {
"/glsl/pass-through.vs"
};
tess_control_shader_paths = {
"/src/2_tessellate_5.tcs",
};
tess_evaluation_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/glsl/interpolate.glsl",
"/src/1_model.glsl",
"/src/3_snap_to_sphere.tes",
};
fragment_shader_paths = {
"/src/1_blue_and_gray.fs",
};
}
else if (task == 4) {
vertex_shader_paths = {
"/glsl/pass-through.vs"
};
tess_control_shader_paths = {
"/src/2_tessellate_5.tcs",
};
tess_evaluation_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/glsl/interpolate.glsl",
"/src/1_model.glsl",
"/src/3_snap_to_sphere.tes",
};
fragment_shader_paths = {
"/glsl/PI.glsl",
"/src/4_blinn_phong.glsl",
"/src/4_lit.fs",
};
}
else if (task == 5) {
vertex_shader_paths = {
"/glsl/pass-through.vs"
};
tess_control_shader_paths = {
"/src/2_tessellate_5.tcs",
};
tess_evaluation_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/glsl/interpolate.glsl",
"/src/1_model.glsl",
"/src/3_snap_to_sphere.tes",
};
fragment_shader_paths = {
"/glsl/PI.glsl",
"/glsl/random2.glsl",
"/src/5_random_direction.glsl",
"/src/5_smooth_step.glsl",
"/src/5_perlin_noise.glsl",
"/src/4_blinn_phong.glsl",
"/src/5_procedural_color.fs",
};
}
else if (task == 6) {
vertex_shader_paths = {
"/glsl/pass-through.vs"
};
tess_control_shader_paths = {
"/src/2_tessellate_5.tcs",
};
tess_evaluation_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/glsl/interpolate.glsl",
"/src/1_model.glsl",
"/src/3_snap_to_sphere.tes",
};
fragment_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/glsl/interpolate.glsl",
"/src/1_model.glsl",
"/glsl/random2.glsl",
"/src/5_random_direction.glsl",
"/src/5_smooth_step.glsl",
"/src/5_perlin_noise.glsl",
"/src/4_blinn_phong.glsl",
"/glsl/smooth_heaviside.glsl",
"/glsl/bump_height.glsl",
"/src/6_bump_position.glsl",
"/src/6_tangent.glsl",
"/src/6_bump.fs",
};
}
else if (task == 7) {
vertex_shader_paths = {
"/glsl/pass-through.vs"
};
tess_control_shader_paths = {
"/src/2_tessellate_5.tcs",
};
tess_evaluation_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/glsl/interpolate.glsl",
"/src/1_model.glsl",
"/src/3_snap_to_sphere.tes",
};
fragment_shader_paths = {
"/glsl/PI.glsl",
"/src/1_identity.glsl",
"/src/1_uniform_scale.glsl",
"/src/1_translate.glsl",
"/src/1_rotate_about_y.glsl",
"/glsl/interpolate.glsl",
"/src/1_model.glsl",
"/glsl/random2.glsl",
"/src/5_random_direction.glsl",
"/src/5_smooth_step.glsl",
"/src/5_perlin_noise.glsl",
"/src/4_blinn_phong.glsl",
"/glsl/smooth_heaviside.glsl",
"/glsl/bump_height.glsl",
"/src/6_bump_position.glsl",
"/src/6_tangent.glsl",
"/src/7_planet.fs",
};
}
// Print to command line
std::cout << "==== Used glsl files: ====" << std::endl;
std::cout << " vertex:" << std::endl;
for (auto& s : vertex_shader_paths) {
std::cout << " " << s << std::endl;
}
std::cout << " tessellation control:" << std::endl;
for (auto& s : tess_control_shader_paths) {
std::cout << " " << s << std::endl;
}
std::cout << " tessellation evaluation:" << std::endl;
for (auto& s : tess_evaluation_shader_paths) {
std::cout << " " << s << std::endl;
}
std::cout << " fragment:" << std::endl;
for (auto& s : fragment_shader_paths) {
std::cout << " " << s << std::endl;
}
std::cout << "==========================" << std::endl;
// Add cmakelists_dir (from main.cpp)
for (std::string& s : vertex_shader_paths) {
s = cmakelists_dir + s;
}
for (std::string& s : tess_control_shader_paths) {
s = cmakelists_dir + s;
}
for (std::string& s : tess_evaluation_shader_paths) {
s = cmakelists_dir + s;
}
for (std::string& s : fragment_shader_paths) {
s = cmakelists_dir + s;
}
// Add "/glsl/version410.glsl" to the beginning of each vector
vertex_shader_paths.insert(vertex_shader_paths.begin(), cmakelists_dir + "/glsl/version410.glsl");
tess_control_shader_paths.insert(tess_control_shader_paths.begin(), cmakelists_dir + "/glsl/version410.glsl");
tess_evaluation_shader_paths.insert(tess_evaluation_shader_paths.begin(), cmakelists_dir + "/glsl/version410.glsl");
fragment_shader_paths.insert(fragment_shader_paths.begin(), cmakelists_dir + "/glsl/version410.glsl");
// Concatenate into one vector
all_paths.insert(all_paths.end(), vertex_shader_paths.begin(), vertex_shader_paths.end());
all_paths.insert(all_paths.end(), tess_control_shader_paths.begin(), tess_control_shader_paths.end());
all_paths.insert(all_paths.end(), tess_evaluation_shader_paths.begin(), tess_evaluation_shader_paths.end());
all_paths.insert(all_paths.end(), fragment_shader_paths.begin(), fragment_shader_paths.end());
}
#endif

View file

@ -1,21 +0,0 @@
#ifndef PER_CORNER_NORMALS_H
#define PER_CORNER_NORMALS_H
#include <Eigen/Core>
// Compute per corner normals for a triangle mesh by computing the area-weighted
// average of normals at incident faces whose normals deviate less than the
// provided threshold.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of mesh triangle indices into V
// corner_threshold threshold in degrees on sharp angles
// Outputs:
// N #F*3 by 3 list of mesh vertex 3D normals, where the normal
// for corner F(i,j) is at N.row(i*3+j)
void per_corner_normals(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const double corner_threshold,
Eigen::MatrixXd & N);
#endif

View file

@ -1,16 +0,0 @@
#ifndef PER_FACE_NORMALS_H
#define PER_FACE_NORMALS_H
#include <Eigen/Core>
// Compute per-face normals for a triangle mesh
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of mesh triangle indices into V
// Outputs:
// N #F by 3 list of per-face unit normal vectors
void per_face_normals(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
Eigen::MatrixXd & N);
#endif

View file

@ -1,16 +0,0 @@
#ifndef PER_VERTEX_NORMALS_H
#define PER_VERTEX_NORMALS_H
#include <Eigen/Core>
// Compute per vertex normals for a triangle mesh by computing the area-weighted
// average of normals at incident faces.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of mesh triangle indices into V
// Outputs:
// N #V by 3 list of per-face unit normal vectors
void per_vertex_normals(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
Eigen::MatrixXd & N);
#endif

View file

@ -0,0 +1,21 @@
#ifndef PRINT_OPENGL_INFO_H
#define PRINT_OPENGL_INFO_H
// Use glfw to print information about the current opengl context
// Should be called after glfwMakeContextCurrent(...)
void print_opengl_info(GLFWwindow * window);
// Implementation
#include <cstdio>
void print_opengl_info(GLFWwindow * window)
{
int major, minor, rev;
major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
rev = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);
printf("OpenGL version recieved: %d.%d.%d\n", major, minor, rev);
printf("Supported OpenGL is %s\n", (const char*)glGetString(GL_VERSION));
printf("Supported GLSL is %s\n", (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
}
#endif

View file

@ -0,0 +1,36 @@
#ifndef PRINT_PROGRAM_INFO_LOG_H
#define PRINT_PROGRAM_INFO_LOG_H
#include <string>
// Print information about a given glsl shader program.
//
// Inputs:
// obj id of object we're querying
// Returns true if printed anything.
bool print_program_info_log(const GLuint obj);
// Implementation
#include "REDRUM.h"
#include "STR.h"
bool print_program_info_log(const GLuint obj)
{
GLint infologLength = 0;
GLint charsWritten = 0;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 0)
{
char * infoLog = new char[infologLength];
glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
std::string log(infoLog);
std::cerr<<log<<std::endl;
delete[] infoLog;
return true;
}
return false;
}
#endif

View file

@ -0,0 +1,51 @@
#ifndef PRINT_SHADER_INFO_LOG_H
#define PRINT_SHADER_INFO_LOG_H
#include <string>
#include <vector>
// Print information (e.g., compilation errors and warnings) about a give glsl
// shader.
//
// Inputs:
// type_str string identifying which kind of shader we're asking about (just
// a prefix to print)
// obj id of object we're querying
// paths list of file paths containing corresponding shader source code
// (assumings `#line ...` directive has been inserted between files).
// Returns true if printed anything.
bool print_shader_info_log(
const std::string & type_str,
const GLuint obj,
const std::vector<std::string> & paths);
// Implementation
#include "REDRUM.h"
#include "STR.h"
#include <iostream>
bool print_shader_info_log(
const std::string & type_str,
const GLuint obj,
const std::vector<std::string> & paths)
{
GLint infologLength = 0;
GLint charsWritten = 0;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 0)
{
char * infoLog = new char[infologLength];
std::cerr<<REDRUM("ERROR")<<": failed to compile "<<type_str<<std::endl;
glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
std::string log(infoLog);
std::cerr<<log<<std::endl;
delete[] infoLog;
return true;
}
return false;
}
#endif

94
include/report_gl_error.h Normal file
View file

@ -0,0 +1,94 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL_REPORT_GL_ERROR_H
#define IGL_OPENGL_REPORT_GL_ERROR_H
#define IGL_INLINE inline
// Hack to allow both opengl/ and opengl2 to use this (we shouldn't allow this)
#ifndef __gl_h_
# include "gl.h"
#endif
#include <string>
namespace igl
{
namespace opengl
{
// Print last OpenGL error to stderr prefixed by specified id string
// Inputs:
// id string to appear before any error msgs
// Returns result of glGetError()
IGL_INLINE GLenum report_gl_error(const std::string id);
// No prefix
IGL_INLINE GLenum report_gl_error();
}
}
// Implementation
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "report_gl_error.h"
#include <cstdio>
IGL_INLINE GLenum igl::opengl::report_gl_error(const std::string id)
{
// http://stackoverflow.com/q/28485180/148668
// gluErrorString was deprecated
const auto gluErrorString = [](GLenum errorCode)->const char *
{
switch(errorCode)
{
default:
return "unknown error code";
case GL_NO_ERROR:
return "no error";
case GL_INVALID_ENUM:
return "invalid enumerant";
case GL_INVALID_VALUE:
return "invalid value";
case GL_INVALID_OPERATION:
return "invalid operation";
#ifndef GL_VERSION_3_0
case GL_STACK_OVERFLOW:
return "stack overflow";
case GL_STACK_UNDERFLOW:
return "stack underflow";
case GL_TABLE_TOO_LARGE:
return "table too large";
#endif
case GL_OUT_OF_MEMORY:
return "out of memory";
#ifdef GL_EXT_framebuffer_object
case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
return "invalid framebuffer operation";
#endif
}
};
GLenum err = glGetError();
if(GL_NO_ERROR != err)
{
fprintf(stderr,"GL_ERROR: %s%s\n",id.c_str(),gluErrorString(err));
}
return err;
}
IGL_INLINE GLenum igl::opengl::report_gl_error()
{
return igl::opengl::report_gl_error(std::string(""));
}
#endif

View file

@ -1,39 +0,0 @@
#ifndef SET_TEXTURE_FROM_PNG_H
#define SET_TEXTURE_FROM_PNG_H
#include <igl/opengl/ViewerData.h>
//#include <igl/png/texture_from_png.h>
#include <igl/stb/read_image.h>
#include <Eigen/Core>
#include <string>
// Read and set texture from a file (basically wrap up
// igl::png::texture_from_png because it's behaving very strangely
//
// Inputs:
// path path to .png file
// data ViewerData (e.g., returned from viewer.data())
// Returns true if file read succeeds
// Side effects:
// sets data uniform colors to white, show_texture to true, and texture colors
// to contents of file (ignoring alpha)
bool set_texture_from_png(const std::string & path,
igl::opengl::ViewerData & data)
{
Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic> R,G,B,A;
// what in the world is going on with igl::png::texture_from_png
//if(!igl::png::texture_from_png(path,R,G,B,A))
if(!igl::stb::read_image(path, R, G, B, A))
{
return false;
}
//R = R.colwise().reverse().eval();
//G = G.colwise().reverse().eval();
//B = B.colwise().reverse().eval();
// No alpha igl::png::texture_from_png seems confused...
A.setConstant(255);
data.set_texture(R,G,B,A);
const Eigen::Vector3d w(1,1,1);
data.uniform_colors( w*0.1,w,w);
data.show_texture = true;
return true;
}
#endif

View file

@ -1,29 +0,0 @@
#ifndef SPHERE_H
#define SPHERE_H
#include <Eigen/Core>
// Construct a quad mesh of a sphere wth num_faces_u × num_faces_v faces
// using a latitude-longitude Mercator parameterization.
//
// Inputs:
// num_faces_u number of faces in the longitudinal direction
// num_faces_v number of faces in the latitudinal direction
// Outputs:
// V #V by 3 list of 3D corner vertex positions
// F #F by 4 list of quad face indices into rows of V
// UV #UV by 2 list of corner parameterization positions
// UF #F by 4 list of quad face indices into rows of UV
// NV #NV by 3 list of 3D unit normal vectors
// NF #F by 4 list of quad face indices into rows of NV
void sphere(
const int num_faces_u,
const int num_faces_v,
Eigen::MatrixXd & V,
Eigen::MatrixXi & F,
Eigen::MatrixXd & UV,
Eigen::MatrixXi & UF,
Eigen::MatrixXd & NV,
Eigen::MatrixXi & NF);
#endif

View file

@ -1,18 +0,0 @@
#ifndef TRIANGLE_AREA_NORMAL_H
#define TRIANGLE_AREA_NORMAL_H
#include <Eigen/Core>
// Compute the normal vector of a 3D triangle given its corner locations. The
// output vector should have length equal to the area of the triangle.
//
// Inputs:
// a 3D position of the first corner as a **row vector**
// b 3D position of the second corner as a **row vector**
// c 3D position of the third corner as a **row vector**
// Returns the area normal of the triangle as a 3D row vector
Eigen::RowVector3d triangle_area_normal(
const Eigen::RowVector3d & a,
const Eigen::RowVector3d & b,
const Eigen::RowVector3d & c);
#endif

View file

@ -1,19 +0,0 @@
#ifndef VERTEX_TRIANGLE_ADJACENCY_H
#define VERTEX_TRIANGLE_ADJACENCY_H
#include <Eigen/Core>
#include <vector>
// Compute a vertex-triangle adjacency list. For each vertex store a list of all
// incident faces.
//
// Inputs:
// F #F by 3 list of mesh triangle indices
// num_vertices number of vertices (i.e., V.rows(); usually ==F.maxCoeff()+1)
// Outputs:
// VF num_verticess-long list of lists so that f=VF[i][j] means that face f
// is the jth face among those incident on vertex i. Adjacency faces are
// listed in no particular order (but no duplicates).
void vertex_triangle_adjacency(
const Eigen::MatrixXi & F,
const int num_vertices,
std::vector<std::vector<int> > & VF);
#endif

View file

@ -1,24 +0,0 @@
#ifndef WRITE_OBJ_H
#define WRITE_OBJ_H
#include <Eigen/Core>
#include <string>
// Write a triangle or quad mesh to a .obj file
//
// Inputs:
// filename path to .obj file
// V #V by 3 list of vertex positions
// F #F by poly=(3 or 4) list of mesh face indices into V
// UV #UV by 2 list of UV positions
// UF #F by poly list of mesh face indices into UV
// NV #NV by 3 list of normal vectors
// NF #F by poly list of mesh face indices into NV
// Returns true if write was successful
bool write_obj(
const std::string & filename,
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & UV,
const Eigen::MatrixXi & UF,
const Eigen::MatrixXd & NV,
const Eigen::MatrixXi & NF);
#endif

1
lib/eigen Submodule

@ -0,0 +1 @@
Subproject commit dd8c71e62852b2fe429edb6682ac91fd1c578a26

1
lib/glfw Submodule

@ -0,0 +1 @@
Subproject commit 23ea072c4157f2a7760d26f4d6e375833646bd88

147
main.cpp Normal file
View file

@ -0,0 +1,147 @@
#define NOMINMAX
#define _USE_MATH_DEFINES
#include <cmath>
#include <glad/glad.h>
#define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h>
#include "icosahedron.h"
#include "mesh_to_vao.h"
#include "print_opengl_info.h"
#include "get_seconds.h"
#include "report_gl_error.h"
#include "create_shader_program_from_files.h"
#include "last_modification_time.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <thread>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <algorithm>
// From CMAKE preprocessor
std::string cmakelists_dir = CMAKELISTS_SOURCE_DIR;
// Default width and height
int width = 640;
int height = 360;
GLuint prog_id = 0; // OpenGL index to shader
// some user input state
bool wire_frame = false;
bool mouse_down = false;
bool is_animating = true;
double last_time = 0;
double animation_seconds = 0;
Eigen::Affine3f view = Eigen::Affine3f::Identity() * Eigen::Translation3f(Eigen::Vector3f(0, 0, -10));
Eigen::Matrix4f proj = Eigen::Matrix4f::Identity();
GLuint VAO;
// Mesh data: RowMajor is important to directly use in OpenGL
Eigen::Matrix< float, Eigen::Dynamic, 3, Eigen::RowMajor> V;
Eigen::Matrix<GLuint, Eigen::Dynamic, 3, Eigen::RowMajor> F;
// needs to be included here
#include "glHelper.h"
int main(int argc, char* argv[])
{
// Process command line args
int task = -1;
if (argc == 2) {
try {
task = std::stoi(argv[1]); // char* to int
std::cout << "Using glsl files for task " << task << std::endl;
}
catch (...) {
std::cout << "Error: failed to parse second argument to an int: " << argv[1] << std::endl;
}
}
if (task < 0 || task > 8) {
std::cout << "Usage:" << std::endl;
std::cout << " Unix: ./shaderpipeline <task nr>" << std::endl;
std::cout << " Windows: shaderpipeline.exe <task nr>" << std::endl;
std::cout << "where <task nr> is an int in [0, 8]" << std::endl;
std::cout << "For example: ./shaderpipeline 0" << std::endl;
return 0;
}
GlHelper glHelper(task);
GLFWwindow* window = glHelper.createWindow();
if (!window) {
return -1;
}
print_opengl_info(window);
igl::opengl::report_gl_error("init");
glHelper.setPerspectiveMatrixBasedOnWindowScale();
glHelper.createVAO();
glHelper.setKeyboardAndMouseCallbacks();
// Enable depth testing and delete faces seen from the back
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// Bind the VAO, which knows where to find the vertex and triangle data
glBindVertexArray(VAO);
// Main display routine
while (!glfwWindowShouldClose(window))
{
double tic = get_seconds();
// Compile the glsl files into a shader program
if (!glHelper.compileShaderIfChanged()) {
std::cout << "Error: failed to compile shader" << std::endl;
break;
}
// Clear screen
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set viewport and output framebuffer size
glfwGetFramebufferSize(window, &::width, &::height);
glViewport(0, 0, ::width, ::height);
// Update the uniforms used in the GLSL shaders
glHelper.updateShaderUniforms();
// Render an icosahedron for the planet and moon
for (int i = 0; i < 2; i++)
{
// Set the shader uniform "is_moon"
glUniform1i(glGetUniformLocation(prog_id, "is_moon"), i == 1);
// Draw the vertices in the VAO
glDrawElements(GL_PATCHES, F.size(), GL_UNSIGNED_INT, 0);
}
// Swap the front and back buffers
glfwSwapBuffers(window);
// 60 fps
{
glfwPollEvents();
double duration = 1000000. * (get_seconds() - tic); // In microseconds
const double min_duration = 1000000. / 60.;
if (duration < min_duration)
{
std::this_thread::sleep_for(std::chrono::microseconds((int)(min_duration - duration)));
}
}
}
// Graceful exit
glfwDestroyWindow(window);
glfwTerminate();
return 1;
}

View file

@ -1,9 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="8.578936000000013pt" readme2tex:offset="-6.217248937900877e-15" version="1.1" viewBox="-52.07469 -66.326817 8.747333999999995 8.578936000000013" width="8.747333999999995pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M0.876712 -0.587796C0.846824 -0.438356 0.787049 -0.209215 0.787049 -0.159402C0.787049 0.019925 0.926526 0.109589 1.075965 0.109589C1.195517 0.109589 1.374844 0.029888 1.444583 -0.169365C1.454545 -0.18929 1.574097 -0.657534 1.633873 -0.9066L1.853051 -1.803238C1.912827 -2.022416 1.972603 -2.241594 2.022416 -2.470735C2.062267 -2.6401 2.141968 -2.929016 2.15193 -2.968867C2.30137 -3.277709 2.82939 -4.184309 3.775841 -4.184309C4.224159 -4.184309 4.313823 -3.815691 4.313823 -3.486924C4.313823 -3.237858 4.244085 -2.958904 4.164384 -2.660025L3.88543 -1.504359L3.686177 -0.747198C3.646326 -0.547945 3.556663 -0.209215 3.556663 -0.159402C3.556663 0.019925 3.696139 0.109589 3.845579 0.109589C4.154421 0.109589 4.214197 -0.139477 4.293898 -0.458281C4.433375 -1.016189 4.801993 -2.470735 4.891656 -2.859278C4.921544 -2.988792 5.449564 -4.184309 6.535492 -4.184309C6.963885 -4.184309 7.073474 -3.845579 7.073474 -3.486924C7.073474 -2.919054 6.655044 -1.783313 6.455791 -1.255293C6.366127 -1.016189 6.326276 -0.9066 6.326276 -0.707347C6.326276 -0.239103 6.674969 0.109589 7.143213 0.109589C8.079701 0.109589 8.448319 -1.344956 8.448319 -1.424658C8.448319 -1.524284 8.358655 -1.524284 8.328767 -1.524284C8.229141 -1.524284 8.229141 -1.494396 8.179328 -1.344956C8.029888 -0.816936 7.711083 -0.109589 7.163138 -0.109589C6.993773 -0.109589 6.924035 -0.209215 6.924035 -0.438356C6.924035 -0.687422 7.013699 -0.926526 7.103362 -1.145704C7.292653 -1.663761 7.711083 -2.769614 7.711083 -3.337484C7.711083 -3.985056 7.312578 -4.403487 6.56538 -4.403487S5.310087 -3.965131 4.941469 -3.437111C4.931507 -3.566625 4.901619 -3.905355 4.622665 -4.144458C4.373599 -4.353674 4.054795 -4.403487 3.805729 -4.403487C2.909091 -4.403487 2.420922 -3.765878 2.251557 -3.536737C2.201743 -4.104608 1.783313 -4.403487 1.334994 -4.403487C0.876712 -4.403487 0.687422 -4.014944 0.597758 -3.835616C0.418431 -3.486924 0.288917 -2.899128 0.288917 -2.86924C0.288917 -2.769614 0.388543 -2.769614 0.408468 -2.769614C0.508095 -2.769614 0.518057 -2.779577 0.577833 -2.998755C0.747198 -3.706102 0.946451 -4.184309 1.305106 -4.184309C1.464508 -4.184309 1.613948 -4.104608 1.613948 -3.726027C1.613948 -3.516812 1.58406 -3.407223 1.454545 -2.889166L0.876712 -0.587796Z" id="g0-109" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-109" />
</ns0:g>
</ns0:svg>

View file

@ -1,9 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="13.837003999999993pt" readme2tex:offset="1.9371820000000035" version="1.1" viewBox="-52.07469 -68.955851 5.949948999999995 13.837003999999993" width="5.949948999999995pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M3.656289 -3.985056H4.513076C4.712329 -3.985056 4.811955 -3.985056 4.811955 -4.184309C4.811955 -4.293898 4.712329 -4.293898 4.542964 -4.293898H3.716065L3.92528 -5.429639C3.965131 -5.638854 4.104608 -6.346202 4.164384 -6.465753C4.254047 -6.655044 4.423412 -6.804483 4.632628 -6.804483C4.672478 -6.804483 4.931507 -6.804483 5.120797 -6.625156C4.682441 -6.585305 4.582814 -6.236613 4.582814 -6.087173C4.582814 -5.858032 4.762142 -5.738481 4.951432 -5.738481C5.210461 -5.738481 5.499377 -5.957659 5.499377 -6.336239C5.499377 -6.794521 5.041096 -7.023661 4.632628 -7.023661C4.293898 -7.023661 3.666252 -6.844334 3.367372 -5.858032C3.307597 -5.648817 3.277709 -5.549191 3.038605 -4.293898H2.351183C2.161893 -4.293898 2.052304 -4.293898 2.052304 -4.104608C2.052304 -3.985056 2.141968 -3.985056 2.331258 -3.985056H2.988792L2.241594 -0.049813C2.062267 0.916563 1.892902 1.823163 1.374844 1.823163C1.334994 1.823163 1.085928 1.823163 0.896638 1.643836C1.354919 1.613948 1.444583 1.255293 1.444583 1.105853C1.444583 0.876712 1.265255 0.757161 1.075965 0.757161C0.816936 0.757161 0.52802 0.976339 0.52802 1.354919C0.52802 1.803238 0.966376 2.042341 1.374844 2.042341C1.92279 2.042341 2.321295 1.454545 2.500623 1.075965C2.819427 0.448319 3.048568 -0.757161 3.058531 -0.826899L3.656289 -3.985056Z" id="g0-102" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-102" />
</ns0:g>
</ns0:svg>

View file

@ -1,9 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="8.578936000000013pt" readme2tex:offset="-6.217248937900877e-15" version="1.1" viewBox="-52.07469 -66.326817 4.043873999999995 8.578936000000013" width="4.043873999999995pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M2.968867 -2.251557C3.128269 -2.251557 3.307597 -2.251557 3.307597 -2.420922C3.307597 -2.560399 3.188045 -2.560399 3.01868 -2.560399H1.404732C1.643836 -3.407223 2.201743 -3.985056 3.108344 -3.985056H3.417186C3.58655 -3.985056 3.745953 -3.985056 3.745953 -4.154421C3.745953 -4.293898 3.616438 -4.293898 3.447073 -4.293898H3.098381C1.803238 -4.293898 0.468244 -3.297634 0.468244 -1.77335C0.468244 -0.67746 1.215442 0.109589 2.271482 0.109589C2.919054 0.109589 3.566625 -0.288917 3.566625 -0.398506C3.566625 -0.428394 3.556663 -0.537983 3.466999 -0.537983C3.447073 -0.537983 3.427148 -0.537983 3.337484 -0.478207C3.028643 -0.278954 2.660025 -0.109589 2.291407 -0.109589C1.713574 -0.109589 1.215442 -0.52802 1.215442 -1.404732C1.215442 -1.753425 1.295143 -2.132005 1.325031 -2.251557H2.968867Z" id="g0-15" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-15" />
</ns0:g>
</ns0:svg>

View file

@ -1,11 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="8.85568400000001pt" readme2tex:offset="2.8504079999999945" version="1.1" viewBox="-52.07469 -66.465191 9.746438999999995 8.85568400000001" width="9.746438999999995pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M3.061519 -4.358655C3.061519 -4.47721 2.970859 -4.623661 2.782565 -4.623661C2.580324 -4.623661 2.39203 -4.428394 2.39203 -4.2401C2.39203 -4.128518 2.475716 -3.975093 2.670984 -3.975093C2.859278 -3.975093 3.061519 -4.156413 3.061519 -4.358655ZM1.583064 0.341719C1.464508 0.822914 1.094894 1.227397 0.683437 1.227397C0.592777 1.227397 0.509091 1.21345 0.432379 1.185554C0.613699 1.101868 0.669489 0.934496 0.669489 0.829888C0.669489 0.662516 0.536986 0.571856 0.397509 0.571856C0.18132 0.571856 0 0.760149 0 0.983313C0 1.248319 0.27198 1.422665 0.690411 1.422665S1.924782 1.171606 2.140971 0.320797L2.768618 -2.175841C2.789539 -2.252553 2.803487 -2.315318 2.803487 -2.419925C2.803487 -2.803487 2.475716 -3.075467 2.057285 -3.075467C1.283188 -3.075467 0.836862 -2.106102 0.836862 -2.008468C0.836862 -1.917808 0.934496 -1.917808 0.955417 -1.917808C1.039103 -1.917808 1.046077 -1.93873 1.094894 -2.043337C1.26924 -2.447821 1.63188 -2.880199 2.036364 -2.880199C2.21071 -2.880199 2.273474 -2.761644 2.273474 -2.538481C2.273474 -2.461768 2.259527 -2.364134 2.252553 -2.329265L1.583064 0.341719Z" id="g1-106" />
<ns0:path d="M5.041096 -3.745953C5.100872 -3.88543 5.140722 -3.955168 5.778331 -3.955168V-4.423412C5.529265 -4.403487 5.240349 -4.393524 4.991283 -4.393524S4.293898 -4.41345 4.084682 -4.423412V-3.955168C4.273973 -3.955168 4.562889 -3.92528 4.562889 -3.845579C4.562889 -3.835616 4.552927 -3.815691 4.513076 -3.726027L3.35741 -1.235367L2.092154 -3.955168H2.630137V-4.423412C2.30137 -4.403487 1.404732 -4.393524 1.39477 -4.393524C1.115816 -4.393524 0.667497 -4.41345 0.259029 -4.423412V-3.955168H0.896638L2.6401 -0.209215C2.759651 0.039851 2.889166 0.039851 3.01868 0.039851C3.188045 0.039851 3.287671 0.009963 3.387298 -0.199253L5.041096 -3.745953Z" id="g0-118" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g2-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-118" />
<ns0:use x="-46.027953" y="-60.542968" ns1:href="#g1-106" />
</ns0:g>
</ns0:svg>

View file

@ -1,11 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="8.85568400000001pt" readme2tex:offset="1.4943809999999944" version="1.1" viewBox="-52.07469 -66.465191 8.865463999999994 8.85568400000001" width="8.865463999999994pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M2.259527 -4.358655C2.259527 -4.470237 2.175841 -4.623661 1.980573 -4.623661C1.792279 -4.623661 1.590037 -4.442341 1.590037 -4.2401C1.590037 -4.121544 1.680697 -3.975093 1.868991 -3.975093C2.071233 -3.975093 2.259527 -4.170361 2.259527 -4.358655ZM0.836862 -0.81594C0.808966 -0.72528 0.774097 -0.641594 0.774097 -0.523039C0.774097 -0.195268 1.053051 0.069738 1.436613 0.069738C2.133998 0.069738 2.440847 -0.892653 2.440847 -0.99726C2.440847 -1.08792 2.350187 -1.08792 2.329265 -1.08792C2.231631 -1.08792 2.224658 -1.046077 2.196762 -0.969365C2.036364 -0.411457 1.729514 -0.125529 1.457534 -0.125529C1.318057 -0.125529 1.283188 -0.216189 1.283188 -0.369614C1.283188 -0.530012 1.332005 -0.662516 1.39477 -0.81594C1.464508 -1.004234 1.54122 -1.192528 1.617933 -1.373848C1.680697 -1.54122 1.931756 -2.175841 1.959651 -2.259527C1.980573 -2.329265 2.001494 -2.412951 2.001494 -2.48269C2.001494 -2.810461 1.72254 -3.075467 1.338979 -3.075467C0.648568 -3.075467 0.327771 -2.127024 0.327771 -2.008468C0.327771 -1.917808 0.425405 -1.917808 0.446326 -1.917808C0.54396 -1.917808 0.550934 -1.952677 0.571856 -2.02939C0.753176 -2.629141 1.060025 -2.880199 1.318057 -2.880199C1.429639 -2.880199 1.492403 -2.824408 1.492403 -2.636115C1.492403 -2.475716 1.45056 -2.371108 1.276214 -1.93873L0.836862 -0.81594Z" id="g1-105" />
<ns0:path d="M5.041096 -3.745953C5.100872 -3.88543 5.140722 -3.955168 5.778331 -3.955168V-4.423412C5.529265 -4.403487 5.240349 -4.393524 4.991283 -4.393524S4.293898 -4.41345 4.084682 -4.423412V-3.955168C4.273973 -3.955168 4.562889 -3.92528 4.562889 -3.845579C4.562889 -3.835616 4.552927 -3.815691 4.513076 -3.726027L3.35741 -1.235367L2.092154 -3.955168H2.630137V-4.423412C2.30137 -4.403487 1.404732 -4.393524 1.39477 -4.393524C1.115816 -4.393524 0.667497 -4.41345 0.259029 -4.423412V-3.955168H0.896638L2.6401 -0.209215C2.759651 0.039851 2.889166 0.039851 3.01868 0.039851C3.188045 0.039851 3.287671 0.009963 3.387298 -0.199253L5.041096 -3.745953Z" id="g0-118" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g2-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-118" />
<ns0:use x="-46.027953" y="-60.542968" ns1:href="#g1-105" />
</ns0:g>
</ns0:svg>

View file

@ -1,9 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="8.578936000000013pt" readme2tex:offset="-6.217248937900877e-15" version="1.1" viewBox="-52.07469 -66.326817 5.979924999999994 8.578936000000013" width="5.979924999999994pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M0.876712 -0.587796C0.846824 -0.438356 0.787049 -0.209215 0.787049 -0.159402C0.787049 0.019925 0.926526 0.109589 1.075965 0.109589C1.195517 0.109589 1.374844 0.029888 1.444583 -0.169365C1.454545 -0.18929 1.574097 -0.657534 1.633873 -0.9066L1.853051 -1.803238C1.912827 -2.022416 1.972603 -2.241594 2.022416 -2.470735C2.062267 -2.6401 2.141968 -2.929016 2.15193 -2.968867C2.30137 -3.277709 2.82939 -4.184309 3.775841 -4.184309C4.224159 -4.184309 4.313823 -3.815691 4.313823 -3.486924C4.313823 -2.86924 3.825654 -1.594022 3.666252 -1.165629C3.576588 -0.936488 3.566625 -0.816936 3.566625 -0.707347C3.566625 -0.239103 3.915318 0.109589 4.383562 0.109589C5.32005 0.109589 5.688667 -1.344956 5.688667 -1.424658C5.688667 -1.524284 5.599004 -1.524284 5.569116 -1.524284C5.469489 -1.524284 5.469489 -1.494396 5.419676 -1.344956C5.220423 -0.667497 4.891656 -0.109589 4.403487 -0.109589C4.234122 -0.109589 4.164384 -0.209215 4.164384 -0.438356C4.164384 -0.687422 4.254047 -0.926526 4.343711 -1.145704C4.533001 -1.673724 4.951432 -2.769614 4.951432 -3.337484C4.951432 -4.004981 4.523039 -4.403487 3.805729 -4.403487C2.909091 -4.403487 2.420922 -3.765878 2.251557 -3.536737C2.201743 -4.094645 1.793275 -4.403487 1.334994 -4.403487S0.687422 -4.014944 0.587796 -3.835616C0.428394 -3.496887 0.288917 -2.909091 0.288917 -2.86924C0.288917 -2.769614 0.388543 -2.769614 0.408468 -2.769614C0.508095 -2.769614 0.518057 -2.779577 0.577833 -2.998755C0.747198 -3.706102 0.946451 -4.184309 1.305106 -4.184309C1.504359 -4.184309 1.613948 -4.054795 1.613948 -3.726027C1.613948 -3.516812 1.58406 -3.407223 1.454545 -2.889166L0.876712 -0.587796Z" id="g0-110" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-110" />
</ns0:g>
</ns0:svg>

View file

@ -1,16 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="13.837003999999993pt" readme2tex:offset="1.9371820000000035" version="1.1" viewBox="-52.07469 -68.955851 21.907595999999995 13.837003999999993" width="21.907595999999995pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M2.022416 -0.009963C2.022416 -0.667497 1.77335 -1.05604 1.384807 -1.05604C1.05604 -1.05604 0.856787 -0.806974 0.856787 -0.52802C0.856787 -0.259029 1.05604 0 1.384807 0C1.504359 0 1.633873 -0.039851 1.733499 -0.129514C1.763387 -0.14944 1.77335 -0.159402 1.783313 -0.159402S1.803238 -0.14944 1.803238 -0.009963C1.803238 0.727273 1.454545 1.325031 1.125778 1.653798C1.016189 1.763387 1.016189 1.783313 1.016189 1.8132C1.016189 1.882939 1.066002 1.92279 1.115816 1.92279C1.225405 1.92279 2.022416 1.155666 2.022416 -0.009963Z" id="g0-59" />
<ns0:path d="M2.82939 -6.22665C2.82939 -6.425903 2.689913 -6.585305 2.460772 -6.585305C2.191781 -6.585305 1.92279 -6.326276 1.92279 -6.057285C1.92279 -5.867995 2.062267 -5.69863 2.30137 -5.69863C2.530511 -5.69863 2.82939 -5.927771 2.82939 -6.22665ZM2.072229 -2.480697C2.191781 -2.769614 2.191781 -2.789539 2.291407 -3.058531C2.371108 -3.257783 2.420922 -3.39726 2.420922 -3.58655C2.420922 -4.034869 2.102117 -4.403487 1.603985 -4.403487C0.667497 -4.403487 0.288917 -2.958904 0.288917 -2.86924C0.288917 -2.769614 0.388543 -2.769614 0.408468 -2.769614C0.508095 -2.769614 0.518057 -2.789539 0.56787 -2.948941C0.836862 -3.88543 1.235367 -4.184309 1.574097 -4.184309C1.653798 -4.184309 1.823163 -4.184309 1.823163 -3.865504C1.823163 -3.656289 1.753425 -3.447073 1.713574 -3.347447C1.633873 -3.088418 1.185554 -1.932752 1.026152 -1.504359C0.926526 -1.24533 0.797011 -0.916563 0.797011 -0.707347C0.797011 -0.239103 1.135741 0.109589 1.613948 0.109589C2.550436 0.109589 2.919054 -1.334994 2.919054 -1.424658C2.919054 -1.524284 2.82939 -1.524284 2.799502 -1.524284C2.699875 -1.524284 2.699875 -1.494396 2.650062 -1.344956C2.470735 -0.71731 2.141968 -0.109589 1.633873 -0.109589C1.464508 -0.109589 1.39477 -0.209215 1.39477 -0.438356C1.39477 -0.687422 1.454545 -0.826899 1.683686 -1.43462L2.072229 -2.480697Z" id="g0-105" />
<ns0:path d="M3.955168 -6.22665C3.955168 -6.41594 3.815691 -6.585305 3.576588 -6.585305C3.347447 -6.585305 3.048568 -6.356164 3.048568 -6.057285C3.048568 -5.858032 3.188045 -5.69863 3.417186 -5.69863C3.686177 -5.69863 3.955168 -5.957659 3.955168 -6.22665ZM1.952677 0.498132C1.763387 1.255293 1.285181 1.823163 0.727273 1.823163C0.667497 1.823163 0.518057 1.823163 0.33873 1.733499C0.637609 1.663761 0.787049 1.404732 0.787049 1.205479C0.787049 1.046077 0.67746 0.856787 0.408468 0.856787C0.159402 0.856787 -0.129514 1.066002 -0.129514 1.424658C-0.129514 1.823163 0.268991 2.042341 0.747198 2.042341C1.444583 2.042341 2.371108 1.514321 2.620174 0.52802L3.536737 -3.118306C3.58655 -3.317559 3.58655 -3.457036 3.58655 -3.486924C3.58655 -4.054795 3.16812 -4.403487 2.669988 -4.403487C1.653798 -4.403487 1.085928 -2.958904 1.085928 -2.86924C1.085928 -2.769614 1.185554 -2.769614 1.205479 -2.769614C1.295143 -2.769614 1.305106 -2.779577 1.384807 -2.968867C1.633873 -3.576588 2.092154 -4.184309 2.6401 -4.184309C2.779577 -4.184309 2.958904 -4.144458 2.958904 -3.726027C2.958904 -3.496887 2.929016 -3.387298 2.889166 -3.217933L1.952677 0.498132Z" id="g0-106" />
<ns0:path d="M2.859278 -6.804483C2.859278 -6.814446 2.859278 -6.914072 2.729763 -6.914072C2.500623 -6.914072 1.77335 -6.834371 1.514321 -6.814446C1.43462 -6.804483 1.325031 -6.794521 1.325031 -6.615193C1.325031 -6.495641 1.414695 -6.495641 1.564134 -6.495641C2.042341 -6.495641 2.062267 -6.425903 2.062267 -6.326276L2.032379 -6.127024L0.587796 -0.388543C0.547945 -0.249066 0.547945 -0.229141 0.547945 -0.169365C0.547945 0.059776 0.747198 0.109589 0.836862 0.109589C0.966376 0.109589 1.115816 0.019925 1.175592 -0.099626C1.225405 -0.18929 1.673724 -2.032379 1.733499 -2.281445C2.072229 -2.251557 2.889166 -2.092154 2.889166 -1.43462C2.889166 -1.364882 2.889166 -1.325031 2.859278 -1.225405C2.839352 -1.105853 2.819427 -0.986301 2.819427 -0.876712C2.819427 -0.288917 3.217933 0.109589 3.73599 0.109589C4.034869 0.109589 4.303861 -0.049813 4.523039 -0.418431C4.772105 -0.856787 4.881694 -1.404732 4.881694 -1.424658C4.881694 -1.524284 4.79203 -1.524284 4.762142 -1.524284C4.662516 -1.524284 4.652553 -1.484433 4.622665 -1.344956C4.423412 -0.617684 4.194271 -0.109589 3.755915 -0.109589C3.566625 -0.109589 3.437111 -0.219178 3.437111 -0.577833C3.437111 -0.747198 3.476961 -0.976339 3.516812 -1.135741C3.556663 -1.305106 3.556663 -1.344956 3.556663 -1.444583C3.556663 -2.092154 2.929016 -2.381071 2.082192 -2.49066C2.391034 -2.669988 2.709838 -2.988792 2.938979 -3.227895C3.417186 -3.755915 3.875467 -4.184309 4.363636 -4.184309C4.423412 -4.184309 4.433375 -4.184309 4.4533 -4.174346C4.572852 -4.154421 4.582814 -4.154421 4.662516 -4.094645C4.682441 -4.084682 4.682441 -4.07472 4.702366 -4.054795C4.224159 -4.024907 4.134496 -3.636364 4.134496 -3.516812C4.134496 -3.35741 4.244085 -3.16812 4.513076 -3.16812C4.772105 -3.16812 5.061021 -3.387298 5.061021 -3.775841C5.061021 -4.07472 4.83188 -4.403487 4.383562 -4.403487C4.104608 -4.403487 3.646326 -4.323786 2.929016 -3.526775C2.590286 -3.148194 2.201743 -2.749689 1.823163 -2.600249L2.859278 -6.804483Z" id="g0-107" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-105" />
<ns0:use x="-48.642431" y="-62.037349" ns1:href="#g0-59" />
<ns0:use x="-44.214623" y="-62.037349" ns1:href="#g0-106" />
<ns0:use x="-40.095125" y="-62.037349" ns1:href="#g0-59" />
<ns0:use x="-35.667317" y="-62.037349" ns1:href="#g0-107" />
</ns0:g>
</ns0:svg>

View file

@ -1,49 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="25.150068pt" readme2tex:offset="0" version="1.1" viewBox="91.294532 -61.041096 97.819445 25.150068" width="97.819445pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M1.444583 5.818182C1.444583 5.977584 1.444583 6.1868 1.653798 6.1868C1.872976 6.1868 1.872976 5.987547 1.872976 5.818182V0.159402C1.872976 0 1.872976 -0.209215 1.663761 -0.209215C1.444583 -0.209215 1.444583 -0.009963 1.444583 0.159402V5.818182ZM3.656289 5.818182C3.656289 5.977584 3.656289 6.1868 3.865504 6.1868C4.084682 6.1868 4.084682 5.987547 4.084682 5.818182V0.159402C4.084682 0 4.084682 -0.209215 3.875467 -0.209215C3.656289 -0.209215 3.656289 -0.009963 3.656289 0.159402V5.818182Z" id="g6-13" />
<ns0:path d="M2.475716 -5.230386C1.150685 -4.29589 0.801993 -2.817435 0.801993 -1.750436C0.801993 -0.767123 1.094894 0.760149 2.475716 1.736488C2.531507 1.736488 2.615193 1.736488 2.615193 1.652802C2.615193 1.610959 2.594271 1.597011 2.545455 1.548194C1.617933 0.711333 1.276214 -0.474222 1.276214 -1.743462C1.276214 -3.626401 1.994521 -4.546949 2.566376 -5.063014C2.594271 -5.090909 2.615193 -5.111831 2.615193 -5.1467C2.615193 -5.230386 2.531507 -5.230386 2.475716 -5.230386Z" id="g5-40" />
<ns0:path d="M0.627646 -5.230386C0.578829 -5.230386 0.495143 -5.230386 0.495143 -5.1467C0.495143 -5.111831 0.516065 -5.090909 0.557908 -5.042092C1.157659 -4.491158 1.827148 -3.549689 1.827148 -1.750436C1.827148 -0.292902 1.373848 0.808966 0.620672 1.492403C0.502117 1.610959 0.495143 1.617933 0.495143 1.652802S0.516065 1.736488 0.585803 1.736488C0.669489 1.736488 1.332005 1.276214 1.792279 0.404483C2.099128 -0.174346 2.30137 -0.927522 2.30137 -1.743462C2.30137 -2.726775 2.008468 -4.254047 0.627646 -5.230386Z" id="g5-41" />
<ns0:path d="M2.022416 -0.009963C2.022416 -0.667497 1.77335 -1.05604 1.384807 -1.05604C1.05604 -1.05604 0.856787 -0.806974 0.856787 -0.52802C0.856787 -0.259029 1.05604 0 1.384807 0C1.504359 0 1.633873 -0.039851 1.733499 -0.129514C1.763387 -0.14944 1.77335 -0.159402 1.783313 -0.159402S1.803238 -0.14944 1.803238 -0.009963C1.803238 0.727273 1.454545 1.325031 1.125778 1.653798C1.016189 1.763387 1.016189 1.783313 1.016189 1.8132C1.016189 1.882939 1.066002 1.92279 1.115816 1.92279C1.225405 1.92279 2.022416 1.155666 2.022416 -0.009963Z" id="g2-59" />
<ns0:path d="M3.716065 -3.765878C3.536737 -4.134496 3.247821 -4.403487 2.799502 -4.403487C1.633873 -4.403487 0.398506 -2.938979 0.398506 -1.484433C0.398506 -0.547945 0.946451 0.109589 1.723537 0.109589C1.92279 0.109589 2.420922 0.069738 3.01868 -0.637609C3.098381 -0.219178 3.447073 0.109589 3.92528 0.109589C4.273973 0.109589 4.503113 -0.119552 4.662516 -0.438356C4.83188 -0.797011 4.961395 -1.404732 4.961395 -1.424658C4.961395 -1.524284 4.871731 -1.524284 4.841843 -1.524284C4.742217 -1.524284 4.732254 -1.484433 4.702366 -1.344956C4.533001 -0.697385 4.353674 -0.109589 3.945205 -0.109589C3.676214 -0.109589 3.646326 -0.368618 3.646326 -0.56787C3.646326 -0.787049 3.666252 -0.86675 3.775841 -1.305106C3.88543 -1.723537 3.905355 -1.823163 3.995019 -2.201743L4.353674 -3.596513C4.423412 -3.875467 4.423412 -3.895392 4.423412 -3.935243C4.423412 -4.104608 4.303861 -4.204234 4.134496 -4.204234C3.895392 -4.204234 3.745953 -3.985056 3.716065 -3.765878ZM3.068493 -1.185554C3.01868 -1.006227 3.01868 -0.986301 2.86924 -0.816936C2.430884 -0.268991 2.022416 -0.109589 1.743462 -0.109589C1.24533 -0.109589 1.105853 -0.657534 1.105853 -1.046077C1.105853 -1.544209 1.424658 -2.769614 1.653798 -3.227895C1.96264 -3.815691 2.410959 -4.184309 2.809465 -4.184309C3.457036 -4.184309 3.596513 -3.367372 3.596513 -3.307597S3.576588 -3.188045 3.566625 -3.138232L3.068493 -1.185554Z" id="g2-97" />
<ns0:path d="M3.706102 -3.247821C3.795766 -3.347447 3.795766 -3.387298 3.795766 -3.407223C3.795766 -3.457036 3.755915 -3.506849 3.726027 -3.5467L1.683686 -6.495641H3.985056C5.668742 -6.495641 6.166874 -6.136986 6.37609 -4.562889H6.625156L6.346202 -6.804483H0.816936C0.577833 -6.804483 0.557908 -6.804483 0.557908 -6.575342L3.038605 -2.968867L0.667497 -0.268991C0.56787 -0.159402 0.56787 -0.139477 0.56787 -0.109589C0.56787 0 0.667497 0 0.816936 0H6.346202L6.625156 -2.351183H6.37609C6.196762 -0.687422 5.519303 -0.418431 3.955168 -0.418431H1.205479L3.706102 -3.247821Z" id="g4-6" />
<ns0:path d="M6.844334 -3.257783C6.993773 -3.257783 7.183064 -3.257783 7.183064 -3.457036S6.993773 -3.656289 6.854296 -3.656289H0.886675C0.747198 -3.656289 0.557908 -3.656289 0.557908 -3.457036S0.747198 -3.257783 0.896638 -3.257783H6.844334ZM6.854296 -1.325031C6.993773 -1.325031 7.183064 -1.325031 7.183064 -1.524284S6.993773 -1.723537 6.844334 -1.723537H0.896638C0.747198 -1.723537 0.557908 -1.723537 0.557908 -1.524284S0.747198 -1.325031 0.886675 -1.325031H6.854296Z" id="g4-61" />
<ns0:path d="M4.33076 -1.57609C4.442341 -1.57609 4.609714 -1.57609 4.609714 -1.743462C4.609714 -1.917808 4.449315 -1.917808 4.33076 -1.917808H1.101868C1.206476 -2.929016 2.050311 -3.682192 3.138232 -3.682192H4.33076C4.442341 -3.682192 4.609714 -3.682192 4.609714 -3.849564C4.609714 -4.02391 4.449315 -4.02391 4.33076 -4.02391H3.110336C1.8132 -4.02391 0.753176 -3.005729 0.753176 -1.750436C0.753176 -0.467248 1.827148 0.530012 3.110336 0.530012H4.33076C4.442341 0.530012 4.609714 0.530012 4.609714 0.36264C4.609714 0.188294 4.449315 0.188294 4.33076 0.188294H3.138232C2.050311 0.188294 1.206476 -0.564882 1.101868 -1.57609H4.33076Z" id="g1-50" />
<ns0:path d="M5.816189 -4.002989C5.885928 -4.267995 5.997509 -4.498132 6.555417 -4.51208C6.590286 -4.51208 6.694894 -4.519054 6.694894 -4.665504C6.694894 -4.707347 6.660025 -4.763138 6.590286 -4.763138C6.360149 -4.763138 6.102117 -4.735243 5.865006 -4.735243C5.697634 -4.735243 5.293151 -4.763138 5.125778 -4.763138C5.090909 -4.763138 4.986301 -4.763138 4.986301 -4.609714C4.986301 -4.519054 5.076961 -4.51208 5.139726 -4.51208C5.467497 -4.505106 5.586052 -4.400498 5.586052 -4.226152C5.586052 -4.170361 5.579078 -4.135492 5.558157 -4.05878L4.798007 -1.018182L3.02665 -4.644583C2.970859 -4.763138 2.956912 -4.763138 2.789539 -4.763138H1.834122C1.701619 -4.763138 1.610959 -4.763138 1.610959 -4.609714C1.610959 -4.51208 1.694645 -4.51208 1.841096 -4.51208S2.140971 -4.505106 2.287422 -4.47721L1.352927 -0.746202C1.290162 -0.481196 1.171606 -0.27198 0.627646 -0.251059C0.578829 -0.251059 0.481196 -0.244085 0.481196 -0.104608C0.481196 -0.027895 0.536986 0 0.585803 0C0.81594 0 1.073973 -0.027895 1.311083 -0.027895C1.478456 -0.027895 1.882939 0 2.050311 0C2.12005 0 2.189788 -0.034869 2.189788 -0.146451C2.189788 -0.244085 2.106102 -0.251059 2.02939 -0.251059C1.590037 -0.265006 1.590037 -0.446326 1.590037 -0.54396C1.590037 -0.571856 1.590037 -0.606725 1.617933 -0.718306L2.510585 -4.288917L4.546949 -0.118555C4.60274 -0.006974 4.630635 0 4.700374 0C4.811955 0 4.811955 -0.020922 4.846824 -0.146451L5.816189 -4.002989Z" id="g3-78" />
<ns0:path d="M2.838356 -2.75467H3.521793C3.66127 -2.75467 3.75193 -2.75467 3.75193 -2.908095C3.75193 -3.005729 3.66127 -3.005729 3.535741 -3.005729H2.887173C3.047572 -3.891407 3.103362 -4.212204 3.159153 -4.414446C3.194022 -4.56787 3.347447 -4.714321 3.514819 -4.714321C3.521793 -4.714321 3.710087 -4.714321 3.84259 -4.630635C3.556663 -4.539975 3.535741 -4.288917 3.535741 -4.247073C3.535741 -4.093649 3.654296 -3.989041 3.814695 -3.989041C4.002989 -3.989041 4.212204 -4.14944 4.212204 -4.414446C4.212204 -4.735243 3.870486 -4.909589 3.514819 -4.909589C3.20797 -4.909589 2.866252 -4.735243 2.677958 -4.38655C2.538481 -4.128518 2.48269 -3.814695 2.336239 -3.005729H1.785305C1.645828 -3.005729 1.555168 -3.005729 1.555168 -2.852304C1.555168 -2.75467 1.645828 -2.75467 1.771357 -2.75467H2.287422C2.280448 -2.712827 1.841096 -0.202242 1.673724 0.54396C1.638854 0.697385 1.520299 1.227397 1.185554 1.227397C1.17858 1.227397 1.011208 1.227397 0.878705 1.143711C1.164633 1.053051 1.185554 0.801993 1.185554 0.760149C1.185554 0.606725 1.066999 0.502117 0.9066 0.502117C0.718306 0.502117 0.509091 0.662516 0.509091 0.927522C0.509091 1.241345 0.836862 1.422665 1.185554 1.422665C1.63188 1.422665 1.93873 0.962391 2.022416 0.808966C2.273474 0.341719 2.433873 -0.516065 2.447821 -0.599751L2.838356 -2.75467Z" id="g3-102" />
<ns0:path d="M3.724035 -2.531507C3.724035 -3.075467 3.396264 -3.082441 3.375342 -3.082441C3.194022 -3.082441 2.998755 -2.894147 2.998755 -2.712827C2.998755 -2.594271 3.068493 -2.538481 3.11731 -2.496638C3.235866 -2.399004 3.375342 -2.217684 3.375342 -1.93873C3.375342 -1.624907 2.915068 -0.125529 2.085181 -0.125529C1.520299 -0.125529 1.520299 -0.627646 1.520299 -0.746202C1.520299 -1.066999 1.645828 -1.457534 1.903861 -2.106102C1.959651 -2.252553 2.001494 -2.357161 2.001494 -2.475716C2.001494 -2.838356 1.694645 -3.075467 1.338979 -3.075467C0.641594 -3.075467 0.327771 -2.12005 0.327771 -2.008468C0.327771 -1.917808 0.425405 -1.917808 0.446326 -1.917808C0.54396 -1.917808 0.550934 -1.952677 0.571856 -2.02939C0.739228 -2.601245 1.039103 -2.880199 1.318057 -2.880199C1.436613 -2.880199 1.492403 -2.803487 1.492403 -2.636115C1.492403 -2.475716 1.436613 -2.329265 1.366874 -2.168867C1.066999 -1.39477 0.990286 -1.094894 0.990286 -0.843836C0.990286 -0.153425 1.534247 0.069738 2.064259 0.069738C3.235866 0.069738 3.724035 -1.959651 3.724035 -2.531507Z" id="g3-118" />
<ns0:path d="M1.135741 -3.5467V-0.468244H0.448319V0C0.727273 -0.009963 1.325031 -0.029888 1.703611 -0.029888C2.092154 -0.029888 2.67995 -0.009963 2.958904 0V-0.468244H2.271482V-2.550436C2.271482 -3.636364 3.128269 -4.124533 3.755915 -4.124533C4.094645 -4.124533 4.303861 -3.915318 4.303861 -3.158157V-0.468244H3.616438V0C3.895392 -0.009963 4.493151 -0.029888 4.871731 -0.029888C5.260274 -0.029888 5.84807 -0.009963 6.127024 0V-0.468244H5.439601V-3.048568C5.439601 -4.094645 4.901619 -4.483188 3.905355 -4.483188C2.948941 -4.483188 2.420922 -3.915318 2.161893 -3.407223V-4.483188L0.448319 -4.403487V-3.935243C1.066002 -3.935243 1.135741 -3.935243 1.135741 -3.5467Z" id="g0-110" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="91.294532" y="-46.805649" ns1:href="#g0-110" />
<ns0:use x="97.659518" y="-45.311269" ns1:href="#g3-118" />
<ns0:use x="105.160291" y="-46.805649" ns1:href="#g4-61" />
<ns0:use x="122.406701" y="-54.233301" ns1:href="#g4-6" />
<ns0:use x="129.601961" y="-52.434474" ns1:href="#g3-102" />
<ns0:use x="134.268546" y="-52.434474" ns1:href="#g1-50" />
<ns0:use x="139.637328" y="-52.434474" ns1:href="#g3-78" />
<ns0:use x="146.695594" y="-52.434474" ns1:href="#g5-40" />
<ns0:use x="149.808937" y="-52.434474" ns1:href="#g3-118" />
<ns0:use x="154.044246" y="-52.434474" ns1:href="#g5-41" />
<ns0:use x="157.655696" y="-54.233301" ns1:href="#g2-97" />
<ns0:use x="162.921849" y="-52.73892" ns1:href="#g3-102" />
<ns0:use x="168.086564" y="-54.233301" ns1:href="#g0-110" />
<ns0:use x="174.45155" y="-52.73892" ns1:href="#g3-102" />
<ns0:rect height="0.398484" width="68.27917" x="116.871884" y="-49.495559" />
<ns0:use x="116.871884" y="-47.901622" ns1:href="#g6-13" />
<ns0:use x="116.871884" y="-41.923977" ns1:href="#g6-13" />
<ns0:use x="122.406701" y="-39.433317" ns1:href="#g4-6" />
<ns0:use x="129.601961" y="-37.63449" ns1:href="#g3-102" />
<ns0:use x="134.268546" y="-37.63449" ns1:href="#g1-50" />
<ns0:use x="139.637328" y="-37.63449" ns1:href="#g3-78" />
<ns0:use x="146.695594" y="-37.63449" ns1:href="#g5-40" />
<ns0:use x="149.808937" y="-37.63449" ns1:href="#g3-118" />
<ns0:use x="154.044246" y="-37.63449" ns1:href="#g5-41" />
<ns0:use x="157.655696" y="-39.433317" ns1:href="#g2-97" />
<ns0:use x="162.921849" y="-37.938936" ns1:href="#g3-102" />
<ns0:use x="168.086564" y="-39.433317" ns1:href="#g0-110" />
<ns0:use x="174.45155" y="-37.938936" ns1:href="#g3-102" />
<ns0:use x="179.616264" y="-47.901622" ns1:href="#g6-13" />
<ns0:use x="179.616264" y="-41.923977" ns1:href="#g6-13" />
<ns0:use x="186.346569" y="-46.805649" ns1:href="#g2-59" />
</ns0:g>
</ns0:svg>

View file

@ -1,9 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="8.578936000000013pt" readme2tex:offset="-6.217248937900877e-15" version="1.1" viewBox="-52.07469 -66.326817 5.186581999999994 8.578936000000013" width="5.186581999999994pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M4.662516 -3.706102C4.662516 -4.244085 4.403487 -4.403487 4.224159 -4.403487C3.975093 -4.403487 3.73599 -4.144458 3.73599 -3.92528C3.73599 -3.795766 3.785803 -3.73599 3.895392 -3.626401C4.104608 -3.427148 4.234122 -3.16812 4.234122 -2.809465C4.234122 -2.391034 3.626401 -0.109589 2.460772 -0.109589C1.952677 -0.109589 1.723537 -0.458281 1.723537 -0.976339C1.723537 -1.534247 1.992528 -2.261519 2.30137 -3.088418C2.371108 -3.257783 2.420922 -3.39726 2.420922 -3.58655C2.420922 -4.034869 2.102117 -4.403487 1.603985 -4.403487C0.667497 -4.403487 0.288917 -2.958904 0.288917 -2.86924C0.288917 -2.769614 0.388543 -2.769614 0.408468 -2.769614C0.508095 -2.769614 0.518057 -2.789539 0.56787 -2.948941C0.856787 -3.955168 1.285181 -4.184309 1.574097 -4.184309C1.653798 -4.184309 1.823163 -4.184309 1.823163 -3.865504C1.823163 -3.616438 1.723537 -3.347447 1.653798 -3.16812C1.215442 -2.012453 1.085928 -1.554172 1.085928 -1.125778C1.085928 -0.049813 1.96264 0.109589 2.420922 0.109589C4.094645 0.109589 4.662516 -3.188045 4.662516 -3.706102Z" id="g0-118" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-118" />
</ns0:g>
</ns0:svg>

View file

@ -1,9 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="13.141217999999995pt" readme2tex:offset="2.6645352591003757e-15" version="1.1" viewBox="-52.07469 -68.607958 3.432257999999994 13.141217999999995" width="3.432257999999994pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M2.82939 -6.22665C2.82939 -6.425903 2.689913 -6.585305 2.460772 -6.585305C2.191781 -6.585305 1.92279 -6.326276 1.92279 -6.057285C1.92279 -5.867995 2.062267 -5.69863 2.30137 -5.69863C2.530511 -5.69863 2.82939 -5.927771 2.82939 -6.22665ZM2.072229 -2.480697C2.191781 -2.769614 2.191781 -2.789539 2.291407 -3.058531C2.371108 -3.257783 2.420922 -3.39726 2.420922 -3.58655C2.420922 -4.034869 2.102117 -4.403487 1.603985 -4.403487C0.667497 -4.403487 0.288917 -2.958904 0.288917 -2.86924C0.288917 -2.769614 0.388543 -2.769614 0.408468 -2.769614C0.508095 -2.769614 0.518057 -2.789539 0.56787 -2.948941C0.836862 -3.88543 1.235367 -4.184309 1.574097 -4.184309C1.653798 -4.184309 1.823163 -4.184309 1.823163 -3.865504C1.823163 -3.656289 1.753425 -3.447073 1.713574 -3.347447C1.633873 -3.088418 1.185554 -1.932752 1.026152 -1.504359C0.926526 -1.24533 0.797011 -0.916563 0.797011 -0.707347C0.797011 -0.239103 1.135741 0.109589 1.613948 0.109589C2.550436 0.109589 2.919054 -1.334994 2.919054 -1.424658C2.919054 -1.524284 2.82939 -1.524284 2.799502 -1.524284C2.699875 -1.524284 2.699875 -1.494396 2.650062 -1.344956C2.470735 -0.71731 2.141968 -0.109589 1.633873 -0.109589C1.464508 -0.109589 1.39477 -0.209215 1.39477 -0.438356C1.39477 -0.687422 1.454545 -0.826899 1.683686 -1.43462L2.072229 -2.480697Z" id="g0-105" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-105" />
</ns0:g>
</ns0:svg>

View file

@ -1,19 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="16.21924399999999pt" readme2tex:offset="0.389517000000005" version="1.1" viewBox="-52.07469 -70.146971 44.71301199999999 16.21924399999999" width="44.71301199999999pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M1.903861 -2.329265C2.447821 -2.329265 2.838356 -1.952677 2.838356 -1.206476C2.838356 -0.341719 2.336239 -0.083686 1.931756 -0.083686C1.652802 -0.083686 1.039103 -0.160399 0.746202 -0.571856C1.073973 -0.585803 1.150685 -0.81594 1.150685 -0.962391C1.150685 -1.185554 0.983313 -1.345953 0.767123 -1.345953C0.571856 -1.345953 0.376588 -1.227397 0.376588 -0.941469C0.376588 -0.285928 1.101868 0.139477 1.945704 0.139477C2.915068 0.139477 3.584558 -0.509091 3.584558 -1.206476C3.584558 -1.750436 3.138232 -2.294396 2.371108 -2.454795C3.103362 -2.719801 3.368369 -3.242839 3.368369 -3.668244C3.368369 -4.219178 2.733748 -4.630635 1.959651 -4.630635S0.592777 -4.254047 0.592777 -3.696139C0.592777 -3.459029 0.746202 -3.326526 0.955417 -3.326526C1.171606 -3.326526 1.311083 -3.486924 1.311083 -3.682192C1.311083 -3.884433 1.171606 -4.030884 0.955417 -4.044832C1.199502 -4.351681 1.680697 -4.428394 1.93873 -4.428394C2.252553 -4.428394 2.691905 -4.274969 2.691905 -3.668244C2.691905 -3.375342 2.594271 -3.054545 2.412951 -2.838356C2.182814 -2.57335 1.987547 -2.559402 1.638854 -2.538481C1.464508 -2.524533 1.45056 -2.524533 1.415691 -2.517559C1.401743 -2.517559 1.345953 -2.503611 1.345953 -2.426899C1.345953 -2.329265 1.408717 -2.329265 1.527273 -2.329265H1.903861Z" id="g5-51" />
<ns0:path d="M4.881694 -3.270735C4.958406 -3.347447 4.979328 -3.38929 4.979328 -3.438107C4.979328 -3.549689 4.888667 -3.612453 4.811955 -3.612453C4.742217 -3.612453 4.721295 -3.591532 4.637609 -3.507846L3.110336 -1.987547L1.57609 -3.514819C1.506351 -3.584558 1.478456 -3.612453 1.415691 -3.612453C1.318057 -3.612453 1.241345 -3.535741 1.241345 -3.438107C1.241345 -3.375342 1.262267 -3.354421 1.345953 -3.270735L2.866252 -1.750436L1.345953 -0.230137C1.248319 -0.132503 1.241345 -0.097634 1.241345 -0.055791C1.241345 0.041843 1.318057 0.118555 1.415691 0.118555C1.478456 0.118555 1.499377 0.097634 1.57609 0.020922L3.110336 -1.506351L4.700374 0.083686C4.735243 0.104608 4.770112 0.118555 4.811955 0.118555C4.888667 0.118555 4.979328 0.055791 4.979328 -0.055791C4.979328 -0.111582 4.96538 -0.125529 4.944458 -0.146451C4.930511 -0.174346 3.577584 -1.527273 3.354421 -1.743462L4.881694 -3.270735Z" id="g2-2" />
<ns0:path d="M0.850809 -0.439352C0.822914 -0.348692 0.781071 -0.174346 0.781071 -0.153425C0.781071 0 0.9066 0.069738 1.018182 0.069738C1.143711 0.069738 1.255293 -0.020922 1.290162 -0.083686S1.380822 -0.369614 1.415691 -0.516065C1.45056 -0.648568 1.527273 -0.969365 1.569116 -1.143711C1.610959 -1.297136 1.652802 -1.45056 1.687671 -1.610959C1.764384 -1.896887 1.778331 -1.952677 1.980573 -2.238605C2.175841 -2.517559 2.503611 -2.880199 3.02665 -2.880199C3.431133 -2.880199 3.438107 -2.524533 3.438107 -2.39203C3.438107 -1.973599 3.138232 -1.199502 3.02665 -0.9066C2.949938 -0.711333 2.922042 -0.648568 2.922042 -0.530012C2.922042 -0.160399 3.228892 0.069738 3.584558 0.069738C4.281943 0.069738 4.588792 -0.892653 4.588792 -0.99726C4.588792 -1.08792 4.498132 -1.08792 4.47721 -1.08792C4.379577 -1.08792 4.372603 -1.046077 4.344707 -0.969365C4.184309 -0.411457 3.884433 -0.125529 3.605479 -0.125529C3.459029 -0.125529 3.431133 -0.223163 3.431133 -0.369614C3.431133 -0.530012 3.466002 -0.620672 3.591532 -0.934496C3.675218 -1.150685 3.961146 -1.889913 3.961146 -2.280448C3.961146 -2.956912 3.424159 -3.075467 3.054545 -3.075467C2.475716 -3.075467 2.085181 -2.719801 1.875965 -2.440847C1.827148 -2.922042 1.415691 -3.075467 1.129763 -3.075467C0.829888 -3.075467 0.669489 -2.859278 0.578829 -2.698879C0.425405 -2.440847 0.327771 -2.043337 0.327771 -2.008468C0.327771 -1.917808 0.425405 -1.917808 0.446326 -1.917808C0.54396 -1.917808 0.550934 -1.93873 0.599751 -2.127024C0.704359 -2.538481 0.836862 -2.880199 1.108842 -2.880199C1.290162 -2.880199 1.338979 -2.726775 1.338979 -2.538481C1.338979 -2.405978 1.276214 -2.147945 1.227397 -1.959651S1.108842 -1.48543 1.073973 -1.332005L0.850809 -0.439352Z" id="g3-110" />
<ns0:path d="M5.459527 -2.291407C5.628892 -2.291407 5.808219 -2.291407 5.808219 -2.49066S5.628892 -2.689913 5.459527 -2.689913H1.235367C1.354919 -4.024907 2.500623 -4.98132 3.905355 -4.98132H5.459527C5.628892 -4.98132 5.808219 -4.98132 5.808219 -5.180573S5.628892 -5.379826 5.459527 -5.379826H3.88543C2.181818 -5.379826 0.826899 -4.084682 0.826899 -2.49066S2.181818 0.398506 3.88543 0.398506H5.459527C5.628892 0.398506 5.808219 0.398506 5.808219 0.199253S5.628892 0 5.459527 0H3.905355C2.500623 0 1.354919 -0.956413 1.235367 -2.291407H5.459527Z" id="g1-50" />
<ns0:path d="M2.819427 -3.596513V-6.366127H3.995019C5.599004 -6.366127 5.618929 -5.589041 5.618929 -4.98132C5.618929 -4.423412 5.618929 -3.596513 3.975093 -3.596513H2.819427ZM5.479452 -3.387298C6.635118 -3.686177 7.143213 -4.333748 7.143213 -4.991283C7.143213 -5.997509 6.047323 -6.834371 4.174346 -6.834371H0.388543V-6.366127H1.464508V-0.468244H0.388543V0C0.747198 -0.029888 1.723537 -0.029888 2.141968 -0.029888S3.536737 -0.029888 3.895392 0V-0.468244H2.819427V-3.237858H3.985056C4.124533 -3.237858 4.562889 -3.237858 4.871731 -2.899128C5.190535 -2.550436 5.190535 -2.361146 5.190535 -1.633873C5.190535 -0.976339 5.190535 -0.488169 5.88792 -0.14944C6.326276 0.069738 6.94396 0.109589 7.352428 0.109589C8.418431 0.109589 8.547945 -0.787049 8.547945 -0.946451C8.547945 -1.165629 8.408468 -1.165629 8.308842 -1.165629C8.099626 -1.165629 8.089664 -1.066002 8.079701 -0.936488C8.029888 -0.468244 7.740971 -0.249066 7.442092 -0.249066C6.844334 -0.249066 6.75467 -0.956413 6.704857 -1.374844C6.684932 -1.484433 6.60523 -2.171856 6.595268 -2.221669C6.455791 -2.919054 5.907846 -3.227895 5.479452 -3.387298Z" id="g0-82" />
<ns0:path d="M7.372354 -6.146949C7.43213 -6.276463 7.47198 -6.366127 8.199253 -6.366127H8.388543V-6.834371C8.009963 -6.824408 7.531756 -6.804483 7.262765 -6.804483C6.864259 -6.804483 6.346202 -6.804483 5.957659 -6.834371V-6.366127C6.047323 -6.366127 6.834371 -6.366127 6.834371 -6.246575C6.834371 -6.206725 6.804483 -6.156912 6.794521 -6.127024L4.782067 -1.594022L2.660025 -6.366127H3.596513V-6.834371C3.217933 -6.804483 2.261519 -6.804483 1.833126 -6.804483C1.444583 -6.804483 0.607721 -6.804483 0.259029 -6.834371V-6.366127H1.175592L3.92528 -0.179328C4.004981 0 4.044832 0.079701 4.323786 0.079701C4.483188 0.079701 4.612702 0.079701 4.722291 -0.159402L7.372354 -6.146949Z" id="g0-86" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g4-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-86" />
<ns0:use x="-40.486307" y="-62.037349" ns1:href="#g1-50" />
<ns0:use x="-31.077192" y="-62.037349" ns1:href="#g0-82" />
<ns0:use x="-22.48446" y="-65.652713" ns1:href="#g3-110" />
<ns0:use x="-17.559598" y="-65.652713" ns1:href="#g2-2" />
<ns0:use x="-11.332918" y="-65.652713" ns1:href="#g5-51" />
</ns0:g>
</ns0:svg>

View file

@ -1,17 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="16.21924399999999pt" readme2tex:offset="2.850408000000005" version="1.1" viewBox="-52.07469 -70.146971 36.27011999999999 16.21924399999999" width="36.27011999999999pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M1.903861 -2.329265C2.447821 -2.329265 2.838356 -1.952677 2.838356 -1.206476C2.838356 -0.341719 2.336239 -0.083686 1.931756 -0.083686C1.652802 -0.083686 1.039103 -0.160399 0.746202 -0.571856C1.073973 -0.585803 1.150685 -0.81594 1.150685 -0.962391C1.150685 -1.185554 0.983313 -1.345953 0.767123 -1.345953C0.571856 -1.345953 0.376588 -1.227397 0.376588 -0.941469C0.376588 -0.285928 1.101868 0.139477 1.945704 0.139477C2.915068 0.139477 3.584558 -0.509091 3.584558 -1.206476C3.584558 -1.750436 3.138232 -2.294396 2.371108 -2.454795C3.103362 -2.719801 3.368369 -3.242839 3.368369 -3.668244C3.368369 -4.219178 2.733748 -4.630635 1.959651 -4.630635S0.592777 -4.254047 0.592777 -3.696139C0.592777 -3.459029 0.746202 -3.326526 0.955417 -3.326526C1.171606 -3.326526 1.311083 -3.486924 1.311083 -3.682192C1.311083 -3.884433 1.171606 -4.030884 0.955417 -4.044832C1.199502 -4.351681 1.680697 -4.428394 1.93873 -4.428394C2.252553 -4.428394 2.691905 -4.274969 2.691905 -3.668244C2.691905 -3.375342 2.594271 -3.054545 2.412951 -2.838356C2.182814 -2.57335 1.987547 -2.559402 1.638854 -2.538481C1.464508 -2.524533 1.45056 -2.524533 1.415691 -2.517559C1.401743 -2.517559 1.345953 -2.503611 1.345953 -2.426899C1.345953 -2.329265 1.408717 -2.329265 1.527273 -2.329265H1.903861Z" id="g4-51" />
<ns0:path d="M2.838356 -2.75467H3.521793C3.66127 -2.75467 3.75193 -2.75467 3.75193 -2.908095C3.75193 -3.005729 3.66127 -3.005729 3.535741 -3.005729H2.887173C3.047572 -3.891407 3.103362 -4.212204 3.159153 -4.414446C3.194022 -4.56787 3.347447 -4.714321 3.514819 -4.714321C3.521793 -4.714321 3.710087 -4.714321 3.84259 -4.630635C3.556663 -4.539975 3.535741 -4.288917 3.535741 -4.247073C3.535741 -4.093649 3.654296 -3.989041 3.814695 -3.989041C4.002989 -3.989041 4.212204 -4.14944 4.212204 -4.414446C4.212204 -4.735243 3.870486 -4.909589 3.514819 -4.909589C3.20797 -4.909589 2.866252 -4.735243 2.677958 -4.38655C2.538481 -4.128518 2.48269 -3.814695 2.336239 -3.005729H1.785305C1.645828 -3.005729 1.555168 -3.005729 1.555168 -2.852304C1.555168 -2.75467 1.645828 -2.75467 1.771357 -2.75467H2.287422C2.280448 -2.712827 1.841096 -0.202242 1.673724 0.54396C1.638854 0.697385 1.520299 1.227397 1.185554 1.227397C1.17858 1.227397 1.011208 1.227397 0.878705 1.143711C1.164633 1.053051 1.185554 0.801993 1.185554 0.760149C1.185554 0.606725 1.066999 0.502117 0.9066 0.502117C0.718306 0.502117 0.509091 0.662516 0.509091 0.927522C0.509091 1.241345 0.836862 1.422665 1.185554 1.422665C1.63188 1.422665 1.93873 0.962391 2.022416 0.808966C2.273474 0.341719 2.433873 -0.516065 2.447821 -0.599751L2.838356 -2.75467Z" id="g2-102" />
<ns0:path d="M2.819427 -3.596513V-6.366127H3.995019C5.599004 -6.366127 5.618929 -5.589041 5.618929 -4.98132C5.618929 -4.423412 5.618929 -3.596513 3.975093 -3.596513H2.819427ZM5.479452 -3.387298C6.635118 -3.686177 7.143213 -4.333748 7.143213 -4.991283C7.143213 -5.997509 6.047323 -6.834371 4.174346 -6.834371H0.388543V-6.366127H1.464508V-0.468244H0.388543V0C0.747198 -0.029888 1.723537 -0.029888 2.141968 -0.029888S3.536737 -0.029888 3.895392 0V-0.468244H2.819427V-3.237858H3.985056C4.124533 -3.237858 4.562889 -3.237858 4.871731 -2.899128C5.190535 -2.550436 5.190535 -2.361146 5.190535 -1.633873C5.190535 -0.976339 5.190535 -0.488169 5.88792 -0.14944C6.326276 0.069738 6.94396 0.109589 7.352428 0.109589C8.418431 0.109589 8.547945 -0.787049 8.547945 -0.946451C8.547945 -1.165629 8.408468 -1.165629 8.308842 -1.165629C8.099626 -1.165629 8.089664 -1.066002 8.079701 -0.936488C8.029888 -0.468244 7.740971 -0.249066 7.442092 -0.249066C6.844334 -0.249066 6.75467 -0.956413 6.704857 -1.374844C6.684932 -1.484433 6.60523 -2.171856 6.595268 -2.221669C6.455791 -2.919054 5.907846 -3.227895 5.479452 -3.387298Z" id="g0-82" />
<ns0:path d="M1.135741 -3.5467V-0.468244H0.448319V0C0.727273 -0.009963 1.325031 -0.029888 1.703611 -0.029888C2.092154 -0.029888 2.67995 -0.009963 2.958904 0V-0.468244H2.271482V-2.550436C2.271482 -3.636364 3.128269 -4.124533 3.755915 -4.124533C4.094645 -4.124533 4.303861 -3.915318 4.303861 -3.158157V-0.468244H3.616438V0C3.895392 -0.009963 4.493151 -0.029888 4.871731 -0.029888C5.260274 -0.029888 5.84807 -0.009963 6.127024 0V-0.468244H5.439601V-3.048568C5.439601 -4.094645 4.901619 -4.483188 3.905355 -4.483188C2.948941 -4.483188 2.420922 -3.915318 2.161893 -3.407223V-4.483188L0.448319 -4.403487V-3.935243C1.066002 -3.935243 1.135741 -3.935243 1.135741 -3.5467Z" id="g0-110" />
<ns0:path d="M5.459527 -2.291407C5.628892 -2.291407 5.808219 -2.291407 5.808219 -2.49066S5.628892 -2.689913 5.459527 -2.689913H1.235367C1.354919 -4.024907 2.500623 -4.98132 3.905355 -4.98132H5.459527C5.628892 -4.98132 5.808219 -4.98132 5.808219 -5.180573S5.628892 -5.379826 5.459527 -5.379826H3.88543C2.181818 -5.379826 0.826899 -4.084682 0.826899 -2.49066S2.181818 0.398506 3.88543 0.398506H5.459527C5.628892 0.398506 5.808219 0.398506 5.808219 0.199253S5.628892 0 5.459527 0H3.905355C2.500623 0 1.354919 -0.956413 1.235367 -2.291407H5.459527Z" id="g1-50" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g3-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-110" />
<ns0:use x="-45.709704" y="-60.542968" ns1:href="#g2-102" />
<ns0:use x="-37.777657" y="-62.037349" ns1:href="#g1-50" />
<ns0:use x="-28.368542" y="-62.037349" ns1:href="#g0-82" />
<ns0:use x="-19.775811" y="-65.652713" ns1:href="#g4-51" />
</ns0:g>
</ns0:svg>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

View file

@ -1,31 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="16.21924399999999pt" readme2tex:offset="2.4906600000000054" version="1.1" viewBox="-52.07469 -70.146971 74.734718 16.21924399999999" width="74.734718pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M1.903861 -2.329265C2.447821 -2.329265 2.838356 -1.952677 2.838356 -1.206476C2.838356 -0.341719 2.336239 -0.083686 1.931756 -0.083686C1.652802 -0.083686 1.039103 -0.160399 0.746202 -0.571856C1.073973 -0.585803 1.150685 -0.81594 1.150685 -0.962391C1.150685 -1.185554 0.983313 -1.345953 0.767123 -1.345953C0.571856 -1.345953 0.376588 -1.227397 0.376588 -0.941469C0.376588 -0.285928 1.101868 0.139477 1.945704 0.139477C2.915068 0.139477 3.584558 -0.509091 3.584558 -1.206476C3.584558 -1.750436 3.138232 -2.294396 2.371108 -2.454795C3.103362 -2.719801 3.368369 -3.242839 3.368369 -3.668244C3.368369 -4.219178 2.733748 -4.630635 1.959651 -4.630635S0.592777 -4.254047 0.592777 -3.696139C0.592777 -3.459029 0.746202 -3.326526 0.955417 -3.326526C1.171606 -3.326526 1.311083 -3.486924 1.311083 -3.682192C1.311083 -3.884433 1.171606 -4.030884 0.955417 -4.044832C1.199502 -4.351681 1.680697 -4.428394 1.93873 -4.428394C2.252553 -4.428394 2.691905 -4.274969 2.691905 -3.668244C2.691905 -3.375342 2.594271 -3.054545 2.412951 -2.838356C2.182814 -2.57335 1.987547 -2.559402 1.638854 -2.538481C1.464508 -2.524533 1.45056 -2.524533 1.415691 -2.517559C1.401743 -2.517559 1.345953 -2.503611 1.345953 -2.426899C1.345953 -2.329265 1.408717 -2.329265 1.527273 -2.329265H1.903861Z" id="g6-51" />
<ns0:path d="M4.881694 -3.270735C4.958406 -3.347447 4.979328 -3.38929 4.979328 -3.438107C4.979328 -3.549689 4.888667 -3.612453 4.811955 -3.612453C4.742217 -3.612453 4.721295 -3.591532 4.637609 -3.507846L3.110336 -1.987547L1.57609 -3.514819C1.506351 -3.584558 1.478456 -3.612453 1.415691 -3.612453C1.318057 -3.612453 1.241345 -3.535741 1.241345 -3.438107C1.241345 -3.375342 1.262267 -3.354421 1.345953 -3.270735L2.866252 -1.750436L1.345953 -0.230137C1.248319 -0.132503 1.241345 -0.097634 1.241345 -0.055791C1.241345 0.041843 1.318057 0.118555 1.415691 0.118555C1.478456 0.118555 1.499377 0.097634 1.57609 0.020922L3.110336 -1.506351L4.700374 0.083686C4.735243 0.104608 4.770112 0.118555 4.811955 0.118555C4.888667 0.118555 4.979328 0.055791 4.979328 -0.055791C4.979328 -0.111582 4.96538 -0.125529 4.944458 -0.146451C4.930511 -0.174346 3.577584 -1.527273 3.354421 -1.743462L4.881694 -3.270735Z" id="g2-2" />
<ns0:path d="M3.02665 -0.564882C2.991781 -0.425405 2.929016 -0.188294 2.929016 -0.153425C2.929016 0 3.054545 0.069738 3.166127 0.069738C3.291656 0.069738 3.403238 -0.020922 3.438107 -0.083686S3.528767 -0.369614 3.563636 -0.516065C3.598506 -0.648568 3.675218 -0.969365 3.717061 -1.143711C3.758904 -1.297136 3.800747 -1.45056 3.835616 -1.610959C3.912329 -1.910834 3.912329 -1.924782 4.051806 -2.140971C4.274969 -2.48269 4.623661 -2.880199 5.167621 -2.880199C5.558157 -2.880199 5.579078 -2.559402 5.579078 -2.39203C5.579078 -1.973599 5.279203 -1.199502 5.167621 -0.9066C5.090909 -0.711333 5.063014 -0.648568 5.063014 -0.530012C5.063014 -0.160399 5.369863 0.069738 5.725529 0.069738C6.422914 0.069738 6.729763 -0.892653 6.729763 -0.99726C6.729763 -1.08792 6.639103 -1.08792 6.618182 -1.08792C6.520548 -1.08792 6.513574 -1.046077 6.485679 -0.969365C6.32528 -0.411457 6.025405 -0.125529 5.746451 -0.125529C5.6 -0.125529 5.572105 -0.223163 5.572105 -0.369614C5.572105 -0.530012 5.606974 -0.620672 5.732503 -0.934496C5.816189 -1.150685 6.102117 -1.889913 6.102117 -2.280448C6.102117 -2.39203 6.102117 -2.684932 5.844085 -2.887173C5.725529 -2.977833 5.523288 -3.075467 5.195517 -3.075467C4.56787 -3.075467 4.184309 -2.66401 3.961146 -2.371108C3.905355 -2.963885 3.410212 -3.075467 3.054545 -3.075467C2.475716 -3.075467 2.085181 -2.719801 1.875965 -2.440847C1.827148 -2.922042 1.415691 -3.075467 1.129763 -3.075467C0.829888 -3.075467 0.669489 -2.859278 0.578829 -2.698879C0.425405 -2.440847 0.327771 -2.043337 0.327771 -2.008468C0.327771 -1.917808 0.425405 -1.917808 0.446326 -1.917808C0.54396 -1.917808 0.550934 -1.93873 0.599751 -2.127024C0.704359 -2.538481 0.836862 -2.880199 1.108842 -2.880199C1.290162 -2.880199 1.338979 -2.726775 1.338979 -2.538481C1.338979 -2.405978 1.276214 -2.147945 1.227397 -1.959651S1.108842 -1.48543 1.073973 -1.332005L0.850809 -0.439352C0.822914 -0.348692 0.781071 -0.174346 0.781071 -0.153425C0.781071 0 0.9066 0.069738 1.018182 0.069738C1.143711 0.069738 1.255293 -0.020922 1.290162 -0.083686S1.380822 -0.369614 1.415691 -0.516065C1.45056 -0.648568 1.527273 -0.969365 1.569116 -1.143711C1.610959 -1.297136 1.652802 -1.45056 1.687671 -1.610959C1.764384 -1.896887 1.778331 -1.952677 1.980573 -2.238605C2.175841 -2.517559 2.503611 -2.880199 3.02665 -2.880199C3.431133 -2.880199 3.438107 -2.524533 3.438107 -2.39203C3.438107 -2.217684 3.417186 -2.127024 3.319552 -1.736488L3.02665 -0.564882Z" id="g4-109" />
<ns0:path d="M2.022416 -0.009963C2.022416 -0.667497 1.77335 -1.05604 1.384807 -1.05604C1.05604 -1.05604 0.856787 -0.806974 0.856787 -0.52802C0.856787 -0.259029 1.05604 0 1.384807 0C1.504359 0 1.633873 -0.039851 1.733499 -0.129514C1.763387 -0.14944 1.77335 -0.159402 1.783313 -0.159402S1.803238 -0.14944 1.803238 -0.009963C1.803238 0.727273 1.454545 1.325031 1.125778 1.653798C1.016189 1.763387 1.016189 1.783313 1.016189 1.8132C1.016189 1.882939 1.066002 1.92279 1.115816 1.92279C1.225405 1.92279 2.022416 1.155666 2.022416 -0.009963Z" id="g3-59" />
<ns0:path d="M0.876712 -0.587796C0.846824 -0.438356 0.787049 -0.209215 0.787049 -0.159402C0.787049 0.019925 0.926526 0.109589 1.075965 0.109589C1.195517 0.109589 1.374844 0.029888 1.444583 -0.169365C1.454545 -0.18929 1.574097 -0.657534 1.633873 -0.9066L1.853051 -1.803238C1.912827 -2.022416 1.972603 -2.241594 2.022416 -2.470735C2.062267 -2.6401 2.141968 -2.929016 2.15193 -2.968867C2.30137 -3.277709 2.82939 -4.184309 3.775841 -4.184309C4.224159 -4.184309 4.313823 -3.815691 4.313823 -3.486924C4.313823 -2.86924 3.825654 -1.594022 3.666252 -1.165629C3.576588 -0.936488 3.566625 -0.816936 3.566625 -0.707347C3.566625 -0.239103 3.915318 0.109589 4.383562 0.109589C5.32005 0.109589 5.688667 -1.344956 5.688667 -1.424658C5.688667 -1.524284 5.599004 -1.524284 5.569116 -1.524284C5.469489 -1.524284 5.469489 -1.494396 5.419676 -1.344956C5.220423 -0.667497 4.891656 -0.109589 4.403487 -0.109589C4.234122 -0.109589 4.164384 -0.209215 4.164384 -0.438356C4.164384 -0.687422 4.254047 -0.926526 4.343711 -1.145704C4.533001 -1.673724 4.951432 -2.769614 4.951432 -3.337484C4.951432 -4.004981 4.523039 -4.403487 3.805729 -4.403487C2.909091 -4.403487 2.420922 -3.765878 2.251557 -3.536737C2.201743 -4.094645 1.793275 -4.403487 1.334994 -4.403487S0.687422 -4.014944 0.587796 -3.835616C0.428394 -3.496887 0.288917 -2.909091 0.288917 -2.86924C0.288917 -2.769614 0.388543 -2.769614 0.408468 -2.769614C0.508095 -2.769614 0.518057 -2.779577 0.577833 -2.998755C0.747198 -3.706102 0.946451 -4.184309 1.305106 -4.184309C1.504359 -4.184309 1.613948 -4.054795 1.613948 -3.726027C1.613948 -3.516812 1.58406 -3.407223 1.454545 -2.889166L0.876712 -0.587796Z" id="g3-110" />
<ns0:path d="M6.56538 -2.291407C6.734745 -2.291407 6.914072 -2.291407 6.914072 -2.49066S6.734745 -2.689913 6.56538 -2.689913H1.175592C1.006227 -2.689913 0.826899 -2.689913 0.826899 -2.49066S1.006227 -2.291407 1.175592 -2.291407H6.56538Z" id="g1-0" />
<ns0:path d="M5.459527 -2.291407C5.628892 -2.291407 5.808219 -2.291407 5.808219 -2.49066S5.628892 -2.689913 5.459527 -2.689913H1.235367C1.354919 -4.024907 2.500623 -4.98132 3.905355 -4.98132H5.459527C5.628892 -4.98132 5.808219 -4.98132 5.808219 -5.180573S5.628892 -5.379826 5.459527 -5.379826H3.88543C2.181818 -5.379826 0.826899 -4.084682 0.826899 -2.49066S2.181818 0.398506 3.88543 0.398506H5.459527C5.628892 0.398506 5.808219 0.398506 5.808219 0.199253S5.628892 0 5.459527 0H3.905355C2.500623 0 1.354919 -0.956413 1.235367 -2.291407H5.459527Z" id="g1-50" />
<ns0:path d="M6.41594 -6.774595H0.388543V-6.306351H1.464508V-0.468244H0.388543V0C0.767123 -0.029888 1.77335 -0.029888 2.211706 -0.029888C2.699875 -0.029888 3.785803 -0.029888 4.224159 0V-0.468244H2.879203V-3.158157H3.377335C4.333748 -3.158157 4.423412 -2.729763 4.423412 -1.992528H4.891656V-4.79203H4.423412C4.423412 -4.054795 4.343711 -3.626401 3.377335 -3.626401H2.879203V-6.306351H4.273973C5.877958 -6.306351 6.107098 -5.539228 6.256538 -4.373599H6.724782L6.41594 -6.774595Z" id="g0-70" />
<ns0:path d="M4.582814 -3.188045C4.582814 -3.985056 4.533001 -4.782067 4.184309 -5.519303C3.726027 -6.475716 2.909091 -6.635118 2.49066 -6.635118C1.892902 -6.635118 1.165629 -6.37609 0.757161 -5.449564C0.438356 -4.762142 0.388543 -3.985056 0.388543 -3.188045C0.388543 -2.440847 0.428394 -1.544209 0.836862 -0.787049C1.265255 0.019925 1.992528 0.219178 2.480697 0.219178C3.01868 0.219178 3.775841 0.009963 4.214197 -0.936488C4.533001 -1.62391 4.582814 -2.400996 4.582814 -3.188045ZM2.480697 0C2.092154 0 1.504359 -0.249066 1.325031 -1.205479C1.215442 -1.803238 1.215442 -2.719801 1.215442 -3.307597C1.215442 -3.945205 1.215442 -4.60274 1.295143 -5.140722C1.484433 -6.326276 2.231631 -6.41594 2.480697 -6.41594C2.809465 -6.41594 3.466999 -6.236613 3.656289 -5.250311C3.755915 -4.692403 3.755915 -3.935243 3.755915 -3.307597C3.755915 -2.560399 3.755915 -1.882939 3.646326 -1.24533C3.496887 -0.298879 2.929016 0 2.480697 0Z" id="g5-48" />
<ns0:path d="M2.929016 -6.37609C2.929016 -6.615193 2.929016 -6.635118 2.699875 -6.635118C2.082192 -5.997509 1.205479 -5.997509 0.886675 -5.997509V-5.688667C1.085928 -5.688667 1.673724 -5.688667 2.191781 -5.947696V-0.787049C2.191781 -0.428394 2.161893 -0.308842 1.265255 -0.308842H0.946451V0C1.295143 -0.029888 2.161893 -0.029888 2.560399 -0.029888S3.825654 -0.029888 4.174346 0V-0.308842H3.855542C2.958904 -0.308842 2.929016 -0.418431 2.929016 -0.787049V-6.37609Z" id="g5-49" />
<ns0:path d="M2.540473 2.49066V2.092154H1.574097V-7.073474H2.540473V-7.47198H1.175592V2.49066H2.540473Z" id="g5-91" />
<ns0:path d="M1.58406 -7.47198H0.219178V-7.073474H1.185554V2.092154H0.219178V2.49066H1.58406V-7.47198Z" id="g5-93" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g5-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-70" />
<ns0:use x="-42.098321" y="-62.037349" ns1:href="#g1-50" />
<ns0:use x="-32.689206" y="-62.037349" ns1:href="#g5-91" />
<ns0:use x="-29.921797" y="-62.037349" ns1:href="#g5-48" />
<ns0:use x="-24.940458" y="-62.037349" ns1:href="#g3-59" />
<ns0:use x="-20.51265" y="-62.037349" ns1:href="#g3-110" />
<ns0:use x="-12.318859" y="-62.037349" ns1:href="#g1-0" />
<ns0:use x="-2.356246" y="-62.037349" ns1:href="#g5-49" />
<ns0:use x="2.625093" y="-62.037349" ns1:href="#g5-93" />
<ns0:use x="5.392502" y="-65.652713" ns1:href="#g4-109" />
<ns0:use x="12.462108" y="-65.652713" ns1:href="#g2-2" />
<ns0:use x="18.688787" y="-65.652713" ns1:href="#g6-51" />
</ns0:g>
</ns0:svg>

View file

@ -1,81 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="25.714616pt" readme2tex:offset="0" version="1.1" viewBox="65.750263 -61.041096 148.907984 25.714616" width="148.907984pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M2.022416 -0.009963C2.022416 -0.667497 1.77335 -1.05604 1.384807 -1.05604C1.05604 -1.05604 0.856787 -0.806974 0.856787 -0.52802C0.856787 -0.259029 1.05604 0 1.384807 0C1.504359 0 1.633873 -0.039851 1.733499 -0.129514C1.763387 -0.14944 1.77335 -0.159402 1.783313 -0.159402S1.803238 -0.14944 1.803238 -0.009963C1.803238 0.727273 1.454545 1.325031 1.125778 1.653798C1.016189 1.763387 1.016189 1.783313 1.016189 1.8132C1.016189 1.882939 1.066002 1.92279 1.115816 1.92279C1.225405 1.92279 2.022416 1.155666 2.022416 -0.009963Z" id="g3-59" />
<ns0:path d="M3.716065 -3.765878C3.536737 -4.134496 3.247821 -4.403487 2.799502 -4.403487C1.633873 -4.403487 0.398506 -2.938979 0.398506 -1.484433C0.398506 -0.547945 0.946451 0.109589 1.723537 0.109589C1.92279 0.109589 2.420922 0.069738 3.01868 -0.637609C3.098381 -0.219178 3.447073 0.109589 3.92528 0.109589C4.273973 0.109589 4.503113 -0.119552 4.662516 -0.438356C4.83188 -0.797011 4.961395 -1.404732 4.961395 -1.424658C4.961395 -1.524284 4.871731 -1.524284 4.841843 -1.524284C4.742217 -1.524284 4.732254 -1.484433 4.702366 -1.344956C4.533001 -0.697385 4.353674 -0.109589 3.945205 -0.109589C3.676214 -0.109589 3.646326 -0.368618 3.646326 -0.56787C3.646326 -0.787049 3.666252 -0.86675 3.775841 -1.305106C3.88543 -1.723537 3.905355 -1.823163 3.995019 -2.201743L4.353674 -3.596513C4.423412 -3.875467 4.423412 -3.895392 4.423412 -3.935243C4.423412 -4.104608 4.303861 -4.204234 4.134496 -4.204234C3.895392 -4.204234 3.745953 -3.985056 3.716065 -3.765878ZM3.068493 -1.185554C3.01868 -1.006227 3.01868 -0.986301 2.86924 -0.816936C2.430884 -0.268991 2.022416 -0.109589 1.743462 -0.109589C1.24533 -0.109589 1.105853 -0.657534 1.105853 -1.046077C1.105853 -1.544209 1.424658 -2.769614 1.653798 -3.227895C1.96264 -3.815691 2.410959 -4.184309 2.809465 -4.184309C3.457036 -4.184309 3.596513 -3.367372 3.596513 -3.307597S3.576588 -3.188045 3.566625 -3.138232L3.068493 -1.185554Z" id="g3-97" />
<ns0:path d="M2.371108 -1.92279H2.929016C3.033624 -1.92279 3.038605 -1.927771 3.063512 -1.947696S3.103362 -2.032379 3.103362 -2.062267C3.103362 -2.146949 3.028643 -2.146949 2.94396 -2.146949H2.410959C2.470735 -2.515567 2.570361 -3.148194 2.635118 -3.222914C2.709838 -3.302615 2.789539 -3.342466 2.874222 -3.342466C2.90411 -3.342466 3.013699 -3.342466 3.118306 -3.287671C2.919054 -3.202989 2.919054 -3.023661 2.919054 -3.003736C2.919054 -2.879203 3.013699 -2.799502 3.138232 -2.799502C3.267746 -2.799502 3.447073 -2.909091 3.447073 -3.128269C3.447073 -3.417186 3.118306 -3.511831 2.879203 -3.511831C2.246575 -3.511831 2.122042 -2.909091 2.07721 -2.694894S2.062267 -2.615193 1.977584 -2.146949H1.524284C1.429639 -2.146949 1.349938 -2.146949 1.349938 -2.007472C1.349938 -1.92279 1.424658 -1.92279 1.50934 -1.92279H1.942715C1.84807 -1.43462 1.638854 -0.049813 1.499377 0.478207C1.469489 0.597758 1.349938 0.851806 1.155666 0.851806C1.125778 0.851806 1.016189 0.846824 0.926526 0.801993C1.061021 0.742217 1.125778 0.617684 1.125778 0.513076C1.125778 0.388543 1.031133 0.308842 0.9066 0.308842C0.777086 0.308842 0.597758 0.418431 0.597758 0.637609C0.597758 0.941469 0.956413 1.021171 1.150685 1.021171C1.439601 1.021171 1.65878 0.79203 1.77335 0.637609C1.972603 0.358655 2.087173 -0.303861 2.092154 -0.318804L2.371108 -1.92279Z" id="g5-102" />
<ns0:path d="M3.138232 -1.8132C3.163138 -1.902864 3.163138 -1.912827 3.163138 -1.927771C3.163138 -2.012453 3.098381 -2.102117 2.978829 -2.102117C2.879203 -2.102117 2.769614 -2.032379 2.729763 -1.907846C2.56538 -2.127024 2.351183 -2.201743 2.132005 -2.201743C1.449564 -2.201743 0.747198 -1.554172 0.747198 -0.851806C0.747198 -0.328767 1.145704 0 1.618929 0C1.937733 0 2.206725 -0.174346 2.321295 -0.268991C2.311333 -0.219178 2.221669 0.119552 2.201743 0.204234C2.156912 0.383562 2.122042 0.533001 1.892902 0.692403C1.65878 0.851806 1.439601 0.851806 1.295143 0.851806C1.255293 0.851806 0.891656 0.846824 0.891656 0.816936L0.911582 0.801993C1.001245 0.722291 1.026152 0.612702 1.026152 0.562889C1.026152 0.478207 0.966376 0.358655 0.801993 0.358655C0.64259 0.358655 0.493151 0.498132 0.493151 0.687422C0.493151 1.021171 1.001245 1.021171 1.300125 1.021171C1.982565 1.021171 2.49066 0.79203 2.610212 0.308842L3.138232 -1.8132ZM2.430884 -0.707347C2.410959 -0.627646 2.405978 -0.607721 2.311333 -0.508095C2.127024 -0.323786 1.897883 -0.169365 1.638854 -0.169365C1.444583 -0.169365 1.195517 -0.273973 1.195517 -0.667497C1.195517 -0.861768 1.285181 -1.334994 1.474471 -1.62391C1.608966 -1.843088 1.867995 -2.032379 2.132005 -2.032379C2.545455 -2.032379 2.650062 -1.643836 2.650062 -1.599004C2.650062 -1.589041 2.645081 -1.554172 2.635118 -1.524284L2.430884 -0.707347Z" id="g5-103" />
<ns0:path d="M4.267995 -2.099128C4.267995 -2.956912 3.717061 -3.138232 3.075467 -3.138232C2.231631 -3.138232 1.841096 -2.636115 1.708593 -2.412951V-3.138232L0.446326 -3.082441V-2.691905C0.857783 -2.691905 0.913574 -2.691905 0.913574 -2.419925V-0.390535H0.446326V0C0.4533 0 1.018182 -0.027895 1.352927 -0.027895C1.694645 -0.027895 2.259527 0 2.266501 0V-0.390535H1.799253V-1.736488C1.799253 -2.545455 2.524533 -2.817435 2.942964 -2.817435C3.249813 -2.817435 3.382316 -2.657036 3.382316 -2.154919V-0.390535H2.915068V0C2.922042 0 3.486924 -0.027895 3.821669 -0.027895C4.163387 -0.027895 4.728269 0 4.735243 0V-0.390535H4.267995V-2.099128Z" id="g0-110" />
<ns0:path d="M2.475716 -5.230386C1.150685 -4.29589 0.801993 -2.817435 0.801993 -1.750436C0.801993 -0.767123 1.094894 0.760149 2.475716 1.736488C2.531507 1.736488 2.615193 1.736488 2.615193 1.652802C2.615193 1.610959 2.594271 1.597011 2.545455 1.548194C1.617933 0.711333 1.276214 -0.474222 1.276214 -1.743462C1.276214 -3.626401 1.994521 -4.546949 2.566376 -5.063014C2.594271 -5.090909 2.615193 -5.111831 2.615193 -5.1467C2.615193 -5.230386 2.531507 -5.230386 2.475716 -5.230386Z" id="g7-40" />
<ns0:path d="M0.627646 -5.230386C0.578829 -5.230386 0.495143 -5.230386 0.495143 -5.1467C0.495143 -5.111831 0.516065 -5.090909 0.557908 -5.042092C1.157659 -4.491158 1.827148 -3.549689 1.827148 -1.750436C1.827148 -0.292902 1.373848 0.808966 0.620672 1.492403C0.502117 1.610959 0.495143 1.617933 0.495143 1.652802S0.516065 1.736488 0.585803 1.736488C0.669489 1.736488 1.332005 1.276214 1.792279 0.404483C2.099128 -0.174346 2.30137 -0.927522 2.30137 -1.743462C2.30137 -2.726775 2.008468 -4.254047 0.627646 -5.230386Z" id="g7-41" />
<ns0:path d="M1.583064 -1.743462C1.583064 -1.994521 1.373848 -2.147945 1.185554 -2.147945C0.955417 -2.147945 0.781071 -1.959651 0.781071 -1.750436C0.781071 -1.499377 0.990286 -1.345953 1.17858 -1.345953C1.408717 -1.345953 1.583064 -1.534247 1.583064 -1.743462Z" id="g2-1" />
<ns0:path d="M4.33076 -1.57609C4.442341 -1.57609 4.609714 -1.57609 4.609714 -1.743462C4.609714 -1.917808 4.449315 -1.917808 4.33076 -1.917808H1.101868C1.206476 -2.929016 2.050311 -3.682192 3.138232 -3.682192H4.33076C4.442341 -3.682192 4.609714 -3.682192 4.609714 -3.849564C4.609714 -4.02391 4.449315 -4.02391 4.33076 -4.02391H3.110336C1.8132 -4.02391 0.753176 -3.005729 0.753176 -1.750436C0.753176 -0.467248 1.827148 0.530012 3.110336 0.530012H4.33076C4.442341 0.530012 4.609714 0.530012 4.609714 0.36264C4.609714 0.188294 4.449315 0.188294 4.33076 0.188294H3.138232C2.050311 0.188294 1.206476 -0.564882 1.101868 -1.57609H4.33076Z" id="g2-50" />
<ns0:path d="M1.352927 -4.958406C1.352927 -5.063014 1.352927 -5.230386 1.185554 -5.230386C1.011208 -5.230386 1.011208 -5.069988 1.011208 -4.958406V1.471482C1.011208 1.57609 1.011208 1.743462 1.17858 1.743462C1.352927 1.743462 1.352927 1.583064 1.352927 1.471482V-4.958406Z" id="g2-106" />
<ns0:path d="M1.444583 5.818182C1.444583 5.977584 1.444583 6.1868 1.653798 6.1868C1.872976 6.1868 1.872976 5.987547 1.872976 5.818182V0.159402C1.872976 0 1.872976 -0.209215 1.663761 -0.209215C1.444583 -0.209215 1.444583 -0.009963 1.444583 0.159402V5.818182ZM3.656289 5.818182C3.656289 5.977584 3.656289 6.1868 3.865504 6.1868C4.084682 6.1868 4.084682 5.987547 4.084682 5.818182V0.159402C4.084682 0 4.084682 -0.209215 3.875467 -0.209215C3.656289 -0.209215 3.656289 -0.009963 3.656289 0.159402V5.818182Z" id="g8-13" />
<ns0:path d="M3.706102 -3.247821C3.795766 -3.347447 3.795766 -3.387298 3.795766 -3.407223C3.795766 -3.457036 3.755915 -3.506849 3.726027 -3.5467L1.683686 -6.495641H3.985056C5.668742 -6.495641 6.166874 -6.136986 6.37609 -4.562889H6.625156L6.346202 -6.804483H0.816936C0.577833 -6.804483 0.557908 -6.804483 0.557908 -6.575342L3.038605 -2.968867L0.667497 -0.268991C0.56787 -0.159402 0.56787 -0.139477 0.56787 -0.109589C0.56787 0 0.667497 0 0.816936 0H6.346202L6.625156 -2.351183H6.37609C6.196762 -0.687422 5.519303 -0.418431 3.955168 -0.418431H1.205479L3.706102 -3.247821Z" id="g6-6" />
<ns0:path d="M6.844334 -3.257783C6.993773 -3.257783 7.183064 -3.257783 7.183064 -3.457036S6.993773 -3.656289 6.854296 -3.656289H0.886675C0.747198 -3.656289 0.557908 -3.656289 0.557908 -3.457036S0.747198 -3.257783 0.896638 -3.257783H6.844334ZM6.854296 -1.325031C6.993773 -1.325031 7.183064 -1.325031 7.183064 -1.524284S6.993773 -1.723537 6.844334 -1.723537H0.896638C0.747198 -1.723537 0.557908 -1.723537 0.557908 -1.524284S0.747198 -1.325031 0.886675 -1.325031H6.854296Z" id="g6-61" />
<ns0:path d="M2.433873 -1.562142C2.538481 -1.562142 2.670984 -1.562142 2.670984 -1.694645C2.670984 -1.8132 2.566376 -1.8132 2.433873 -1.8132H1.185554C1.39477 -2.447821 1.84807 -2.75467 2.461768 -2.75467H2.726775C2.838356 -2.75467 2.970859 -2.75467 2.970859 -2.887173C2.970859 -3.005729 2.873225 -3.005729 2.740722 -3.005729H2.440847C1.513325 -3.005729 0.474222 -2.357161 0.474222 -1.297136C0.474222 -0.481196 1.094894 0.069738 1.903861 0.069738C2.113076 0.069738 2.405978 0.034869 2.775592 -0.174346C2.915068 -0.251059 2.929016 -0.27198 2.929016 -0.313823C2.929016 -0.334745 2.929016 -0.4533 2.824408 -0.4533C2.796513 -0.4533 2.782565 -0.446326 2.740722 -0.418431C2.496638 -0.258032 2.203736 -0.125529 1.917808 -0.125529C1.638854 -0.125529 1.060025 -0.265006 1.060025 -1.060025C1.060025 -1.157659 1.060025 -1.297136 1.12279 -1.562142H2.433873Z" id="g4-15" />
<ns0:path d="M1.471482 -0.111582C1.471482 0.27198 1.401743 0.718306 0.927522 1.164633C0.899626 1.192528 0.878705 1.21345 0.878705 1.248319C0.878705 1.297136 0.934496 1.345953 0.976339 1.345953C1.073973 1.345953 1.66675 0.788045 1.66675 -0.041843C1.66675 -0.474222 1.499377 -0.801993 1.17858 -0.801993C0.948443 -0.801993 0.781071 -0.620672 0.781071 -0.404483C0.781071 -0.18132 0.941469 0 1.185554 0C1.352927 0 1.464508 -0.111582 1.471482 -0.111582Z" id="g4-59" />
<ns0:path d="M5.314072 -1.562142C5.397758 -1.603985 5.467497 -1.652802 5.467497 -1.743462C5.467497 -1.855044 5.390785 -1.889913 5.321046 -1.924782L1.066999 -3.975093C0.969365 -4.02391 0.941469 -4.02391 0.927522 -4.02391C0.829888 -4.02391 0.753176 -3.947198 0.753176 -3.849564C0.753176 -3.744956 0.836862 -3.703113 0.899626 -3.675218L4.902615 -1.750436L0.9066 0.174346C0.822914 0.216189 0.753176 0.265006 0.753176 0.355666C0.753176 0.4533 0.829888 0.530012 0.927522 0.530012C0.934496 0.530012 0.969365 0.530012 1.053051 0.488169L5.314072 -1.562142Z" id="g4-62" />
<ns0:path d="M5.816189 -4.002989C5.885928 -4.267995 5.997509 -4.498132 6.555417 -4.51208C6.590286 -4.51208 6.694894 -4.519054 6.694894 -4.665504C6.694894 -4.707347 6.660025 -4.763138 6.590286 -4.763138C6.360149 -4.763138 6.102117 -4.735243 5.865006 -4.735243C5.697634 -4.735243 5.293151 -4.763138 5.125778 -4.763138C5.090909 -4.763138 4.986301 -4.763138 4.986301 -4.609714C4.986301 -4.519054 5.076961 -4.51208 5.139726 -4.51208C5.467497 -4.505106 5.586052 -4.400498 5.586052 -4.226152C5.586052 -4.170361 5.579078 -4.135492 5.558157 -4.05878L4.798007 -1.018182L3.02665 -4.644583C2.970859 -4.763138 2.956912 -4.763138 2.789539 -4.763138H1.834122C1.701619 -4.763138 1.610959 -4.763138 1.610959 -4.609714C1.610959 -4.51208 1.694645 -4.51208 1.841096 -4.51208S2.140971 -4.505106 2.287422 -4.47721L1.352927 -0.746202C1.290162 -0.481196 1.171606 -0.27198 0.627646 -0.251059C0.578829 -0.251059 0.481196 -0.244085 0.481196 -0.104608C0.481196 -0.027895 0.536986 0 0.585803 0C0.81594 0 1.073973 -0.027895 1.311083 -0.027895C1.478456 -0.027895 1.882939 0 2.050311 0C2.12005 0 2.189788 -0.034869 2.189788 -0.146451C2.189788 -0.244085 2.106102 -0.251059 2.02939 -0.251059C1.590037 -0.265006 1.590037 -0.446326 1.590037 -0.54396C1.590037 -0.571856 1.590037 -0.606725 1.617933 -0.718306L2.510585 -4.288917L4.546949 -0.118555C4.60274 -0.006974 4.630635 0 4.700374 0C4.811955 0 4.811955 -0.020922 4.846824 -0.146451L5.816189 -4.002989Z" id="g4-78" />
<ns0:path d="M3.054545 -2.670984C2.803487 -2.629141 2.698879 -2.433873 2.698879 -2.280448C2.698879 -2.092154 2.84533 -2.022416 2.970859 -2.022416C3.124284 -2.022416 3.368369 -2.133998 3.368369 -2.468742C3.368369 -2.942964 2.824408 -3.075467 2.447821 -3.075467C1.401743 -3.075467 0.432379 -2.113076 0.432379 -1.143711C0.432379 -0.54396 0.850809 0.069738 1.72254 0.069738C2.901121 0.069738 3.452055 -0.620672 3.452055 -0.718306C3.452055 -0.760149 3.38929 -0.836862 3.333499 -0.836862C3.291656 -0.836862 3.277709 -0.822914 3.221918 -0.767123C2.677958 -0.125529 1.862017 -0.125529 1.736488 -0.125529C1.234371 -0.125529 1.011208 -0.467248 1.011208 -0.899626C1.011208 -1.101868 1.108842 -1.862017 1.471482 -2.343213C1.736488 -2.684932 2.099128 -2.880199 2.447821 -2.880199C2.545455 -2.880199 2.880199 -2.866252 3.054545 -2.670984Z" id="g4-99" />
<ns0:path d="M2.838356 -2.75467H3.521793C3.66127 -2.75467 3.75193 -2.75467 3.75193 -2.908095C3.75193 -3.005729 3.66127 -3.005729 3.535741 -3.005729H2.887173C3.047572 -3.891407 3.103362 -4.212204 3.159153 -4.414446C3.194022 -4.56787 3.347447 -4.714321 3.514819 -4.714321C3.521793 -4.714321 3.710087 -4.714321 3.84259 -4.630635C3.556663 -4.539975 3.535741 -4.288917 3.535741 -4.247073C3.535741 -4.093649 3.654296 -3.989041 3.814695 -3.989041C4.002989 -3.989041 4.212204 -4.14944 4.212204 -4.414446C4.212204 -4.735243 3.870486 -4.909589 3.514819 -4.909589C3.20797 -4.909589 2.866252 -4.735243 2.677958 -4.38655C2.538481 -4.128518 2.48269 -3.814695 2.336239 -3.005729H1.785305C1.645828 -3.005729 1.555168 -3.005729 1.555168 -2.852304C1.555168 -2.75467 1.645828 -2.75467 1.771357 -2.75467H2.287422C2.280448 -2.712827 1.841096 -0.202242 1.673724 0.54396C1.638854 0.697385 1.520299 1.227397 1.185554 1.227397C1.17858 1.227397 1.011208 1.227397 0.878705 1.143711C1.164633 1.053051 1.185554 0.801993 1.185554 0.760149C1.185554 0.606725 1.066999 0.502117 0.9066 0.502117C0.718306 0.502117 0.509091 0.662516 0.509091 0.927522C0.509091 1.241345 0.836862 1.422665 1.185554 1.422665C1.63188 1.422665 1.93873 0.962391 2.022416 0.808966C2.273474 0.341719 2.433873 -0.516065 2.447821 -0.599751L2.838356 -2.75467Z" id="g4-102" />
<ns0:path d="M3.710087 -2.57335C3.737983 -2.677958 3.737983 -2.712827 3.737983 -2.719801C3.737983 -2.873225 3.612453 -2.942964 3.500872 -2.942964C3.340473 -2.942964 3.20797 -2.810461 3.180075 -2.677958C3.061519 -2.866252 2.824408 -3.075467 2.461768 -3.075467C1.590037 -3.075467 0.676463 -2.140971 0.676463 -1.143711C0.676463 -0.425405 1.164633 0 1.736488 0C2.057285 0 2.364134 -0.160399 2.608219 -0.376588L2.454795 0.251059C2.378082 0.54396 2.329265 0.732254 2.064259 0.969365C1.75741 1.227397 1.457534 1.227397 1.283188 1.227397C0.962391 1.227397 0.871731 1.206476 0.746202 1.17858C0.920548 1.094894 0.969365 0.927522 0.969365 0.829888C0.969365 0.662516 0.836862 0.571856 0.697385 0.571856C0.502117 0.571856 0.299875 0.732254 0.299875 0.99726C0.299875 1.415691 0.899626 1.422665 1.290162 1.422665C2.385056 1.422665 2.852304 0.864757 2.949938 0.467248L3.710087 -2.57335ZM2.747696 -0.927522C2.719801 -0.822914 2.719801 -0.808966 2.601245 -0.669489C2.357161 -0.376588 2.022416 -0.195268 1.75741 -0.195268C1.401743 -0.195268 1.234371 -0.495143 1.234371 -0.857783C1.234371 -1.164633 1.422665 -1.945704 1.603985 -2.252553C1.896887 -2.740722 2.224658 -2.880199 2.461768 -2.880199C2.949938 -2.880199 3.082441 -2.357161 3.082441 -2.287422C3.082441 -2.273474 3.082441 -2.259527 3.061519 -2.182814L2.747696 -0.927522Z" id="g4-103" />
<ns0:path d="M3.724035 -2.531507C3.724035 -3.075467 3.396264 -3.082441 3.375342 -3.082441C3.194022 -3.082441 2.998755 -2.894147 2.998755 -2.712827C2.998755 -2.594271 3.068493 -2.538481 3.11731 -2.496638C3.235866 -2.399004 3.375342 -2.217684 3.375342 -1.93873C3.375342 -1.624907 2.915068 -0.125529 2.085181 -0.125529C1.520299 -0.125529 1.520299 -0.627646 1.520299 -0.746202C1.520299 -1.066999 1.645828 -1.457534 1.903861 -2.106102C1.959651 -2.252553 2.001494 -2.357161 2.001494 -2.475716C2.001494 -2.838356 1.694645 -3.075467 1.338979 -3.075467C0.641594 -3.075467 0.327771 -2.12005 0.327771 -2.008468C0.327771 -1.917808 0.425405 -1.917808 0.446326 -1.917808C0.54396 -1.917808 0.550934 -1.952677 0.571856 -2.02939C0.739228 -2.601245 1.039103 -2.880199 1.318057 -2.880199C1.436613 -2.880199 1.492403 -2.803487 1.492403 -2.636115C1.492403 -2.475716 1.436613 -2.329265 1.366874 -2.168867C1.066999 -1.39477 0.990286 -1.094894 0.990286 -0.843836C0.990286 -0.153425 1.534247 0.069738 2.064259 0.069738C3.235866 0.069738 3.724035 -1.959651 3.724035 -2.531507Z" id="g4-118" />
<ns0:path d="M1.135741 -3.5467V-0.468244H0.448319V0C0.727273 -0.009963 1.325031 -0.029888 1.703611 -0.029888C2.092154 -0.029888 2.67995 -0.009963 2.958904 0V-0.468244H2.271482V-2.550436C2.271482 -3.636364 3.128269 -4.124533 3.755915 -4.124533C4.094645 -4.124533 4.303861 -3.915318 4.303861 -3.158157V-0.468244H3.616438V0C3.895392 -0.009963 4.493151 -0.029888 4.871731 -0.029888C5.260274 -0.029888 5.84807 -0.009963 6.127024 0V-0.468244H5.439601V-3.048568C5.439601 -4.094645 4.901619 -4.483188 3.905355 -4.483188C2.948941 -4.483188 2.420922 -3.915318 2.161893 -3.407223V-4.483188L0.448319 -4.403487V-3.935243C1.066002 -3.935243 1.135741 -3.935243 1.135741 -3.5467Z" id="g1-110" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="65.750263" y="-46.523383" ns1:href="#g1-110" />
<ns0:use x="72.115249" y="-45.029002" ns1:href="#g4-102" />
<ns0:use x="76.352885" y="-45.029002" ns1:href="#g4-59" />
<ns0:use x="78.719026" y="-45.029002" ns1:href="#g4-99" />
<ns0:use x="85.544868" y="-46.523383" ns1:href="#g6-61" />
<ns0:use x="108.326096" y="-54.233301" ns1:href="#g6-6" />
<ns0:use x="115.521356" y="-52.434474" ns1:href="#g4-103" />
<ns0:use x="119.658306" y="-52.434474" ns1:href="#g2-50" />
<ns0:use x="125.027089" y="-52.434474" ns1:href="#g4-78" />
<ns0:use x="132.085355" y="-52.434474" ns1:href="#g7-40" />
<ns0:use x="135.198698" y="-52.434474" ns1:href="#g4-118" />
<ns0:use x="139.434007" y="-52.434474" ns1:href="#g7-41" />
<ns0:use x="143.907985" y="-52.434474" ns1:href="#g2-106" />
<ns0:use x="147.634762" y="-52.434474" ns1:href="#g0-110" />
<ns0:use x="152.643751" y="-51.43821" ns1:href="#g5-103" />
<ns0:use x="156.810437" y="-52.434474" ns1:href="#g2-1" />
<ns0:use x="159.176579" y="-52.434474" ns1:href="#g0-110" />
<ns0:use x="164.185567" y="-51.377327" ns1:href="#g5-102" />
<ns0:use x="168.679168" y="-52.434474" ns1:href="#g4-62" />
<ns0:use x="174.905848" y="-52.434474" ns1:href="#g4-15" />
<ns0:use x="178.724439" y="-54.233301" ns1:href="#g3-97" />
<ns0:use x="183.990593" y="-52.73892" ns1:href="#g4-103" />
<ns0:use x="188.625662" y="-54.233301" ns1:href="#g1-110" />
<ns0:use x="194.990648" y="-52.73892" ns1:href="#g4-103" />
<ns0:rect height="0.398484" width="113.438862" x="97.256462" y="-49.213293" />
<ns0:use x="97.256462" y="-47.619355" ns1:href="#g8-13" />
<ns0:use x="97.256462" y="-41.64171" ns1:href="#g8-13" />
<ns0:use x="102.791279" y="-47.619355" ns1:href="#g8-13" />
<ns0:use x="102.791279" y="-41.64171" ns1:href="#g8-13" />
<ns0:use x="108.326096" y="-39.15105" ns1:href="#g6-6" />
<ns0:use x="115.521356" y="-37.352223" ns1:href="#g4-103" />
<ns0:use x="119.658306" y="-37.352223" ns1:href="#g2-50" />
<ns0:use x="125.027089" y="-37.352223" ns1:href="#g4-78" />
<ns0:use x="132.085355" y="-37.352223" ns1:href="#g7-40" />
<ns0:use x="135.198698" y="-37.352223" ns1:href="#g4-118" />
<ns0:use x="139.434007" y="-37.352223" ns1:href="#g7-41" />
<ns0:use x="143.907985" y="-37.352223" ns1:href="#g2-106" />
<ns0:use x="147.634762" y="-37.352223" ns1:href="#g0-110" />
<ns0:use x="152.643751" y="-36.355959" ns1:href="#g5-103" />
<ns0:use x="156.810437" y="-37.352223" ns1:href="#g2-1" />
<ns0:use x="159.176579" y="-37.352223" ns1:href="#g0-110" />
<ns0:use x="164.185567" y="-36.295076" ns1:href="#g5-102" />
<ns0:use x="168.679168" y="-37.352223" ns1:href="#g4-62" />
<ns0:use x="174.905848" y="-37.352223" ns1:href="#g4-15" />
<ns0:use x="178.724439" y="-39.15105" ns1:href="#g3-97" />
<ns0:use x="183.990593" y="-37.65667" ns1:href="#g4-103" />
<ns0:use x="188.625662" y="-39.15105" ns1:href="#g1-110" />
<ns0:use x="194.990648" y="-37.65667" ns1:href="#g4-103" />
<ns0:use x="199.625717" y="-47.619355" ns1:href="#g8-13" />
<ns0:use x="199.625717" y="-41.64171" ns1:href="#g8-13" />
<ns0:use x="205.160507" y="-47.619355" ns1:href="#g8-13" />
<ns0:use x="205.160507" y="-41.64171" ns1:href="#g8-13" />
<ns0:use x="211.890838" y="-46.523383" ns1:href="#g3-59" />
</ns0:g>
</ns0:svg>

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

View file

@ -1,17 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="16.21924399999999pt" readme2tex:offset="1.494381000000006" version="1.1" viewBox="-52.07469 -70.146971 34.10400299999999 16.21924399999999" width="34.10400299999999pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M1.903861 -2.329265C2.447821 -2.329265 2.838356 -1.952677 2.838356 -1.206476C2.838356 -0.341719 2.336239 -0.083686 1.931756 -0.083686C1.652802 -0.083686 1.039103 -0.160399 0.746202 -0.571856C1.073973 -0.585803 1.150685 -0.81594 1.150685 -0.962391C1.150685 -1.185554 0.983313 -1.345953 0.767123 -1.345953C0.571856 -1.345953 0.376588 -1.227397 0.376588 -0.941469C0.376588 -0.285928 1.101868 0.139477 1.945704 0.139477C2.915068 0.139477 3.584558 -0.509091 3.584558 -1.206476C3.584558 -1.750436 3.138232 -2.294396 2.371108 -2.454795C3.103362 -2.719801 3.368369 -3.242839 3.368369 -3.668244C3.368369 -4.219178 2.733748 -4.630635 1.959651 -4.630635S0.592777 -4.254047 0.592777 -3.696139C0.592777 -3.459029 0.746202 -3.326526 0.955417 -3.326526C1.171606 -3.326526 1.311083 -3.486924 1.311083 -3.682192C1.311083 -3.884433 1.171606 -4.030884 0.955417 -4.044832C1.199502 -4.351681 1.680697 -4.428394 1.93873 -4.428394C2.252553 -4.428394 2.691905 -4.274969 2.691905 -3.668244C2.691905 -3.375342 2.594271 -3.054545 2.412951 -2.838356C2.182814 -2.57335 1.987547 -2.559402 1.638854 -2.538481C1.464508 -2.524533 1.45056 -2.524533 1.415691 -2.517559C1.401743 -2.517559 1.345953 -2.503611 1.345953 -2.426899C1.345953 -2.329265 1.408717 -2.329265 1.527273 -2.329265H1.903861Z" id="g4-51" />
<ns0:path d="M2.259527 -4.358655C2.259527 -4.470237 2.175841 -4.623661 1.980573 -4.623661C1.792279 -4.623661 1.590037 -4.442341 1.590037 -4.2401C1.590037 -4.121544 1.680697 -3.975093 1.868991 -3.975093C2.071233 -3.975093 2.259527 -4.170361 2.259527 -4.358655ZM0.836862 -0.81594C0.808966 -0.72528 0.774097 -0.641594 0.774097 -0.523039C0.774097 -0.195268 1.053051 0.069738 1.436613 0.069738C2.133998 0.069738 2.440847 -0.892653 2.440847 -0.99726C2.440847 -1.08792 2.350187 -1.08792 2.329265 -1.08792C2.231631 -1.08792 2.224658 -1.046077 2.196762 -0.969365C2.036364 -0.411457 1.729514 -0.125529 1.457534 -0.125529C1.318057 -0.125529 1.283188 -0.216189 1.283188 -0.369614C1.283188 -0.530012 1.332005 -0.662516 1.39477 -0.81594C1.464508 -1.004234 1.54122 -1.192528 1.617933 -1.373848C1.680697 -1.54122 1.931756 -2.175841 1.959651 -2.259527C1.980573 -2.329265 2.001494 -2.412951 2.001494 -2.48269C2.001494 -2.810461 1.72254 -3.075467 1.338979 -3.075467C0.648568 -3.075467 0.327771 -2.127024 0.327771 -2.008468C0.327771 -1.917808 0.425405 -1.917808 0.446326 -1.917808C0.54396 -1.917808 0.550934 -1.952677 0.571856 -2.02939C0.753176 -2.629141 1.060025 -2.880199 1.318057 -2.880199C1.429639 -2.880199 1.492403 -2.824408 1.492403 -2.636115C1.492403 -2.475716 1.45056 -2.371108 1.276214 -1.93873L0.836862 -0.81594Z" id="g2-105" />
<ns0:path d="M2.819427 -3.596513V-6.366127H3.995019C5.599004 -6.366127 5.618929 -5.589041 5.618929 -4.98132C5.618929 -4.423412 5.618929 -3.596513 3.975093 -3.596513H2.819427ZM5.479452 -3.387298C6.635118 -3.686177 7.143213 -4.333748 7.143213 -4.991283C7.143213 -5.997509 6.047323 -6.834371 4.174346 -6.834371H0.388543V-6.366127H1.464508V-0.468244H0.388543V0C0.747198 -0.029888 1.723537 -0.029888 2.141968 -0.029888S3.536737 -0.029888 3.895392 0V-0.468244H2.819427V-3.237858H3.985056C4.124533 -3.237858 4.562889 -3.237858 4.871731 -2.899128C5.190535 -2.550436 5.190535 -2.361146 5.190535 -1.633873C5.190535 -0.976339 5.190535 -0.488169 5.88792 -0.14944C6.326276 0.069738 6.94396 0.109589 7.352428 0.109589C8.418431 0.109589 8.547945 -0.787049 8.547945 -0.946451C8.547945 -1.165629 8.408468 -1.165629 8.308842 -1.165629C8.099626 -1.165629 8.089664 -1.066002 8.079701 -0.936488C8.029888 -0.468244 7.740971 -0.249066 7.442092 -0.249066C6.844334 -0.249066 6.75467 -0.956413 6.704857 -1.374844C6.684932 -1.484433 6.60523 -2.171856 6.595268 -2.221669C6.455791 -2.919054 5.907846 -3.227895 5.479452 -3.387298Z" id="g0-82" />
<ns0:path d="M5.041096 -3.745953C5.100872 -3.88543 5.140722 -3.955168 5.778331 -3.955168V-4.423412C5.529265 -4.403487 5.240349 -4.393524 4.991283 -4.393524S4.293898 -4.41345 4.084682 -4.423412V-3.955168C4.273973 -3.955168 4.562889 -3.92528 4.562889 -3.845579C4.562889 -3.835616 4.552927 -3.815691 4.513076 -3.726027L3.35741 -1.235367L2.092154 -3.955168H2.630137V-4.423412C2.30137 -4.403487 1.404732 -4.393524 1.39477 -4.393524C1.115816 -4.393524 0.667497 -4.41345 0.259029 -4.423412V-3.955168H0.896638L2.6401 -0.209215C2.759651 0.039851 2.889166 0.039851 3.01868 0.039851C3.188045 0.039851 3.287671 0.009963 3.387298 -0.199253L5.041096 -3.745953Z" id="g0-118" />
<ns0:path d="M5.459527 -2.291407C5.628892 -2.291407 5.808219 -2.291407 5.808219 -2.49066S5.628892 -2.689913 5.459527 -2.689913H1.235367C1.354919 -4.024907 2.500623 -4.98132 3.905355 -4.98132H5.459527C5.628892 -4.98132 5.808219 -4.98132 5.808219 -5.180573S5.628892 -5.379826 5.459527 -5.379826H3.88543C2.181818 -5.379826 0.826899 -4.084682 0.826899 -2.49066S2.181818 0.398506 3.88543 0.398506H5.459527C5.628892 0.398506 5.808219 0.398506 5.808219 0.199253S5.628892 0 5.459527 0H3.905355C2.500623 0 1.354919 -0.956413 1.235367 -2.291407H5.459527Z" id="g1-50" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g3-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-118" />
<ns0:use x="-46.027953" y="-60.542968" ns1:href="#g2-105" />
<ns0:use x="-39.943774" y="-62.037349" ns1:href="#g1-50" />
<ns0:use x="-30.534659" y="-62.037349" ns1:href="#g0-82" />
<ns0:use x="-21.941928" y="-65.652713" ns1:href="#g4-51" />
</ns0:g>
</ns0:svg>

View file

@ -1,15 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="14.94395999999999pt" readme2tex:offset="2.4906600000000054" version="1.1" viewBox="-52.07469 -69.509329 22.026207999999993 14.94395999999999" width="22.026207999999993pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M7.531756 -5.758406C7.631382 -6.156912 7.81071 -6.465753 8.607721 -6.495641C8.657534 -6.495641 8.777086 -6.505604 8.777086 -6.694894C8.777086 -6.704857 8.777086 -6.804483 8.647572 -6.804483C8.318804 -6.804483 7.970112 -6.774595 7.641345 -6.774595C7.302615 -6.774595 6.953923 -6.804483 6.625156 -6.804483C6.56538 -6.804483 6.445828 -6.804483 6.445828 -6.60523C6.445828 -6.495641 6.545455 -6.495641 6.625156 -6.495641C7.193026 -6.485679 7.302615 -6.276463 7.302615 -6.057285C7.302615 -6.027397 7.28269 -5.877958 7.272727 -5.84807L6.156912 -1.414695L3.955168 -6.615193C3.875467 -6.794521 3.865504 -6.804483 3.636364 -6.804483H2.30137C2.102117 -6.804483 2.012453 -6.804483 2.012453 -6.60523C2.012453 -6.495641 2.102117 -6.495641 2.291407 -6.495641C2.34122 -6.495641 2.968867 -6.495641 2.968867 -6.405978L1.633873 -1.05604C1.534247 -0.657534 1.364882 -0.33873 0.557908 -0.308842C0.498132 -0.308842 0.388543 -0.298879 0.388543 -0.109589C0.388543 -0.039851 0.438356 0 0.518057 0C0.836862 0 1.185554 -0.029888 1.514321 -0.029888C1.853051 -0.029888 2.211706 0 2.540473 0C2.590286 0 2.719801 0 2.719801 -0.199253C2.719801 -0.298879 2.630137 -0.308842 2.520548 -0.308842C1.942715 -0.328767 1.863014 -0.547945 1.863014 -0.747198C1.863014 -0.816936 1.872976 -0.86675 1.902864 -0.976339L3.217933 -6.236613C3.257783 -6.176837 3.257783 -6.156912 3.307597 -6.057285L5.788294 -0.18929C5.858032 -0.019925 5.88792 0 5.977584 0C6.087173 0 6.087173 -0.029888 6.136986 -0.209215L7.531756 -5.758406Z" id="g0-78" />
<ns0:path d="M4.662516 -3.706102C4.662516 -4.244085 4.403487 -4.403487 4.224159 -4.403487C3.975093 -4.403487 3.73599 -4.144458 3.73599 -3.92528C3.73599 -3.795766 3.785803 -3.73599 3.895392 -3.626401C4.104608 -3.427148 4.234122 -3.16812 4.234122 -2.809465C4.234122 -2.391034 3.626401 -0.109589 2.460772 -0.109589C1.952677 -0.109589 1.723537 -0.458281 1.723537 -0.976339C1.723537 -1.534247 1.992528 -2.261519 2.30137 -3.088418C2.371108 -3.257783 2.420922 -3.39726 2.420922 -3.58655C2.420922 -4.034869 2.102117 -4.403487 1.603985 -4.403487C0.667497 -4.403487 0.288917 -2.958904 0.288917 -2.86924C0.288917 -2.769614 0.388543 -2.769614 0.408468 -2.769614C0.508095 -2.769614 0.518057 -2.789539 0.56787 -2.948941C0.856787 -3.955168 1.285181 -4.184309 1.574097 -4.184309C1.653798 -4.184309 1.823163 -4.184309 1.823163 -3.865504C1.823163 -3.616438 1.723537 -3.347447 1.653798 -3.16812C1.215442 -2.012453 1.085928 -1.554172 1.085928 -1.125778C1.085928 -0.049813 1.96264 0.109589 2.420922 0.109589C4.094645 0.109589 4.662516 -3.188045 4.662516 -3.706102Z" id="g0-118" />
<ns0:path d="M3.297634 2.391034C3.297634 2.361146 3.297634 2.34122 3.128269 2.171856C1.882939 0.916563 1.564134 -0.966376 1.564134 -2.49066C1.564134 -4.224159 1.942715 -5.957659 3.16812 -7.202989C3.297634 -7.32254 3.297634 -7.342466 3.297634 -7.372354C3.297634 -7.442092 3.257783 -7.47198 3.198007 -7.47198C3.098381 -7.47198 2.201743 -6.794521 1.613948 -5.529265C1.105853 -4.433375 0.986301 -3.327522 0.986301 -2.49066C0.986301 -1.713574 1.09589 -0.508095 1.643836 0.617684C2.241594 1.843088 3.098381 2.49066 3.198007 2.49066C3.257783 2.49066 3.297634 2.460772 3.297634 2.391034Z" id="g1-40" />
<ns0:path d="M2.879203 -2.49066C2.879203 -3.267746 2.769614 -4.473225 2.221669 -5.599004C1.62391 -6.824408 0.767123 -7.47198 0.667497 -7.47198C0.607721 -7.47198 0.56787 -7.43213 0.56787 -7.372354C0.56787 -7.342466 0.56787 -7.32254 0.757161 -7.143213C1.733499 -6.156912 2.30137 -4.572852 2.30137 -2.49066C2.30137 -0.787049 1.932752 0.966376 0.697385 2.221669C0.56787 2.34122 0.56787 2.361146 0.56787 2.391034C0.56787 2.450809 0.607721 2.49066 0.667497 2.49066C0.767123 2.49066 1.663761 1.8132 2.251557 0.547945C2.759651 -0.547945 2.879203 -1.653798 2.879203 -2.49066Z" id="g1-41" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g1-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-78" />
<ns0:use x="-42.9838" y="-62.037349" ns1:href="#g1-40" />
<ns0:use x="-39.109426" y="-62.037349" ns1:href="#g0-118" />
<ns0:use x="-33.922855" y="-62.037349" ns1:href="#g1-41" />
</ns0:g>
</ns0:svg>

View file

@ -1,11 +0,0 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.w3.org/1999/xlink" height="8.85568400000001pt" readme2tex:offset="1.4943809999999944" version="1.1" viewBox="-52.07469 -66.465191 10.450390999999994 8.85568400000001" width="10.450390999999994pt" xmlns:readme2tex="http://github.com/leegao/readme2tex/">
<ns0:defs>
<ns0:path d="M2.182814 -4.630635C2.189788 -4.644583 2.21071 -4.735243 2.21071 -4.742217C2.21071 -4.777086 2.182814 -4.839851 2.099128 -4.839851C1.959651 -4.839851 1.380822 -4.78406 1.206476 -4.770112C1.150685 -4.763138 1.053051 -4.756164 1.053051 -4.609714C1.053051 -4.51208 1.150685 -4.51208 1.234371 -4.51208C1.569116 -4.51208 1.569116 -4.463263 1.569116 -4.407472C1.569116 -4.358655 1.555168 -4.316812 1.54122 -4.254047L0.557908 -0.306849C0.523039 -0.18132 0.523039 -0.167372 0.523039 -0.153425C0.523039 -0.048817 0.606725 0.069738 0.760149 0.069738C0.948443 0.069738 1.039103 -0.069738 1.080946 -0.223163C1.094894 -0.251059 1.39477 -1.478456 1.422665 -1.57609C1.917808 -1.527273 2.315318 -1.366874 2.315318 -1.004234C2.315318 -0.969365 2.315318 -0.934496 2.30137 -0.864757C2.273474 -0.760149 2.273474 -0.72528 2.273474 -0.648568C2.273474 -0.153425 2.677958 0.069738 3.012702 0.069738C3.689166 0.069738 3.898381 -0.990286 3.898381 -0.99726C3.898381 -1.08792 3.807721 -1.08792 3.7868 -1.08792C3.689166 -1.08792 3.682192 -1.053051 3.647323 -0.920548C3.563636 -0.620672 3.375342 -0.125529 3.033624 -0.125529C2.84533 -0.125529 2.789539 -0.299875 2.789539 -0.488169C2.789539 -0.606725 2.789539 -0.620672 2.831382 -0.801993C2.838356 -0.822914 2.866252 -0.941469 2.866252 -1.018182C2.866252 -1.638854 2.02939 -1.736488 1.736488 -1.75741C1.93873 -1.882939 2.196762 -2.113076 2.315318 -2.217684C2.670984 -2.552428 3.019676 -2.880199 3.410212 -2.880199C3.493898 -2.880199 3.584558 -2.859278 3.640349 -2.789539C3.340473 -2.740722 3.277709 -2.503611 3.277709 -2.399004C3.277709 -2.245579 3.396264 -2.140971 3.556663 -2.140971C3.744956 -2.140971 3.954172 -2.294396 3.954172 -2.587298C3.954172 -2.817435 3.7868 -3.075467 3.417186 -3.075467C3.019676 -3.075467 2.657036 -2.789539 2.30137 -2.461768C2.008468 -2.182814 1.778331 -1.966625 1.492403 -1.84807L2.182814 -4.630635Z" id="g1-107" />
<ns0:path d="M5.041096 -3.745953C5.100872 -3.88543 5.140722 -3.955168 5.778331 -3.955168V-4.423412C5.529265 -4.403487 5.240349 -4.393524 4.991283 -4.393524S4.293898 -4.41345 4.084682 -4.423412V-3.955168C4.273973 -3.955168 4.562889 -3.92528 4.562889 -3.845579C4.562889 -3.835616 4.552927 -3.815691 4.513076 -3.726027L3.35741 -1.235367L2.092154 -3.955168H2.630137V-4.423412C2.30137 -4.403487 1.404732 -4.393524 1.39477 -4.393524C1.115816 -4.393524 0.667497 -4.41345 0.259029 -4.423412V-3.955168H0.896638L2.6401 -0.209215C2.759651 0.039851 2.889166 0.039851 3.01868 0.039851C3.188045 0.039851 3.287671 0.009963 3.387298 -0.199253L5.041096 -3.745953Z" id="g0-118" />
<ns0:path d="M3.317559 -0.757161C3.35741 -0.358655 3.626401 0.059776 4.094645 0.059776C4.303861 0.059776 4.911582 -0.079701 4.911582 -0.886675V-1.444583H4.662516V-0.886675C4.662516 -0.308842 4.41345 -0.249066 4.303861 -0.249066C3.975093 -0.249066 3.935243 -0.697385 3.935243 -0.747198V-2.739726C3.935243 -3.158157 3.935243 -3.5467 3.576588 -3.915318C3.188045 -4.303861 2.689913 -4.463263 2.211706 -4.463263C1.39477 -4.463263 0.707347 -3.995019 0.707347 -3.337484C0.707347 -3.038605 0.9066 -2.86924 1.165629 -2.86924C1.444583 -2.86924 1.62391 -3.068493 1.62391 -3.327522C1.62391 -3.447073 1.574097 -3.775841 1.115816 -3.785803C1.384807 -4.134496 1.872976 -4.244085 2.191781 -4.244085C2.67995 -4.244085 3.247821 -3.855542 3.247821 -2.968867V-2.600249C2.739726 -2.570361 2.042341 -2.540473 1.414695 -2.241594C0.667497 -1.902864 0.418431 -1.384807 0.418431 -0.946451C0.418431 -0.139477 1.384807 0.109589 2.012453 0.109589C2.669988 0.109589 3.128269 -0.288917 3.317559 -0.757161ZM3.247821 -2.391034V-1.39477C3.247821 -0.448319 2.530511 -0.109589 2.082192 -0.109589C1.594022 -0.109589 1.185554 -0.458281 1.185554 -0.956413C1.185554 -1.504359 1.603985 -2.331258 3.247821 -2.391034Z" id="g2-97" />
</ns0:defs>
<ns0:g fill-opacity="0.9" id="page1">
<ns0:use x="-52.07469" y="-62.037349" ns1:href="#g0-118" />
<ns0:use x="-46.027953" y="-60.542968" ns1:href="#g1-107" />
</ns0:g>
</ns0:svg>

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

View file

@ -1,695 +0,0 @@
@font-face {
font-family: octicons-link;
src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff');
}
.markdown-body {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
line-height: 1.5;
color: #24292e;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 16px;
line-height: 1.5;
word-wrap: break-word;
}
.markdown-body .pl-c {
color: #6a737d;
}
.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
color: #005cc5;
}
.markdown-body .pl-e,
.markdown-body .pl-en {
color: #6f42c1;
}
.markdown-body .pl-smi,
.markdown-body .pl-s .pl-s1 {
color: #24292e;
}
.markdown-body .pl-ent {
color: #22863a;
}
.markdown-body .pl-k {
color: #d73a49;
}
.markdown-body .pl-s,
.markdown-body .pl-pds,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sre,
.markdown-body .pl-sr .pl-sra {
color: #032f62;
}
.markdown-body .pl-v,
.markdown-body .pl-smw {
color: #e36209;
}
.markdown-body .pl-bu {
color: #b31d28;
}
.markdown-body .pl-ii {
color: #fafbfc;
background-color: #b31d28;
}
.markdown-body .pl-c2 {
color: #fafbfc;
background-color: #d73a49;
}
.markdown-body .pl-c2::before {
content: "^M";
}
.markdown-body .pl-sr .pl-cce {
font-weight: bold;
color: #22863a;
}
.markdown-body .pl-ml {
color: #735c0f;
}
.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
font-weight: bold;
color: #005cc5;
}
.markdown-body .pl-mi {
font-style: italic;
color: #24292e;
}
.markdown-body .pl-mb {
font-weight: bold;
color: #24292e;
}
.markdown-body .pl-md {
color: #b31d28;
background-color: #ffeef0;
}
.markdown-body .pl-mi1 {
color: #22863a;
background-color: #f0fff4;
}
.markdown-body .pl-mc {
color: #e36209;
background-color: #ffebda;
}
.markdown-body .pl-mi2 {
color: #f6f8fa;
background-color: #005cc5;
}
.markdown-body .pl-mdr {
font-weight: bold;
color: #6f42c1;
}
.markdown-body .pl-ba {
color: #586069;
}
.markdown-body .pl-sg {
color: #959da5;
}
.markdown-body .pl-corl {
text-decoration: underline;
color: #032f62;
}
.markdown-body .octicon {
display: inline-block;
vertical-align: text-top;
fill: currentColor;
}
.markdown-body a {
background-color: transparent;
}
.markdown-body a:active,
.markdown-body a:hover {
outline-width: 0;
}
.markdown-body strong {
font-weight: inherit;
}
.markdown-body strong {
font-weight: bolder;
}
.markdown-body h1 {
font-size: 2em;
margin: 0.67em 0;
}
.markdown-body img {
border-style: none;
}
.markdown-body code,
.markdown-body kbd,
.markdown-body pre {
font-family: monospace, monospace;
font-size: 1em;
}
.markdown-body hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
.markdown-body input {
font: inherit;
margin: 0;
}
.markdown-body input {
overflow: visible;
}
.markdown-body [type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
.markdown-body * {
box-sizing: border-box;
}
.markdown-body input {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
.markdown-body a {
color: #0366d6;
text-decoration: none;
}
.markdown-body a:hover {
text-decoration: underline;
}
.markdown-body strong {
font-weight: 600;
}
.markdown-body hr {
height: 0;
margin: 15px 0;
overflow: hidden;
background: transparent;
border: 0;
border-bottom: 1px solid #dfe2e5;
}
.markdown-body hr::before {
display: table;
content: "";
}
.markdown-body hr::after {
display: table;
clear: both;
content: "";
}
.markdown-body table {
border-spacing: 0;
border-collapse: collapse;
}
.markdown-body td,
.markdown-body th {
padding: 0;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: 0;
margin-bottom: 0;
}
.markdown-body h1 {
font-size: 32px;
font-weight: 600;
}
.markdown-body h2 {
font-size: 24px;
font-weight: 600;
}
.markdown-body h3 {
font-size: 20px;
font-weight: 600;
}
.markdown-body h4 {
font-size: 16px;
font-weight: 600;
}
.markdown-body h5 {
font-size: 14px;
font-weight: 600;
}
.markdown-body h6 {
font-size: 12px;
font-weight: 600;
}
.markdown-body p {
margin-top: 0;
margin-bottom: 10px;
}
.markdown-body blockquote {
margin: 0;
}
.markdown-body ul,
.markdown-body ol {
padding-left: 0;
margin-top: 0;
margin-bottom: 0;
}
.markdown-body ol ol,
.markdown-body ul ol {
list-style-type: lower-roman;
}
.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
list-style-type: lower-alpha;
}
.markdown-body dd {
margin-left: 0;
}
.markdown-body code {
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
}
.markdown-body pre {
margin-top: 0;
margin-bottom: 0;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
}
.markdown-body .octicon {
vertical-align: text-bottom;
}
.markdown-body .pl-0 {
padding-left: 0 !important;
}
.markdown-body .pl-1 {
padding-left: 4px !important;
}
.markdown-body .pl-2 {
padding-left: 8px !important;
}
.markdown-body .pl-3 {
padding-left: 16px !important;
}
.markdown-body .pl-4 {
padding-left: 24px !important;
}
.markdown-body .pl-5 {
padding-left: 32px !important;
}
.markdown-body .pl-6 {
padding-left: 40px !important;
}
.markdown-body::before {
display: table;
content: "";
}
.markdown-body::after {
display: table;
clear: both;
content: "";
}
.markdown-body>*:first-child {
margin-top: 0 !important;
}
.markdown-body>*:last-child {
margin-bottom: 0 !important;
}
.markdown-body a:not([href]) {
color: inherit;
text-decoration: none;
}
.markdown-body .anchor {
float: left;
padding-right: 4px;
margin-left: -20px;
line-height: 1;
}
.markdown-body .anchor:focus {
outline: none;
}
.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre {
margin-top: 0;
margin-bottom: 16px;
}
.markdown-body hr {
height: 0.25em;
padding: 0;
margin: 24px 0;
background-color: #e1e4e8;
border: 0;
}
.markdown-body blockquote {
padding: 0 1em;
color: #6a737d;
border-left: 0.25em solid #dfe2e5;
}
.markdown-body blockquote>:first-child {
margin-top: 0;
}
.markdown-body blockquote>:last-child {
margin-bottom: 0;
}
.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #444d56;
vertical-align: middle;
background-color: #fafbfc;
border: solid 1px #c6cbd1;
border-bottom-color: #959da5;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #959da5;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #1b1f23;
vertical-align: middle;
visibility: hidden;
}
.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
text-decoration: none;
}
.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
visibility: visible;
}
.markdown-body h1 {
padding-bottom: 0.3em;
font-size: 2em;
border-bottom: 1px solid #eaecef;
}
.markdown-body h2 {
padding-bottom: 0.3em;
font-size: 1.5em;
border-bottom: 1px solid #eaecef;
}
.markdown-body h3 {
font-size: 1.25em;
}
.markdown-body h4 {
font-size: 1em;
}
.markdown-body h5 {
font-size: 0.875em;
}
.markdown-body h6 {
font-size: 0.85em;
color: #6a737d;
}
.markdown-body ul,
.markdown-body ol {
padding-left: 2em;
}
.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}
.markdown-body li {
word-wrap: break-all;
}
.markdown-body li>p {
margin-top: 16px;
}
.markdown-body li+li {
margin-top: 0.25em;
}
.markdown-body dl {
padding: 0;
}
.markdown-body dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: 600;
}
.markdown-body dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
.markdown-body table {
display: block;
width: 100%;
overflow: auto;
}
.markdown-body table th {
font-weight: 600;
}
.markdown-body table th,
.markdown-body table td {
padding: 6px 13px;
border: 1px solid #dfe2e5;
}
.markdown-body table tr {
background-color: #fff;
border-top: 1px solid #c6cbd1;
}
.markdown-body table tr:nth-child(2n) {
background-color: #f6f8fa;
}
.markdown-body img {
max-width: 100%;
box-sizing: content-box;
background-color: #fff;
}
.markdown-body img[align=right] {
padding-left: 20px;
}
.markdown-body img[align=left] {
padding-right: 20px;
}
.markdown-body code {
padding: 0.2em 0.4em;
margin: 0;
font-size: 85%;
background-color: rgba(27,31,35,0.05);
border-radius: 3px;
}
.markdown-body pre {
word-wrap: normal;
}
.markdown-body pre>code {
padding: 0;
margin: 0;
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}
.markdown-body .highlight {
margin-bottom: 16px;
}
.markdown-body .highlight pre {
margin-bottom: 0;
word-break: normal;
}
.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f6f8fa;
border-radius: 3px;
}
.markdown-body pre code {
display: inline;
max-width: auto;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}
.markdown-body .full-commit .btn-outline:not(:disabled):hover {
color: #005cc5;
border-color: #005cc5;
}
.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
line-height: 10px;
color: #444d56;
vertical-align: middle;
background-color: #fafbfc;
border: solid 1px #d1d5da;
border-bottom-color: #c6cbd1;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #c6cbd1;
}
.markdown-body :checked+.radio-label {
position: relative;
z-index: 1;
border-color: #0366d6;
}
.markdown-body .task-list-item {
list-style-type: none;
}
.markdown-body .task-list-item+.task-list-item {
margin-top: 3px;
}
.markdown-body .task-list-item input {
margin: 0 0.2em 0.25em -1.6em;
vertical-align: middle;
}
.markdown-body hr {
border-bottom-color: #eee;
}

View file

@ -1,82 +0,0 @@
css: markdown/github-markdown.css
html header: <link rel="stylesheet" href="markdown/github-markdown.css">
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}
@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}
</style>
<article class="markdown-body">
<script type="text/x-mathjax-config">
MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "all"} } });
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<div style="display:none">
$\newcommand{\A}{\mat{A}}$
$\newcommand{\B}{\mat{B}}$
$\newcommand{\C}{\mat{C}}$
$\newcommand{\D}{\mat{D}}$
$\newcommand{\E}{\mat{E}}$
$\newcommand{\F}{\mat{F}}$
$\newcommand{\G}{\mat{G}}$
$\newcommand{\H}{\mat{H}}$
$\newcommand{\I}{\mat{I}}$
$\newcommand{\J}{\mat{J}}$
$\newcommand{\K}{\mat{K}}$
$\newcommand{\L}{\mat{L}}$
$\newcommand{\M}{\mat{M}}$
$\newcommand{\N}{\mat{N}}$
$\newcommand{\One}{\mathbf{1}}$
$\newcommand{\P}{\mat{P}}$
$\newcommand{\Q}{\mat{Q}}$
$\newcommand{\Rot}{\mat{R}}$
$\newcommand{\R}{\mathbb{R}}$
$\newcommand{\S}{\mathcal{S}}$
$\newcommand{\T}{\mat{T}}$
$\newcommand{\U}{\mat{U}}$
$\newcommand{\V}{\mat{V}}$
$\newcommand{\W}{\mat{W}}$
$\newcommand{\X}{\mat{X}}$
$\newcommand{\Y}{\mat{Y}}$
$\newcommand{\argmax}{\mathop{\text{argmax}}}$
$\newcommand{\argmin}{\mathop{\text{argmin}}}$
$\newcommand{\a}{\vec{a}}$
$\newcommand{\b}{\vec{b}}$
$\newcommand{\c}{\vec{c}}$
$\newcommand{\d}{\vec{d}}$
$\newcommand{\e}{\vec{e}}$
$\newcommand{\f}{\vec{f}}$
$\newcommand{\g}{\vec{g}}$
$\newcommand{\mat}[1]{\mathbf{#1}}$
$\newcommand{\min}{\mathop{\text{min}}}$
$\newcommand{\m}{\vec{m}}$
$\newcommand{\n}{\vec{n}}$
$\newcommand{\p}{\vec{p}}$
$\newcommand{\q}{\vec{q}}$
$\newcommand{\r}{\vec{r}}$
$\newcommand{\transpose}{{\mathsf T}}$
$\newcommand{\tr}[1]{\mathop{\text{tr}}{\left(#1\right)}}$
$\newcommand{\s}{\vec{s}}$
$\newcommand{\t}{\vec{t}}$
$\newcommand{\u}{\vec{u}}$
$\newcommand{\vec}[1]{\mathbf{#1}}$
$\newcommand{\x}{\vec{x}}$
$\newcommand{\y}{\vec{y}}$
$\newcommand{\z}{\vec{z}}$
$\newcommand{\0}{\vec{0}}$
$\renewcommand{\v}{\vec{v}}$
<!-- https://github.com/mathjax/MathJax/issues/1766 -->
$\renewcommand{\hat}[1]{\widehat{#1}}$
</div>

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 KiB

Some files were not shown because too many files have changed in this diff Show more